Fortunately, a transmitter is to large extent a receiver operated in reverse - so I hope to re-use a lot of the investment I already have made in developing the code for my receiver in building a transmitter.
Specifically, I plan to share the same IF architecture, with a mix from audio frequency to a parallel pair of IF filters with real-time adjustable bandwidth. One of these filters also implements the 90 degree phase shift of the Hilbert Transform, such that my subsequent mix up to RF using "Tayloe" methods can benefit from side-band cancellation.
Here's my first attempt, in which you can see the Arduino DUE at stage left, with the necessary supporting electronics on a solderless breadboard toward the middle of the photo.
The in-phase and quadrature VFO signals for the mix to RF were derived from the Kanga VFO system (which readers will recall hosts a Kanga / m0xpd DDS Shield which itself features a quadrature clock generator, to derive quadrature signals at a quarter of the DDS Module's square wave output). The "divide by four" and the limited bandwidth of the DDS Module itself imposes a limit of the practicality of this arrangement (to 40 or 30m), as Bill Meara recently reminded me - so I decided to switch to a Si5351-based VFO for further experimentation.
The photo above shows that the RF output is fed to my "Ugly Sudden" PA (because that was literally the first amplifier that I found in the drawer) the output of which was dumped into a dummy load.
Here's my second experiment, now with the quadrature VFO signals coming from an Si5351 (on one of the prototype Kanga / m0xpd / n6qw Si5351 Shields)...
As you can see, I started testing with a (literally) keyed sinewave.
Here's the overall architecture...
Everything on the Arduino DUE (i.e. inside the blue dashed line) is digital signal processing - the remainder is conventional physical electronics. The AF input is mixed up to IF, where it meets the two IF filters. Note that the IF filtering happens in the frequency domain (as denoted by the red background) - there's a Fourier Transform between the green and red areas. The filters are implemented block-wise by fast convolution. If you don't know what that is, don't ask!
The two filters have real-time adjustable bandwidth, as was described here, and validated by measurements here. Further, one of them has the additional 90 degrees phase shift over its pass-band associated with an approximation of the Hilbert Transform.
After Inverse Fourier Transform back into the time domain (at IF), the filter outputs are re-assembled from the block-wise form (using overlap-add) and output from the Ardiuno DUE's DAC channels. These outputs are amplified and passe to a Tayloe mixer, fed from QI VFO signals from the Kanga Si5351 board, to make SSB at the desired RF frequency.
My SDR code is not public domain and is not going to be released in the near future. There is a little description in the slides associated with my 2014 G-QRP Rishworth Mini Convention Presentation "Stretching a Point", but that's all that's going to be disclosed the the moment - so please don't bother asking.
In writing the new extensions to service Tx, the only non-trivial part of coding (over and above what I'd already done for the Rx) was the mix to IF...
The mix currently is implemented in the time domain (the green part of the graphic above). I guess it could be done by shifting the results of the Fourier Transform, but that is probably more computationally intensive. Simply multiplying the input AF signal by a cosine (at the intended "BFO" frequency) works...
however, the cosine function is so slow that - although the mix to IF works - the processor is taking so long doing this that it doesn't have time to complete the rest of the required processing (IF Filtering, IFFT etc) in the available time.
So, I switched to an alternative using modular arithmetic, conveniently available since my IF is at a quarter of my sample frequency (as you saw above)...
where I'd already defined the four possible values of "mix" as follows...
It is only when you come to write all this down on a blog page that the folly of using the word "mix" as a name for an array (when it is also used for the verb meaning "to modulate, multiply or heterodyne") occurs!
The modular arithmetic approach is fast and works well.
Here's a close-up of those physical parts of the system that are not digital signal processing...
which emphasises just how simple this approach is.
For convenience, I also threw together a new piece of code to drive the Kanga Si5351 shield - especially to provide a quadrature VFO output - here's a shot showing that system in operation on 20m (ignore the bottom line - I was actually still in LSB)...
Here I was testing with not just the keyed 600 Hz tone (for CW Tx) but with voice input (actually it was Patrick Malahide reading Chapter 2 of Five Red Herrings - which just happened to be on my computer), which sounded nice on 20m!
So - this works. But you'll notice I called this post "Arduino SDR Tx I", suggesting there might be a part II, II, IV, etc...
In fact there is quite a "to do" list ahead of me - but I can now see a clear path to a stand-alone (i.e. PC-free) HF transceiver based on the Arduino DUE for CW and SSB. I know (because I've already had the Rx code running on an STM32F4 Discovery Board) that this will also run on some other ARM systems, which will offer some interesting opportunities for playing with price and performance.
Exciting times.
...-.- de m0xpd