ajfisher's doing space

From the Blog

I’m a big fan of networked arduinos – especially these EtherTens from Freetronics. When an arduino is networked it opens up a degree of interactivity and awareness that is hard to achieve with serial – not least because your processing can occur somewhere physically distant from your display.

This project (pictures and video in action on the project page) was a proof of concept on exactly that set up, having remote processing that could be anywhere – in this case processing the twitter streaming API for keywords, and sending messages over the network to an arduino which would then manage the display. There are a lot of different ways you could do this including using things like web sockets and doing pubsub messaging etc but this was designed for simplicity and to prove the model more than anything.

To build this project you need an arduino that has networking capability – as mentioned above I use an EtherTen but you could use a standard Ethernet shield as well. Similarly you could do with a WiFi shield too with only a few mods to the code.

The arduino is simply connected to an RGB LED (or light disc in my case) with each of the colour pins coming through to a PWM pin on the arduino. In the code below there are references to “channels” – this code makes very little assumptions about the set up so it simply has the notion that there are PWM channels and you want to do something with them.

The full arduino code is here, however here’s some highlights:

  channel[0] = 3; // etc this will point channel 0 to Digital PWM pin 3
 
  // set up each of your channels as an output.
  for (int i=0; i<MAX_CHANNELS; i++) {
    if (channels[i] > 0) pinMode(channels[i], OUTPUT);
  }

The above code is in the setup() function and maps each of the channels to the relevant PWM output (technically you could actually use any output but you won’t get an analog range on it later).

This next block of code actually manages the timing of the various channels and sets them independently of each other. The code is run much like a state machine with each channel operating independently of the others so there’s a countdown counter that determines how much longer to pulse the channel and that counts down over the loop, eventually switching off the channel when it expires.

  // check the situation with the channels and fade out if the timer has exhausted
  boolean active_channels = false;
  for (int i=0; i<MAX_CHANNELS; i++) {
    if (channels[i] != 0 && channel_timers[i]> 0) {
      DEBUG_PRINT("Timer CD");
      DEBUG_PRINT(i);
      DEBUG_PRINT(": ");
      DEBUG_PRINTLN(channel_timers[i]);
      channel_timers[i] -= (millis() - last_time);
      last_time = millis();
      if (channel_timers[i]<= 0) {
        channel_timers[i] = 0;
        fadeout(i);
      } else {
        active_channels = true;
      }
    }
  }
  if (!active_channels) last_time = 0; // reset the master timer to zero if nothing's using it.
 
  delay(5);

And along with some adaptations of the standard web serving code this pretty much runs just like any other arduino web server.

Assuming you’ve got this up and running you should be able to hit http://yourip-address/1/1000 from a browser and it will pulse channel 1 for 1 second. You can do the same thing on 0, 2 & 3 as well if you have all 4 channels operating. To change channels, change the first part of the URL and to change the time it pulses for change the second parameter thus http://yourip-address/[CHANNEL]/[TIME]

Once that’s running you can then script just about anything to hit those URLs and cause the light to pulse for a defined duration. Here’s how I did it with twitter. This is a python script that runs off the command line. Again, I won’t show the full code but you can get it here.

The main bit of code that does the calling is this:

stream = FilterStream(args.user, args.pwd, track=words)
 
for tweet in stream:
    print "+++++"
    print tweet["user"]["screen_name"]
    print tweet["text"]
 
    try:
        response = urllib2.urlopen(args.url).read()
    except Exception, e:
        print "Unexpected error:", sys.exc_info()[0]

Here, the stream is created (you have to supply twitter credentials to access the streaming API. Words is simply a list of keywords you want to watch. Then every time the stream gets a new tweet it will go round the loop, spitting out the tweet and then calling the URL that was defined (eg http://someip-address/CHANNEL/TIME).

This script is designed to run from the command line so you can run multiple of these as background processes, each of them calling your arduino whenever a tweet comes through that matches. I’ve run this for days at a time without any drama so it’s pretty stable.

Whilst this has been designed to work with twitter, the process is general and I’ve used this with all manner of different sources such as getting an email or an order occurring on a website. Anything you can trap as an event you can then trigger the arduino to do something.