Wednesday, 21 December 2016

BASIC Tech Group - MyNews 10 - ADF4351 project, LPFs, RF Meter update

Wow! Says Gordon (G4EBF) who is building a 35MHz - 4.4GHz VFO based on the ADF4351, to program this he is learning about the Arduino. Today he says he he has got the Arduino IDE installed on his PC, has configured it, and has loaded his first program to Blink and LED. Well done, that's the way everyone starts with the Arduino, and that's what we did at BARS during the Concept SDR project last year.

I have received a set of LPFs from LanguageSpy and have put the values of the components into LTSpice to see what they yield.

IMG 2980

And this is the response in LTSpice for the 20m filter:

Screen Shot 2016 12 21 at 19 53 57

Screen Shot 2016 12 21 at 19 54 06

Quite a nice response and sharp cut off, with a little bit of ripple in the passband.

I have decided to order their 17m filter and use this in my RFMETER design to filter the Si5351 DDS output and remove higher harmonics. The RFMETER design is now complete.

Screen Shot 2016 12 21 at 19 57 32 Screen Shot 2016 12 21 at 19 57 41

I will be ordering the PCBs (10) very soon.

Tuesday, 20 December 2016

BASIC Tech Group - MyNews 9 - New WSPR sketch 40m

Finished the coding of a new WSPR sketch, based on the WsprMessage.h library written by John Newcombe and used and published by M0XPD.

I built this into a library module that can be included in the Arduino sketch. This sketch uses the LCD display routines of my previous WSPR program, but is simplified as it has a fixed repeat interval for transmission of 2sec and a fixed frequency of 7040.1kHz (the previous sketch allowed a Rotary Encoder input to change the frequency and the repeat interval - an upgrade would be easy to do to implement these features).

IMG 3006

Photo shows the 2 shield stack on top of the Arduino UNO, the DDS and a LPF shield

As usual there is an option to define the LCD I2C address as some displays use 0x27 while others use 0x3F.

The system timing is provide by an RTC (DS3231) module on the Si5351 DDS shield. This can be set by a separate Arduino sketch (at the bottom below) to the correct time, which must be good to 1second.

The code to transmit is also hard coded into the sketch, in my case it is currently "M6KWH IO92 20". The WsprMessage.h library encodes this into 162 elements of value 0, 1, 2 or 3 in the array WSPR_Message{ ].

The WSPR system has a 4 level FSK modulation, with frequencies spaced by 1.4548Hz! This is trick to do, and what this sketch does is to define a frequency shift for each element in an array delta[ ]. The data is the frequency shift of each element to the nearest cHz (0.01Hz) as this is the resolution that can be generated by the Si5351 and the si5351.h library. All frequencies are defined for this library in cHz. So, for example, the variable WSPRFreq = 7040.1kHz is 704010000cHz. All frequency variables are uint64_t size.

The newer LiquidCrystal_I2C.h library is used (from HobbyComponents.com) which has a different set of calls, in particular the initialisation is done with lcd.begin(), not the previous library call lcd.init(). And the new si5351.h library is also used which changed some of the calls to program the SI5351 chip. If you are going to use this code, make sure you Google and use the new version of the libraries.

I have put a Zip file of all these libraries here.

Download the code for WSPR and for RTC time setting

WSPR_40M-Basic

RTCSET-Basic

BASIC Tech Group - MyNews 8 - Update LPF, QRP_RIG & BPFs

A few progress reports on the Arduino projects:

1 - LPFs ordered from languageSpy web site for 40, 30 & 20. Maybe incorporated into the buffer amplifier using an ERA-2+ MMIC, on the antenna bridge and/or RF Meter shield designs...

2 - PCB design for the QRP-RIG i done, awaiting checking carefully..

Screen Shot 2016 12 20 at 11 26 55

3 - Band pass filters designed for BPF shield, 40, 30 & 20m, 2MHz BW Chev 0.1dB ripple.

Screen Shot 2016 12 20 at 11 19 12

Screen Shot 2016 12 20 at 11 20 25

Screen Shot 2016 12 20 at 11 25 55

More news coming when QRP-RIG & RF METER PCBs finalised and ordered.

Slides of current BASIC Arduino projects is here.

Monday, 12 December 2016

