Monday, May 16, 2011

Why I hate writing UI code...

Now that the Atmel CPU is back alive, I have been back working on my beacon code.  The underlying beacon code is finished for the most part.  What I have been working on is the user interface (UI) code.  Why is it that UI code is so dang hard to write and debug?  I have decided that I suck at UI design, but I have taken a first stab at it.  As is typical in many of my UI projects, it quickly degenerated into an amazing snake pit of spaghetti code, especially for the code that takes care of changing the various settings on the device.

Take for example the seemingly simple problem of setting the realtime clock to WWV.  Set the clock values for the next minute and wait for the tone.


So, to set the clock, I put the device into clock set mode and display the current RTC information across the bottom line of the 4 line display.  I set the seconds value to zero and put the cursor on the hours value and start it blinking.  In the picture above, I snapped the photo when the hours value was blanked out.  Rotating the dial will change the hours value within the range of values allowed (0 - 23).  To move the the next value, a button push will cycle from Hours -> Min -> Day -> Month -> Year and back to Hours again.  Each value will start blinking once selected and changed with the dial.  Each setting value has a minimum and maximum value.  It can be an 8 bit, 16 bit or 32 bit value.  There is an option to pass in an array of text strings that are displayed rather than the numeric value as was done with the month value.

Once the value has been set, we wait for the top of the current minute and press another button to save the new value.  There is an option to abandon the set operation and return to normal operation.  The idea was to listen to WWV or some other time standard and set the clock at the top of the next minute.  I may allow setting the seconds value if I get tired of waiting.

So, this ends up being a big huge state machine.  It just seems like 80% of the code in this project is related to the UI.  On an embedded processor with limited code memory, this is something to keep track of.

So, I have ripped out all the spaghetti code and replaced it with my new "value setting" utility and now should be able to reuse it to do any settings for this project.  For example, space permitting I could provide a way to set the WSPR/QRSS beacon text by allowing each character to be set by the dial.  The code should now be easier to reuse and eliminate the exponential growth of UI code, at least for the settings utility.

High Voltage programming the ATMega328

Having smoked my first AVR CPU, I now face the need to be able to reset the CPU fuses regardless of their current settings.  After some searching around, I decided to purchase a kit rather than roll my own.  I picked up a "HV Rescue Shield" from "MightyOhm Engineering".

http://mightyohm.com/hvrescue2

A few simple minutes with the soldering iron and quite a few more minutes purusing the ATMega328 data sheet and I determined the values for the fuses that would get me back in business.  A bit after the fact, I realized I could just read the current fuses on a working CPU chip and go with them, but it was educational nevertheless.


This little gem of an Arduino shield will handle the ATMega devices along with the ATiny2313 and 8 pin ATiny CPU chips.  It also generates the +12v programming voltage on-board eliminating the need to have an external programming voltage supply.

So, back in business with my original CPU.

Saturday, April 16, 2011

Smoked my first ATMega328

I have been having a lot of fun upgrading my toolset for building AVR applications and hardware solutions.  I have been playing around with both the raw WinAVR toolset as well as AVR Studio from Atmel.  I also recently obtained a JTAGICE mkII from Atmel to hopefully be able to do some realtime debugging on my projects rather than having to always put serial port print statements in for debugging purposes.

The ATMega328 does not have a JTAG interface but instead has a one-wire On Chip Debug interface called debugWire. I do all my programming of the chip using an ISP (In System Programming) interface.

The Atmel device implements the notion of "fuses" that are basically switches that control certain feature or modes of the device.  One of these fuses (DWEN - debug wire enable) is used to enable/disable debug wire mode.  The debugWire pin is shared with the reset pin, so automatic reset hardware has to be disconnected for debugWire to work, which according to the Arduino Uno schematic is a non-issue.

So, for debugging you start in ISP mode to set the DWEN fuse. Unlike JTAG chips which have the JTAGEN fuse enabled by default the debugWire chips have DWEN disabled by default.

