SDR TX - ALL STOP!!! The PCB for this is wrong. I made a stupid number of mistakes when building the TDA7266D device library for Eagle and got the pin numbering wrong!! Project abandoned, see News 6 for replacement QRP RIG
The long awaited design for the SDTTX_BASIC simple SDR 40m transmitter has got to the PCB order stage. I am still not sure of the design, having seen others using a DRV135 (balanced line driver) audio stage...
This follows a careful check of the schematic and of the board layout. See below.
Software
Two pieces of software are used for the SDRTX. One running on the Arduino which is the same as that used for the SDR RX. This generates the IQ modulation signals at 4 x freq and drives the IQ modulator FST3253 chip.
The FST3253 chip is also fed with the four audio phases 0, 90, 180 & 270 degrees.
The audio is generated by the HDSDR.exe program running on my Macbook under the Wine emulator, and output via a Startech DAC. Anyone wanting to do this MUST download and install the file "ExtIO_SRlite.dll" too (see HDSDR page, download under "Softrock Lite v0.12"), put it in the HDSDR folder to enable the HDSDR program to enter Transmit mode (SPACE bar, use RETURN key to send morse code in CW mode).
Code
// My_SDR_40M // for 40m, with TX/RX control and bandplan display // Si5351 I2C bus // SDA = A4 // SCL = A5 // LCD I2C bus // SDA = A4 // SCL = A5 // ADDR 0x27 or 3F // rotary encoder pins // DT = 2 // CLK = 3 // SW = 4 // I2C, Si5351, LCD and rotary Encoder libraries #include "Wire.h" #include "si5351.h" #include "LiquidCrystal_I2C.h" #include "Rotary.h" // LCD #define LCDADDR 0x27 #define LCDCOLS 16 #define LCDROWS 2 // rotary Encoder pins 2 & 3 (DT & CLK), step change pin 4 (SW) #define DT 2 #define CLK 3 #define SW 4 // Rx & Tx signals #define RX 13 #define TX 12 #define KEY 8 // number of band plans #define PLANS 12 // dds object Si5351 dds; // LCD object LiquidCrystal_I2C lcd(LCDADDR, LCDCOLS, LCDROWS); // rotary Encoder object Rotary rot = Rotary(DT, CLK); // define plan structure typedef struct { uint32_t lower; uint32_t upper; char alloc[30]; } plan; // band plan array contents cHz/cHz/Text plan bp[PLANS] = { {700000000, 700100000, "CW QRSS 7000.7 "}, {700100000, 703990000, "CW QRP 7030 "}, {703990000, 704690000, "NB WSPR 7040 "}, {704600000, 704990000, "NB Auto "}, {704990000, 705290000, "ALL Auto "}, {705290000, 705990000, "ALL Digital "}, {705990000, 706990000, "ALL "}, {706990000, 707990000, "ALL HELL 7077 "}, {707990000, 709990000, "ALL SSB QRP 7090"}, {709990000, 712990000, "ALL EMGCY 7110 "}, {712990000, 717490000, "ALL SSB CON 7165"}, {717490000, 720010000, "ALL DX INTNL "}, }; uint32_t freq = 700000000; // cHz, start frequency uint32_t step = 10000; // cHz, init 100Hz step void setup() { // init LCD & backlight on lcd.init(); lcd.backlight(); // init dds si5351 module, "0" = default 25MHz XTAL dds.init(SI5351_CRYSTAL_LOAD_8PF, 0); // set 8mA output drive (max possible) dds.drive_strength(SI5351_CLK2, SI5351_DRIVE_8MA); // can insert Si5351 calibration here if required // enable SDR output CLK2, disable CLK0 & 1 dds.output_enable(SI5351_CLK0, 0); dds.output_enable(SI5351_CLK1, 0); dds.output_enable(SI5351_CLK2, 1); // encoder, button, RX, TX, band and KEY pins pinMode(DT, INPUT_PULLUP); pinMode(CLK, INPUT_PULLUP); pinMode(SW, INPUT_PULLUP); pinMode(RX, OUTPUT); pinMode(TX, OUTPUT); pinMode(KEY, INPUT_PULLUP); xmit(digitalRead(KEY)); // set RX|TX, KEY = LOW is TX freqOut(freq); // cHz, output freq dispFreq(4, 0, freq, 1); // display freq kHz col 4 row 0 dispMsg(0, 1, scanPlan()); // display band plan col 0 row 1 } void loop() { // tune? if (tune()) { freqOut(freq); // output freq dispFreq(4, 0, freq, 1); // update freq display dispMsg(0, 1, scanPlan()); // update band plan display } // step? if (button()) { dispStep(step, 14, 0); } xmit(digitalRead(KEY)); // RX|TX } // tune? bool tune() { unsigned char dir; // tuning direction CW/CCW dir = rot.process(); // read encoder if (dir != DIR_NONE) { // turned? if (dir == DIR_CW && (freq < bp[PLANS - 1].upper - step)) freq += step; if (dir == DIR_CCW && (freq >= bp[0].lower + step)) freq -= step; return true; } return false; } // change step? bool button() { if (digitalRead(SW) == LOW) { // button pressed? while (!digitalRead(SW)); // wait for release if (step == 1000000) step = 10000; // reset else step = step * 10; // or increment by x10 return true; } return false; } // search for band info char *scanPlan() { for (int i = 0; i < 15; i++) { if (freq >= bp[i].lower && freq < bp[i].upper) // find plan return bp[i].alloc; // return when found } } // Output Freq for SDR, on CLK2, f cHz void freqOut(uint32_t f) { dds.set_freq(f * 4ULL, 0ULL, SI5351_CLK2); } // Tx/Rx KEY HIGH = RX, LOW = TX void xmit(bool x) { if (x == LOW) // TX { dispMsg(0, 0, "TX "); digitalWrite(RX, HIGH); // Rx off digitalWrite(TX, LOW); // Tx on } else { dispMsg(0, 0, "SDR"); digitalWrite(RX, LOW); // Rx on digitalWrite(TX, HIGH); // Tx off } } // display char msg at col c, row r void dispMsg(uint8_t c, uint8_t r, char *m) { lcd.setCursor(c, r); lcd.print(m); } // display freq in kHz at col c, row r, f cHz, d decimal places void dispFreq(uint8_t c, uint8_t r, uint32_t f, uint8_t d) { lcd.setCursor(c, r); lcd.print((float)f / 100000, d); // convert to float & kHz lcd.print("kHz "); } // display step void dispStep(uint32_t s, byte c, byte r) { switch (s) // display step { case 10000: dispMsg(c, r, " "); break; case 100000: dispMsg(c, r, " +"); break; case 1000000: dispMsg(c, r, "++"); break; } }
The code include RX/TX switching, and so you must ground the Arduino UNO pin 8 for PTT, this pulls D12 low (and D12 high to disable the SDR RX) and enables the FST3253 TX Mixer.
No comments:
Post a Comment