The software was initially developed from Martin Thomas' GCC port of the Atmel example application ( www.siwawi.arubi.uni-kl.de). Open source tools were used for the project to ensure usability and access for hobbyists and professionals alike.
A constant advantage of an open source solution is that if it isn't quite right for what you want then you can get in and change it. Because of this, the creation of open source software, has been a major goal of this project from the outset. The most widely used mechanism used in the project is pre-processor definitions. Listing 1 below displays an example of these from the main.h file. This file is used to control global application- wide settings. Smaller scope settings are changed in individual header files. Some changes are also needed to include different files in the Makefile in order to keep the binary size as small as possible.
Listing 1: Excerpt from the main.h configuration file
//constants to enable Channels on logger // #define EN_LOG_DATE 1 #define EN_LOG_CLOCK 1 #define EN_LOG_LIGHT 1 #define EN_LOG_BATTERY 1 #define EN_LOG_SHT 0 #define EN_LOG_SPEED 0 #define EN_LOG_TEMP 1 #define EN_LOG_DS1820 1 #define EN_LOG_DIR 1 //number of ADCs used by direction. 4 channels max #define DIRECTION_ADCS 1 //Number of 1-Wire Temperature sensors #define DS1820_COUNT 2 // Constants for controlling the behaviour of the flash // when logging // #define BYTESPERPAGE 264 #define TOTALPAGESINFLASH 2048 #define DATESIZE (2 * EN_LOG_DATE) + (3 * EN_LOG_CLOCK) #define NOOFPARAMS (EN_LOG_LIGHT+ (EN_LOG_DIR*DIRECTION_ADCS)+ EN_LOG_TEMP+ EN_LOG_SPEED+ EN_LOG_BATTERY+ (2 * EN_LOG_SHT)) #define BYTESPERPARAMETER 2 #define NONSTDPARAMS (EN_LOG_TEMP + EN_LOG_SPEED+ EN_LOG_BATTERY+(2 * EN_LOG_SHT)) #define RECORDSIZE (DATESIZE + (NOOFPARAMS * BYTESPERPARAMETER) + (3 * EN_LOG_DS1820 * DS1820_COUNT)) #define RECORDSPERPAGE (BYTESPERPAGE/RECORDSIZE)
The period of logging is adjustable via the RS232 interface and the joystick menu. It can be set to 0 - 90 for any time unit of ticks, seconds, minutes or hours. There are 16 ticks in a second. This time is in addition to any time spent logging Timer1 (wind speed), which is adjustable from 0 - 65535 seconds.
Flash Data Format
When I began this project I was in a rush to get a prototype out the door and literally into the field. As a consequence of this I simply stored all my data as ASCII text in the flash. This made my download routine very simple: read a byte from the flash then echo it out the serial port. Using one page of flash per sample was pretty inefficient but it made my code simple and with the application only needing to run for only 3 to 4 weeks at a time, 2048 samples was perfectly adequate. In a later application when I was interested in sampling at speeds greater than 1 Hz 2048 samples began to feel very cramped (at 16 Hz this is only two minutes of data).
The result of this was a change in operation of the code. Now all data is stored in the flash as a two byte binary value. The date and time values were compressed further as using seven bytes for date and time seemed wasteful when five would do (if anyone is still using this beyond the year 2127 then they do so at their own risk). Although a gain of two bytes seems small, if you multiply by the total number of samples then it's quite a substantial gain in space
Due to the increased memory size and download times a binary download option was added to allow the data to be read from the device very quickly. This binary data however needs to be converted into readable values via an external PC side program (which has not yet been written). This would be useful when communicating over a cell phone or wireless link as data transfer is costly.
The Atmel example code (and the corresponding GCC port) uses a state machine idea to process user input from the joystick, display appropriate information on the display and run the corresponding code. The state machine itself is coded via a series tables in menu.h and main.h. Extending or altering this state machine is a simple matter of editing these tables.
Due to the space requirements some features of the logger can only be accessed via the serial interface.
An interface was designed for communication using the serial port. As a compromise between space and human readability a single character command set was used. No end of line character is used with all numerical inputs consisting of two digits with a leading zero if necessary.
Non-destructive queries are entered as lower case characters with related adjustment commands on the same capital letter. The idea being if a human is communicating to the device (as opposed to some software or automated script) it should be safe to enter anything from the keyboard so long as the shift or caps lock keys are not pressed.
The default baud rate is 115200
Tweaking the Clock
One feature I've always liked of in the Butterfly code was its ability to retune its main oscillator using the onboard crystal. By simply changing the constants used in this routine I was able to tune the internal oscillator to 7.3728 MHZ rather than 8MHz. This change in frequency doesn't offer much in power saving as the majority of the time is spent in sleep mode. The advantage of this frequency is that higher baud rates are achievable by the USART. This allows us to increase our communication speed to 115200bps or even 230400bps. This makes a big difference when downloading over 40,000 lines of data.
If you can't think of anything new just add an alarm clock to an existing product. While this is a pretty good rule of thumb for any design in this case it proved to be remarkably useful. After configuring the device with the correct time and a suitable logging interval via the serial interface the alarm clock function allows you to set a time to enable the logging to begin. At the alarm time the logging enabled flag will be set and the alarm cleared. The alarm clock function can be set via the serial interface only, and incorporates a date as well. This means that the device can be set up ready to go with logging disabled until any chosen date in the future.
The dynamic logging feature was introduced in version 0.31. This allows you to set a desired threshold for an ADC channel. If the ADC selected does not change by at least the threshold amount then a log is not taken and no data is stored on the dataflash. The threshold can be expressed as either a percentage of the previous ADC value or as an absolute difference in ADC value. This feature allows you to acquire readings as often as every second but only when needed. If the ADC signal is not changing then all those near identical logs will be ignored. This gives a similar effect to compressing standard periodically logged data.
When using the dynamic logging feature you will need to log time and date to enable you to reconstruct the data once downloaded.
The system also has an optional timeout value so that if no change has been read from the ADC for a large number of log attempts then a log is forced to ensure a minimum resolution such as 1 sample every hour is maintained.
Setup and options for the dynamic logging features are maintained in the file main.h
Future enhancements planned for this project include the implementation of a minimal LCD/Joystick interface to make room for more advanced logging techniques such as control functions, alarm systems and real time analysis of incoming data.