Friday 27 November 2015

New BPFs

Trolling around the web I found a new configuration for BPFs. A couple of coils and three capacitors make a rather good response. Here's the design, simulated in LTSpice, for 20m and 40m.

20m

20mf

40m

40mf



These could be good for both RX and TX, the skirts are narrow and the central loss is zero.

Tuesday 24 November 2015

Low Pass filter, SWR and TXRX switch

I have completed the PCB for the LowPass FIlter, SWR and TXRX switching for the Concept SDR system. The SWR part is based on the design and kit from Kits and Parts. Note that it uses FT37-43 cores which have a much higher Al than the T37-6 of the LPF, the inductance of the 10t windings is 44uH to make the broadband transformers. Have a look at the kit also to see how they are mounted and wired.

This is the schematic:

Screen Shot 2015 11 24 at 14 10 40 And here is the board, the PA input is top right. The links on the board at the left allow you to connect directly to the G0 output of the VFO (for example for direct WSPR transmissions) or the TX shield output (TX shield yet to be made...):

Photo 11 24 2015 14 07 05

This is the stack of Arduino Uno, VFO & RTC, SDR RX and the new LPF & SWR & TXRX switch shields:

Photo 11 24 2015 14 07 34



This is the LPF_SWR_40M shield mounted on a VFO_RTC_IQ shield to form a WSPR beacon:

Photo 11 26 2015 16 05 34

Note the wire link bottom left to connect the VFO G0 output to the LPF input.

Monday 23 November 2015

How about an FPGA Arduino compatible SDR?

I have been fascinated recently with a new PCB that has been announced - the FleaFPGA:

Screen Shot 2015 11 23 at 11 18 57

I am dreaming of an SDR based on the FPGA, but I have no idea how to go about it. If there is anyone out there interested to investigate this let me know, antonywatts at me dot com.

Unfortunately all the development software runs on Windows 7-8, and I have only Macs, so that would present a problem!

Thursday 19 November 2015

Desktop WSPR

Just to see if my software works, I am sending WSPR messages across my desktop! I cannot send them out into the ether as I do not have a LPF on the transmitter/VFO and there are tons of harmonics at the moment. Anyway the VFO output is only a few milliwatts, so I don't think I would get far with my small stick aerial.

Here's the set up. The transmitter is an Arduino Uno with the VFO shield (described previously) mounted on top, I have a 6" piece of wire as an antenna on output "G0". The receiver is also an Arduino Uno with another VFO shield and the SDR shield on top. The antenna is a, very inefficient, Wonder-Wand.

IMG 5219

iMac running both HDSDR receiver software, Soundflower to send the audio across to WSPR software. HDSDR is running under Wine on the Mac as it is a Windows program, WSPR is native to OSX.

IMG 5220

This is the transmitter LCD display. The code being sent, hardcoded into the Arduino sketch, is shown at the top (Call, Locator, Power). The Interval between sends is 2 min shown bottom left, this can be changed by pushing the encoder button to 4, 6, or 8 min. The frequency of the transmission is set to 7040.100, but can be tuned in 10Hz steps by the encoder.

IMG 5222
And the SDR receiver display. This show the time at the top, the SDR centre frequency and the 40m band plan for this frequency at the bottom.

IMG 5223

The Screen shots of HDSDR and WSPR. HDSDR is tuned to 7038.600 to have an output of 1500Hz from the received WSPR signal. This is fed to the WSPR program and should display at "100" on the scale. As you can see either the transmitter or SDR are about 50Hz off frequency - neither has been calibrated.

Screen Shot 2015 11 17 at 12 21 02

Screen Shot 2015 11 17 at 12 20 40

Fun and it works, which at least shows the software on both the TX and SDR Arduino is OK.

Tuesday 10 November 2015

New Concept SDR User Manual

Here is a user manual for the Concept SDR, CONCEPT MANUAL

Work in progess:

- A Direct Conversion RX, PCB assembled, some solder blobs to cure...

- A LPF + SWR + TXRX Switch, built and working, see future posting

- A TX, PCB to be designed

More new later...

Saturday 31 October 2015

Have a deeper look at Tayloe SDR

I have taken a couple of days to put together a closer look at an RXTX using the Tayloe detector design.

The PDF can be downloaded here TAYLOE DETECTOR

