Tuesday, 5 May 2015

CONCEPT - a flexible QRP TXRX

I have been developing a new Concept over the last few months. Based on the Arduino UNO with added shields to implement a QRP TXRX. This system will be presented to Banbury Amateur Radio Society in June with a view to building the system cooperatively. The basic system is

Screen Shot 2015 05 05 at 20 20 30

to have stack of boards, all of which are shown here. By using some or all of these many different applications and modes can be implemented.

Screen Shot 2015 05 05 at 20 20 21

In addition to the shields a series of program sketches have been written to provide

1 Universal_VFO. Driving the VFO shield to generate a single frequency, which can be used as a source of RF for experiments or for CW. I have in mind to have an alternative receiver which is a simple Direct Conversion circuit to use also the VFO single output.

2 Universal_SDR. Driving the VFO shield to generate the I & Q outputs for the SDR RX and SDR TX shields

3 Universal_QRSS_KB. For driving the PA shield directly (either a low power version ~200mW) or a 5W PA with slow morse signals for QRSS communication. Text to send can be entered on the computer KB. The SDR RX shield can be used for reception.

4 Universal_WSPR. For generating WSPR transmissions, which again can be used with the 5W or low power PA to make a fixed beacon

5 Universal_HELL_KB. Which generates Hellschrieber signals.

6 WSPR_symbol_generator. A useful tool is a sketch which generates the WSPR symbols for transmission based on your call sign, location and transmit power.

Future sketch development will be for the GPS shield or RTC shield to give accurate timing for the transmissions. The signals to and from the Arduino UNO are

Screen Shot 2015 05 05 at 22 13 22

And the table of builds for different applications is

Screen Shot 2015 05 11 at 11 36 16

Universal_VFO

The first and most important shield is the Universal_VFO.

It has an added 8 pin connector at the left. This carries four RF signals from the DDS, VFO, BFO I & Q. The idea is that the VFO output can directly drive a PA for digital modes, the BFO can be used in superhet designs (think BITX) and the I & Q can be used for SDR TX & RX. The VFO shield is based on the Si5351 module DDS and has in addition a 74AC74 to generate the I & Q signals.

Universal_SDR_RX

The SDR RX sheild is a conventional SDR design somewhat like the famous Softrock series. Its simplicity belies its performance.

Screen Shot 2015 05 05 at 20 22 52

The 8 pin connector carries teh RX input from shields above - the PA or the ATU. The system use is

Screen Shot 2015 05 05 at 20 23 06

Which shows the RX configuration.

Sunday, 3 May 2015

JT65.EXE running under Mac OSX

I installed the windows emulator "Wine" and downloaded the latest JT65 software. This is the reception on a web SDR.

Screen Shot 2015 05 03 at 18 40 43

Screen Shot 2015 05 03 at 18 37 54

I am getting some drop-outs where the RX freezes... but it is encouraging.

Saturday, 2 May 2015

Busy Saturday on 20m Digital?

Unbelievably busy today on 20m digital modes.

Screen Shot 2015 05 02 at 16 07 07

From the left: PSK31, MFSK, JT65, and tons of RTTY.

Digital Modes frequencies

Friday, 1 May 2015

Digital Modes

Just getting into the digital modes. Here is the SDR waterfall on 20m.

Screen Shot 2015 05 01 at 15 46 33

On the left are PSK31 signals, in the centre Hellschreiber and on the right JT65 mode.

I am using two programs to view these JT64hf109.exe running under Wine on OSX, and native flidgi.app on my Mac.

Here is some Hellschreiber signals and their decode

Screen Shot 2015 05 01 at 15 46 49

Screen Shot 2015 05 01 at 15 46 55

Different looking signals

Hellschrieber

Hellschrieber

JT65

JT65

PSK31

PSK31

PSH63

PSK63

RTTY

RTTY

WSPR

WSPR

Tuesday, 28 April 2015

WSPR symbol generator

WSPR requires a set of 162 symbols 0-3, each representing one of four frequencies of transmission - see previous post. The encoding take place in four steps. Encode the call, encode the locator, this builds the first 81 bit word. This is then interleaved to generate a 162 bit output which is combined with the sync vector to produce the final output symbols 0-3.

Until now the way most people have generated the symbol table was to use a Windows program WSPR.exe. There seems to be no Mac version of this, and anyway I wanted to do it on the Arduino.

