WEB Interface with ENC28J60

Hi everyone !

I bought the Ethernet Shiel ENC28J60 (datasheet : here)

I would like to create a web interface which will allow me to control different elements of my arduino (like led, change values of some variables, play sound…)

For this, I use the EtherCard.h library

For now, I had this simple interface permitting to change the color of an RGB led from Adafruit with three button on my interface

My probleme come after that…

When I want add other element on my page (like buton to change the difficulty of a game or play some sounds), my page stop working…

Here is my code :

#include <EtherCard.h>
#include <PololuLedStrip.h>

#define LED_COUNT 1   //Number of led connected
#define LED1 4  // define LED pin
PololuLedStrip<4> ledStrip;
rgb_color colors[LED_COUNT];


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

bool boolLedR = false;
bool boolLedG = false;
bool boolLedB = false;
byte Red = 0, Green = 0, Blue = 0;

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

void setup() {
  Serial.begin(9600);
  pinMode(LED1, OUTPUT);

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
    Serial.println( "Failed to access Ethernet controller");
  ether.staticSetup(myip, gwip);


  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);
  ether.printIp("DNS: ", ether.dnsip);
}

//En tête HTML
const char http_OK[] PROGMEM =
  "HTTP/1.0 200 OK\r\n"
  "Content-Type: text/html\r\n"
  "Pragma: no-cache\r\n\r\n";

const char http_Found[] PROGMEM =
  "HTTP/1.0 302 Found\r\n"
  "Location: /\r\n\r\n";

const char http_Unauthorized[] PROGMEM =
  "HTTP/1.0 401 Unauthorized\r\n"
  "Content-Type: text/html\r\n\r\n"
  "<h1>401 Unauthorized</h1>";

//Principal page of my interface
void homePage()
{
  bfill.emit_p(PSTR("$F"
                    "<html>"
                    "<head>"
                    "<title>Escape Dimension</title>"
                    "<meta http-equiv='refresh' content='5'/>"
                    "</head>"

                    "<body>"
                    "<h1 style='text-align:center'> Game master </h1>"
                    "<div style='border-style: solid'>"
                    "Color led :"
                    "<button><a href=\"?ledr=$F\">$F</a></button>"
//Add those 3 butons (or just one) stop the program...
//                    "<button>Difficulte 1</button>"
//                    "<button>Difficulte 2</button>"
//                    "<button>Difficulte 3</button>"

                    "</div>"
                    "</body>"
                    "</html>"
                   ),
               http_OK,
               boolLedR ? PSTR("off") : PSTR("on"),
               boolLedR ? PSTR("RED allume") : PSTR("RED eteint"),
               boolLedG ? PSTR("off") : PSTR("on"),
               boolLedG ? PSTR("GREEN allume") : PSTR("GREEN eteint"),
               boolLedB ? PSTR("off") : PSTR("on"),
               boolLedB ? PSTR("BLUE allume") : PSTR("BLUE eteint")
              );
}

void loop() {
  colors[0] = rgb_color(Green, Red, Blue);
  ledStrip.write(colors, LED_COUNT);


  // wait for an incoming TCP packet, but ignore its contents
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);

  if (pos) {
    delay(1);   // necessary for my system
    bfill = ether.tcpOffset();
    char *data = (char *) Ethernet::buffer + pos;

    if (strncmp("GET /", data, 5) != 0) {
      // Unsupported HTTP request
      // 304 or 501 response would be more appropriate
      bfill.emit_p(http_Unauthorized);
    }
    else {
      data += 5;

      if (data[0] == ' ') {
        // Return home page
        homePage();
      }
      else if (strncmp("?ledr=on", data, 8) == 0) {
        // Set boolLedR true and redirect to home page
        boolLedR = true;
        Red = 255;
        bfill.emit_p(http_Found);
      }
      else if (strncmp("?ledr=off", data, 9) == 0) {
        // Set boolLedR false and redirect to home page
        boolLedR = false;
        Red = 0;
        bfill.emit_p(http_Found);
      }
      else if (strncmp("?ledg=on", data, 8) == 0) {
        // Set boolLedR true and redirect to home page
        boolLedG = true;
        Green = 255;
        bfill.emit_p(http_Found);
      }
      else if (strncmp("?ledg=off", data, 9) == 0) {
        // Set boolLedR false and redirect to home page
        boolLedG = false;
        Green = 0;
        bfill.emit_p(http_Found);
      }
      else if (strncmp("?ledb=on", data, 8) == 0) {
        // Set boolLedR true and redirect to home page
        boolLedB = true;
        Blue = 255;
        bfill.emit_p(http_Found);
      }
      else if (strncmp("?ledb=off", data, 9) == 0) {
        // Set boolLedR false and redirect to home page
        boolLedB = false;
        Blue = 0;
        bfill.emit_p(http_Found);
      }
      else {
        // Page not found
        bfill.emit_p(http_Unauthorized);
      }
    }

    ether.httpServerReply(bfill.position());    // send http response
  }

}

I put in comment of the homePage function butons which don’t want to work…

I hope someone here will be able to give me some help or maybe another solution more simple to create my interface ? :slight_smile:

I was not sure where post my subject... Sorry