This QRP RXTX has not yet been implemented on an Arduino shield, it will be a tight squeeze, but I will attempt the PCB layout in the next few weeks. And if all goes well fabricate the design early next year.

The Low Pass Filter is already in production.

Saturday 17 October 2015

Antenna Analyser

An antenna analyser is just a simple bridge circuit. A signal source drives the bridge, and the sensing is made between the centre of the 2 x 50 ohm resistor side and a 50ohm resistor and antenna on the other side. This yields two signals, FORWARD and REVERSE.

VSWR = (FWD - REV)/(FWD + REV).

PWR = (FWD * 2) ^ 2 / 50

Using a clever IC, the MCP6002, which is a a rail-to-rail op-amp, amplifies the output from the bridge, so that low power from the VFO shield (see previous postings) can be used to drive it. The frequency is tuned by the Rotary Encoder connected to the VFO and the LCD, also connected to the VFO shield, displays the results.

CIRCUIT

Screen Shot 2015 10 17 at 20 27 24

A similar circuit, with RF input from your TX can make a very good resistor SWR/PWR meter. But in this case the gain and signals to the op-amps must be attenuated to keep the outputs below 5V for the Arduino A/D converters on A0 & A1.

Note:

1W = +30dBm = 7.1V

2W = +33dBm = 10V

10W = +40dBm = 22.5V

Friday 9 October 2015

Concept - The Next Steps

So where do we go from here? I have decided to split the Concept program in two parts:

1. A Concept program for beginners

2. A development of the current program towards a complete Transceiver.

Beginners

For beginners a more simple pair of shields will allow them to build a receiver and, most importantly, learn basic coding of Arduino Sketches. The existing VFO Shield can be simplified by not including the Real Time Cock module, A low cost 16 x 2 line LCD can be used, and a new Direct Conversion receiver shield can be designed and added.

A new, simplified sketch will provide just the VFO tuning for the 40m Band.

This is the new DCRX:

DCRX sch
It uses one of the most common circuits for a simple DC RX, using a balanced mixer followed by an audio amplifier. The circuit has been copied and emulated many times. What I have tried to do here is to simplify it to the most, both for the mixer stage (SA612 or SA602 device) with a band pass input filter, and direct push-pull output to the audio amplifier. And a simple audio stage using the LM386. The LM386 includes input resistors so no external one are needed, and its gain can be adjusted by feed back - giving a gain of x1 -200 - so here an external 5K pot is used as a volume control. This is the board out:

DCRX brd

The beginners VFO software sketch has not yet been written, but will be published when the DC RX prototype is built. It will be "modular" so that beginners can follow how it is made up of the various functions.

Extending Concept

To extend the Concept full program further shields are being designed:

1. A Low Pass Filter with built-in SWR metering - with display on the LCD screen.

2. A Transmitter shield, using SDR techniques to output all modes LSB/USB, CW etc under software control. This transmitter shield will have a very low output, in theoriser of 5mW, so will required a PA to build a full QRP rig.

3. A PA with input at 5mW and output of 2-5W (it is yet to determine how to absorb the heat generated in the output stage.

All of these three developments have been drafted and are included below, the LPF_SWR shield is in prototyping right now.

LPF SWR 40M

TX

PA

More about these designs to come.

Wednesday 7 October 2015

Concept Session 7 - SDR Build

The final session of the Concept program (for now... we may build a LPF, TX and PA in the future) is the build of the SDR shield. The PCB for this shield is a little bit more complicated than the VFO and include one SMD to be mounted.

Concept S7 SDR kit 006

As mentioned in the last posting two toroid colds have to be wound:

Concept S7 SDR kit 007

These are a single coil of 37 turns on a T30-6 toroid (4.2uH) and a tri-filar coil of 10 turns on a T30-6 toroid (0.35uH).

Build sequence

The first component to mount is the FST3253 CMOS switch SMD device. Take a look back at the instructions in the VFO Build session to help with this step. Be sure to get the orientation of the part correct, pin 1 & 16 at the TOP.

Concept S7 SDR kit 009

Concept S7 SDR kit 010

Concept S7 SDR kit 011

Concept S7 SDR kit 012

Concept S7 SDR kit 013

Concept S7 SDR kit 014

Concept S7 SDR kit 015

Connect up and testing

Connect your LCD display and rotary encoder to the VFO shield, plug the SDR shield in above it and connect the audio cable to your PC or USB A-to-D convertor. Then connect an aerial to the RFbus pins RX and RXGND. Many users have preferred to use a larger display of 20 x 4 lines and the sketch below is for this display. Load and run it. Start the SDR program HDSDR on your PC and chose the correct sound put source. Then hit the START button and your SDR should be on the air!

Concept S7 SDR kit 017

Code

NOTE: not all LCD displays have the same I2C address, check your and change "0x27" in the code to your CLDs address (e.g. 0x3F is a common alternative).

// My_SDR_40M_4
// 20 x 4 display
// for 40m, with TX/RX control and bandplan display
// Si5351 I2C bus
// SDA = A4
// SCL = A5
// LCD I2C bus
// SDA = A4
// SCL = A5
// 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"

// RTC I2C address
#define RTCADDR 0x68

// LCD
#define LCDADDR 0x27
#define LCDCOLS 20
#define LCDROWS 4

// 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    PSK31 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      "},
};

