Friday 23 December 2016

BASIC Tech Group - MyNews 12 - All my hardware shieldprojects update

I need a list of where I am with all my projects. So here it is

CONCEPT - 2015

1. DDS & RTC shield. Si5351 DDS, outputs G0 (CLK0), G1 (CLK1) & 74AC74 for I/Q outputs. Eagle SCH & BRD files OK, PCBs made

2. SDR RX shield. FST3251 QSD & TLV6424 Amp. 40m input filter. I/Q inputs from DDS & RTC shield. Eagle SCH & BRD files OK, PCBs made.

BASIC - 2016/7

3. VFO-Simple shield. A 40m Varicap tuned VFO for Intermediate students to build. Eagle SCH & BRD OK, PCBs in production.

4. DCRX shield. NE602/SA612 mixer & LM386 Amp. 40m input filter, input from DDS & RTC. Eagle SCG & BRD OK, PCBs made.

5. DCRX_WIDE shield. NE602/SA612 mixer & LM386 Amp. Wide band 50R input matching. Use external BPF for each band. Eagle SCH & BRD OK. PCBs not made, as PCB above can be used.

6. QRP_RIG_BASIC shield. Complete Rig RX & TX. FST3251 QSD & QSE, SSM2135 for audio ccts. Wide band input, use BPF for band selection. Eagle SCH & BRD OK. PCB in production.

7. RF_METER shield. Input 40dB attenuator, AD8307. Output 20MHz LPF ERA-2SM buffer. Eagle SCH & BRD OK, PCB made

8. RETURN_LOSS shield. Antenna analyser bridge, circuit under development. Proto done, software shaky

9. WSPR_PA. No design done, may use commercial 2W wide band amp driven by DDS & RTC via BPF, need LPF on output? Could use for QRP_RIG if arrange TX/RX switching...

10. BPF_BASIC shield. Design done for 40, 30 & 20m BPF, 2KHZ BW Chev. Eagle SCH &BRD OK. PCB in production. Tested, doesn't work abandoned Replaced by 3xLPF shield

Future

External PA 20-50W to be defined, stand alone with internal PSU & LPFs, maybe Antenna auto tuning?

BASIC Tech Group - MyNews 11 - Final BPF, QRP_RIG & RF METER PCBs

Well I've taken the plunge, or in other words ordered my Christmas present! I have ordered the PCBs for three of my projects. Yes three!

The BPF-Basic - note: this abandoned as doesn't work...

This is a set of three Band Pass Filters for 40, 30 & 20m bands. Intended for use both for the front end for the QRP_RIG TXRX, the DCRX Direct Conversion RX, or any other input/output that needs a BPF on one of the bands.

Screen Shot 2016 12 23 at 10 16 48

Screen Shot 2016 12 23 at 10 16 58

The QRP_RIG-Basic a single board TXRX

This has been on of my long term aims, to build a single board Arduino shield which is an SDR based TX and RX able to work over a wide band of frequencies - is it a broadband design, the working frequency is determined by the DDS input and BPF on the input/output.

Screen Shot 2016 12 23 at 10 17 27

Screen Shot 2016 12 23 at 10 17 43

An RF METER-Basic - schematic updated, see later blog

A sensitive RF Meter with RF output also from the DDS via a LPF and buffer amplifier

This is one of the most useful measurement tools for an amateur shack, able to measure RF inputs, to 50R impedance, from -60dBm to more than +20dBm. And an RF source at around 1-10mW programmable by the Arduino from 100kHz to 20MHz.

Screen Shot 2016 12 23 at 10 18 01

Screen Shot 2016 12 23 at 10 18 11

Let's hope these work first time as the PCB costs are going up as the UK Pound falls - they come from Eurocircuits in Belgium, one fo the few PCB makers that accept Eagle "BRD" file inputs.

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.

Monday 7 November 2016

BASIC Tech Group - MyNews 3 - RF Meter

Here's the RFMETER. Input impedance is 50R, input attenuator of 20dB, max input power 2W. Two line display of dBm, Watts & Volts

Screen Shot 2016 11 07 at 17 53 10

Input is to Arduino Uno pin A0, AREF analog reference is connected to 3.3V.

Code

