RSS
 

Controlling Arduino via Serial USB + PHP

28 Dec

Paloma bought me an Arduino for Christmas, and I’ve been having lots of fun with it, first following some tutorials to get familiar with the platform but of course the real excitement for me is being able to control it from my computer, so I’ve started playing around with serial communication over the USB port.

I messed around with Processing a bit, and while Processing seems pretty cool and pretty powerful for drawing and making a quick interface, I want to be able to get up and running fast communicating with all of our existing systems, so I thought PHP would be ideal.

I’ve never used PHP to communicate over a serial port before, so I did some digging and actually came across an example of using PHP to communicate with an Arduino, but it wasn’t working properly for me. My LED was blinking twice every time, and if I changed it to a value comparison (i.e. sending 1 in PHP and checking for 1 on Arduino) it was never matching. Turns out for some reason by default the com port wasn’t running in the right mode from PHP. The solution is a simple additional line:

exec("mode com3: BAUD=9600 PARITY=N data=8 stop=1 xon=off");

…but make sure you adjust to match the settings appropriate for your computer.

Of course I had to write my own little demo once I got it working. This PHP script takes command line arguments and passes them along to the arduino, which looks for ones and zeroes to turn the LEDs off or on. Unlike the example I linked to, I’m working with a shift register to drive 8 LEDs, but you’ll get the idea, and it should be obvious how to convert it to work with a single LED.

<?php
ini_set('display_errors', 'On');
exec("mode com3: BAUD=9600 PARITY=N data=8 stop=1 xon=off");
$fp = fopen("COM3", "w");
 
 foreach ($argv as $i => $arg) {
    if ($i > 0) {//skip the first arg since it's the name of the file
        print "writing " . $arg . "\n";
        $arg = chr($arg);//fwrite takes a string, so convert
        fwrite($fp, $arg);
        sleep(1);
    }
 }
print "closing\n";
fclose($fp);
?>

And for the Arduino:

//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 4;
const int clockPin = 3;
const int dataPin = 2;
void setup() {
    pinMode(latchPin, OUTPUT);
    pinMode(dataPin, OUTPUT);  
    pinMode(clockPin, OUTPUT);
    Serial.begin(9600);
    //reset LEDs to all off
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
    digitalWrite(latchPin, HIGH);
}

void loop() {
    byte val = B11111111;
    if (Serial.available() > 0) {
        byte x = Serial.read();
        if (x == 1) {
            val = B11111111;
        } else {
            val = B00000000;
        }

        digitalWrite(latchPin, LOW);
        shiftOut(dataPin, clockPin, MSBFIRST, val);
        digitalWrite(latchPin, HIGH);
        delay(500);
    }
}

For bonus debugging points, if you’re using a shift register like this, send x instead of val to shiftOut, and you can actually see which bytes are being sent, very handy if you’re not getting what you are expecting (like I was)!

 
1 Comment

Posted in Coding, fun

 
  1. Arthur Farias

    March 20, 2011 at 10:11 pm

    Cool!

    I’ve tried to do something just like this, but without success =P