// start freq & step
uint32_t freq = 700000000; // cHz, start frequency
uint32_t step = 10000; // cHz, init 100Hz step

// RTC time and date
byte Second, prevSecond, Minute, Hour, DoW, Date, prevDate, Month, Year;

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
  getRTC(); // get time

  freqOut(freq); // cHz, output freq

  dispDate(0, 0);
  dispTime(12, 0);
  dispFreq(6, 2, freq, 1); // display freq kHz col 4 row 2
  dispMsg(0, 3, scanPlan()); // display band plan col 0 row 3
}

void loop() {
  getRTC(); // get time
  if (Date != prevDate) {
    dispDate(0, 0);
    prevDate = Date;
  }
  if (Second != prevSecond) {
    dispTime(12, 0); // display it, if changed
    prevSecond = Second;
  }

  // tune?
  if (tune()) {
    freqOut(freq); // output freq
    dispFreq(6, 2, freq, 1); // update freq display
    dispMsg(0, 3, scanPlan()); // update band plan display
  }

  // step?
  if (button()) {
    dispStep(step, 17, 2);
  }
  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, 2, "TX ");
    digitalWrite(RX, HIGH); // Rx off
    digitalWrite(TX, LOW); // Tx on
  }
  else
  {
    dispMsg(0, 2, "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);
}

// get time from RTC, convert bcd to decimal
void getRTC() {
  // Reset the RTC register pointer
  Wire.beginTransmission(RTCADDR);
  byte zero = 0x00;
  Wire.write(zero);
  Wire.endTransmission();

  // request 7 bytes from the RTC address
  Wire.requestFrom(RTCADDR, 7);

  // get the time data
  Second = bcdToDec(Wire.read()); // 0 - 59
  Minute = bcdToDec(Wire.read()); // 0 - 59
  Hour = bcdToDec(Wire.read() & 0b111111); // mask 12/24 bit
  DoW = bcdToDec(Wire.read()); //0 - 6 = Sunday - Saturday
  Date = bcdToDec(Wire.read()); // 1 - 31
  Month = bcdToDec(Wire.read()); // 0 = jan
  Year = bcdToDec(Wire.read()); // 20xx
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val) {
  return ( (val / 16 * 10) + (val % 16) );
}

// 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;
  }
}


// display date and time
void dispDate(byte c, byte r) {
  lcd.setCursor(c, r);
  switch (DoW) {
    case 1:
      lcd.print("Mon");
      break;
    case 2:
      lcd.print("Tue");
      break;
    case 3:
      lcd.print("Wed");
      break;
    case 4:
      lcd.print("Thu");
      break;
    case 5:
      lcd.print("Fri");
      break;
    case 6:
      lcd.print("Sat");
      break;
    case 7:
      lcd.print("Sun");
      break;
  }

  lcd.print(" ");
  lcd.print(Date);

  lcd.print(" ");
  switch (Month)
  {
    case 1:
      lcd.print("Jan");
      break;
    case 2:
      lcd.print("Feb");
      break;
    case 3:
      lcd.print("Mar");
      break;
    case 4:
      lcd.print("Apr");
      break;
    case 5:
      lcd.print("May");
      break;
    case 6:
      lcd.print("Jun");
      break;
    case 7:
      lcd.print("Jul");
      break;
    case 8:
      lcd.print("Aug");
      break;
    case 9:
      lcd.print("Sep");
      break;
    case 10:
      lcd.print("Oct");
      break;
    case 11:
      lcd.print("Nov");
      break;
    case 12:
      lcd.print("Dec");
      break;
  }
}

