HTTP GET Parameters with Arduino

For a while now Kevin B has been working on writing a library for communication using the NRF24l01 radio with the Arduino’s. The idea is to use them for home automation purposes. But of course that’s only one piece of the puzzle… what good is home automation unless it’s also internet ready?

20150419_115405

I took it upon myself to start looking into that portion, since it’s right up my alley (between server-side scripting such as PHP along with a database such as MySQL, and the API needing to working with Android of course).

Kevin’s thought was to use RS-232 between the Arduino and a Raspberry Pi or Seagate Dockstar. At first it seemed like a great idea until I started reading up on different methods to make this work.

Using Python + PHP

This seems to be the most popular recommendation, but I’ve never touched Python before. The idea was to have Python and LAMP running on a Raspberry Pi while connected to RS-232 and send/receive commands that way. Seemed simple enough, but boy was I wrong. Python boasts being extremely easy to learn for people new to programming, but after seeing a handful of examples, I didn’t even want to touch it. Maybe it’s from years of Java and over a decade of PHP, but my brain just didn’t want to even look at Python never mind understand it. NEXT!

PHP with Serial Library

My next thought was that there must be a library to do RS-232 communication through PHP alone. There were a few limitations that bothered me though. First, PHP is a server-side scripting language. It’s not really meant to run in loops forever waiting for serial data to be received in the same way an Arduino runs in a loop forever. Most web servers (such as Apache) come default with a 30 second max execution time, so if your script runs for more than 30 seconds the server will just terminate it anyway. There is also the issue that the Arduino resets every time you open a serial connection with it, which means even if you don’t loop the PHP script and just call it when needed, the serial data will be reset as soon as the script runs… not good. Kevin pointed out that this is due to DTR signal on RS-232 pulling the reset pin to ground, which isn’t an issue if using a Pro Mini without DTR connected, but in my case I had planned to use one of my Arduino Duemilanove boards as the base station (USB is built on board, so “it is what it is”).

Too Many Layers

Lastly since RS-232 doesn’t do any form of acknowledgements it means there would have to be another software layer in between to control and confirm data. At this point just to get the Arduino to talk to a web server, there was waaay too many points of failure for me:

arduino-pi-rs232The Simple Solution

20150419_115553

Then it hit me… the route I should have been going all along. An ethernet shield. This will take care of nearly all the problems. The Arduino can act as a web server, and with a bit of programming we can have it serving data or receiving and processing data. Using HTTP response headers, we already have a form of acknowledgements built-in. And lastly, later down the road I could actually remove the Pi from the picture completely if I wanted and instead use my VPS located off site, or even control multiple houses from a single server without the need of separate Pis everywhere or being limited by the processing power of the Pi.

arduino-pi-ethernet

So I plugged my Ethernet shield into my Arduino, along with a battery source for power (my USB ports weren’t giving enough current to keep it powered on by itself), and off to the races I went.

HTTP GET Parameters with Arduino

While not secure by any means, HTTP GET provides an easy solution. The idea is simple. Commands can be sent from the Pi by a GET parameter in the URL to the Arduino, the Arduino can then parse this data and do whatever needs to be done and then output the result (eg. Success or Fail). The Pi can wait for the output/result, and then process whatever it needs to do (eg. informing the user of the result).

20150419_120346

First we need to set up the network information for the shield. The Ethernet library does support DHCP, but its easier to use a static IP for testing.

Next we setup the ethernet server on port 80 (default HTTP port) as well as a string to store the GET parameter in.

The setup() function is pretty straight forward. Remember we can’t use pins 10 through 13 for any thing else as they are used for Ethernet. Unfortunately the NRF also needs some of those pins though, so I will have to look into using a SoftSPI library or figuring out how to use the SS pin (slave select) down the road.

Next is the loop() function. We’re going to check and see if there is a client trying to connect, if there is then we are going to send out a standard HTTP response header and start the processClient function

The processClient function is where the magic is going to happen. An HTTP request will end with a blank line, so we need to keep track of this so we know when were done processing data. We also need to find the “?” so we know where the HTTP GET begins. Once we found the “?”, we simple start looping through the characters one by one and store them into the string we created earlier: HTTPget.

Lastly we want to print the result onto the page, close the connection, and clear out our HTTPget variable so we can use it again on the next connection

 Putting It All Together

The End Result

The final result is being able to read HTTP GET parameters with Arduino. The Arduino will output it onto the page for the client (in this case a browser) to display. And the HTTP response header working perfectly.

arduino-http-get-parameter

2 thoughts on “HTTP GET Parameters with Arduino”

Leave a Reply

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