Sunday, March 27, 2011

QRSS/WSPR band befuddlement...

I know that on 30 metres, the dial frequency of 10.1387 plus
1300 Hz is the bottom of the QRSS band and plus 1400 Hz is the bottom of the WSPR
band.  Is this true on all bands?


Here are the WSPR dial frequencies(USB) for everything below
60 MHz (limit of the DDS-60) according to http://www.wsprnet.org.

// WSPR standard frequencies
// Shown are the dial frequencies plus 1500 Hz to put in the
// middle of the 200 Hz WSPR band

long rgWSPRFreq[] =
{
    502400 + 1500,    // 500 KHz
   1836600 + 1500,    // 160 meters
   3592600 + 1500,    //  80 meters
   5287200 + 1500,    //  60 meters
   7038600 + 1500,    //  40 meters
  10138700 + 1500,    //  30 meters
  14095600 + 1500,    //  20 meters
  18104600 + 1500,    //  17 meters
  21094600 + 1500,    //  15 meters
  24924600 + 1500,    //  12 meters
  28124600 + 1500,    //  10 meters
  50293000 + 1500     //   6 meters
};

enum
{
  WSPR500KHZ, WSPR160M, WSPR80M, WSPR60M,
  WSPR40M, WSPR30M, WSPR20M, WSPR17M,
  WSPR15M, WSPR12M, WSPR10M, WSPR6M
};

So, as I have defined them, I can set the DDS frequency to
the centre of the WSPR band with the array above.  Are these WSPR/QRSS
band relationships consistent across all these bands as they are on 30M ?


I see from the KnightQRSS blog that there appears to be a more scattered set of standard frequencies, though I am not certain I understand the decision making process and therefore don't have much confidence in this list:

* 137.6 - 137.8 kHz
* 1.8432
* 3.500, 3.575, 3.579, 3.5999
* 7.000, 7.0402, 7.0599
* 10.140
* 14.000, 14.0989, 14.31818
* 18.1089
* 21.000, 21.1489
* 24.9289
* 28.000, 28.188, 28.322
* 50.294,400-600

On a side note, the 60 metre WSPR frequency surprises me as I thought only USB transmissions are available on 60 metres.  Granted, most people typically inject tones into their SSB transceiver to transmit WSPR.  What you get out when you do that however is FSK, so I am not so certain WSPR on 60 metres makes sense.  What did I miss?

On a similar note, it is a bit "funny" to note the number of times I hear computer annunciation beeps and even an occasional VOIP phone call or MP3 tracks that makes its way into the SSB transceiver MIC input when in digital modes in "non-voice" portions of the ham bands, especially 30 metres...

Thursday, March 24, 2011

I2C LCD performance

I am a bit disappointed in the performance of the Arduino LCD driver, especially with the I2C interface enabled.  I am not sure how much time I want to spend optimizing the standard Arduino libraries, especially since a beacon in operation really doesn't need a display.  Realistically, it is just convenient for me while developing this project.  I think what I will do is just optimize the display usage to only update what actually changes rather than repainting everything whenever anything changes.  If that is insufficient, I will turn off the frequently updated portions of the LCD when doing time critical operations such as when transmitting signals with critical timing criteria such as WSPR.

Tuesday, March 22, 2011

WSPR Beacon update

Now that I have liberated GPIO pins for the RTC clock, I have incorporated it into my breadboard design.  I have the code to the point where it will begin transmitting on the next even minute.  I now need to implement the TX percent control, however I am uncertain what it means.  Obviously, TX percent set to 100% will transmit every 2 minute window and 0% will not transmit at all (Idle).  However, what does 50% mean?  Does it mean I will transmit every other 2 minute window?  Don't think so, but not sure...  I did see one online reference that 20% means transmitting every 10 minutes or so.  This came from the WSPR 2.0 user manual.  Here is that text:


