Improving built-in generate command
Posted: Thu May 21, 2015 8:26 am
Hi, we are trying to use our RP board for some projects here as a signal generator, and ended up reworking quite large chunk of that code to provide more useful output. Our interest right now is to generate low-freq pulses of specific duty cycle, but we feel it's been pretty good improvement in general. The improvements made so far:
1. Existing anti-aliasing algorithm was rather naive and cryptic, as it involved bunch of hard-to-make-sense-of parameters that are probably crafted for some specific frequency around few MHz. That resulted in very lousy rise/fall time at lower frequencies, so that generated signal is more like trapezoid than real square wave. The fix was to use real digital LP filter instead with a well defined cut-off frequency. That's been done, and we are now getting consistent rise/fall time of around 15ns in all freq range from DC to max 62.5MHz.
1a. As a nice bonus, you can now request specific upper bandwidth, so for example if you are generating audio signal you can cut it off at 22kHz instead of having harmonics all the way up to 62.5MHz and beyond.
2. No way to generate specific duty cycle for sqr. Appropriate option has been implemented and works fine.
3. No way to add DC offset. Appropriate option has been implemented. Still bit TODO, I've been fooled by the "1 Vpp ==> 4000 DAC counts" comment in the code, it's basically off by the factor of 2 right now. In fact 1Vpp => *8000* DAC counts, from -4000 to 4000, so DC offset of 0.5 Volt is 4000 counts, not 2000.
4. In general the tool was not easy to extend due to rather simplistic parameters parsing code with each parameter taking a specific place. From what I've seen on the forum the previous attempts to improve it just whacked even more positional params, which is getting messier and messier to extend and use. Instead, I've added ability to pass named attribute-value param after signal type, so it's nice and clean, and can scale i.e.:
$ generate 1 2.0 3330.0 sqr dcycle=0.2 bw=22000.0 dcoff=0.12
Still TODO items:
5. synthesize_signal() is rather sub-optimal with regards to the double<->int conversions. Each generated sample goes through few rounding operations and then the code sparingly mixes doubles with ints in expressions etc, which is probably adding some round-off/quantization noise here and there. Instead, it should be (A) either going with integer ops all way down, or (B) just stick with doubles and convert into int once all math is done. That is something I'll be working on tomorrow, probably taking plan B. That should also make code more easy to follow and understand.
6. There is no reason why different kinds of signals be handled differently with regards to the anti-aliasing, so that that new filter code needs to apply to all cases not only sqr.
7. Apart from overall bandwidth limit, it would be nice to have specific control for the rise time/fall time for the sqr/triangle.
8. Add more signal types, e.g. sawtooth, which could be just sub-type of triangle with either rise or fall time = 0. Gotta check what others function gen provide.
9. Updated usage/documentation.
Code is here if somebody wants to test/explore/comment on:
https://github.com/sobomax/RedPitaya
I'm planning to make a pull request once it's been completed.
-Max
1. Existing anti-aliasing algorithm was rather naive and cryptic, as it involved bunch of hard-to-make-sense-of parameters that are probably crafted for some specific frequency around few MHz. That resulted in very lousy rise/fall time at lower frequencies, so that generated signal is more like trapezoid than real square wave. The fix was to use real digital LP filter instead with a well defined cut-off frequency. That's been done, and we are now getting consistent rise/fall time of around 15ns in all freq range from DC to max 62.5MHz.
1a. As a nice bonus, you can now request specific upper bandwidth, so for example if you are generating audio signal you can cut it off at 22kHz instead of having harmonics all the way up to 62.5MHz and beyond.
2. No way to generate specific duty cycle for sqr. Appropriate option has been implemented and works fine.
3. No way to add DC offset. Appropriate option has been implemented. Still bit TODO, I've been fooled by the "1 Vpp ==> 4000 DAC counts" comment in the code, it's basically off by the factor of 2 right now. In fact 1Vpp => *8000* DAC counts, from -4000 to 4000, so DC offset of 0.5 Volt is 4000 counts, not 2000.
4. In general the tool was not easy to extend due to rather simplistic parameters parsing code with each parameter taking a specific place. From what I've seen on the forum the previous attempts to improve it just whacked even more positional params, which is getting messier and messier to extend and use. Instead, I've added ability to pass named attribute-value param after signal type, so it's nice and clean, and can scale i.e.:
$ generate 1 2.0 3330.0 sqr dcycle=0.2 bw=22000.0 dcoff=0.12
Still TODO items:
5. synthesize_signal() is rather sub-optimal with regards to the double<->int conversions. Each generated sample goes through few rounding operations and then the code sparingly mixes doubles with ints in expressions etc, which is probably adding some round-off/quantization noise here and there. Instead, it should be (A) either going with integer ops all way down, or (B) just stick with doubles and convert into int once all math is done. That is something I'll be working on tomorrow, probably taking plan B. That should also make code more easy to follow and understand.
6. There is no reason why different kinds of signals be handled differently with regards to the anti-aliasing, so that that new filter code needs to apply to all cases not only sqr.
7. Apart from overall bandwidth limit, it would be nice to have specific control for the rise time/fall time for the sqr/triangle.
8. Add more signal types, e.g. sawtooth, which could be just sub-type of triangle with either rise or fall time = 0. Gotta check what others function gen provide.
9. Updated usage/documentation.
Code is here if somebody wants to test/explore/comment on:
https://github.com/sobomax/RedPitaya
I'm planning to make a pull request once it's been completed.
-Max