BASIC Tech Group - MyNews 7 - Harmonics from Si5351 DDS?

Using a Si5351 module from Adafruit (Kanga) as a VFO for my Direct conversion RX and for my WSPR TX.

The WSPR TX is transmitting on 7040.1kHz with the "M6KWH IO92 20" message..

IMG 0479

I have the RX connected to my Macbook via a Startech A/D convertor running at 48kHz sample rate. The on the Macbook I ran two programs, Argo.exe a Windows program running un Wine emulator, and WSPR program native to the Mac.

These are what the two prgrams show when the RX is tuned to 7038.6kHz.

Screen Shot 2016 12 12 at 12 51 33

and

Screen Shot 2016 12 12 at 13 53 40

What you can see here is that a lot of harmonics or side lobes are being received. I don't know if these are being transmitted by the WSPR TX or if they are spurious reception by the RX. What I get on the WSPR readout is two IDs, one at the nominal 7040.1 frequency (at 100 on the scale) and another which is 100Hz above. These two and others can be seen on the Argo screen.

I have tried all sorts of software changes but not found the cause...

Monday, 28 November 2016

BASIC Tech Group - MyNews 6 - WSPR reception using DCRX

Wonderful day today for WSPR reception on 40m, mainly from PA & DL.

Screen Shot 2016 11 28 at 14 59 00

This is again using the set up of Arduino UNO, Concept DDS, and DCRX receiver. With a squatty small vertical indoor aerial.

SDRTX abandoned - now to be a QRP TXRX RIG

I have re-thought the SDRTX and decided to try for a more ambitious full QRP rig, a single board (shield) with an SDR RX and SDR TX on it, output around 10mW. This will be topped off with a three band BPF shield to work on 40, 30 & 20m.



Screen Shot 2016 11 28 at 15 10 42 Components researched and found for this are the FST3253 for the Mixers, and the SSM2135 dual op-amp for the audio side. This device is a new find for me and is a kind of super op-amp with very high output drive capability needed for the TX driver (4 channels into 50R loads).

Schematic later and PCB layout when ready. WIll probably breadboard the TX first as not yet got one running...

Decided also to move across to SMA connectors, these are much lighter but can handle up to 20W! and plentifull low cost cables are on eBay (SMA-SMA, SMA-BNC, SMA-PL59...).

Saturday, 12 November 2016

BASIC Tech Group - MyNews 5 - Arduino Sketches & libraries

New initiative

At the Banbury Amateur Radio Society we are starting a group to play with technology for Amateur Radio, we call it the BASIC Tech Group.

IMG 0459

The aim is to bring together people interested in building equipment and tools for Amateur Radio, and cooperating to get them done. I will post things of possible interest here.

First here are some interesting Arduino Sketches:

Sketches

CAP-Basic - a capacitance measurement sketch

FREQ-Basic - a frequency measurement sketch, needs an external divide by 10, CMOS 4017

I2CSCAN - a popular public program to scan the I2C bus (Arduino UNO pins A4 SDA and A5 SCL) and report any I2C addresses found

RFMETER - using an external circuit of a 20dB attenuator feeding an AD8307 IC, input on pin A0, with Arduino AREF connected to 3.3V

RTCSET-Basic - this allows you to set the date/time on the DS3231 IC on our DDS Arduino Shield.

SDR_40M-Basic - generates 40m I/Q signals from our DDS Arduino Shield to drive a Tayloe style detector

VFO-Basic - a general purpose VFO with output from 10kHz to 250MHz based on our DDS Arduino Shield using the Si5351 synthesiser. The output gives about 1Vrms into 100R load

VFO-Basic-4 - a version of the above that uses a 4 line 20x4 display, the top line showing date & time from the DDS Shield RTC.

libraries

You will need some Arduino BASIC-libraries to run these sketches, a whole bunch of libraries I have collected is here. Take care using the new LiquidCrystal_I2C library, HobbyComponents have posted a changed: the "init" routine, it is now called "begin".

The hardware projects have been posted before on this blog.

Tuesday, 8 November 2016

BASIC Tech Group - MyNews 4 - SDR TX

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.

Screen Shot 2016 11 08 at 15 15 56

Screen Shot 2016 11 08 at 15 16 05

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.