WSPR uses two-minute time slots for transmitting and receiving. The slider labeled
Tx fraction sets the average proportion of time allocated for transmitting. The default setting of 20% is a good compromise under typical conditions: it means that you will transmit approximately once every ten minutes and receive the rest of the time. The exact T/R sequence will be randomized so as to maximize your chances of receiving other WSPR stations. For receive-only operation, set the Tx fraction slider to zero
My brain refuses to understand this for some reason...

I think what is intended here is the following:

transmit time = (1/transmit percent) * 2 min

If I round this up to the nearest integer, the following transmit times result:

100% - every 2 minutes
90% - every 4 minutes
80% - every 4 minutes
70% - every 4 minutes
60% - every 4 minutes
50% - every 4 minutes
40% - every 6 minutes
30% - every 8 minutes
20% - every 10 minutes
10% - every 20 minutes
0% - never transmit

I am not sure this is precisely what Joe Taylor intended, but I think it will be adaquate for the beacon project.  I will further randomize the precise amount of time between transmissions up to the calculated value to better match what Joe Taylor suggests for minimizing collisions between transmitting stations.

Friday, March 18, 2011

GPIO Liberation

I have been endeavoring to liberate I/O pins on my Arduino project.  To that end, I have moved to an I2C LCD interface.  This is necessary to enable integration of an RTC (real-time clock) for WSPR timing.  The new setup looks like this:
I have some concerns about the performance of the LCD driver so I may have to do some customization of the driver.  The good news is that the beacon in operation is unlikely to have or need a display or rotary encoder as the set of operational frequencies will be fixed.  Calibration of the DDS-60 can be accomplished with a test setup that includes a rotary encoder to set the clock and then disconnected for day-to-day operation.

So, hopefully I can get the RTC integration done soon and have a fully functional WSPR/QRSS beacon breadboard completed.

Many thanks to the good folks at Adafruit for the excellent work on the I2C LCD interface.

Sunday, March 6, 2011

WSPR Beacon with Arduino and DDS-60

Today I got my WSPR beacon code running for the most part.  I have the WSPR encoding all done and the Symbol transmission bits are complete.  The setup is the same as for the previous post.

I added a WSPR mode to the controller software and can trigger the transmission manually at this point.  Watching the received signal on Spectran, I can see the normal WSPR four tone pattern.  The test however is can Joe Taylor's fine WSPR program decode what I am transmitting?  I am happy to say the answer is yes!  Click on the image below for a full size version that can be read.


I am using just a cheap Grundig G6 receiver which only has 1 KHz resolution on the dial.  Since the entire 30 metre WSPR band is only 200 Hz wide, I used Spectran to set received audio tone to around 1450 Hz.  With Joe Taylor's application set with a dial frequency of 10.138.700 this put me in the band.  I then waited for an even minute to come around and pushed a button to initiate the WSPR transmission.  As you can see above, it decoded just fine!  Whoo hoo!

So, now I need to implement the RTC clock in order to have transmissions begin 2 seconds into even minutes and to implement the percent of the time the beacon is transmitting.

Geting close to having a software solution on breadboarded hardware.  It will then be time to build a custom PCB hardware solution.

Thursday, March 3, 2011

QRSS with a DDS-60

I have been having fun messing around with an old DDS-60 board that I obtained some time ago.  I have cabled it up to the Arduino.  Here is the setup:

The DDS-60 is plugged into the Arduino breadboard.   I have a small four line LCD display on a separate board below.  The LCD is certainly not necessary for this project, but is nice to have.

Looking at the DDS-60 output on around 10 MHz, we see a nice clean signal.
A little more code and we have a simple QRSS beacon putting out about 1.4 V peak-to-peak signal into a 50 ohm load.  Hooked up a simple Grundig G6 portable radio and cabled the audio out to the computer audio in.  Using Spectran, we can see the 6 hertz FSK signal on 10.140 Mhz sending my call sign (KO7M).

Sunday, February 27, 2011

Fun with DACs

