Using the Arduino Ethernet to host a website that control the outputs
Moderators: adafruit_support_bill, adafruit

Was this code helpful for you?

Yes
1
100%
No
0
No votes
 
Total votes : 1

Using the Arduino Ethernet to host a website that control the outputs

by dimbeault on Sat Mar 30, 2013 9:18 pm

Hi, I'm currently working on a code for hosting a website withing an Arduino that would allow you to control the outputs.

This is the working code :

Code: Select all | TOGGLE FULL SIZE

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { your Arduino MAC address };
IPAddress ip( your Arduino IP address);

EthernetServer server(80);

String HTTP_req;

boolean Status5 = LOW;
boolean Status6 = LOW;
boolean Status7 = LOW;
boolean Status8 = LOW;
boolean Status9 = LOW;

void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("Server is at ");
  Serial.println(Ethernet.localIP());
  pinMode( 5, OUTPUT);
  pinMode( 6, OUTPUT);
  pinMode( 7, OUTPUT);
  pinMode( 8, OUTPUT);
  pinMode( 9, OUTPUT);
}

void loop()
{
  EthernetClient client = server.available();

  if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        HTTP_req += c;
        if (c == '\n' && currentLineIsBlank) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");
          client.println();
          client.println("<!DOCTYPE html>");
          client.println("<html>");
          client.println("<head>");
          client.println("<title>LED Controller</title>");
          client.println("</head>");
          client.println("<body>");
          client.println("<h1>Arduino Ethernet LED Controller</h1>");
          client.println("<p>Click to switch LEDS on and off.</p>");
          client.println("<form method=\"get\">");
          ProcessCheckbox(client);
          client.println("</form>");
          client.println("</body>");
          client.println("</html>");
          Serial.print(HTTP_req);
          HTTP_req = "";
          break;
        }
        if (c == '\n') {
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
    delay(2);
    client.stop();
  }
}

void ProcessCheckbox(EthernetClient cl)
{
  Status5 = LOW;
  cl.print("<input type=\"checkbox\" name=\"LED5\" value=\"2\" onclick=\"submit();\"");
  if(HTTP_req.indexOf("LED5=2") > -1) {
    Status5 = HIGH;
    if(HTTP_req.indexOf("Referer:") > -1) {
      if(HTTP_req.indexOf("LED5=2") > HTTP_req.indexOf("Referer:")) {
        Status5 = LOW;
      }
    }
  }
  if(Status5) {
    cl.print(" checked");
  }
  digitalWrite(5, Status5);
  cl.println(">LED 5<br>");

  Status6 = LOW;
  cl.print("<input type=\"checkbox\" name=\"LED6\" value=\"2\" onclick=\"submit();\"");
  if(HTTP_req.indexOf("LED6=2") > -1) {
    Status6 = HIGH;
    if(HTTP_req.indexOf("Referer:") > -1) {
      if(HTTP_req.indexOf("LED6=2") > HTTP_req.indexOf("Referer:")) {
        Status6 = LOW;
      }
    }
  }
  if(Status6) {
    cl.print(" checked");
  }
  digitalWrite(6, Status6);
  cl.println(">LED 6<br>");

  Status7 = LOW;
  cl.print("<input type=\"checkbox\" name=\"LED7\" value=\"2\" onclick=\"submit();\"");
  if(HTTP_req.indexOf("LED7=2") > -1) {
    Status7 = HIGH;
    if(HTTP_req.indexOf("Referer:") > -1) {
      if(HTTP_req.indexOf("LED7=2") > HTTP_req.indexOf("Referer:")) {
        Status7 = LOW;
      }
    }
  }
  if(Status7) {
    cl.print(" checked");
  }
  digitalWrite(7, Status7);
  cl.println(">LED 7<br>");

  Status8 = LOW;
  cl.print("<input type=\"checkbox\" name=\"LED8\" value=\"2\" onclick=\"submit();\"");
  if(HTTP_req.indexOf("LED8=2") > -1) {
    Status8 = HIGH;
    if(HTTP_req.indexOf("Referer:") > -1) {
      if(HTTP_req.indexOf("LED8=2") > HTTP_req.indexOf("Referer:")) {
        Status8 = LOW;
      }
    }
  }
  if(Status8) {
    cl.print(" checked");
  }
  digitalWrite(8, Status8);
  cl.println(">LED 8<br>");

  Status9 = LOW;
  cl.print("<input type=\"checkbox\" name=\"LED9\" value=\"2\" onclick=\"submit();\"");
  if(HTTP_req.indexOf("LED9=2") > -1) {
    Status9 = HIGH;
    if(HTTP_req.indexOf("Referer:") > -1) {
      if(HTTP_req.indexOf("LED9=2") > HTTP_req.indexOf("Referer:")) {
        Status9 = LOW;
      }
    }
  }
  if(Status9) {
    cl.print(" checked");
  }
  digitalWrite(9, Status9);
  cl.println(">LED 9<br>");
}