// RF-Meter,
// input 50R/2W via a pi 20dB attenuator 82R - 240R - 68R
// displays dBm, Watts, Volts. Autoscaling

#include 
#include 

#define LCDADDR 0x3F
#define LCDCOLS 16
#define LCDROWS 2

// Analog input pin
#define DCIN A0
#define AREF 3.3

// intercept (dBm), slope (mw/dB), input impedance, attenuator (dB).
#define INTERCEPT 84.0
#define SLOPE 25.0
#define IMP 50
#define ATTN -20

LiquidCrystal_I2C lcd(LCDADDR, LCDCOLS, LCDROWS);

void setup() {
  lcd.begin();
  lcd.backlight();

  // 3.3V connected to AREF
  analogReference(EXTERNAL);

  lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print("RF METER");
}

void loop() {
  float mV, dBm, mW, V;
  
  // calculations for MV input, dBM, mW, and Volts
  mV = 1000.0 * (float)analogRead(DCIN) * (AREF / 1023);
  dBm = (mV / SLOPE) - INTERCEPT;
  dBm -= ATTN;
  mW = pow(10, (dBm / 10));
  V = sqrt((mW / 1000) * IMP);

  // dBm
  lcd.setCursor(0, 1);
  lcd.print(dBm, 0);
  lcd.print("dBm ");

  // Watts
  if (mW < 1.0) {
    lcd.print(mW * 1000, 0);
    lcd.print("uW ");
  }
  else if (mW < 1000.0) {
    lcd.print(mW, 0);
    lcd.print("mW ");
  }
  else {
    lcd.print(mW / 1000, 1);
    lcd.print("W ");
  }

  // Volts
  if (V < 1.0) {
    lcd.print(V * 1000.0, 0);
    lcd.print("mV  ");
  }
  else {
    lcd.print(V, 1);
    lcd.print("V  ");
  }

  delay(500);
}

float dbmMw(float dbm)
{
  return pow(10, (dbm / 10));
}

Saturday 29 October 2016

BASIC Tech Group - MyNews 2 - Freq Meter

This project has been abandoned as the accuracy is too low

Natively the Arduino UNO can use its timers to count up to around 6MHz. This can be extended up to a more useful 60MHz by using a divide by ten pre-scaler, for example the CD74HC4017 chip.

Here's the schematic for a FREQ_BASIC shield, it uses a 2 line by 16 column I2C Serial LCD display:

Screen Shot 2016 10 29 at 18 07 27

Code

// FREQ-Basic, v2, Input Pin 5

#include 
#include 
#include 

// this LCD has an address of 3F, some others use 27. 16 columns, 2 rows
#define LCDADDR 0x3F
#define LCDCOLS 16
#define LCDROWS 2

// lcd object
LiquidCrystal_I2C lcd(LCDADDR, LCDCOLS, LCDROWS);

// count result, and Arduino crystal correction
unsigned long count;
float freq;
float corr = 0.99852;

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.clear();

  FreqCount.begin(1000);
}

void loop() {
  if (FreqCount.available()) {
    count = FreqCount.read();
    
    lcd.setCursor(3, 0);
    lcd.print("Frequency");
    freq = (float)count * corr / 100000; //
    lcd.setCursor(3, 1);
    lcd.print(freq, 3);
    lcd.print("MHz     ");
  }
}

On test with Arduino Si5351 DDS VFO on the left

IMG 0391

Accuracy is better than +/-500Hz, so not so good for accurate readings or frequency calibration, But OK for a general purpose indicator.

Thursday 6 October 2016

BASIC Tech Group - MyNews 1 - Concept & Basic

VFO-Basic and DCRX-Basic

Last year we made a DDS in the "Concept" program, this provides us with an Arduino shield for frequency synthesis from 100kHz to 250MHz, SDR IQ outputs and a real time clock.

Screen Shot 2016 10 06 at 10 34 07

New BASIC project

The list of possible boards in the project is:

1. VFO - A 40m Basic VFO along the lines of that needed by the Amateur Radio Intermediate course. Introducing a Colpitts serial tuned oscillator with vari-cap tuning and an output buffer stage.

Screen Shot 2016 10 28 at 11 42 24

Eagle files can be downloaded here Schematic, Board.

