Arduino, Xport, PHP and the Internet

This article explains how to use the Arduino and an Xport Ethernet module to send and retrieve data to an external web server. I discuss the advantages of this method over various other methods of communications between Arduino and the internet. After discussing hardware setup, some simple test code for Arduino and the PHP code that you need to run on the web server is provided. Some real world extensions of this project are a web page that lets you control the lights in your house, or sending sensor data to a web page and graphing it so you have a pretty record of sensor readings.

The first stage in this project was researching how I wanted to connect Arduino to the internet. There are a lot of different options. The easiest required an external computer, but I avoided this because I wanted a highly reliable and very low power solution which a PC could not provide. I wanted a fairly simple solution that would use a minimal amount of flash memory on my Arduino. There is only 16K of flash memory on Arduino to hold your code. Since talking to a web server will always just part of a larger project I wanted to use the least memory possible so the rest of the project had enough space. After this research phase, I decided one the Xport modules from Lantronix would fit my needs best. The three Lantronix Ethernet modules I considered were the Xport, Xport Direct+ and Xport Direct. Xport has a different pin out than the Direct modules, but other than that they are very similar. As far as functionality the main difference is that Xport and Xport Direct+ have a web server, but Xport Direct does not. I went with the Xport because it was slightly smaller and had a web server. Knowing what I know now I would just get Xport Direct because it’s $30 instead of $50 like Xport Direct+ and Xport and I don’t need the web server.

Why don’t I care about a web server? At first I thought having a web server built into Xport was important, but for my use case it is not. The reason is because I would rather upload my data to a real web server. This way I don’t have to worry about a bunch of people connecting to my Arduino and effectively launching a denial of service attack on my Arduino. I would rather push data up to a real web server and then let it dish out the data to the rest of the world. This model also means I don’t need to worry about my firewall or getting my router to forward ports to my Arduino since all requests are initiated with Arduino. Another benefit of not using Xport’s web server is that it is quite limiting, but if I use an external web server then I can have much more flexibility like running PHP, SQL, Java, and any other common features that the Xport web server does not support.

I have a cheap hosted web server through Dreamhost. I mention dreamhost because I use them, but any web server that supports PHP and has a dedicated IP address should work fine for this project. One issue that took a long time to figure out is that cheap hosted account usually don’t have dedicated IP addresses for each domain name. I had to pay dreamhost an extra $4 a month for this option. One way to see if the domain you want to use has a dedicated IP address is to ping the server and then type that IP address into your web browser. If you have a dedicated IP address then you will go to your domain. If you don’t your browser will return an error. Another limitation of using a hosting service like dreamhost is that they have firewalls that get triggered if you try to connect too frequently. You can see in my code below how I added a delay to work around the firewall issues I found. I had to contact dreamhost a few times to get everything working. I must say their tech support was great and I was very pleased with the service they provided.

At this point I needed a way to connect the Xport to Arduino. I could have done this with a breadboard, but I found this cheap ($15) shield for the Xport module at Adafruit and it works great. That page also links to a great tutorial about putting the shield together and some code examples on how to setup a web server on Xport if you choose to go that route instead of what I’m describing here.

Now I could power up the Xport module and plug and Ethernet cable into it. Then I could configure it with telnet. You can get full documentation on your xport module and how to configure it here. Here is a list of the things I changed on my xport module.

  • Set the Channel 1 ConnectMode to “D4″ which changed the serial responce to single character mode (my code expects this mode)
  • Changed the Channel 1 port to 81 to work around my webhosting firewall
  • (Optional) Set the Xport to use a static IP address since I prefer that over the default dynamic IP address

The last part of the hardware setup was to hook up 3 wires between the Arduino and the Xport. Before doing this I decided to use the AFSoftSerial library. To install this library you just copy the AFSoftSerial directory into your Arduino-0011/hardware/libraries folder where all the libraries live. You could use the hardware serial port by using pins 0 and 1, but I wanted to allow those to talk to my PC so I used this soft serial port library. You can reconfigure all this in the code if you want, but I choose to use pin 2 as TX, pin 3 as RX and pin 4 as Xport Reset. Remember you need to connect Arduino’s TX pin to Xport’s RX pin, and Arduino’s RX pin to Xport’s TX pin. I made this stupid mistake. Just remember you need the transmit pins talking to the recieving pins or things just won’t work.

I have one note about the php code below. You can test test the php code with your web browser to make sure the php code is setup correctly. All you need to do is type this into your browsers address bar: http://www.yourdomain.com/arduino/xPortTest.php?value0=111&value1=222. Of course you’ll need to make sure the the location of the php file matches where it is located on your web server. This will append the values 111 and 222 to xportTest.txt and create the file if needed. If it doesn’t work the most likely issues are that your web server doesn’t support php or you don’t have the permissions setup to allow the php script to create/modify the text file.

That’s pretty much it. The code I used on Arduino and the PHP code I put on my web server is listed below. If anyone has any questions don’t hesitate to ask them here or on the Arduino Forums.

Arduino Code:

