Categories

# Perl + Arduino (+ ShiftBrite)

Back when I revealed the Twitter Monkey I had a dark secret… I got the Perl script to work, but just barely, and I really didn’t grok exactly how the code worked. I was just thankful MCQN Ltd. published the Alertuino code for me to get started.

I’m happy to say that I’ve made some good progress in getting Perl and the Arduino to talk to each other, and if you keep reading, you’ll see what I’ve got so far.

I’ll be using a ShiftBrite from macetech for this example. You can buy direct for \$4.99, get them from Adafruit for \$5.00 or use your #freeday money to get one from Sparkfun.

To connect the ShiftBrite, you just run it’s GND to the GND on the Arduino, the V+ to the 5V on the Arduino, and the run DI, LI, CI, EI to digital pins 10, 11, 12, 13 respectively, on the Arduino. Just 6 wires… pretty simple.

Once again, I stand on the shoulders of others… a hacker named Ashley Hughes wrote a post titled ShiftBrites and the Arduino and provided a library named shiftbritehughesyarduino. Grab it and drop it in your Arduino/libraries folder before we get started.

The library makes it pretty easy to send a color to the ShiftBrite using a command like this:

sb.sendColour(200,400,600);

Where the colors are in R,G,B value. Though the scale is not 0-255, or 0-100, but 0-1023. I’m not great at math, so I’m going to use the 0-100 scale and just multiply by 10. So for the line above we’d be sending a RED value of 200, a GREEN value of 400, and a BLUE value of 600.

Here’s the code for the Arduino:

/*
* ShiftBrite.pde
*/

#include "HughesyShiftBrite.h";

HughesyShiftBrite sb;

void setup() {
sb = HughesyShiftBrite(10,11,12,13);
sb.sendColour(10,10,10);
Serial.begin(9600);
}

void loop() {

switch (input) {
case 48:
sb.sendColour(0,0,100);
break;
case 49:
sb.sendColour(0,0,200);
break;
case 50:
sb.sendColour(0,0,400);
break;
case 51:
sb.sendColour(0,0,600);
break;
case 52:
sb.sendColour(0,400,0);
break;
case 53:
sb.sendColour(0,600,0);
break;
case 54:
sb.sendColour(0,800,0);
break;
case 55:
sb.sendColour(600,0,0);
break;
case 56:
sb.sendColour(800,0,0);
break;
case 57:
sb.sendColour(1000,0,0);
break;
}
delay(5);
}

See all those “case” commands followed by numbers? They are looking for the ASCII code being sent from the serial port. Don’t have an ASCII chart handy? Look at this simple one and you’ll see that the decimal value for 0 is 48, for 1 is 49, etc. So our case statements are looking for anything between 0 and 9, which is a nice scale to use.

OK, if you’ve uploaded the code, you should see the ShiftBrite lit up, since the initialization sent this:

sb.sendColour(10,10,10);

The code on the Arduino is now listening to the serial port waiting for some input. The input should be a number between 0 and 9. We should probably send it some numbers… that’s where Perl comes in:

#!/usr/bin/perl
#
# sendserial.pl
#

use Device::SerialPort;

my \$port = Device::SerialPort->new("/dev/tty.usbmodem1d21");
\$port->databits(8);
\$port->baudrate(9600);
\$port->parity("none");
\$port->stopbits(1);

sleep(3);

for (\$i = 0; \$i <= 9; \$i++) {
print \$i . "\n";
\$port->write("\$i");
sleep(1);
}

exit;

This is the shortest, simplest example I’ve got. You’ll obviously need the Device::SerialPort module installed. If you’ve written anything in Perl (or other languages) this should make some sense. We’re connecting to the serial port (/dev/tty.usbmodem1d21) and sending characters (0 through 9) to it, as well as printing them to the console so you can see them.

When you run the Perl script you should see the ShiftBrite light up and change about once per second, cycling through various levels of blue, green, and red.

Note: We got the port /dev/tty.usbmodem1d21 from the Arduino IDE (though I’ll show you another way to get it) and the sleep command is in there to give things time to initialize. I’ve found that without it, the serial port communication may miss the first commands.

Gotchas: The serial port may change. Mine is ‘/dev/tty.usbmodem1d21′ but it will be different on different machines, and may even change after a reboot. We’ll have a fix for that next time. The other gotcha is that when the Perl script is running, it’s using the serial port, so if you try to upload a new sketch to the Arduino, you will get an error. Since this script only runs for about 13 seconds, you probably won’t hit that problem here… for scripts that loop, you probably will.

I hope that wasn’t too complex. In theory, you could write the Perl part using Ruby, Python, or any scripting language that can do serial communications. In the future I’d like to try to use seriality to see if I can do it via HTML/JavaScript.

In a future installment I’ll have a complete project using all the bits we just covered…. stay tuned!