Other thread removed.

Use Report to moderator if you want your thread moved to another section.

I put in comment of the homePage function butons which don't want to work...

But, your comment is not in English, so don't expect all of us to be able to read it.

The buttons you are trying to add are useless, in that they will NOT cause a GET request to be made to the Arduino.

The first thing I would question is whether the buffer to hold the page is large enough. When I paste just the page content into a text editor, and remove the comment and comment symbol, I see that that page is 792 characters. Going to be a really tight squeeze in a 500 character buffer.

Thanks for your reply !

In fact, the buffer size can’t be more than 850… Now, I try to make the most of my code in PROGMEM, like this :

const char http_OK[] PROGMEM =
  "HTTP/1.0 200 OK\r\n"
  "Content-Type: text/html\r\n"
  "Pragma: no-cache\r\n\r\n";

const char http_Found[] PROGMEM =
  "HTTP/1.0 302 Found\r\n"
  "Location: /\r\n\r\n";

const char http_Unauthorized[] PROGMEM =
  "HTTP/1.0 401 Unauthorized\r\n"
  "Content-Type: text/html\r\n\r\n"
  "<h1>401 Unauthorized</h1>";

const char title[] PROGMEM =
  "<html>"
  "<head>"
  "<title>Escape Dimension</title>"
  "<meta http-equiv='refresh' content='5'/>"
  "</head>";


void homePage()
{
  bfill.emit_p(PSTR(
                    "$F"
                    "$F"
                    "<body>"
                    "Couleur led : "
                    "<button><a href=\"?ledr=$F\">$F</a></button>"
                    "<button><a href=\"?ledg=$F\">$F</a></button>"
                    "<button><a href=\"?ledb=$F\">$F</a></button>
"
                    "Difficulte : "
                    "<button><a href=\"?diff1=$F\">$F</a></button>"
                    "<button><a href=\"?diff2=$F\">$F</a></button>"
                    "<button><a href=\"?diff3=$F\">$F</a></button>"
                    "</body>"
                    "</html>"
                   ),
               http_OK,
               title,
               boolLedR ? PSTR("off") : PSTR("on"),
               boolLedR ? PSTR("RED allume") : PSTR("RED eteint"),
               boolLedG ? PSTR("off") : PSTR("on"),
               boolLedG ? PSTR("GREEN allume") : PSTR("GREEN eteint"),
               boolLedB ? PSTR("off") : PSTR("on"),
               boolLedB ? PSTR("BLUE allume") : PSTR("BLUE eteint"),
               
               boolLedR ? PSTR("off") : PSTR("on"),
               boolLedR ? PSTR("Difficulte 1 on") : PSTR("Difficulte 1 off"),
               boolLedG ? PSTR("off") : PSTR("on"),
               boolLedG ? PSTR("Difficulte 2 on") : PSTR("Difficulte 2 off"),
               boolLedB ? PSTR("off") : PSTR("on"),
               boolLedB ? PSTR("Difficulte 3 on") : PSTR("Difficulte 3 off")
              );

The probleme, I can’t make those parts ("<a href="?ledr=$F">$F") in PROGMEM because they are not constants… How can I avoid the PROGMEM to avoid to put the code in the buffer and thus free up the RAM

Thanks for your help ! :slight_smile:

How can I avoid the PROGMEM to avoid to put the code in the buffer and thus free up the RAM

I don't think you want to avoid the PROGMEM. 8)

You just can't use it for non-constant data.

Get a different ethernet shield, with a W5100, W5200, or W5500 chip, and use the F() macro, instead of SRAM.

Yes I want use the PROGMEM :stuck_out_tongue_closed_eyes:

I really need to use this chip... I have no choice :slightly_frowning_face:

Is there another solution ?

I try to do something like this :

const char http_OK[] PROGMEM =
  "HTTP/1.0 200 OK\r\n"
  "Content-Type: text/html\r\n"
  "Pragma: no-cache\r\n\r\n";


const char title[] PROGMEM =
  "<html>"
  "<head>"
  "<title>Escape Dimension</title>"
  "<meta http-equiv='refresh' content='5'/>"
  "</head>";


const char btnColor[] PROGMEM = {
  PSTR(
    "<body>"
    "Couleur led : "
    "<button><a href=\"?ledr=$F\">$F</a></button>"
    "<button><a href=\"?ledg=$F\">$F</a></button>"
    "<button><a href=\"?ledb=$F\">$F</a></button>
"
    "</body>"
    "</html>"),
  boolLedR ? PSTR("off") : PSTR("on"),
  boolLedR ? PSTR("RED allume") : PSTR("RED eteint"),
  boolLedG ? PSTR("off") : PSTR("on"),
  boolLedG ? PSTR("GREEN allume") : PSTR("GREEN eteint"),
  boolLedB ? PSTR("off") : PSTR("on"),
  boolLedB ? PSTR("BLUE allume") : PSTR("BLUE eteint")
};


void homePage()
{
  bfill.emit_p(PSTR(
                    "$F"
                    "$F"
                    "$F"
                   ),
               http_OK,
               title,
               btnColor
              );
}

But, I can’t because PROGMEM need to be a const…