// Maurice Ribble
// 4-3-2008
// http://www.glacialwanderer.com/hobbyrobotics

// The flow of data is Arduino -> Xport -> PHP -> text file
// Once the connection is established by Arduino to the PHP page
// the PHP page can also send data back to Arduino

// This code demonstrates a simple yet flexible way to let Arduino
// talk to a webserver.  While there are versions of xport that
// have a webserver built in they are more expensive and require you
// to setup your internet connection to allow you to run a server.
// With this method you can just use a cheap hosted website.
// I use dreamhost and am very satisfied with their service, but there are
// many other options (any host that support PHP should work fine).
// With Dreamhost I needed to sign up for a dedicated IP address and I
// had port 80 with connections no more frequent than once per minute or
// I had problems with their firewall blocking my connection attempts.
// If you want to send data back and forth frequently just connect once
// and just keep using that connection.  This will avoid issues with
// web hosting firewalls.

// Xport Settings (everything default except)
//  Channel 1 -- CoonnectMode : D4 -- This changes serial responce to single char mode
//  Channel 1 -- Port 80
//   I also changed my IP address to a static IP, but you could leave this alone

#define XPORT_SERIAL_RX_PIN 3
#define XPORT_SERIAL_TX_PIN 2
#define XPORT_RESET_PIN 4

// These are web server specific values
#define PHP_PAGE_LOCATION "/arduino/xPortTest.php"
#define WEB_HOST "HOST: yourdomain.com\n\n"
#define IP_AND_PORT "C111.111.111.111/80\n"

#include 

AFSoftSerial xPortSerial = AFSoftSerial(XPORT_SERIAL_RX_PIN, XPORT_SERIAL_TX_PIN);

void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);
  xPortSerial.begin(9600);
}

void loop()
{
  xportReset();
  xportConnect();
  httpRequest();

  // Delay for 1 minute to aviod triggering my host's firewall
  delay(60000);
}

void xportReset()
{
  pinMode(XPORT_RESET_PIN, OUTPUT);
  digitalWrite(XPORT_RESET_PIN, LOW);
  delay(100);
  digitalWrite(XPORT_RESET_PIN, HIGH);
  delay(3000);
}

void xportConnect()
{
  byte theByte = 0;

  while (theByte != 'C')
  {
    xPortSerial.print(IP_AND_PORT);
    while(!xPortSerial.available()) {} // Just loop until available
    theByte = xPortSerial.read();
    Serial.print(theByte);
    Serial.print(" ");
  }
}

void httpRequest()
{
  byte theByte;

  xPortSerial.print("GET ");
  xPortSerial.print(PHP_PAGE_LOCATION);

  // value0 = 123 and value1 = 456
  // You should change these to be your sensor values or whatever you want to send
  // (see php code if you want to add more values or change the names value0/value1
  xPortSerial.print("?value0=123&value1=456");
  xPortSerial.print(" HTTP/1.1\n");
  xPortSerial.print(WEB_HOST);

  while(!xPortSerial.available()) {} // Just loop until available
  theByte = xPortSerial.read();
  if (theByte != 0)
    Serial.println("Passed.");
  else
    Serial.println("Failed.");
}

PHP Code:

You need to pass in valid _GET parameters. Script Terminated."; exit; } $fp = fopen("./xportTest.txt", 'at'); if (!$fp) { echo '

Failed to open file'; exit; } $outputstring = "$value0 $value1\r\n"; fwrite($fp, $outputstring, strlen($outputstring)); // end with a 0 to close the session to the client: echo "\0"; end; ?>

