PHP and the Arduino – Follow-up

I’ve had a bit of interest on the original entry, asking for more detail on the code used in the video demonstation at the end.

Download the relevent files here: arduinophp.zip

The zip file contains three files: index.php, serial.php and arduino_serial.pde. Two more files are required: the jQuery JavaScript library, and the PHP Serial class.

The code isn’t exactly elegant. It was just something I was playing around with, so there is probably scope for a lot of improvement. I’m not always great at explaining things like this, but I’ll give it a crack:

index.php

This doesn’t actually need to be a PHP file, since it only contains HTML and JavaScript. It’s just force of habit that caused me to save it as .php instead of .html.

This is the file I navigated to on my iPod touch. It consists of a HTML form containing two option boxes; one to select the LED and another to select the brightness. The value attributes on the options contains the actual data that’s sent to the Arduino.

An onClick event is added to the submit button that triggers the AJAXness, which is done using jQuery’s getJSON function. It calls serial.php with the values from the option boxes as GET variables. It also displays the returned values from serial.php on the page.

serial.php

This file does the actual communication with the Arduino. If first checks that the necessary GET variables are set, then does a bit of input sanitising and then constructs a packet to send via the serial port to the Arduino. The packet is three bytes:

  • The first byte is an @ symbol, which denotes the start of the packet to the Arduino.
  • The second byte is the index (0, 1, 2) of the LED to adjust, encoded to ASCII using PHP’s chr function.
  • The third byte is the desired brightness (0 – 255), similarly encoded using chr.

This is then sent, and the response from the Arduino is echoed.

arduino_serial.pde

This is the code loaded onto the Arduino itself. The most important part of it is the nest of ifs that check for and interpret the data packet sent by serial.php:

if (Serial.available() > 2) { // if there are at least 3 bytes in the serial buffer
  int p,i;
  incomingByte = Serial.read(); // read first byte
  if(incomingByte == 64){ // check if it is packet start (@ = 64 in ASCII)
    p = Serial.read(); // read second byte
    if(p >= 0 && p < numPins){ // check it is within a valid range
      i = Serial.read(); // read the third byte
      if(i >=0 && i <=255){ // check it is within a valid range
        set(p,i); // set LED p to brightness i
        printVals(); // respond with status
      }
    }
  }
}

That’s basically it. Hopfully that makes sense…

This entry was posted in Hardware and tagged , . Bookmark the permalink.

8 Responses to PHP and the Arduino – Follow-up

  1. dabrain13 says:

    This is a great project! I just have a few questions. One, where are you hosting the php code, on an Apache server on your Mac? Two, when you define the serial port, do you specify a port on the server? Clearly your iPod has no usb ports so how does it know where the arduino is?

    • Tinlad says:

      Hi dabrain,

      The PHP was indeed hosted on the built-in Apache server on my Mac.

      The iPod doesn’t perform any other function other than as a web-browser. It’s connected, via Wi-Fi, to the LAN my Mac’s on. Then I just point Safari to http://computername.local to see the Apache hosted files.

      The serial port to use is defined in the PHP code, which uses the PHP Serial class to do the actual communication.

      I hope that answers your questions.

      Thanks,

      Tinlad

      • Dabrain13 says:

        Thanks for your reply.

        I have everything setup now including Apache and have auto-reset disable using a 110 ohm resistor. However I still cannot get the LED’s to turn on. I edited my serial port address in serial.php and downloaded the other two files needed and put them in the correct directory but it has yet to function. With the jquery library, do you download the compressed, uncompressed, or minified versions? I downloaded the uncompressed and then renamed it as jquery.js as is referenced. Perhaps that’s where I went wrong?

        The arduino tx and rx lights blink when I send the signal, but nothing happens. Any suggestions?

        • Tinlad says:

          The version of jQuery you use shouldn’t matter. The uncompressed version is nicely formatted and uses sensible variable names, and is as such quite “human-readable”. The minified version uses short variable names and removes all white space from the script so that the file-size is smaller (to save bandwidth), at the expense of human-readability. Both produce identical results though.

          It’s an encouraging sign that the Arduino’s TX/RX lights are blinking when you send the signal. To me that suggests that although it’s receiving the packet, it’s not being interpreted as a valid set of values.

          To test this I would strip the Arduino code back to basics – have it turn on the LED regardless of what character(s) are received, i.e.:

          if(Serial.available() > 0){
          analogWrite(9,255);
          }

          (replace 9 with the pin your LED’s attached to)

          If that works, then it’s probably a problem with the packet system – either PHP’s not encoding it right, or the Arduino isn’t interpreting it correctly.

          Good luck! Please feel free to ask more questions.

          • Dabrain13 says:

            Thanks so much for your help!

            Ok, I’ve got the communication working and the lights are turning on! Unfortunately, I’m not getting any status reports. I noticed that in index.php, there’s nothing in the “status” div, is that ok?

            In addition, I’d like to add another form that just has the options on and off for two of the ports. I tried simply copying and editing, but it seems to only work if it’s in that original form, any suggestions? Here’s the HTML for the form currently:

            Lights
            Fan
            Water Pump

            0%
            10%
            20%
            30%
            40%
            50%
            60%
            70%
            80%
            90%
            100%

            Water Pump
            Stove

            Off
            On

            I’m using this for a Power controller hence the random appliance names.

            Thanks for your help!

  2. Dabrain13 says:

    Well, I guess it won’t let me post the HTML exactly, but they’re both in the same format, just different options. They’re even in the same .

    • Tinlad says:

      Yeah, I’ve had issues with getting WordPress to play nicely with code in comments. I think I see your aim though.

      To be honest, if I were doing this project again I’d do it slightly differently because, as you’re finding, the way I’ve done it is not very flexible.

      To have both incremental and toggle controls for a single device could be achieved (in a fairly hackish way) using JavaScript. If you had two drop-down menus, inc_dropdown with values 0, 25, 50, …, 255 and toggle_dropdown with 0 and 255:


      var myValue;
      $(document).ready(function(){
      $('#inc_dropdown, #toggle_dropdown').change(function(){myValue = $(this).val();});
      $('#submit').click(function(){
      ping($('#l').val(), myValue);
      return false;
      });
      });

      What that would do (hopefully, it’s untested) is set the value of the variable ‘myValue’ to that of whichever of the two drop-downs was changed last. The ping() function is then given ‘myValue’ as a parameter instead of the value of any single form control. I hope that makes sense…

      Regarding status reports – it’s been well over a year since I had this actually set up and running, but if I recall correctly I did have trouble getting the PHP Serial class to reliably receive data from the Arduino. The ‘status’ div is meant to be empty though – it’s populated using JavaScript. I can’t really think why it wouldn’t be working for you though.

      Sorry if this hasn’t been a very helpful message!

  3. ilium007 says:

    Hi – Great tutorial !!!

    I am having some issues, I can’t for the life of me get PHP to read the serial buffer via the readPort() function ? I can communicate with the Arduino fine, change the LEDs etc, but I never get a value returned. I am running Ubuntu 10.10 Desktop and everything else as per this doco.

    Any help would be appreciated – I have been trying to get this to work for 2 days now !!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Current day month ye@r *