Saturday, August 25, 2012

Arduino, Ethernet, Ethercard, XAMPP web server, PHP web page controlling 2 LEDs

[UPDATE 17 Sept 2012 - I have modified the XAMPP webserver code  get the details for the Arduino(s) from a database.  See the updated version here

I tinkered a while back with using a web server to control and Arduino over a serial connection and then I got an ENC28J60.  A really cheap Ethernet socket that can work with the Arduino. It uses the Ethercard community provided library.

My goal was to find a way to turn on and off LEDs which can later become Servos once I've done the hard coding from a web server that then connects to the Arduino over Ethernet.

Using this method the web server and the Arduino don't have to be near each other and even more importantly they don't need to be physically connected.

After a bit of research and trial and error I have something working.
This example presents a simple PHP based web page on the web server with the options to turn on or off 2 LEDs. (sorry for the gaudy colours in the video I thought it would be good to match the LED colours with the menus.

When you click a button on the web page it calls itself with a POST variable set.
The PHP page then interprets this and does an fopen() to the Arduino to do the requested action.

By doing an fopen() the actual connection to the Arduino is not shown on the web page.

The fun with this is that it could be expanded to control more pins easily and also control more than 1 Arduino.



PHP Code on the Server


<!--
Winlkeink
August 2012
For feedback, comments and questions go to winkleink.blogspot.com

This code works with the Ethercard_LED_ONOFF_PHPCall code for Arduino to control Pin2 and Pin4 on
the Arduino using a web server as the interface.
The web page is served with the options and when you click the button it does an fopen in the background
to the Arduino with the relevant command.
By doing this the IP address of the Arduino is not needed and also the commands to control the Arduino is not 
shown publicly when compared to using the Arduino as the web server itself and using a GET REQUEST.

By doing it this way you have more control over the Arduino and the web interface.

NOTE:
As always my code is rough and is designed to get things done rather than beign perfect or pretty.
Use as you wish and let me know your thoughts.

-->

<!-- Start of the HTML -->
<html>
<head>
<title>Click to Turn on or OFF the LED in the background</title>
</head>
<body bgcolor="#FF9933">
<?php

// Check of LED2 is set.  If it is use it
if (isset($_POST["LED2"]))
{
$LED2= $_POST["LED2"];
//echo "<b>$LED2</b>";
}
else
{
$LED2 ="";
}
if ($LED2 == "ON")
{
// Set led2 ON by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h = @fopen("http://192.168.1.5/?LED2=ON", "rb");
}
else if ($LED2 == "OFF")
{
// Set led2 OFF by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h= @fopen("http://192.168.1.5/?LED2=OFF", "rb");
}

// Check of LED4 is set.  If it is use it
if (isset($_POST["LED4"]))
{
$LED4= $_POST["LED4"];
//echo "<b>LED4 is $LED4</b>";
}
else
{
$LED4 ="";
}
if ($LED4 == "ON")
{
// Set led4 ON by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h = @fopen("http://192.168.1.5/?LED4=ON", "rb");
}
else if ($LED4 == "OFF")
{
// Set led4 OFF by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h= @fopen("http://192.168.1.5/?LED4=OFF", "rb");
}

?>
<!-- LED2 FORM -->
<table>
<tr><td colspan="2"><font size="4" color="yellow">Turn on and off the LED2</font></H4></td></tr>
<tr><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED2" value="ON">
<input type="submit" name="submit" value="ON">
</form>
</td><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED2" value="OFF">
<input type="submit" name="submit" value="OFF">
</form>
</td></tr>
</table>

<table>
<tr><td colspan="2"><font size="4" color="green">Turn on and off the LED4</font></td></tr>
<tr><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED4" value="ON">
<input type="submit" name="submit" value="ON">
</form>
</td><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED4" value="OFF">
<input type="submit" name="submit" value="OFF">
</form>
</td></tr>
</table>


</body>
</html>

Arduino code

/*
Winlkeink
August 2012
For feedback, comments and questions go to winkleink.blogspot.com

Script to allow the controling on the Arduino over Ethernet using an ENC28J60 Ethernet socket and the Ethercard library
Assigning Static IP for the Arduino so I can know exactly which Arduino I am controlling
For this example the request is either http://192.168.1.5/?LED2=ON or http://192.168.1.5/?LED2=OFF
These can be called directly but then the Arduino would have to be the web server and present back the web page
with the option to turn the LED off or ON

For this example I am controlling the Arduino from a webserver on my PC (XAMP) using a PHP script.

*/
// I took took inspiration from the following 2 examples

// The BackSoon example provided with the EtherCard library
// Present a "Will be back soon web page", as stand-in webserver.
// 2011-01-30 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php

// Example from the Internet
// https://github.com/lucadentella/enc28j60_tutorial/blob/master/_5_BasicServer/_5_BasicServer.ino
#include <EtherCard.h>

// ethernet mac address - must be unique on your network
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
// ethernet interface ip address
static byte myip[] = { 192,168,1,5 };
// gateway ip address
static byte gwip[] = { 192,168,1,1 };

byte Ethernet::buffer[500]; // tcp/ip send and receive buffer

// Using a Variable for the Pin, but it is not necessary 
const int ledPin2 = 2;
const int ledPin4 = 4;


// Some stuff for responding to the request
char* on = "ON";
char* off = "OFF";
char* statusLabel;
char* buttonLabel;

// Small web page to return so the request is completed
char page[] PROGMEM =
"HTTP/1.0 503 Service Unavailable\r\n"
"Content-Type: text/html\r\n"
"Retry-After: 600\r\n"
"\r\n"
"<html>"
  "<head><title>"
    "Arduino 192.168.1.5"
  "</title></head>"
  "<body>"
    "<h3>Arduino 192.168.1.5</h3>"
  "</body>"
"</html>"
;

void setup(){
// Set Pin2 to be an Output
  pinMode(ledPin2, OUTPUT);
// Set Pin4 to be an Output
  pinMode(ledPin4, OUTPUT);

// Scary complex intializing of the EtherCard - I don't understand this stuff (yet0  
  ether.begin(sizeof Ethernet::buffer, mymac);
// Set IP using Static
  ether.staticSetup(myip, gwip);
}

void loop(){
  
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);

// IF LED2=ON turn it ON
  if(strstr((char *)Ethernet::buffer + pos, "GET /?LED2=ON") != 0) {
      Serial.println("Received ON command");
      digitalWrite(ledPin2, HIGH);
    }

// IF LED2=OFF turn it OFF  
    if(strstr((char *)Ethernet::buffer + pos, "GET /?LED2=OFF") != 0) {
      Serial.println("Received OFF command");
      digitalWrite(ledPin2, LOW);
    }

// IF LED4=ON turn it ON
  if(strstr((char *)Ethernet::buffer + pos, "GET /?LED4=ON") != 0) {
      Serial.println("Received ON command");
      digitalWrite(ledPin4, HIGH);
    }

// IF LED4=OFF turn it OFF  
    if(strstr((char *)Ethernet::buffer + pos, "GET /?LED4=OFF") != 0) {
      Serial.println("Received OFF command");
      digitalWrite(ledPin4, LOW);
    }

//Return a page so the request is completed.

    memcpy_P(ether.tcpOffset(), page, sizeof page);
    ether.httpServerReply(sizeof page - 1);
  
}

If you want more details on using the ENC28J60 check out my previous post on it.  It gives details on wiring and various libraries for it.







16 comments:

  1. Hello
    Do you need to connect the INT pin on the enc28j60?

    ReplyDelete
  2. No need to wire up INT.

    See the following post with the wiring details.
    http://winkleink.blogspot.co.uk/2012/01/arduino-enc28j60-ethernet-module-part-2.html

    ReplyDelete
  3. thank you for the php code but the arduino code is deprecated and useless for our project ;).

    ReplyDelete
  4. how to get ethernet library arduino? i dont know how to get this library. thanks before

    ReplyDelete
  5. Hi...

    Can i ask whether can we use 2 client to connect to one server using 2 arduino ethernet shield?

    ReplyDelete
  6. sorry,i have arduino uno and an old tp link 54M wireless access point (TL-WA501G) and i want to control arduino through my laptop wireless, all i know so far is that i need to buy ethernet module for arduino and use the router as a client and make PHP web server. so can i get some help with software and hardware ??? sadly i am a beginner in networking

    ReplyDelete
  7. i did it from example and fail , i am ping not found

    ReplyDelete
  8. hey,
    when compiling the arduino code in the IDE 0021 i found an error:
    ( ethernet is not a class or namespace) in the following part in your code :
    byte Ethernet::buffer[500]; // tcp/ip send and receive buffer

    tell mehow i can fix this problem
    thanks for ur consideration

    ReplyDelete
  9. This comment has been removed by the author.

    ReplyDelete
  10. Hi
    Liked yo blogs, very interesting !!
    Let me tell you the status before telling about the problem I am facing:
    1) I am using Windows
    2) I have installed and have been running xampp on my computer
    3) I got the IP of arduino from DHCP client list of my router and it is 192.168.2.8. I have put this IP in the PHP code as well as in Arduino code.
    4) The connections between arduino uno, enc28j60 and the LEDs are correctly rigged up

    The problem I am facing is :
    I have put the PHP code in root directory of xampp(htdocs). When I type the url http://localhost/learnphp/ on the web browser, then I get the following error :
    "Object not found!
    The requested URL was not found on this server. If you entered the URL manually please check your spelling and try again."

    Please give me a solution.

    Thanks

    ReplyDelete
  11. if the ethernet shield and library programs ethercard this, use the AVR ATMega32+ENC28J60 whether it can also be accessed from a web server xampp php?

    ReplyDelete
    Replies
    1. please help me. because my final assignment exactly as you created. but I use ENC28J60 + AVR ATMega32. requests your server using LED and my stepper motors.

      Delete
  12. I need your help!!

    Im trying to edit a .TXT file when LED2=ON.
    To do that, i created another php file:




    An in your arduino code, after ' digitalWrite(ledPin2, HIGH); ' :

    ether.browseUrl(PSTR("/Arduino/Test.php?value0=111&value1=222"), NULL,website, NULL);

    where website is the servers name.

    This is NOT working!! Any ideas!?

    Thanx

    ReplyDelete
    Replies
    1. // Setup variables
      $value0 = $_GET['value0'];
      $value1 = $_GET['value1'];

      if (!$value0 || !$value1)
      {
      echo "invalid data";
      exit;
      }

      $fp = fopen("./xportTest.txt", 'at');
      if (!$fp)
      {
      echo 'Failed';
      exit;
      }

      $outputstring = "$value0 $value1\r\n";
      fwrite($fp, $outputstring, strlen($outputstring));

      // end with a 0 to close the session to the client:
      echo "\0";


      Delete
  13. Great !!! Working perfectly fine....Thanks

    Is there a way to get the status of the LEDs(whether ON or OFF)on the php page??? Please help

    ReplyDelete
  14. 1) arduino 3.3v output connected to vcc of enc28j60 usb is disabled why it is so
    2) i am connecting one end of Ethernet cable to enc28j60 module and other to ut300r2u modem in this case yellow and green light remains off.
    please give me the solution.

    ReplyDelete