Screen Shot 2016 10 28 at 11 42 40

2. DCRX - A 40m Basic Direct Conversion Receiver for CW and SSB, based on the world's simplest circuit using the SA612 mixer and LM386 audio amplifier.

Screen Shot 2016 10 06 at 10 24 21

Screen Shot 2016 10 06 at 10 24 46

Eagle files can be downloaded here Schematic, Board

Combined together the VFO and DCRX it makes a simple receiver for 40m, with manual or Arduino software tuning.

Here are the input filter LTSpice simulations:

Screen Shot 2016 11 13 at 21 02 12

Screen Shot 2016 11 13 at 21 02 18

Combined with the DDS frequency synthesiser board of the previous CONCEPT project, instead of using the VFO, the receiver can be tuned to an accurate frequency in the 7MHz band.

Here is the DDS & DCRX in operation, with WSPR signals being received on 40m, with the RX output fed to a Startech ADC running at 16bit/44.1kHz and fed to the WSPR program running on my iMac.

Screen Shot 2016 11 15 at 15 46 51

Screen Shot 2016 11 15 at 15 47 56

IMG 0460

IMG 0461

3. Future projects which are just ideas today and would be developed by members include:

- RFMETER - An RF measurement meter, measuring -80 to +10dBm. Update see later posting for completed design.

- BRIDGE - An Antenna Analyser, basically a 50 ohm bridge that shows the antenna impedance and SWR. RF input from the VFO or DDS

- QRP_RIG - a complete SDR based QRP TX RX

- WSPR PA - a 2W PA for 40, 30, 20m for a WSPR beacon.

- BPF - a switchable 40, 30 20m BPF board that can be used with the RFMETER and QRP_RIG

... and as many other ideas that members have. As an aside have a look at this web site by PY2OHH for a combine measurement system, similar to a combination of our boards stacked on our Arduino UNO. Could give some inspiration.

Thursday 18 August 2016

BBC Micro:bit calls CQ CQ...

There is a new module available for the BBC micro:bit in the MicroPython programming language. This is a speech generating module.

The results are crude, unless you very carefully adjust the message content and speech settings. But it works out of the box.

Here is a short program to call CQ for myself, M6KWH.

Code

# Call CQ M6KWH
from microbit import *
import speech

# init pin0 to 0 to define a level and stop "hum"
pin0.write_digital(0)

message = "C Q! C Q! C Q!   M 6 K W H! calling C Q!"
while True:
    # flash arrow W
    display.show(Image.ARROW_W)
    sleep(500)
    display.clear()
    sleep(500)
    
    # if A pressed, say greetings
    if button_a.was_pressed():
        speech.say(message, speed=80)
        sleep(1000)

Wednesday 17 August 2016

433MHz control of room lighting

The Energenie sockets that are very low cost on Amazon, are controlled by a push button hand-held controller. It outputs codes over a 433.92MHz RF signal, which the sockets receive and respond to.

Each socket has a different code, one for ON and one for OFF.

RX & TX

There are some very low cost 433.92MHz transmitters and receivers on the market (below £2 the pair!). Using the receiver and some Arduino software the codes for your personal sockets can be read from the hand-held controller. Once you know these, a second Arduino program can be used to send these code out using the transmitter, and this will control the sockets.

The software for all this is in a library called "RCSwitch.h" downloadable here. The examples given with this library show how to use it.

Screen Shot 2016 08 17 at 10 41 11

These are the Energenie sockets and their controller. Each socket has to initialised to match a code from the controller, but when this is done the sockets can be controlled from the Arduino and connected transmitter.

Screen Shot 2016 08 17 at 10 51 12

The receiver is on the right and the transmitter to the left. Each has three connections (the OUTput of the receiver is on two connected pins). The receiver is connected to +5V, pin 2 (interrupt 0) and GND when you run the code reading sketch (see RCSwitch Examples). The transmitter is connected to +5V, Arduino pin 10 and GND. The sketch below allows you to type 1/2, 3/4, 5/6 into the Arduino Serial Monitor window and to switch ON or OFF three of the sockets (the code could easily be extended to cover the four sockets, and the ability to switch ON/OFF all the sockets at once. The codes below are for the sockets I bought, you will have to read and substitute your own codes.

Code to read remote codes

// RX_find_code_1
// detects remote RF signals and IDs LOW, HIGH and length
// start program, then push a button on the remote
// reset to re-run the program

// LED pin, RX input pin
 #define LEDPIN 13
 #define RXPIN A0

 //Create an array to store the data
 const int dataSize = 500;
 byte storedData[dataSize];

 // upper and lower thresholds
 const unsigned int upperThreshold = 100;
 const unsigned int lowerThreshold = 80;
 
// maximum length of the signal, length of signal
 int maxSignalLength = 255;
 int dataCounter = 0;

 // start time, end time, read time
 unsigned long startTime = 0;
 unsigned long endTime = 0;
 unsigned long signalDuration = 0;
 
 void setup(){
  Serial.begin(9600);
  pinMode(LEDPIN, OUTPUT);
  
  /* The following code will only run ONCE --------------
  ---Press the reset button on the Arduino to run again-- */
  
  //Wait here until a LOW signal is received
  while(analogRead(RXPIN) < 1) {
      startTime = micros();  //Update start time with every cycle.
  }
  digitalWrite(LEDPIN, HIGH);  //Turn LED ON
  
  //Read and store the rest of the signal into the storedData array
  for(int i = 0; i < dataSize; i = i+2) {
    
    //Identify the length of the LOW signal---------------LOW
    dataCounter = 0; //reset the counter
    while(analogRead(RXPIN) > upperThreshold && dataCounter < maxSignalLength) {
      dataCounter++;
    }
    storedData[i] = dataCounter;
    
    //Identify the length of the HIGH signal---------------HIGH
    dataCounter = 0;//reset the counter
    while(analogRead(RXPIN) < lowerThreshold && dataCounter < maxSignalLength){
      dataCounter++;
    }
    storedData[i+1] = dataCounter;
    
    /* Any readings between the two threshold values will be ignored.
     *
     * The LOW or HIGH signal length must be less than the variable "maxSignalLength"
     * otherwise it will be truncated.
     *
     * All of the HIGH signals and LOW signals combined must not exceed the variable "dataSize"
     * otherwise it will be truncated.
     *
     * The maximum number of signals is 1700 (memory limit)
     * If you try to extend this variable to a higher number than 1700
     * then the Arduino will freeze up and sketch will not work.*/
  }


  //Record the end time of the read period.
  endTime = micros();
  signalDuration = endTime - startTime;

  //Turn LED OFF
  digitalWrite(LEDPIN, LOW);
  
  //Send report to the Serial Monitor
  Serial.println("=====================");
  Serial.print("Read duration: ");
  Serial.print(signalDuration);
  Serial.println(" us");
  Serial.println("=====================");
  Serial.println("LOW, HIGH");
  delay(20);
  for(int i = 0; i < dataSize; i = i+2) {
    Serial.print(storedData[i]);
    Serial.print(", ");
    Serial.println(storedData[i+1]);
    delay(20);
  }
 }

 void loop(){
   //Do nothing here, press reset to re-run the program
 }
Code to transmit the codes

/*
 Example for my own codes, yours may be different
*/
 
#include 
 
// constructor for mySwitch object
RCSwitch mySwitch = RCSwitch();

byte inByte = 0;

void setup() {
 
 Serial.begin(9600);
 
 // Transmitter is connected to Arduino Pin 10
 mySwitch.enableTransmit(10);
 
// Optional set pulse length.
 // mySwitch.setPulseLength(320);
 
 // Optional set protocol (default is 1, will work for most outlets)
 // mySwitch.setProtocol(2);
 
 // Optional set number of transmission repetitions.
  mySwitch.setRepeatTransmit(4);
 
 Serial.println("Ready"); // Ready to receive commands
}
 
void loop() {
 /* Switch using decimal code */
 if(Serial.available() > 0) { // A byte is ready to receive
   inByte = Serial.read();

   if(inByte == '1') { // byte is '1'
     mySwitch.send(14237327, 24);
     Serial.println("1 ON");
   }
   else if(inByte == '2') { // byte is '2'
     mySwitch.send(14237326, 24);
     Serial.println("1 OFF");
   }
   else if(inByte == '3') { // byte is '3'
     mySwitch.send(14237319, 24);
     Serial.println("2 ON");
   }
   else if(inByte == '4') { // byte is '4'
     mySwitch.send(14237318, 24);
     Serial.println("2 OFF");
   }
   else if(inByte == '5') { // byte is '5'
     mySwitch.send(14237323, 24);
     Serial.println("3 ON");
   }
   else if(inByte == '6') { // byte is '6'
     mySwitch.send(14237322, 24);
     Serial.println("3 OFF");
   }
 }
}
My future target is to add a speech recognition board from Audeme to the Arduino UNO and control my lighting by voice!

Thursday 11 August 2016

Morse Code Trainer

One thing about morse code is you need repetitive training. No better way to learn and improve your reception. So here's a thing - a MicroPython program running on the BBC micro:bbit that generates random morse letters and sounds for you to train by.

IMG 0146

The connections are simple, pin'0' and GND go to an active piezo buzzer.

Code

The code is self explanatory, for those that know Python. It was written in the "Mu" code editor which has been specifically written to support the micro:bit on all platforms.

from microbit import *
import random

# 'constants' for delays all derived from dot length
dotlength = 250
dashlength = dotlength * 3
interelement = dotlength
interletter = dotlength * 2

# images for displaying dots and dashes

dot_img = Image('00000:00000:00900:00000:00000:')
dash_img = Image('00000:00000:09990:00000:00000:')

letter = ("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")

# Dictionary
morse = {
    "A":".-",
    "B":"-...",
    "C":"-.-.",
    "D":"-..",
    "E":".",
    "F":"..-.",
    "G":"--.",
    "H":"....",
    "I":"..",
    "J":".---",
    "K":"-.-",
    "L":".-..",
    "M":"--",
    "N":"-.",
    "O":"---",
    "P":".--.",
    "Q":"--.-",
    "R":".-.",
    "S":"...",
    "T":"-",
    "U":"..-",
    "V":"...-",
    "W":".--",
    "X":"-..-",
    "Y":"-.--",
    "Z":"--.."
}

# function to convert string to pattern of dots and spaces
def EncodeMorse(message):
    m = message.upper()
    enc = ""
    for c in m:
        enc = enc + morse.get(c," ")
        if morse.get(c," ") != " ":
            enc = enc + " "
    return enc
    
# function to flash out a Morse pattern on the matrix
def FlashMorse(pattern):
   for c in pattern:
       if c == ".":
           display.show(dot_img)
           pin0.write_digital(1)
           sleep(dotlength)
           display.clear()
           pin0.write_digital(0)
           sleep(interelement)
       elif c=="-":
           display.show(dash_img)
           pin0.write_digital(1)
           sleep(dashlength)
           display.clear()
           pin0.write_digital(0)
           sleep(interelement)
       elif c==" ":
           sleep(interletter)
   return

# helper function to encode and flash in one go
def MorseCode(message):
    m = EncodeMorse(message)
    print(m)
    FlashMorse(m)
    return

while True:
    message = random.choice(letter)
    MorseCode(message)
    sleep(2000)


    
    

Tuesday 9 August 2016

Micro:bit Traffic Lights

A simple, but fun, application of the BBC Micro:bit is to build a set of pedestrian traffic lights. You push the button, the lights cycle to red, it goes pip-pip-pip then the lights cycle back to green.

IMG 0143

Pin 0 goes to the active piezo buzzer, pins 13, 14, 15 are the G, Y, R LEDs and the "cross" switch is on pin 16. The LEDs have series 330R resistors (the current must be limited to less than 5mA for the micro:bit), and the switch has a pull up resistor of 10k to 3V.

Code

# Traffic lights
# pins 330R-LED-GND: 13 green, 14 yellow, 15 red, 16 switch(10k pull-up, active LOW)

# import the micropython library
from microbit import *

# set period of pin 0 pwm output
pin0.set_analog_period(400)
pin0.write_analog(0)

while True:
    # green on
    pin13.write_digital(1)
    display.show("G")
    
    # wait for switch
    if pin16.read_digital() != 1:
        
        # green off, yellow on
        pin13.write_digital(0)
        pin14.write_digital(1)
        display.show("Y")
        sleep(2000)
        
        # yellow off, red on, pip-pip-pip
        pin14.write_digital(0)
        pin15.write_digital(1)
        display.show("R")
        pin0.write_analog(200)
        sleep(8000)
        
        # yellow on, red remains on, pip off
        pin14.write_digital(1)
        display.show("Y")
        pin0.write_analog(0)
        sleep(2000)
        
        # red & yellow off
        pin14.write_digital(0)
        pin15.write_digital(0)

# loop
Press the button to cross the road

Saturday 30 July 2016

Got my Micro:bit

I received my BBC Micro:bit this morning. Here's one of the first programs I tried out:

Using the Micropython editor "Mu" which runs on all platforms, edits code, and flashes the micro:bit directly - very easy and efficient... A note I should mention is that Micropython runtime is downloaded to the micro:bit along with your program when you "Flash".

Screen Shot 2016 07 30 at 12 23 42

Code

from microbit import *

while True:
    reading = accelerometer.get_y()
    if reading > 400:
        display.show(Image.HAPPY)
    else:
        display.show(Image.SAD)


Resulting in two images on the micro:bit:

IMG 0125

and when you tip it up:

IMG 0126

Saturday 9 April 2016

Plan for a Home Automation system

Actually what I would like to do is just control the lights in my home. But in a new way.

Recently there has been announced a very interesting new Arduino Shield product, the MOVI Voice Recognition shield. This is a stand alone VR shield that has its own 2GB dictionary and phonetic sound translation system. You train it with text phrases, it translates these into English phonetics and is then able to recognise these phrases when you speak into the built-in (or external) microphone. Providing a unique output to the Arduino for each phrase recognised.

Screen Shot 2016 04 09 at 17 13 27

My plan is like this:

Block Diagram

I would use the Energenie RF controlled sockets, these have a 433.92MHz RX and recognise a unique ID, Number and control (ON/OFF) transmission from a small TX on a new Arduino shield. The recognised voice phrase will be translated by software on the Arduino to transmit the correct codes to turn ON/OFF the sockets.

So that's the project, now to acquire the MOVI shield, some Energenie sockets and build the RF TX shield (very simple) I will also build a RX shield so that I can find out the codes sent by an Energenie transmitter.

Wednesday 23 March 2016

SSB from Raspberry Pi

The next thing I want to try is to generate SSB from the Raspberry Pi. To do this I use the "rpitx" program. To get this go to GitHub/F5OEO/rpitx where you will find everything you need and also stuff for SSTV, NBFM modes.

But first I need an audio file, which must be a mono, "wav" format, file and sampled at 48kHz. My Raspberry Pi is called "fido" and my "SSB" directory looks like this:

  pi@fido:~/SSB $ ls
  CQIQ.wav  CQ.wav  pissb  rpitx  usage.txt
Here you can see the original "CQ.wav" file. I generated this file on my Mac using the built-in microphone and Soundstudio software. I recorded it, converted it to mono, converted the sample rate to 48kHz, then applied some EQ and compression/normalisation. The result is not marvellous but its OK for testing.

Screen Shot 2016 03 23 at 11 26 43

You can also see in the directory this file after conversion to an "IQ" format file, "CQIQ.wav" - the kind you get from or send to your SDR radio to receive or transmit SSB, this is a stereo file with I = left and Q = right.

Screen Shot 2016 03 23 at 11 29 34

The conversion is made with the program "pissb", it converts to USB today, LSB is not yet an option:
  ./pissb CQ.wav CQIQ.wav
Then to transmit this as SSB, with the output on GPIO18 (pin12) of the R_PI, at 7110kHz:
  sudo ./rpitx -m IQ -i audioIQ.wav -f 7110.0 -l
"sudo", or run as superuser, is needed to access the GPIO pins. The command line is made up like this
  -m IQ                   - is the mode of transmission, that is IQ
  -i audioIQ.wav          - is the input file name
  -f 7110.0               - is the frequency in kHz
  -l                      - means loop, or repeat the transmission
This is the received signal on my Arduino SDR using the HDSDR software. Frankly it is not very good SSB and the bandwidth is over 3.5kHz, but it is readable.

Screen Shot 2016 03 23 at 11 18 50

The creator of the program is said to be working on improving the SSB generation.