So here it is. To use it edit the sketch code to put in your person call, locator and TX power (in dBm - must end with 0, 3 or 7). In this example my call is M6KWH, my locator IO92 and my TX power 100mW or 20dBm. The call sign must be entered so that the third character is a number - so mine is "[SP]M6KWH". Upload the program, then open the IDE monitor window and hit RETURN, this will output the sync vector and symbols as below:

Screen Shot 2015 05 12 at 11 32 08

Cut and paste these into your WSPR transmit program (I am working on a WSPR TX program using my Universal_VFO design).

Code

// WSPR_symbol_generator input coded, output on monitor
// based on code from Martin Nawrath, Acedemy of Media Arts, Cologne

const char SyncVec[162] = {
  1,1,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,1,0,0,1,0,1,1,1,1,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0,
  1,1,0,0,1,1,0,1,0,0,0,1,1,0,1,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0,1,0,1,1,0,0,0,1,1,0,1,0,1,0,
  0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,1,1,0,1,1,0,0,1,1,0,1,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,0,
  0,0,0,1,1,0,1,0,1,1,0,0,0,1,1,0,0,0
};

unsigned long n1;    // encoded callsign
unsigned long m1;    // encodes locator

byte c[11];                // encoded message
byte sym[170];             // symbol table 162
byte symt[170];            // symbol table temp

// put your data here
char call[] = " M6KWH";    // default values, 6 chars. 3rd numeric
char locator[] = "IO92";   // default value 4 chars
byte power = 20;           // default value 2 numberic

int ii,bb;

void setup()
{
  Serial.begin(9600);        // connect to the serial port
}

void loop()
{
  while(Serial.available() == 0);
  Serial.println("WSPR beacon");
  Serial.flush();
    
  encode_call();
  
  Serial.print("Call: ");
  Serial.print(call);
  Serial.print(" ");
//  Serial.print(n1,HEX);
  Serial.println(" ");

  encode_locator();
  
  Serial.print("Locator: ");
  Serial.print(locator);
  Serial.print(" ");
//  Serial.print(m1 << 2,HEX);
  Serial.println(" ");

//  for (bb=0;bb<=10;bb++)
//  {
//    Serial.print(c[bb],HEX);
//    Serial.print(",");
//  }
//  Serial.println("");
  
  encode_conv();

  Serial.println("");

  for (bb=0;bb<162 ;bb++)
  {
    Serial.print(symt[bb],DEC);
    Serial.print(",");
    if ( (bb+1) %32 == 0) Serial.println("");
  }
  Serial.println("");

  interleave_sync();

  for (bb=0;bb<162 ;bb++)
  {
    Serial.print(sym[bb],DEC);
    Serial.print(",");
    if ((bb+1) %32 == 0) Serial.println("");
  }
  Serial.println("");
  
  while(Serial.available() > 0) Serial.read();
}


// encode sequence
void encode() 
{
  encode_call();
  encode_locator();
  encode_conv();
  interleave_sync();
};

// normalize characters 0..9 A..Z Space in order 0..36
char chr_normf(char bc ) 
{
  char cc=36;
  
  if (bc >= '0' && bc <= '9') cc=bc-'0';
  if (bc >= 'A' && bc <= 'Z') cc=bc-'A'+10;
  if (bc == ' ' ) cc=36;

  return(cc);
}

// encode call sign
void encode_call()
{
  unsigned long t1;

  n1=chr_normf(call[0]);
  n1=n1*36+chr_normf(call[1]);
  n1=n1*10+chr_normf(call[2]);
  n1=n1*27+chr_normf(call[3])-10;
  n1=n1*27+chr_normf(call[4])-10;
  n1=n1*27+chr_normf(call[5])-10;

  // merge coded callsign into message array c[]
  t1=n1;
  c[0]= t1 >> 20;
  t1=n1;
  c[1]= t1 >> 12;
  t1=n1;
  c[2]= t1 >> 4;
  t1=n1;
  c[3]= t1 << 4;
}

// encode locator
void encode_locator()
{
  unsigned long t1;
  
  // coding of locator
  m1=179-10*(chr_normf(locator[0])-10)-chr_normf(locator[2]);
  m1=m1*180+10*(chr_normf(locator[1])-10)+chr_normf(locator[3]);
  m1=m1*128+power+64;

  // merge coded locator and power into message array c[]
  t1=m1;
  c[3]= c[3] + ( 0x0f & t1 >> 18);
  t1=m1;
  c[4]= t1 >> 10;
  t1=m1;
  c[5]= t1 >> 2;
  t1=m1;
  c[6]= t1 << 6;
}