void dispTime(byte c, byte r) {
  lcd.setCursor(c, r);
  if (Hour < 10)
    lcd.print("0");
  lcd.print(Hour);
  lcd.print(":");
  if (Minute < 10)
    lcd.print("0");
  lcd.print(Minute);
  lcd.print(":");
  if (Second < 10)
    lcd.print("0");
  lcd.print(Second);
}

Concept Session 6 - SDR Design

The next step in building the complete Concept Arduino based SDR receiver is to study and understand the design of the SDR shield. And to install the HDSDR software on your PC and to check the sound card capability of your PC, ready for testing the completed project.

Concept S6 SDRX Design 003

An outline of the SDR shield is:

Concept S6 SDRX Design 004

A good sound card is required for SDR operation. A microphone input level input should feed a A-to-D convertor, preferably running at a 96kHz data rate. This will give a thing range on screen of +/- 48kHz. A data rate of 48kHz is acceptable, but will reduce the tuning range to +/-24kHz. If your PC does not have a suitable sound input or A-to-D convertor then an external one can be used. I recommend the StarTech ICUSBAUDIO2D (search on Amazon) which provides input and output at 96kHz.

Concept S6 SDRX Design 005

The basic configuration of an SDR set-up is

Concept S6 SDRX Design 006

The 3 board Arduino stack - Arduino Uno + VFO + SDR - has two audio outputs that feed the A-to-D convertor. This in turn feeds the signals to the PC HDSDR software (or the DSP Radio software on a Mac). This illustrates the installation of the HDSDR software from www.hdsdr.de or the DSP Radio software from DL2SDR

Concept S6 SDRX Design 007

The HDSDR program looks like this when in operation:

Concept S6 SDRX Design 011

SDR shield design

The complete schematic of the SDR shield is shown below. The circuit is made up of three parts, an input BPF, the Baseband filter CMOS switch and the audio output amplifiers.

Concept S6 SDRX Design 013

In detail:

Concept S6 SDRX Design 014

Concept S6 SDRX Design 015

Concept S6 SDRX Design 018

The Baseband filter is fed with I & Q quadrature signals from the Johnson counter on the VFO shield, These commutate the switch through four positions and switch the incoming RF in four quadrants onto output capacitors, and on to the audio amplifies.

Concept S6 SDRX Design 016

Concept S6 SDRX Design 017

In order to connect the SDR to the PC or A-to-D convertor a short cable is needed:

Concept S6 SDRX Design 020

And before the build, covered in the next posting, two toroid should be wound:

Concept S6 SDRX Design 022

Now you are ready to build and use the SDR receiver.

Thursday 1 October 2015

Concept Session 5 - VFO Build

This session covers the build of the actual VFO PCB shield. The shield carries both the VFO module, a SN74AC74 IQ generator and the RTC module.

Concept S5 VFO kit 003



The build needs a number of tools including a good small-point soldering iron of reasonable wattage (>40W suggested), cutters, tweezers and a lens for SMD mounting.

Concept S5 VFO kit 004

The first thing to do is to mount the SMD device, the SN74AC74. This mounts with the ident at the bottom.

Concept S5 VFO kit 013

Concept S5 VFO kit 014

Next mount the passive components (just three parts).

Concept S5 VFO kit 015

The the two modules Si5351 and RTC.

Concept S5 VFO kit 016

Lastly the headers with connections to the Arduino (2 x 8 & 2 x 6 pin), the RFbus (8 pin) , the Rotary Encoder (5 pin) and the LCD (4 pin).

Concept S5 VFO kit 017

At this point you are ready to test your VFO. Plug it into your Arduino, power it up and load the sketch My_VFO_40M. This will give you a VFO for the 40m band. It will display the frequency and the Band Plan. Pushing the encoder shaft/button will change the tuning steps from 100Hz to 1kHZ to 10kHz and back again.

Final board

VFO Complete