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

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked

Was this code helpful for you?

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

dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 7:15 pm

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

Post by dimbeault »

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


#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 8:13 pm, edited 2 times in total.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

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

Post by adafruit_support_bill »

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?

dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 7:15 pm

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

Post by dimbeault »

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
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

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

Post by adafruit_support_bill »

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

dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 7:15 pm

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

Post by dimbeault »

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!

dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 7:15 pm

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

Post by dimbeault »

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

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

</form>
</body>
</html>
and the new Arduino code :

Code: Select all

#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
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

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

Post by adafruit_support_bill »

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.

dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 7:15 pm

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

Post by dimbeault »

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

Code: Select all

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

  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.

dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 7:15 pm

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

Post by dimbeault »

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
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

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

Post by adafruit_support_bill »

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.

fabfor
 
Posts: 2
Joined: Mon Sep 09, 2013 11:45 am

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

Post by fabfor »

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?

dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 7:15 pm

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

Post by dimbeault »

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.

fabfor
 
Posts: 2
Joined: Mon Sep 09, 2013 11:45 am

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

Post by fabfor »

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

dimbeault
 
Posts: 51
Joined: Sun Dec 30, 2012 7:15 pm

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

Post by dimbeault »

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.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”