void encode_conv()
{
  int bc=0;
  int cnt=0;
  int cc;
  unsigned long sh1=0;

  cc=c[0];

  for (int i=0; i < 81;i++) 
  {
    if (i % 8 == 0 ) 
    {
      cc=c[bc];
      bc++;
    }
    if (cc & 0x80) sh1=sh1 | 1;

    symt[cnt++]=parity(sh1 & 0xF2D05351);
    symt[cnt++]=parity(sh1 & 0xE4613C47);

    cc=cc << 1;
    sh1=sh1 << 1;
  }
}

// calculate parity
byte parity(unsigned long li)
{
  byte po = 0;
  while(li != 0)
  {
    po++;
    li&= (li-1);
  }
  return (po & 1);
}

// interleave reorder the 162 data bits and and merge table with the sync vector
void interleave_sync()
{
  int ii,ij,b2,bis,ip;
  ip=0;

  for (ii=0;ii<=255;ii++) 
  {
    bis=1;
    ij=0;
    
    for (b2=0;b2 < 8 ;b2++) 
    {
      if (ii & bis) ij= ij | (0x80 >> b2);
      bis=bis << 1;
    }
    
    if (ij < 162 ) 
    {
      sym[ij]= SyncVec[ij] +2*symt[ip];
      ip++;
    }
  }
}

Tuesday, 21 April 2015

More serious look at QRSS & WSPR

QRSS is a slow morse sending method, used at very low powers and narrow bandwidths. WSPR is a special signal coding carrying data, which is received and decoded by distant stations and give an idea of your propagation.

QRSS

To send QRSS you need a simple CW transmitter. For example the Universal VFO and the PA shields I have described for the Arduino UNO. The PA shield may be is a bit overkill and a lower output maybe should be used. An interesting design is a PA using a 74HC240 with out of phase signals fed to it from the VFO and the outputs connected to a balanced 1:4 transformer and LPF.

Screen Shot 2015 04 27 at 13 11 38

QRSS can be sent in basically three ways:

1 As simple CW, using dot = 3sec + 1 sec space, dash = 9sec + 1 sec space, word space = 2sec (1 space from each char + 2 extra = 3sec)

2 As frequency shift keying, with the same timing as #1 but on two frequencies, known as FSKCW. The frequencies are typically 2-5Hz apart, with the dot or dash being the higher frequency.

3 As two frequencies representing dot and dash, with a slightly longer gap for character spacing. The dot & dash are the same length. This is known as DFCW.

For example the letter 'C':

Screen Shot 2015 04 29 at 13 01 48

Different speeds have been adopted, but the most common is the one above called QRSS3, FSKCW3 or DFCW3. A transmitter must have better than 5Hz stability.

Reception is made by feeding the output of the RX audio (which can be from a simple direct conversion RX or an SDR RX) into your computer, and using an audio spectrum FFT display to show the frequency of the received audio.

Most HF QRSS activity is on 30m at 10140kHz.

Typical messages

Typical messages are very short, and replies are usually on a slightly different frequency to transmissions, for example:

CQ M6KWH K - M6KWH calling CQ

M6KWH ON7YD K - ON7YD replies

YD XDV 000 K - ON7YD call truncated, received, send report

XVD YD TU 73 K - received ON7YD back to you

YD XVD CL 73 SK - ON7YD received clear 73



WSPR

WSPR transmissions are a lot more complicated. As the message is encoded is a series of symbols/tones, each of which is transmitted on one of 4 frequencies (4FSK). For 30m the nominal "Dial freq" of the receiver is set to 10138.7kHZ USB. This transmits a WSPR message at 10140.2kHz, USB.

Screen Shot 2015 05 13 at 17 10 31

The symbols are transmitted as one of 4 tones like this

Screen Shot 2015 05 13 at 17 10 38

Where tones 0-3 are used for encoding the 4 tone FSK messages. The tone spacing is 1.46Hz (officially 1.465Hz but my DDS cannot resolve the last digit!). This uses a BW of just 6Hz and is transmitted at 1.4648baud, for the whole message the transmission time is 110.6sec. Transmissions are synchronised to start within 0-1 sec at 2 minute intervals based on UTC, that is for example at 00:00-00:01, 00:20-00:21 etc.

Messages

The WSPR message sent is a standard format which must be adhered to

Call Sign - Locator - power (in dBm, must end in 0, 3 or 7)

E.g. _M6KWH_IO92_37, where "_" is a space character - the third character MUST be numeric so there's a space at the front for my callsign

