Tuesday 18 February 2014

Starting thoughts for an Arduino based SDR

Humming about in my mind for some time has been an Arduino based SDR. A few things have come together to at least create a schematic of how it would look.

2014 03 06 11 02 26

On the left is a balanced mixer. This circuit is very interesting as it works both ways. An input from the antenna goes to the SDR Tayloe detector, on the other hand a signal from the Tayloe circuit (for transmitting!) will go out to the antenna. The JFETs used can provide 0.2-0.5W output.

The Tayloe detector uses the FET switch FST3253, which is very common in SDR designs. The I & Q (in-phase and quadrature) signals for the detector switching are generated by the Arduino Uno - more about that below.

The outputs 1B... of the FST3253 go to the summing capacitors of 470nF and the op-amps which provide the audio output. The balanced mixer runs from the Ardunio 3V3 supply, as do the bias to the op-amps (on the +ve inputs). The FST3253 and op-amps run on the Arduino 5V supply.

Arduino Side

The Arduino has to do two things, generate the I & Q signals in quadrature, and drive the DDS AD9850 VFO. A previous post showed how to connect and drive the VFO. So here is the other bit for the I & Q signals.

The chip on my Arduino Uno is the ATmega328. This has three Timers (0, 1 & 2) but no output circuitry to generate quadrature signals (a sad omission on the part of the chip designers...). But in this configuration different signals could be used, generated either by an external counter or directly from the Arduino... which works is to found out when I build it!

So what I do is to set up one of the timers (Timer0) to generate two square waves. One with twice the frequency of the other. Like this:

Screen Shot 2014 02 18 at 12 33 36

To do this you need to understand the complexities of the timers. Timer0 is an 8-bit register which counts up at the clock frequency of 16MHz. Every time is resets it toggles the output signal OC0A which comes out of pin D6 of the Arduino Uno board. The count at which is resets can be set by a value in the OCR0A register. So putting a value of 32 in OCR0A will make it count up to 32 then reset. Thus generating a signal on pin 6.

There is a second separate compare register called OCR0B which can be set up in a mode such that it gets set on the counter reset, and cleared when the count in the OCR0B register is reached. This OC0B signal is then output on pin 5 of the Arduino Uno board. If the OCR0B register is loaded with the value 16 (32/2), then the OC0B signal will be twice the frequency of the OC0A signal as you can see in the diagram.

Other values can be tried for OCR0A & B registers. This has yet to be tried and checked.

The FT3253 can be driven either from a counter, or maybe directly from the two signals from the Arduino...

The snippet of Arduino code to set up Timer0 and generate these signals is:

// Using Timer0, Fast PWM mode
// WGM = 111, mode 7
// COM0A = 01, toggle on match, with WGM02 = 1
// COM0B = 10, clear output OC0B on match, set at BOTTOM
// CS0 = 001, no pre-scale /1
// OCR0A = 32, OCR0B = 16, 50% duty

// includes and object definitions go here

void setup()
{
  pinMode(5, OUTPUT); // OC0B
  pinMode(6, OUTPUT); // OC0A
  // could use DDRD = DDRD | B01100000; i.e. bits 5 & 6 of PORTD OUTPUTS

  // any other setup code goes here

  TCCR0A = 0; // init registers, set all bits to 0
  TCCR0B = 0;

  // set TCCR0A
  // 7        6        5        4        3        2        1        0
  // COMP0A1  COMPA0   COMPB1   COMPB0   -        -        WGM01    WGM00 
  //    0        1       1        0      0        0          1       1    
  // set OC0A on match: COM0A1 = 1, COM0A0 = 1
  // set Fast PWM: WGM01 = 1, WGM00 = 1

  TCCR0A = (1 << COM0A0) | (1 << COM0B1) | (1 << WGM01) | (1 << WGM00);



  // set TCCR0B
  // 7        6        5        4        3        2        1        0
  // FOC0A    FOC0B    -        -        WGM02    CS02     CS01     CS00 
  //   0        0      0        0          1        0        0        1
  //prescale CS02 = 0, CS01 = 0, CS00 = 1, and Fast PWM WGN02 = 1

  TCCR0B = (1 << WGM02) | (1 << CS00);

  OCR0A = 32;
  OCR0B = 16;
}

void loop()
{
 // code for AD9850 goes here
}


The Transmitter

Instead of pins 1B... of the FST3253 going out to the op-amps, a pair of op-amps are used to input 180 deg phase shifted I & Q audio to these pins, this will then be encoded, mixed in the mixer, and transmitted to the antenna. Voila.

Use an SDR program

The I & Q audio signals can be decoded with an SDR progam, for example DSP Radio for the Mac, this progran can also generate the I & Q signals from the Mac microphone input on transmit.

The only part of the SDR "loop" not yet joined up is the control of the AD9850 VFO by the SDR prorgam. Almost all SDRs use a micro chip with sofware pre-loaded to repond to commends from the SDR software over a USB connection. But so far I have not found out how this works...

No comments: