HAH and the Arduino
The Arduino board is a low cost, off the shelf, micro-controller that is readily available. These make great external devices that can be controlled and connected to the HAH system.
Arduino boards come in three interfacing flavours: Board types
- Arduino Serial
- Arduino USB
- Arduino Ethernet (with a shield)
All can be interfaced with the HAH unit. Depending on your existing knowledge of things like FTP/the vi editor/unix style operating systems/the Lua scripting language, it might take you a little time to read up on these topics. However, the examples and support library code have been designed to help you along.
Once a USB Arduino is connected it will be presented as a /dev/ttyUSBx or /dev/ttyACMx device to the HAH system. At this point it can be interfaced to the xAP bus via the xap serial adapter software.
/var/log/messages usbserial.c: FTDI 8U232AM converter detected usbserial.c: FTDI 8U232AM converter now attached to ttyUSB0 (or usb/tts/0 for devfs) ttyACM0: USB ACM device
Programming the Arduino from the HAH
Arduino: Duemilanove
# stty -F /dev/ttyUSB0 hupcl # avrdude -v -c arduino -p m328p -P /dev/ttyUSB0 -b 57600 -Uflash:w:FILE.hex
Arduino: UNO
# stty -F /dev/ttyACM0 hupcl # avrdude -v -c arduino -p m328p -P /dev/ttyACM0 -b 115200 -Uflash:w:FILE.hex
Checking out from SVN
All the examples are managed in the projects Google code repository. I recommend installing a SVN client, then you can checkout the samples like this.
- Install Tortoise SVN client.
- Create a work folder for example. “C:\Users\brett\Documents\Arduino”
- Inside this “Arduino” directory, Right click to get the “SVN Checkout…” context menu option.
- Complete the dialogue as follows.
If you're not a project maintainer you should use HTTP for a read-only copy.
http://livebox-hah.googlecode.com/svn/trunk/userapps/arduino
See a list of files checked out onto your computer:
Tested with v18 of the IDE
Ethernet xAP Arduino Library
To aid writing xAP compliant applications for the Arduino, an xAP processing library has been written. This allows Arduino to be connected to your LAN and will transmit xAP messages without any HAH involvement. See http://wiki.london.hackspace.org.uk/view/Project:Ethernet_Arduino
These are the classes exposed by the library. Grab the source and browse to see the inner working.
xapClass
This is a base class that provide the ability to parse an xAP message and extract information from it. It also provides a helper function to assist with performing activities on a regular basis.
class XapClass { class XapClass { public: XapClass(void); XapClass(char *source, char *uid); char *getValue(char *section, char *key); // Get the contents of a parsed xAP message by section/key. int getState(char *section, char *key); // Get a BSC state value int isValue(char *section, char *key, char *value); // does section/key have value ? int getType(void); // The (TYPE) of the xAP message int parseMsg(byte *buf, int size); // Parse a raw XAP message; exposed for Ethernet shield users. int after(long); // Useful for managing TIMED events such as heartbeats and info void dumpParsedMsg(); void heartbeat(void); virtual void sendHeartbeat() {}; const char *SOURCE; const char *UID; }
after
The after function allows you to easily setup recurring events. Example of how this would be used to do something every 2 mins.
const int infoBeat = 120000; // 120 seconds (120,000ms) long infoTimeout = smillis()+infoBeat; XapClass xap(); … if(xap.after(infoTimeout)) { … do something. infoTimeout = smillis()+infoBeat; // Reset the timer }
xapEther
This class makes it easy to interface an arduino with the nuelectronics ethershield and manage Transmission and Receiving xAP messages. The nuelectronics ethershield uses the ENC28J60 chip, however I found their library overly complicated, to that end an Ethernet library has also been supplied. This is a modified version of ethercard from the jeenode project extended to handle UDP broadcast and UDP packets > 220 bytes.
class XapEther : public XapClass { public: XapEther(); XapEther(byte *mac, byte *ip); XapEther(char *source, char *uid, byte *mac, byte *ip); void setBuffer(byte *buf, word len); void process(word len, void (*callback)()); void sendHeartbeat(void);
Examples
LED control with a BSC schema
These code samples are checked into the SVN code repository:
Using the BSC library and the xap serial daemon we can construct a BSC compliant endpoint that will control a LED attached to an Arduino.
Step 1. Compile this sketch and flash it to your Arduino This SKETCH accepts the commands “LED ON” and “LED OFF” to control a LED connected to PIN 13 of your Arduino
#define LEDPIN 13 const int inBufferLen = 255; uint8_t inPtr = 0; char inBuffer[inBufferLen+1]; void doCommand() { if(strcmp("led on", inBuffer) == 0) { digitalWrite(LEDPIN, HIGH); } else if(strcmp("led off", inBuffer) == 0) { digitalWrite(LEDPIN, LOW); } } void readSerial() { int inByte = Serial.read(); if(inByte == '\r') { // CR to LF inByte = '\n'; } switch(inByte) { case '\n': if(inPtr > 0) { doCommand(); } inPtr = 0; break; default: if(inPtr < inBufferLen) { inBuffer[inPtr] = inByte; inPtr++; inBuffer[inPtr] = '\0'; } } } void setup() { Serial.begin(9600); } void loop() { while(Serial.available()) { readSerial(); } }
Step 2. Plug your Arduino into your HAH. Identify the correct USB serial port and adjust the sample below.
# dmesg usbserial.c: FTDI 8U232AM converter detected usbserial.c: FTDI 8U232AM converter now attached to ttyUSB0 (or usb/tts/0 for devfs)
In this case we are using /dev/ttyUSB0
Step 3. Now we will create a Lua plugboard applet and a BSC endpoint so this LED can be easily controlled. This will take care of converting the xAPBSC.cmd message into a xap-serial message for us, along with providing xAPBSC.query capabilities, and regular xAPBSC.info reporting about the status of our LED.
Like all Plugboard scripts, this must be placed in the /etc/plugboard directory on the HAH. The vi editor is included in the HAH Busybox operating system build, so you can create/edit the script directly from a Telnet session onto the HAH (default username/password is root/admin). Remember that your script filename must end in 'Applet.lua' (case sensitive). Also check that you have enabled the plugboard scripting engine and the serial schema services via the HAH web UI (Automation/Assists tab).
--[[ Arduino to xAP Endpoint mapping --]] module(...,package.seeall) require("xap") require("xap.bsc") info={ version="1.0", description="Arduino control" } port="/dev/ttyUSB0" function cmd(endpoint) xap.sendShort(string.format([[ xap-header { class=Serial.Comms target=dbzoo.livebox.serial } Serial.Send { port=%s data=led %s\n }]], port, endpoint.state)) end function init() local serialSetup = [[ xap-header { class=Serial.Comms target=dbzoo.livebox.serial } Serial.Setup { port=%s baud=9600 stop=1 databits=8 parity=none flow=none }]] xap.sendShort(string.format(serialSetup, port)) bsc.Endpoint{ source="dbzoo.livebox.arduino:led", direction=bsc.OUTPUT, type=bsc.BINARY, cmdCB=cmd } end
Step 4. Restart the plugboard daemon to make sure the new Applet is loaded. One easy way to do this is to reboot the HAH.
Step 5. Send a BSC control message to our endpoint and turn the LED on/off. An easy way to send BSC control messages and to view the new LED endpoint itself is to use xFx Viewer.
xap-header { v=12 hop=1 uid=FF00D800 class=xAPBSC.cmd target=dbzoo.livebox.arduino:led source=dbzoo.acme.test } output.state.1 { id=* state=on }