Skip to Content

Arduino -> FunkFeuer -> Pachube: How To

How to get your Arduino collected data through a WRT FunkFeuer node to the Pachube data accumulation service.

At the 2011 Internet of Things Hackathon we looked at how we could combine some of our favourite toys: Arduinos, FunkFeuer and Pachube. This is meant to be a HOWTO, i.e. a document that will get you doing the same thing. First we will tell you what these three things are, then show you a simple way to connect them all together.

Definitions and Background

The Arduino is a very simple microcontroller that is easy to use for collecting data, controlling motors and other devices and doing simple computations. It has become almost ubiquitous for simple prototyping, and many artists projects. For this howto, we simply use it as a sensor reading and manipulation tool. Sensors that we might use are simple resistive sensors, digital sensors, one wire systems, I2C or even more complex ones.

FunkFeuer is an Austrian mesh networking system, related to the  German FreiFunk community. It is a system for creating a simple active node from a Wifi point. that will use the existing network to connect outwards to the internet, giving you internet access, whilst simultaneously extending the mesh network. It is possible to run a FunkFeuer node on simple hardware (we will use the Linksys WRT54GL that is widely used as a wifi access point and can be bought for around 40 Euros) and to reasonably simply get interesting things working.

Pachube is a data accumulation system where global data streams from sensors can be sent, collated and used. It is an initiative aimed at making the infrastructure of the "Internet of Things" easy to use. For people interested in data streams, whether it be weather, power usage, water levels or radioactivity, Pachube systems have been set up.

We will presume that you have some ideas what is going on here with all these parts, but below there will be some links to get you started on each part of the process.

What we will do

So how do we connect these things together? Arduinos can communicate over a serial connection, usually this is run through a USB chip so that it can be simply attached to a computer. from the perspective of the Arduiono board, this looks just like a normal serial interface with no hardware flow control (if you don't know what that means, or you do and, like us, have never got your head around it, don't worry: we will ignore it because it is not there!) But here we will connect before the USB and have a plain serial connection.
The WRT54GL has two serial connections on the circuit board. One of them is the "console" so when you get things all mixed up (called bricking the WRT) you can connect to the console and, just like some  l33T hacker (which you are doing) and repair everything from the command line. You could use this, but it is just as easy to use the second serial interface (it is 0.1 inches away) with no problem.
So we have the communication from the arduino to the WRT. The WRT is a very simple computer and, more importantly, it has very little memory. Luckily we will use the Leipzig firmware which has a nice interface (so you will not need to be such a hacker) and the software that makes the nice interface gives us a scripting environment in a language called Lua developed in Brazil in the 1990s. Some kind person has developed a small pachube interface module in lua which we can use, so the date can get spat out to pachube.

Getting your hands dirty

First thing is to get the three elements working independently.
First get your Arduino data collection working. Whatever sensors you are using, you will need to get the data values, arrange them into a string, and send the data over the serial connection. The following is possibly the simplest data sending patch ever:

void setup() 
{ 
  Serial.begin(9600); 
} 

void loop() 
{ 
  Serial.print(analogRead(0)); 
  Serial.print(" ");
  Serial.print(analogRead(1)); 
  Serial.print(" ");
  Serial.print(analogRead(2)); 
  Serial.print(" ");
  Serial.print(analogRead(3)); 
  Serial.print("\n");
  // go on to the next data set after a pause
  delay(20000);
} 

You can check that it is working by attaching some potentiometers to the arduino, then after uploading the patch, use the serial monitor to watch the data values coming in.
There is a lot of documentation for setting up a feed on Pachube. You can send dummy data from the command line using curl, or you could use a simple python or processing patch to send data that you get from your arduino via the USB connection.

So far you have a quite standard setup to allow you to take this data and send it to pachube. But this means that you always need to have your laptop attached to your arduino and the internet. Not so optimal.

So now we add the FunkFeuer element. This of course assumes you are living somewhere were a FunkFeuer network, or something similar exists. But you can easily set up a small network yourself, and the wonderful thing about mesh networking, is that the mesh can easily extend itself! Share your internet connectivity, be the network.