I can control 5 output with this at the moment. But there is 14 output on the Arduino Ethernet. When I add more the Arduino freeze.

I have determine that :

    0 - Serial RX
    1 - Serial TX
    2 - ...
    3 - ...
    4 - SD Card
    10 - Ethernet module
    11 - Ethernet module
    12 - Ethernet module
    13 - Ethernet module

I don't know what 2 & 3 are used for. If someone knows, can you share your knowledge?

If someone can control more outputs on the Arduino Ethernet, can you share this knowledge too?
Last edited by dimbeault on Thu May 09, 2013 7:13 pm, edited 2 times in total.
User avatar
dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 6:15 pm
Location: Franquelin, Québec, Canada

Re: Using the Arduino to host a website that control the outputs

by adafruit_support_bill on Sun Mar 31, 2013 5:48 am

Pins 2 and 3 are the external interrupt pins, but I don't believe they are used by the Uno-Ethernet. There is a link to the schematics here: http://arduino.cc/en/Main/ArduinoBoardEthernet

It is also possible that you are running out of SRAM. Can you control pin 2 if you disable some of the other pins?
User avatar
adafruit_support_bill
 
Posts: 29172
Joined: Sat Feb 07, 2009 9:11 am

Re: Using the Arduino to host a website that control the outputs

by dimbeault on Sun Mar 31, 2013 3:35 pm

I tried with only pin 2 and 3 and I can control them without problem...

For the memory use, the compiler tell me that it uses 16k out of 32k...

Why when I try 2, 3, 5, 6, 7, 8 and 9 it freeze during operation? It works when it starts but freeze when I change the outputs...
User avatar
dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 6:15 pm
Location: Franquelin, Québec, Canada

Re: Using the Arduino to host a website that control the outputs

by adafruit_support_bill on Sun Mar 31, 2013 3:42 pm

For the memory use, the compiler tell me that it uses 16k out of 32k...

That is your flash usage. A SRAM shortage is the more likely problem. The Arduino only has 2K of SRAM for variables, buffers stack etc. Overflowing the stack causes unpredictable behavior such as the freezing you describe.
http://itp.nyu.edu/~gpv206/2008/04/maki ... o_mem.html
User avatar
adafruit_support_bill
 
Posts: 29172
Joined: Sat Feb 07, 2009 9:11 am

Re: Using the Arduino to host a website that control the outputs

by dimbeault on Sun Mar 31, 2013 7:17 pm

It must be it, everything in print or println counts, and all the content of the website is placed in there! Not too long for reaching the limit!!!

I'll work on a compression and repost the newer version!
User avatar
dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 6:15 pm
Location: Franquelin, Québec, Canada

Re: Using the Arduino to host a website that control the outputs

by dimbeault on Sun Mar 31, 2013 8:50 pm

You where right, I put parts of the website in the SD Card and removed the maximum I could.

Here is the new code :

First create two files

header.txt :

Code: Select all | TOGGLE FULL SIZE
HTTP/1.1 200 OK
Content-Type: text/html
Connection: close

<!DOCTYPE html>
<html>
<head>
<title>LED Controller</title>
</head>
<body>
<h1>Arduino Ethernet LED Controller</h1>
<p>Click to switch LEDS on and off.</p>
<form method="get">


