Firmdata - Send and receive data using the IO ports on an AVR Atmega328p based Arduino Duemilanove or Uno
Firmdata is a firmware load for the Arduino ATmega328p Duemilanove that allows a client to connect to the Arduino then use it to send and receive data from the AVR IO ports such as the ADC input and PWM output. This provides functionality similar to the Firmata software for the Arduino platform but with the following major differences:
* There are currently two usable PWM outputs in Firmdata and they run at 50hz with a 16 bit resolution instead of 6 PWM outputs running with 8 bit resolution. * Each of the 6 ADC pins can be sampled at an arbitrary rate configured in the session. Sample scheduling can be controlled so that each sample is taken at a consistent but still independent interval. * Data sent to a Firmdata client includes enough information to calculate the absolute time the data was collected with a precision down to 64us regardless of communication line latency. * All IO with Firmdata is done using a simple message format providing 30 user configurable data channels for input and output. The message header is a single byte and each message can include up to 7 bytes of content. * The protocol does not deal with connected device types. For instance When controlling a servo using PWM it is up to the client to send the time data for the pulse width that will control the servo position and not the explicit desired servo angle. * The processor consumption on the microcontroller can be calculated from the session events. * The Arduino software development kit is not used. The firmware is written in C99, cross compiled with GCC, and linked against GNU avr-libc.
The following features are operational:
* Device identification and presence broadcast. * Session creation, termination, and expiration. * Multiple data subscriptions at arbitrary intervals on arbitrary ADC pins. * Clock events and time data with samples giving a precision down to 64us regardless of latency on the serial line. * Reference client written in Perl that tracks serial speed and microcontroller processor usage and is broken up into a device class, a message driver class, and a session class.
The following devices have been tested:
* Arduino Duemilanove under Windows 7 with Cygwin and Perl 5.16.0 * Reliability: very high * Subscriptions possible on analog in 0 to 5 via pin numbers 0 to 5 respectively * Publications possible for PWM to digital pins 9 and 10 as output pin 1 and 2 * Arduino Uno under Mac OS X * Reliability: lightly tested but spotty * Subscriptions: untested but should work on analog in 0 to 5 via pin numbers 0 to 5 respectively * Publications: untested but should work for PWM to digital pins 9 and 10 as output pin 1 and 2
The following problems are known to exist:
* The serial port configuration does not always work - try pre-configuring your serial port for 57600 BPS and 8 data bits, 1 stop bit, no parity bit then launch Firmdata. * There is very little comments in the firmware because the code has been changing a lot; it is starting to settle down and parts that I don't expect to get replaced I'll comment. * The client interaction and sessions do not quite work as documented here; see the reference client * The client currently performs some arbitrary restrictions on the message channels used for publication; this was done to set a stable client API before accompying changes are made to the firmware. This restriction will be removed ASAP.
Currently Firmdata is able to provide the data to calculate the speed of a shaft spinning at 1300 RPM when it has 3 magnets attached to it and field strength readings coming from a linear fluxgate magnetometer sampled at about 800 hz.
The following features remain to be implemented:
* Set up the firmware to receive messages to data channels and output them vs the current hack where a command is used to write the values into the registers. * More useful LED information because tracking processor usage is not as critical anymore * 8 bit CRC byte with each message. * Allow client to configure the session * clock precision and minimum timer interval * generation of processor overflow events * Allow the client to configure IO details * precision of a pin such as 8 or 10 bits on the ADC * Precision of a data channel - 8, 16, 24, 32 bits etc * Synchronization between client clock and AVR clock * Allow a default session configuration to be stored in the AVR; the session configuration could be run with out having the client issue any subscribe or publish commands by sending a RUN event when the session opens with out the client sending a RUN command. * Expand stdio support to allow the Firmdata device to receive stdio characters from the client so they can be displayed on an attached LCD panel. Or maybe there is a better way but nicely supporting a display would be very good. * Get faster, better, stronger IO channels running such as Ethernet.
These are examples and you may need to modify them a bit to get it working. You'll also need the avrdude utility: http://www.nongnu.org/avrdude/
Uploading to Arduino Uno on MacOSX
- avrdude -F -V -c arduino -p ATMEGA328P -P /dev/cu.usbmodem641 -b 115200 -U flash:w:Firmdata-atmega328p.hex
Uploading to Arduino Duemilanove on Windows
- avrdude -pm328p -cstk500v1 -Pcom3 -b57600 -Uflash:w:Firmdata-atmega328p.hex:a
The Firmware is built using the avr-gcc/avr-libc integration for Eclipse. To compile the software outside of Eclipse follow this guide:
Install the following required GNU tools as detailed at http://www.nongnu.org/avr-libc/user-manual/install_tools.html
* GNU Binutils * GCC * AVR LibC * AVRDUDE
There should be a Makefile but there isn't right now so once all the tools are installed do something like this:
avr-gcc -DF_CPU=16000000UL -mmcu=atmega328p -Wall -g2 -gstabs -Os \ -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned-bitfields \ -Wl,-Map,Firmdata-atmega328p.map -o "Firmdata-atmega328p.elf" *.c
avr-objcopy -j .text -j .data -O ihex Firmdata-atmega328p.elf Firmdata-atmega328p.hex
Then upload the Firmdata-atmega328p.elf file to the Arduino using the INSTALL instructions above.