So get a WRT54GL and prepare to void your warranty! We are sure this will work on other WRT hardware, OpenWRT is quite powerful.
Start by putting new firmware on your WRT, we will use the Leipzig firmware using this local but still usable HowTo. There will be some usage of the command line, vi, and some other gnashing of teeth, but I am sure it will all be okay.
Once you know that all is well, it is time to really get serious. Break open your WRT. There are no screws, you have to hold the case upside down and pop the blue part of the case off.
where to push to open the WRT

(Thanks to hendlsofen for the image - I hope I am not infringing on your image copyrighT!)
BINGO! warranty voided! You now really own your hardware.  Two screws hold the circuit board onto the bottom plastic panel. Undo these.
This discussion of serial connections touches on some of our issues that we will deal with. And it shows you where we will connect things to. Our system is a bit simpler. We will only be doing oneway communication from the arduino to the WRT, so we will only need one wire from the Tx pin on the arduino to the Rx pin (pin 5) on the WRT. We will then take 12V from the power inlet on the WRT and use that to power the Arduino.
EXCEPT: we have one final issue. the WRT operates at 3.3V, while the Arduino operates at 5V, which is pretty standard for electronics over the past 30 odd years. 3.3V has become more common in the past 10 years. For our prototype we used a Seeeduino Mega board which can be switched to operate at 3.3V. If you wanted to do a system that uses some of the WRT intelligence to communicate to the arduino, you could use one of these. But they are not as cheap or as ubiquitous as the Arduino.
showing connection from arduino /seeeduino to WRT serial connector
Here we can see the connection between the header of the WRT and the Tx and Rx connectors on the Seeeduino.

IMG_8255

The power connection taken straight from the 12V wall wart connection.
So we now have the hardware set up. Now the final step, the Lua script in the WRT.

The following script takes the data from the second serial port and passes it on. Note that the serial port is set up to be 9600 baud automagically. Note also that the 20 second time steps in the pachube updates is set by the arduino loop.

-- adapted from the last version, added code from caog on pachube                                                            
                                                                                                                             
function send(s)                                                                                                             
       local nixio = require "nixio", require "nixio.util"                                                                   
       local mysock = nixio.connect("api.pachube.com", 80)                                                                   
       if mysock == nil then                                                                                                 
         print("Mysock is nil! No data sent!\n")                                                                             
         return                                                                                                              
       end                                                                                                                   
       mysock:write("PUT /v2/feeds/.csv HTTP/1.1\r\n")                                                                   
       mysock:write("Host: api.pachube.com\r\n")                                                                             
       mysock:write("X-PachubeApiKey: \r\n")                 
       mysock:write("Content-Length: "..#s.."\r\n")                                                                          
       mysock:write("Connection: close\r\n\r\n")                                                                             
       mysock:write(s)                                                                                                       
       print(mysock:read(1024))                                                                                              
       mysock:close()                                                                                                        
end                                                                                                                          
                                                                                                                             
io.input("/dev/cua/1")                                                                                                       
                                                                                                                             
while true do                                                                                                                
       -- io.write("Starting a loop now\n")                                                                                     
       local line = io.read()                                                                                                
       if line == nil then break end                                                                                         
       if line ~= "" then                                                                                                    
               io.write("Input line: ",line,"\n")                                                                            
               n = 0                                                                                                         
               s = ""                                                                                                                                                                                                           
               for word in string.gmatch(line, "%S+") do                                                                     
                       s = s .. n .. ',' .. word .. '\r\n'                                                                   
                       n = n + 1                                                                                             
               end                                                                                                           
               send(s)                                                                                                       
       end                                                                                                                   
end   

Put this into a file, e.g. /root/dataTransfer.lua and start it with a  startup script. We use these instructions, which means that we create the file /etc/init.d/pachube with content:

#!/bin/sh /etc/rc.common
# Copyright (C) 2006 OpenWrt.org 

START=99
start() {
	[ -f /root/pachubeData.lua ] && lua /root/pachubeData.lua >&-
}

Then we call /etc/init.d/pachube enable and we are done.

If you do not have a seeeduino to play with, you will need to use a voltage divider to lower the output voltage from 5V to 3.3V. To do this (I have not done this myself yet! - this is still theory!), solder a 2.2k resistor between the Rx pin (pin 5) on the WRT header and ground, and connect the Tx lead on the arduino to a 1k resistor, the other end of which goes to the Rx pin on the WRT.