and footer.txt :
Code: Select all | TOGGLE FULL SIZE
</form>
</body>
</html>


and the new Arduino code :

Code: Select all | TOGGLE FULL SIZE
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

byte mac[] = { mac address of your Arduino };
IPAddress ip( ip address of your Arduino );

EthernetServer server(80);

String HTTP_req;

File myFile;

void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("Server is at ");
  Serial.println(Ethernet.localIP());
  pinMode( 2, OUTPUT);
  pinMode( 3, OUTPUT);
  pinMode( 5, OUTPUT);
  pinMode( 6, OUTPUT);
  pinMode( 7, OUTPUT);
  pinMode( 8, OUTPUT);
  pinMode( 9, OUTPUT);
  pinMode(10, OUTPUT);
  SD.begin(4);
}

void loop()
{
  EthernetClient client = server.available();

  if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        HTTP_req += c;
        if (c == '\n' && currentLineIsBlank) {

          myFile = SD.open("header.txt");
          if (myFile) {
            while (myFile.available()) {
              client.write(myFile.read());
            }
            myFile.close();
          }

          ProcessCheckbox(client, 0);
          ProcessCheckbox(client, 1);
          ProcessCheckbox(client, 2);
          ProcessCheckbox(client, 3);
          ProcessCheckbox(client, 5);
          ProcessCheckbox(client, 6);
          ProcessCheckbox(client, 7);
          ProcessCheckbox(client, 8);
          ProcessCheckbox(client, 9);

          // Footer
          myFile = SD.open("footer.txt");
          if (myFile) {
            while (myFile.available()) {
              client.write(myFile.read());
            }
            myFile.close();
          }

          HTTP_req = "";
          break;
        }
        if (c == '\n') {
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
    delay(1);
    client.stop();
  }
}

void ProcessCheckbox(EthernetClient cl, int PinOut)
{
  int Status = LOW;
  String R = "Referer:";
  String GetValue = "L";
  GetValue += PinOut;
  GetValue += "=2";
  cl.print("<input type=\"checkbox\" name=\"L");
  cl.print(PinOut);
  cl.print("\" value=\"2\" onclick=\"submit();\"");
  if(HTTP_req.indexOf(GetValue) > -1) {
    Status = HIGH;
    if(HTTP_req.indexOf(R) > -1) {
      if(HTTP_req.indexOf(GetValue) > HTTP_req.indexOf(R)) {
        Status = LOW;
      }
    }
  }
  if(Status) {
    cl.print(" checked");
  }
  digitalWrite(PinOut, Status);
  cl.print(">LED ");
  cl.print(PinOut);
  cl.println("<br>");
}


So this new code works fine with all these outputs : 0, 1, 2, 3, 5, 6, 7, 8, 9. But Memory is very tight. Altering might cause read error to SD or make the Arduino freeze. I'm looking to include the analog outputs. I'll publish my result when I find a way to do this without overloading the memory.
User avatar
dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 6:15 pm
Location: Franquelin, Québec, Canada

Re: Using the Arduino to host a website that control the outputs

by adafruit_support_bill on Mon Apr 01, 2013 5:01 am

You can squeeze out a bit more memory there using the "F()" macro for your literal strings;

Instead of: print("abcdef");
use: print(F("abcdef"));

That will keep the string in Flash memory untill needed instead of copying it to SRAM at load time.
User avatar
adafruit_support_bill
 
Posts: 29172
Joined: Sat Feb 07, 2009 9:11 am

Re: Using the Arduino to host a website that control the outputs

by dimbeault on Mon Apr 01, 2013 6:07 am

Cool! I've added the modification for the last function :

Code: Select all | TOGGLE FULL SIZE
void ProcessCheckbox(EthernetClient cl, int PinOut)
{
  String GetValue = "L";
  GetValue += PinOut;
  GetValue += "=2";

  cl.print(F("<input type=\"checkbox\" name=\"L"));
  cl.print(PinOut);
  cl.print(F("\" value=\"2\" onclick=\"submit();\""));

  int Status = LOW;
  if(HTTP_req.indexOf(GetValue) > -1) {
    Status = HIGH;
    cl.print(F(" checked"));
  }
  digitalWrite(PinOut, Status);

  cl.print(F(">LED "));
  cl.print(PinOut);
  cl.println(F("<br>"));
}