25 Comments

  1. rasputnik said,

    July 23, 2008 @ 3:50 am

    As long as you set the Host: header in the request (which you seem to do by editing WEB_HOST) then this should work fine with websites that don’t have dedicated IP addresses.

  2. Glacial Wanderer said,

    July 23, 2008 @ 6:27 am

    I have not tried this, but that’s a great tip. I’ll probably give it a try next time I have a need for this functionality.

  3. billyboy said,

    August 19, 2008 @ 1:20 am

    I just orderd my xport to connect my arduino to my network. Your PHP code link doesn’t work. no PHP code avable.
    Thanks for your contribution.

  4. Glacial Wanderer said,

    August 19, 2008 @ 5:31 am

    The link is working fine for me. Can you try it again? Also the code listed on this page matches what’s in that link so you could just cut and paste from this page.

  5. lett85 said,

    September 8, 2008 @ 12:48 pm

    Trying to get the code as well as a starter. Eventually I want to write some code to make it possible that two Arduino’s with XPORTs can read each others values. On one side somebody can put the light on that is attached to the other Arduino. Does anybody have any ideas how I can set this up? Tnx

  6. Caleb Cohoon said,

    December 29, 2008 @ 1:37 am

    Thanks a lot for this article. It really helped me out!

  7. Zachary Zimmerman said,

    May 31, 2009 @ 8:58 pm

    Thank you for this article! I’ve been trying to implement a hardware serial option for using the XPort with the Arduino Mega and I had been stumped by the TX -> RX to RX -> TX stupid mistake. Now it seems that all is well!

  8. patricio sthandier said,

    August 21, 2009 @ 4:23 pm

    It works

  9. Ken Dewey said,

    September 24, 2009 @ 4:55 pm

    My app sends data to a mysql database after the php code checks to verify
    that the rfid code is there. I need the php to send back a verify of
    to my xport so far no luck? Can you help?

    Ken

  10. Ron said,

    October 29, 2009 @ 1:17 am

    I’ve built an Arduino Ethernet shield with an xport Direct module and I have a strange thing happen. I’m only able to connect to a web server once. Thereafter, the module fails. I’m worried that it might be overheating. Did you do any heatsinking with your xport? I’m not sure if my experience is anomalous or what.

    Thanks

  11. Maurice Ribble said,

    October 29, 2009 @ 1:30 am

    I didn’t need a heatsink. One issue like this that I did run into was stated in the article above: Another limitation of using a hosting service like dreamhost is that they have firewalls that get triggered if you try to connect too frequently. You can see in my code below how I added a delay to work around the firewall issues I found.

    I found that connecting too frequently turned out to be twice. Web browsers only connect once and then hold on to that connection.

  12. Purnima said,

    January 20, 2010 @ 1:00 am

    I’m not able to see the php code.

    I’ve a web server and It needs to send data to the Arduino through XPORT.

    your php code might help me.
    Thanks in advance

  13. Sarim Rafiq said,

    April 21, 2010 @ 4:34 pm

    Hello,

    Uptill now i am successful to connect my pc to the xport using atmega32. i am receiving data on xport sent by pc…

    anyone please tell me how to ptogram my atmega32 to send data to my pc by using ip address or hostname…

    Thanx in advance….

  14. mike said,

    June 4, 2010 @ 11:22 pm

    The Arduino code doesn’t compile because the #include statement has no file. Is this where you specifiy the AFSoftSerial library?

  15. Maurice Ribble said,

    June 7, 2010 @ 4:52 am

    There is a link to the AFSoftSerial library in my blog post and directions on how to install it.

  16. Jeff said,

    December 30, 2010 @ 12:55 pm

    I have attempted to get this working, but am running into some snag-ups. I installed both sets of code in thier locations and can force the PHP file to add to the text file successfully through the browser. When I run the arduino code with my web host info put in, it just resets over and over. I put in some comment serial prints: it runs the setup(), then goes into loop(), runs reset() and then runs setup() again and repeats endlessly. Other than the comments that I added for troubleshooting, the serial monitor prints out nothing. Not sure whats wrong, all i changed was the host name and static IP, any suggestions?

  17. Snap said,

    December 30, 2010 @ 10:41 pm

    I too spent all night trying to connect to the ip adresses in the book making things talk. then i tried tying them into my brouser and they didnt work that way either. I spent the extra 2.99 a month with go daddy and got a dedicated ip and boom, it worked. I would like to try your project but I can’t seem to view the PHP code it is a blank page could you verify it is there or send it to me?
    Thanks

  18. jordotech said,

    February 1, 2011 @ 12:08 am

    fellas, the php code is in the link above the truncated code on this page.

  19. Tony Zampini said,

    February 24, 2011 @ 9:57 am

    Hi,

    Your example is proving to be very helpful to me. I’m using
    an XPort to control the thermostat in my office.

    I can pretty much follow your code, but was wondering
    what the 111.111.111.111 IP is in your code? This
    doesn’t look like any valid IP I’ve ever seen. Can you explain?

    Thanks so much!
    Tony

  20. Ulises said,

    May 5, 2011 @ 9:26 pm

    Ok, so now how can we make that from a pc on other part of the world control the arduino from internet?

    With this example we only see data, but how do we chang it?

    Thank you

  21. toby said,

    June 26, 2011 @ 6:04 am

    Hi there just wondering im not too good on this arduino but im a tv tech so i work with electronics and im building a sensor that detects temp of the ground then i want to send that data to a website so anyone can see the results is this what this can do or can you suggest anything else thanks could you send replys to my email address thanks

  22. Initial Data Capture @ Peter Ananin's DIXD Blog said,

    February 19, 2012 @ 6:43 am

    [...] A good article on Xport shield versus Ethernet shield Hobby Robotics ยป Arduino, Xport, PHP and the Internet [...]

  23. Ricardo said,

    March 7, 2012 @ 12:10 am

    Hi, Can I test this code using a xport pro?

  24. click here said,

    February 9, 2013 @ 8:40 pm

    What’s up to every one, it’s actually a good for me to pay a quick visit this
    site, it includes important Information.

  25. Bryan said,

    May 21, 2013 @ 1:39 pm

    It is also used as a balanced dietary supplement to your body.
    You may design your own personal gift pack from
    a number of different moisturizing and fragrant oils, including the beautiful Argan
    oil that keeps your skin moist and supple even under the driest sun and wind, or
    perhaps calendula if her skin is more sensitive.
    This small kernal is what provides the Moroccan argan oil.

RSS feed for comments on this post