Their is a very good program called WSPR available on the web which runs under all OSs. This program both decodes and generates audio WSPR signals, including generating the symbol data from your information and outputting a modulated audio signal.

Screen Shot 2015 05 13 at 17 12 01

Your SDR radio tuned to dial 10138.7kHz USB will look like this

Screen Shot 2015 04 20 at 16 22 22

The WSPR program will display a narrow band of audio input from 100 - 300Hz around 1500Hz The display will look like this

Screen Shot 2015 04 20 at 16 22 59

It will read the signals being sent in the correct time slots (your PC clock must be accurate!) and decode them like this

Screen Shot 2015 04 20 at 16 23 07

the interesting parts which show the time (UTC), the frequency received, the call sign, locator and the power.

By uploading these received signals to a data base at WSPRnet you can plot them on a Google map and see either where you are receiving them from, or how far your signal is reaching.

Setup

There are two ways to set up a WSPR transmitter.

1 Use a program WSPR.exe to encode your symbols. Or use my Arduino based program described above, which tunes your transmitter with a sketch to shift the frequency of the DDS by the correct tone frequency.

2 Use an SDR TX shield and modulate your transmission with the audio output of the PC based WSPR program audio signals.

I will be investigating both or these methods and the transmission of QRSS in the future.

Tuesday, 10 February 2015

EAGLE - Making the PCB

Errata!!! In the previous post I had the connection VCC & GND going to the WRONG pins on the LM741. Here I have corrected this to pins 7 and 4.

So let's take the simple design of the previous post, complete it and make the PCB.

Here's the completed design:

Screen Shot 2015 02 10 at 16 42 28
I have added component values

- Edit > Value, to the resistors R1 & R2

I have named the signals IN, OUT, VCC, VCC2 & GND on the connector and on the circuit, so that Eagle will automatically connect them.

- Edit > Name

Now to create the PCB.

File > Switch to Board, and create it "Yes".

The square representing the board starts off large, reduced it to the size you want using

- Edit > Move, and dragging in the top and right sides to make a board about a inch square

- Tool > Move is used again to place the components on the board. Like this

Screen Shot 2015 02 10 at 17 04 41

The components have been moved around and rotated to simplify the layout (a matter of trial and error to get the best layout). The wiring is shown as thin black lines called Airwires.

Run the Auto-Router

- File > Autoroute. This is the result

Screen Shot 2015 02 10 at 17 05 35

As you can see there are only red lines. The red ones are on the top of the PCB (blue ones would be on the bottom). You can see all the layers of the PCB design using

- View > Layer Settings, which will open up a window showing all the layers. Various parts of the drawing are located on different layers. Partly defined by the Device characteristics and part by the routing, The most important are the 1Red (Top) and 16Blue (Bottom) layers.

The design as it is Auto-routed is over-complex and can be simplified if only we could get the GND wire from JP1 (centre pin) to the Pin 4 of IC1 without going all round the houses.

A cunning way to do this, and to save removing tons of copper from the PCB, is to create a ground plane. Draw a polygon round the circuit

- Draw > Polygon

Screen Shot 2015 02 10 at 17 10 34

Then name it as GND

- Edit > Name, and click on the dotted line

- Edit > Ripup the existing connection from JP1 to IC1 pin 4, as this will now be made with the ground plane (by the way all traces can be ripped up to start again by entering the command "RIPUP;" in the top command line.)

Screen Shot 2015 02 10 at 17 15 21

Now re-run the Auto-router and you will get this

Screen Shot 2015 02 10 at 17 32 57

As you can see the ground connection is now made with the ground plane which connects to JP1 centre pin and pin 4 of IC1

Layers

Within the Eagle PCB layout items are maintained on "Layers" as follows

Screen Shot 2015 02 12 at 16 40 46

You can view layers separately by turing them off/on using View > Layer Settings.

Checks

You can check two aspects of your design

1 Electrical rules in the schematic, Tools > ERC, which will report Errors and Warnings

Screen Shot 2015 02 10 at 17 18 06

2 Design rule check on the board, Tools > DRC. This will check that the layout meets the design rules, like the spacing of wires etc.

Screen Shot 2015 02 10 at 17 19 17

We have no errors so no report is made.

Design Rules

Suppliers, like Eurocircuits, provide their own Design Rules to ensure that you design will meet their fabrication specs. You can download these from their site and place them in Eagle's /drc folder. Then from the control panel chose Design Rules and load the Eurocircuit one you want to use.