Today I have been playing around with an AD5330 8 bit DAC (datasheet) and generating different waveforms.  For inspiration, I am using a document from Analog Devices (MT-085 Tutorial) on the Fundamentals of Direct Digital Synthesis (DDS).  This is an excellent primer on the subject and I recommend it highly.

The setup is an Arduino Uno and a breadboarded AD5330 DAC from SparkFun.

From a block diagramme perspective, I have implemented a Numerically Controlled Oscillator as shown below (from MT-085 referenced above):

The "System Clock" initially in my software implementation is just the main loop of the Arduino sketch.  Each time through the loop, the phase accumulator contents is updated.  The tuning word (M stored in the delta phase register) is added to the number in the phase accumulator.  I use the upper 8 bits of the phase accumulator as the address of a lookup table containing the digital amplitude information for whatever waveform I am generating.  This table maps the phase information from the phase accumulator to a digital amplitude word which then drives the DAC.

As you can see from the photographs below, this prototype is only a proof-of-concept implementation and the system clock will need be a much more granular (and stable) implementation.  The next step is to implement the system clock in a timer interrupt handler firing at about a 32KHz rate to make the waveform output much smoother.

I can change the waveform by just filling the digital amplitude lookup table with appropriate values.  I have implemented SIN, Square, Triangle, Sawtooth with a positive slope, Sawtooth with a negative slope and random waveforms.  It should be a simple matter to allow for a custom waveform to be uploaded in a general purpose function generator implementation (a project for another day perhaps...).

Off to figure out Arduino timers.  I have used them to generate PWM output, but now need to figure out how to just generate an interrupt a precise intervals without interfering with the various digital output pins I require for DAC purposes.

Saturday, February 26, 2011

Checking out the DS1307 RTC with Bus Pirate

Today I am checking out the functionality of the DS1307 with Bus Pirate.  I am supplying power and clock from the Bus Pirate board so +5/Gnd, MOSI/CLK are the only required pins.   Here is the setup:


I set Bus Pirate to I2C at 50khz and turned on the power:
HiZ>m
1. HiZ
2. 1-WIRE
3. UART
4. I2C
5. SPI
6. JTAG
7. RAW2WIRE
8. RAW3WIRE
9. PC KEYBOARD
10. LCD
(1) >4
Mode selected
Set speed:
 1. ~5KHz
 2. ~50KHz
 3. ~100KHz
 4. ~400KHz
(1) >2
READY
I2C>W
POWER SUPPLIES ON
I2C>
Now I should be able to search for the device on the I2C bus and it finds the device at 0xD0, 0xD1 as expected, so at least it is responding.
I2C>(1)
Searching 7bit I2C address space.
   Found devices at:
0xD0(0x68 W) 0xD1(0x68 R)
I2C>
Now, I try to read four bytes from the DS1307:
I2C>[0xd1 rrrr]
I2C START BIT
WRITE: 0xD1 ACK
READ: 0x00 ACK
READ: 0x00 ACK
READ: 0x01 ACK
READ: 0x01 NACK
I2C STOP BIT
I2C>
So, it looks like things are working, yay!

Friday, February 25, 2011

PC-less WSPR project

It is long past time for me to start posting to this blog.  My current project is an Arduino-based WSPR tone generation module.  I am currently using an Arduino Uno along with a DS1307 Real-Time-Clock (RTC) for timing of WSPR transmissions and an MCP4725 DAC.


I am currently breadboarding the circuit as can be seen above and learning a lot about I2C communications programming.  I have basic DDS software written and generating tones using the PWM functionality on the Uno and an external low-pass filter.  I am now moving to a hardware DAC solution.

WSPR encoding and channel symbol generation code has been completed and verified against WSPRCode.exe available from Joe Taylor, the creator of WSPR so I am confident the WSPR generation bits are functional.

Initially, I am using my software DDS code to generate WSPR tones that could be then fed into an SSB transmitter.  Longer term, I plan to use a hardware DDS to generate RF at the transmit frequency for stand-alone beacon use.