Once you have used ISP to switch to debugWire mode in theory you only need two of the 6 wires in the ISP header but as you need all 6 to get the chip back from debugWire to ISP mode (you can't change fuses in debugWire mode) you might as well leave all 6 connected. While in debugWire mode, the ISP mode is completely disabled.

So, since Murphy is still on the payroll of course, my first debugging experience ended up putting my ATMega328 in a mode where it can no longer debug, but the ISP interface is disabled so I can do nothing with it.


One possibility is that I have messed up the system clock fuses somehow.  If that is the case, I should be able to apply an external clock to the chip and get it back.  The other option is to use high voltage programming which should be able to recover from any of these states and get the fuses back to a coherent state.

So, my next project will be to build a high voltage programming setup.  Oh sigh...  Probably just as well as I need to build one of these HVSP (High Voltage Serial Programming) jigs eventually anyway... 

Sunday, April 10, 2011

Working with new tool chain

As the Arduino beacon project has progressed, I have spent some time trying to minimize the code size.  For one thing, there are a number of components that the beacon project does not need that are drug into the final image.  To do this I have moved away from the Arduino IDE for development of this project.  I am using the GNU AVR tool chain now.  I copied all the headers and code files from Arduino install and have been modifying them to eliminate components that I do not need.  For example I don't need the serial port stuff, string classes, interrupt classes, etc.  Rather than use generic port libraries, I am moving to talk directly to the ports instead.  These kinds of changes have netted me 6-8 kb of space savings.  I need to hack on the wire libraries to eliminate the stuff I am not using.  Lastly, the Arduino boot loader is no longer necessary as I am using an in-circuit programmer (usbTinyISP) from the good folks at AdaFruit.  This saves another 0.5 kb at the upper end of flash.  The optiboot boot loader is pretty small, but others are not so compact.  All things considered, the savings in code size are significant.  Lastly, the tool chain is available for Windows, Linux and Mac platforms, so I think I will stick with it.

Converting from Arduino IDE is pretty straight forward:

1. Add #include "WProgram.h" to the top of your sketch.
2. Add a main() function at the bottom that calls setup() and loops calling loop() infinitely.
3. Provide forward declarations for all of your functions.
4. Create a Makefile to drive the build process if desired (recommended).

I copied all the components from my project into a new folder and built a Makefile to compile and link everything.  Now I can hack on the Arduino components referenced in my Beacon project without affecting my Arduino IDE environment.

Saturday, April 2, 2011

New RTC and data logging shield for beacon project

I have built one of the fine data logging shields for Arduino from the fine folks at Adafruit to further clean up my beacon project rats nest.  The new setup looks like this attached to my Arduino Uno.
I need to add a socket for the DDS-60 and a couple headers to bring data GPIO lines out.  The real-time clock has been tested and is functional.  This should be my final setup until a PCB is created for this project.

Thanks for all the emails!

I created this blog originally as a place to catalogue my ramblings and notes for myself.  I have been receiving quite a bit of email from around the world however expressing interest in the project, the code, hardware details and interest in the software.  While the project is not yet to a place where I am ready to publish details, that is the long-term plan.

I am however happy to help in any way I can anyone with a similar interest in this kind of project and have had some fun email exchanges as a result.  I appreciate all the offers to help from many folks as well.

I invite anyone with comments or suggestions to email or more ideally to post comments on the blog so that everyone can benefit from the discussion.  I will initially opt to not post emails as I want to respect the privacy of those involved unless explicit permission is provided to post those emails.

Trying to spruce up the Arduino beacon project

The Arduino WSPR/QRSS beacon project has gotten to the point where it is time to try and get rid of some of the rats nest of the breadboard nature of the project so far.  To that end, I have mounted the controls and display in a panel.

Next, I will be eliminating the breadboard and using a data logger shield for the Arduino.  This shield has an SD card slot (which I do not need) as well as the same real-time-clock (RTC) I chose for my beacon project the DS1307.  There is also some breadboard space available to mount a socket for the DDS-60 and any other associated discrete components I may need.  This should tidy things up sufficiently to allow the software components to be finalized.

After the software bits are complete (as much as any software project ever is) I will be producing a PCB for the entire project.

So far, my project has grown a bit bloated as I have allowed myself to be sidetracked on numerous occasions by additional modes such as Feld Hell.  I have added some test code to experiment in geneating Hellschrieber-like displays on a QRSS waterfall such as we have in Spectran or Argo.  The resultant bloat has put the code size beyond the code size limit of the ATMega168.  Since I am using an Arduino Uno with the 328 chip, this has not been a problem, but it does increase the expense of this project for others to duplicate or leverage the code.  I will have to work on that and will try to get the code size as small as possible in the final versions.  Things like my choice to do frequency calculations for the DDS using 64 bit integers has no doubt drug in the entire 64 bit math library whereas I only need one operation.  Obviously many opportunities exist for further optimization.

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.