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".

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.