It's only there where I have string. With this I can attempt to add control of the Analog.

I also made more test with the Arduino, and pin 0 and 1 and not usable. So you have to remove those line :

Code: Select all | TOGGLE FULL SIZE
  pinMode( 0, OUTPUT);
  pinMode( 1, OUTPUT);

  ProcessCheckbox(client, 0);
  ProcessCheckbox(client, 1);


It didn't freeze the Arduino, but LEDS connected to the outputs didn't responded. Those are really reserved for RX and TX.
User avatar
dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 6:15 pm
Location: Franquelin, Québec, Canada

Re: Using the Arduino to host a website that control the outputs

by dimbeault on Mon Apr 01, 2013 6:17 am

I found a problem with the 0 and 1, if you set them HIGH and then reprogram the Arduino, you will get a communication error. Set them LOW and try again, it will work.
User avatar
dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 6:15 pm
Location: Franquelin, Québec, Canada

Re: Using the Arduino to host a website that control the outputs

by adafruit_support_bill on Mon Apr 01, 2013 7:00 am

Yes. Pins 0 and 1 are connected to the 16U2 processor which does the USB/Serial conversion for host communication and bootloading. Using them for other purposes sometimes interferes with bootloading.
User avatar
adafruit_support_bill
 
Posts: 29172
Joined: Sat Feb 07, 2009 9:11 am

Re: Using the Arduino Ethernet to host a website that control the outputs

by fabfor on Mon Sep 09, 2013 10:52 am

Hi. This is an old post, but it is very interresting to me.

I tried the code provided here, but with no success.
At firs try, i found header and footer was not read from sd card. so i included header and footer text in arduino code.
Then i got a display of check boxes into internet explorer, but clicking on any one of them doesn't activate any led.
Any idea?
Thanks in advance
Did you tried this code with success?
fabfor
 
Posts: 2
Joined: Mon Sep 09, 2013 10:45 am

Re: Using the Arduino Ethernet to host a website that control the outputs

by dimbeault on Mon Sep 09, 2013 7:09 pm

Hi, I builded this code and it worked fine with the Arduino Ethernet. I dont know if the Arduino Ethernet Shield would work.

I suggest that you add some print in the code so you can know what your Arduino is doing or not.

You can also try one entry at a time, so you can find if one is not responding.

Hope this helps.
User avatar
dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 6:15 pm
Location: Franquelin, Québec, Canada

Re: Using the Arduino Ethernet to host a website that control the outputs

by fabfor on Tue Sep 10, 2013 7:56 am

Thank you. i finally made it working, i found tha using the serial monitor lock the web accecs to the arduino. Don't found why but would like to.
whit your unmodified code, i get this little bproblem.

At first login every led are off, and check boxes unchecked.
Then...

If i click anyone . suppose led2, it turn on for about 200mS, then off and stay off, the checkbox is checked.
i reclick on the checkbox, and same thing happen, checkkbox is still checked
i reclick for a third time, and then the checkbox is unchecked.

every check box work like this
this with orginal code
it looks like the Processcheckbox procedure run twice? Any idea?
OK i found value appear at beginning of html request when checked, and at end when not checked. so thi is the snag!
There is also something weird about digitalwrit high or low, it seems to doesn'T work steady. i replace wit 0 and 1 an it work fine now.
LAck of memory comes fast, i had to reduce the code to be able to check all 7 boxes without crashing the web page.

You said you want to access analog values too , did you where able to do this into this single web page?

Thank for your help
fabfor
 
Posts: 2
Joined: Mon Sep 09, 2013 10:45 am

Re: Using the Arduino Ethernet to host a website that control the outputs

by dimbeault on Tue Sep 10, 2013 8:47 pm

I have'nt worked on an other version that would include the control of an analog output. But it's not really complicated. If I have time, I will try to add this feature.

Bye.
User avatar
dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 6:15 pm
Location: Franquelin, Québec, Canada