The basics of controlling an Arduino with PHP

You can easily add Internet-based control for your Arduino if it is close enough to your server to be connected via USB. This tutorial will give the basics you need to get it working.

The gist of this method involves a webpage that includes PHP elements. When one of those elements is manipulated, a command is sent via serial connection to the Arduino which then reacts based on what it received. This example uses an Ubuntu box that is running an Apache server. The Arduino sketch sets up the serial connection and then listens for incoming traffic. Whenever it receives a non-zero character an LED will blink. On the server side of things you’ll need to make sure that the system user that runs Apache (www-data) has permission to write to a serial port.

This base example may seem extremely simple, but there’s no end to what you can build on top of it. Different PHP events can be added to push new commands over the serial connection with matching test conditions added to the sketch.

[Thanks Jarryd]

Comments

  1. Michael says:

    Yeah i used this for a project, but abandoned it, because PHP -> Arduino works great, but Arduino -> PHP works really bad. And there’s not really anything else out there that can. Basically, you want Arduino outputted messages to be read by PHP, but that’s not currently possible. I mean if you send out serial.out(“sometext”) in Arduino PHP will nog be able to read it!

  2. hudson says:

    Why the heck someone would like to use arduino with php? There is nothing wrong with php(Not a flamebait, really). But I mean I think that for real one should use a bit more robust language? Like C, C++ or JAVA, Python?

    PHP also limits the maximum script run time and is ment for totally different usage scenes..

  3. PodeCoet says:

    @Michael

    I don’t know much about Arduinos, but I’m guessing they work similar to PICs/AVRs code-wise (in the sense that you have access to UART receive interrupts)

    A work-around for the issue you mentioned would be to make it poll-based; ie: we have an interrupt that waits for a special qualifier or ‘attention word’ to be received on the RX line of your microcontroller. Once the character is received, the microcontroller sends its status update, it becomes like a PING? PONG!, kinda sorta QA session.

    The PHP script can then occasionally/automagically (say, every few seconds) send the qualifier to the microcontroller, which will then reply with its status or anything else you want to send to the PC

    …Of course, there’s a default maximum execution time for PHP scripts (30 seconds I believe), so it’s best to call the polling routine from your browser using AJAX/javascript, rather than leaving the script running for so long. If you’re game and there’s no urgency for the responses, you can run the polling PHP script as a scheduled task or cron job, and have the responses stored in a table, etc

    Not the best solution, but it’ll work!

  4. PodeCoet says:

    @hudsen

    Heh unforutunately PHP is more “n00b friendly’ than the other languages you’ve mentioned, it’s also interpreted. I agree though, there’s alot of potential issues – Python would’ve been a great alternative.

    That said, I’m guilty of using PHP-CLI for general purpose scripting on occasion, I can be as retardedly inefficient as I bloody well want :P

  5. Michael says:

    @hudson simply because they want something done from the web? for every other kind of project yeah, use a more robust language :)

    @PodeCoet I understand your solution, thing is, Arduino can’t really ‘send’ anything else then Serial messages. the class used can’t read those, so there’s no duplex communication. get what i mean? so it doesn’t matter what you send, it won’t arrive ‘in’ PHP. At least this is what i found out. If some uber PHP guru can make Arduino tell PHP stuff, please let me know :)

  6. PodeCoet says:

    @Michael

    Forgive me if I’m wrong – It appears as though the PHP class supports both read and write capability – there’s a function called readPort() in the PHP class (line 470), which is able to read a byte of data from the servers serial FIFO (you can chose to read one, many or all characters), Linux only of course.

    Looking at the Arduino commandset, there’s serial.read() and serial.write()

    Could one not send ‘something’ to the Arduino using the PHP class, then immediately call readPort() and wait for the Arduinos response or a timeout occurs? Simplex communication, but it’ll work

    This is the exact same way Parallax’s one-wire ‘serial’ thermopile sensors work

  7. Michael says:

    @PodeCoet you’re right, I tried that but somehow it didn’t work. Maybe someone else got it to work?
    Maybe it had something to do with the baud rate but i think i got that right, otherwise the PHP -> Arduino wouldn’t work either right?

    Maybe i’ll give it a new try later on, to see if i was correct.

  8. fartface says:

    Nice, but I prefer rs232 as it’s universal and allows me to hook up 5 arduinos and address them all from the same port. Cant do that with the low grade USB consumer connection.

  9. Daid says:

    @fartface: rs232 is NOT multi slave. And just a point to point connection.
    You’re looking for rs422 or rs485, which support multiple devices on a single bus.

  10. Daniel says:

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaargh PHP

  11. rizla says:

    Whoever said you can have php read incoming serial and send data via serial clearly hasnt really tried.

    When i first attempted to use php-cli (Disclosure: i’m more familiar with php than any other scripting language, so i used php-cli for my “scripting”) I tried to to use the php serial library thats floating out there.

    I found that script if left running ends up going apeshit consuming resources. So i found, a “clever” solution to read data from the arduino.

    I use linux (ubuntu, yea go figure..) and since you can easily read/write from /dev/ttyUSB* I decided to create a little shell script that runs infinity that cats the output received from ttyUSB* to a flat file ( cat /dev/ttyUSB* | tee file.txt I used tee so i could also see the output that was written to the file in my term)

    A file gets created in some working dir php has access to. Then i created my php script that loops while true, to check the file, read the contents then parse each line of data. I have a counter that keeps track of what the last line read in the loop was, saves it to a variable so that the next time the loop increments it doesnt read the file from the top again, just the last lines that were written since the loop last checked.

    Its resource intensive and i have a great way of reading data and acting intelligently on it.

    For sending data to the arduino from php. Once again, i cheated and used the backtick `

    //send data
    `echo “$mydatforduino” >> /dev/ttyUSB*`;

    There you go. FYI, this works in full duplex. I’ve tested it and use it for one of my projects using 8 xbees talking to one computer running the php parsing script.

    In summary, is it wise to use php to handle the serial reading/writing. My testing has proven no. Is it ok to use php to do intelligent things once you have the data? Yes, by all means if thats what you are comfortable with go ahead and write a script that does what you want. Is it production worthy? thats up to your target.

    Also, note if you use xbee’s. You will get flakey comm every now and then. Make sure you configure the xbee’s themselves properly (be mindful of the ATRR, retry rate. It helps make sure no corruption happens). Also, add integrity checking in your script so that you know if you have a bad string of data otherwise you can get junk data.

    Just use some sort of delimeters for your start of string and end of string. Then parse the string looking for your delimeters.

    Sorry for the long post, but i figured i’d share what I’ve had pretty good results with.

  12. rizla says:

    Crap.. I meant to say that my solution is NOT resource intensive. barely hits the cpu and i’m running this script on an old eeePC netbook.

  13. shorts says:

    @PodeCoet, @michael

    just send the information back through the url…GET

    Or did I misunderstand your situation?

  14. mdonoughe says:

    What happens if you get two requests simultaneously?

  15. rizla says:

    In my case i was using an xbee for my serial comm. the xbee protocol should take care of multiple requests happening at once. obviously there would be some error checking. Thats why i recommended setting the ATRR setting to something other than zero so that if it fails (if a collision or some other event) it will resend. By default the ATRR is set to zero. I set mine at 2 retries.

    If you’re using just a straight serial cable i dont see how you would have two requests coming in simultaneously. Since its serial afterall.

    Another thing that could help preventing corruption (assuming your doing wireless via xbee) is by increasing the baudrate so that the packets get there faster. Default is 9600, i upped mine to 57600 (ATBD 6)

  16. mdonoughe says:

    @rizia: Starting to read at a certain line number involves reading the entire file up to that point to look for new line characters. Can you save the offset from the beginning of the file to the end and seek/skip back to that position the next time you read? You could possibly improve it further by waiting for filesystem notifications instead of polling the file(although that means that you’ll timeout if the Arduino doesn’t respond).

  17. rizla says:

    @mdonoughe

    Thats a good tip thats possibly worth implementing to help speed things up a bit, but given that its not super time sensitive in nature the current approach works. I’ll have to check to see what sort of seek/skip functions php has built in. Writing the whole contents of a couple hundred k file, then only parsing the last nth string does seem to be the kludgy way. The more i think of it, i’m going to check your approach out.

    thanks!

  18. mdonoughe says:

    Oh, I meant two web requests coming in at once. I’m guessing that a proper serial library will only allow one request to go through, causing the other to return an error instead.

    With a pipe into /dev/ttyUSB, it’s possible your requests could become mixed like “GET GET a a” instead of “GET a GET a”. The kernel probably (unintentionally) prevents this for small messages so long as you send the entire message using a single echo.

    Depending on your protocol, you might mix up your responses from the serial port when sending them back to the client.

  19. Taylor Alexander says:

    Man, there is a lot of misunderstandings going on on this page!

    1) The post is not about writing code for an Arduino in PHP, it is about using PHP on a web server to control anything connected to that web server’s serial port. In this case, that is an arduino.

    2) Whoever said they prefer RS232 over “low grade consumer USB” because “RS232 allows multiple devices on one line” is sorely misinformed. “Low grade consumer USB” is just a (great) data pipe over which anything, including RS232, can be transmitted. RS232 USB adapters are common, and exactly what the article is mentioning.

    Personally, I never knew you could do this, but it seems like people have had problems. When I needed to do something like this, I wrote a helper program in C# that ran on my windows host. It then sent an HTTP GET (or POST?) request to a PHP script that would take whatever parameters I had and update a database. Finally, I had some AJAX that would update values onscreen. The end result was that I could show sensor data on a web page in real time, without page refreshes. It was pretty slick! Note that I went *TO* the web, not *FROM* the web, but something like that could be tweaked to go both ways.

  20. Taylor Alexander says:

    Oh, and I forgot to mention that RS232 doesn’t support multiple endpoints, but someone else mentioned that.

    More than anything I was just surprised at how many people completely missed the point of this (yes, I know, I must be new here).
    -Taylor

  21. digitalfx says:

    I could have used this when I was getting stared with arduino a few months ago. I used php to control my arduino from the web, but as many people posted here it passing data back to php was a pain. I ended up using php to send data and python to receive it.

  22. Michael says:

    @digitalfx Yes! i’m not the only one :) As i don’t know Python (yet) i used TinkerProxy (actionscript 3) eventually. Although that worked really nicely, you had to have a server running. not the most native kind of solution, but it worked well :)

    @rizia, that’s a solution indeed. however, it’s not really a nice solution as it should just be possible to actually read serial data from php. But then again, who cares? There’s way nastier solutions to way bigger problems in software-hardware-land. Maybe you could contribute that to the serialphp project? In the end people just need to read that data, they don’t care (in most cases) where it’s coming from.

    Controlling 8 xbees from the web via PHP is frikking awesome, will check xbees out in the near future for sure!

  23. ilianko says:

    There is very nice tool called ser2net. It is daemon that provides a way for a user to connect from a network connection to a serial port. If it is running, serial port can be accessed for write and reading with somethink like this ” $fp =fsockopen(“localhost”, 2000) “.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 96,725 other followers