Pages: [1] 2   Go Down
Author Topic: multiple led webserver help  (Read 7293 times)
0 Members and 1 Guest are viewing this topic.
Hyderabad, India.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hey guys, i am using the etherCard library and have found a code for controlling a single led using a web server which toggles led on and off when button is pressed,

i got help from the same forum to control multiple leds but that was for etherShield library, and etherShield is not working with my breakout board so please help me on how to implement it for etherCard library


i want to implement this for 3-4 leds, so guys please help me on how to proceed smiley

this is the code which is working perfectly to control a single led..
Code:

#include <EtherCard.h>

#define STATIC 0  // set to 1 to disable DHCP (adjust myip/gwip values below)

#if STATIC
// ethernet interface ip address
static byte myip[] = { 192,168,1,200 };
// gateway ip address
static byte gwip[] = { 192,168,1,1 };
#endif

// ethernet mac address - must be unique on your network
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
#define LED 5  // define LED pin
bool ledStatus = false;

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

void setup(){
  Serial.begin(57600);
  Serial.println("\n[backSoon]");
  
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
    Serial.println( "Failed to access Ethernet controller");
#if STATIC
  ether.staticSetup(myip, gwip);
#else
  if (!ether.dhcpSetup())
    Serial.println("DHCP failed");
#endif

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);  
  ether.printIp("DNS: ", ether.dnsip);  
}
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>";

void homePage()
{
    bfill.emit_p(PSTR("$F"
        "<meta http-equiv='refresh' content='5'/>"
        "<title>Ethercard LED</title>"
        "ledStatus: <a href=\"?led=$F\">$F</a>"),
        http_OK,
        ledStatus?PSTR("off"):PSTR("on"),
        ledStatus?PSTR("ON"):PSTR("OFF"));
}

void loop(){
  // DHCP expiration is a bit brutal, because all other ethernet activity and
  // incoming packets will be ignored until a new lease has been acquired
  if (!STATIC && ether.dhcpExpired()) {
    Serial.println("Acquiring DHCP lease again");
    ether.dhcpSetup();
  }
    digitalWrite(LED, ledStatus);
    Serial.println(ledStatus);
  // wait for an incoming TCP packet, but ignore its contents
   word len = ether.packetReceive();
   word pos = ether.packetLoop(len);
  if (pos) {
      // write to LED digital output
    
    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("?led=on ", data, 8) == 0) {
                // Set ledStatus true and redirect to home page
                ledStatus = true;
                bfill.emit_p(http_Found);
            }
            else if (strncmp("?led=off ", data, 9) == 0) {
                // Set ledStatus false and redirect to home page
                ledStatus = false;
                bfill.emit_p(http_Found);
            }
            else {
                // Page not found
                bfill.emit_p(http_Unauthorized);
            }
        }
        
        ether.httpServerReply(bfill.position());    // send http response
    }

  }
Logged

Sussex UK / CT USA
Offline Offline
Edison Member
*
Karma: 0
Posts: 1028
Forums forever
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Some of the pages you can get to from Arduserver.com may help...
Logged

Hyderabad, India.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hey, ardu server uses ethershield library but i am using ethercard library because ethershield does not work with my breakout module smiley-sad

so help me extend the given code which is in ethercard library smiley
Logged

Hyderabad, India.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

any one???
some one help me modify it?? and i guess this needs modification....
and parameter can be simple like ?led=1010....  where 1 represents on and 0 represents off
void homePage()
{
    bfill.emit_p(PSTR("$F"
        "<meta http-equiv='refresh' content='5'/>"
        "<title>Ethercard LED</title>"
        "ledStatus: <a href=\"?led=$F\">$F</a>"),
        http_OK,
        ledStatus?PSTR("off"):PSTR("on"),
        ledStatus?PSTR("ON"):PSTR("OFF"));
}
Logged

Leeds, UK
Offline Offline
Edison Member
*
Karma: 80
Posts: 1726
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

First question, is this supposed to be all one string, or more than one?

"$F" "<meta http-equiv='refresh' content='5'/>" "<title>Ethercard LED</title>" "ledStatus: <a href=\"?led=$F\">$F</a>"


I tried to compile your code, and it wont as you have done some weird things with strings.
Other examples:
Code:
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>";
Are they suppose to be an array of three strings, or all one string?


If you need to use the " character in a string, you need to write: \"  which will inform the compiler it is supposed to be part of the string, not indicating one.

Once I can get the code to compile I can try and help you as you asked in the PM.
Logged

~Tom~

Hyderabad, India.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hey tom, it complies and works well for me without any erorrs.... do u have the ethercard library??

coz its working perfectly fine for me....
and i dont know if its a single string or not, i am not able to understand the code as i found this and did not write on my own....


this is the link for etherCard library https://github.com/jcw/ethercard
Logged

Leeds, UK
Offline Offline
Edison Member
*
Karma: 80
Posts: 1726
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Never mind, the code you put in your first post doesn't have any problems with the strings - the code you sent in your PM is slightly different, possibly the message removed something, how weird.
Logged

~Tom~

Hyderabad, India.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok smiley-grin so is it working for multiple leds?
Logged

Leeds, UK
Offline Offline
Edison Member
*
Karma: 80
Posts: 1726
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ahh right, I think I understand how it work's now.

bfill.emit_p(progmem string) takes a pstr() and replaces anything with $... with one of the other arguments in a similar way to sprintf.

$D = word data type
$L = long data type
$S = c string
$F = progmem string
$E = byte from the eeprom.


So what needs to be done is to convert the solution I gave you in your other thread to work with this instead of sprintf.
As a reference this is what was used before.
Code:
char string[150];
void loop()
{
  char* params;
  if (params = e.serviceRequest())
  {
    int startIndex = strcspn (params,"01"); //Find the first '1' or '0' in the parameters string
    for(byte i = 0; i < 5; i++){ //Work through each button in turn
      char ledStatus[6] = {0};
      strncpy(ledStatus, params + startIndex, 5); //Extract the 5 led statuses to a char array
      digitalWrite(LED[i],(ledStatus[i] == '1')?true:false); //Output to the correct LED
      ledStatus[i] = (ledStatus[i] == '1')?'0':'1'; //Swap the status for sending back in the HTML
      sprintf(string,"<a href='?led=%s'><br><button style='border: 1px solid #ff0000; border-left: 10px solid #ff0000' type='button'>LED%d IS %s</button></a>",i+1, ledStatus,((ledStatus[i] == '1')?"ON":"OFF"));
      e.print(string);
    }
  }
}

So, lets use the same URLs, e.g. ?led=00101 etc. and I will walk you through one way in which you could build the code. Learning is fun smiley

from your new code, the pointer to the recieved string is called data:
Code:
   ...
    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;
      ...

So we'll use that instead of params. To start with, as before, we need to work out where the important part  of the string starts, i.e. the '0's and '1's. The function strcspn does this. It starts at the given pointer and finds te relative position of the first character it finds which matches one of the characters from the given list.

So where are we at so far. Based on your current code, this is a starting point:
Code:
   ...
    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] == ' ') { //Check if the home page, i.e. no URL
        homePage();
      } else if (!strncmp("?led=",data,5)){ //Check if a url which changes the leds has been recieved
        data += strcspn (data,"01"); //Move to the start of the URL
      
        for(byte i = 0; i < 5; i++){ //Work through each led in turn, lets say for example there are 5 LEDs
          
          ... //Something here to change the LEDs.
          
          
        }
        bfill.emit_p(http_Found);
      } else { //Otherwise, page isn't found
        // Page not found
        bfill.emit_p(http_Unauthorized);
      }
      ...

So now what, we have worked out how to recieve the data and check whether it is the required string. So next we need to be able to actually change the LEDs to what the URL demanded. Lets again assume there are 5 leds (as there were in your old thread). We shall then requre an array which says what pins the LEDs are connected to, and another which stores the URL required to change each LED.
Code:
...
#define numberOfLeds 5
byte LED[] = {2,3,4,5,6}; //This would use digital2 to digital6, but you could choose any
char LedURL[numberOfLeds][numberOfLeds +1] ={ "10000", "01000", "00100", "00010", "00001"}; //All leds begin off, so the LEDs in the array are off except for the one which a given hyperlinks would turn on.
void setup(){
  for(byte i = 0; i < numberOfLeds; i++){
    pinMode(LED[i],OUTPUT); //LEDs are outputs
    digitalWrite(LED[i],LOW); //Off to begin with
  }
  ...


There will be 5 hyperlinks on the webpage which allow us to turn on
Code:
...
#define numberOfLeds 5
byte LED[numberOfLeds ] = {2,3,4,5,6}; //This would use digital2 to digital6, but you could choose any
char LedURL[numberOfLeds][numberOfLeds +1] ={ "10000", "01000", "00100", "00010", "00001"}; //All leds begin off, so the LEDs in the array are off except for the one which a given hyperlinks would turn on.

void setup(){
  for(byte i = 0; i < numberOfLeds; i++){
    pinMode(LED[i],OUTPUT); //LEDs are outputs
    digitalWrite(LED[i],LOW); //Off to begin with
  }
  ...


    ...
    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] == ' ') { //Check if the home page, i.e. no URL
        homePage();
      } else if (!strncmp("?led=",data,5)){ //Check if a url which changes the leds has been recieved
        data += strcspn (data,"01"); //Move to the start of the URL
        char tempURL[numberOfLeds+1] = {0};
        strncpy(tempURL, data, numberOfLeds); //Extract the recieved URL to the temporary string
        for(byte i = 0; i < numberOfLeds ; i++){ //Check through each of the LEDs URLs
          if(!strcmp(tempURL,LedURL[i])){
             //The recieved URL matches the one required to turn this LED on, so we will turn it on.
             digitalWrite(LED[i],(tempURL[i] == '1')?HIGH:LOW); //Set the led state to match the URL.
             //Now we need to toggle the state of this LED in all of the URLs, so that all the hyperlinks can be corrected to match this state.
             for(byte j = 0; j < 5; j++){
               LedURL[j][i] = (tempURL[i] == '1')?'0':'1'; //Notice how we toggle the 'i'th led in each url.    
             }
             //The URL was found, so we don't need to check any others.
             break; //Exit the for loop.
          }          
        }
        bfill.emit_p(http_Found);
      } else { //Otherwise, page isn't found
        // Page not found
        bfill.emit_p(http_Unauthorized);
      }
      ...

So that is the LEDs delt with. Notice how there is a URL to control each LED. Take the first LED for example. In that URL the first character is the state which clicking on the button will change the first LED to be, the remaining 4 characters represent the current state of the other LEDs, as they will be unchanged. This method only works if you want to change 1 led at a time.

So now for the response. When the Arduino recieves a request to change the LED, it does so. It then updates the array of URLs. However we still haven't sent the URL back to the computer as a new hyperlink, so we will tackle that next. I believe this is the purpose of the homePage() function, so we will put it there.
Before we put some code, lets work out how it should work. Well, you send some HTML which sets the page title, and then adds an hyperlink for each LED. There will be 5 hyperlinks, each will one of the URLs the arduino needs to change each of the LEDs. The name of the hyperlink can be whatever you want, but for this example it will be either  "Turn LEDx ON" or "Turn LEDx = OFF" (where x is the xth LED).
From what I can see then, there are 3 variables for the hyperlink per LED. The URL, which is a c string, the index of the LED which will be a byte (we'll use word as there is not option for byte), and the title of the hyperlink, ON or OFF, which is a cstring.

So, the code for example for LED 1 needs to be something like (note the x in the URL depends on the other leds):
"Turn LED1 <a href=\"?led=1xxxx\">ON</a>"  to turn it on
"Turn LED1 <a href=\"?led=0xxxx\">OFF</a>"  to turn it off

Lets break that down and make it more general. The '1' after LED is replaced with the index. The "1xxxx" is replaced by the URL, and the ON/OFF is replaced by the current state. Based on the list of wildcards I gave you at the beginning for the emit() function, this becomes:

"Turn LED$D <a href=\"?led=$S\">$S</a>"

$D = word = the led index
first $S = cstring = the URL
second $S = cstring = the name

So that is all we need to modify your current homePage() function...
Code:
...
void homePage(){
  //$F represents p string, $D represents word or byte, $S represents string.
  //There are 5 leds, so 5 hyperlinks.
  bfill.emit_p(PSTR("$F"
    "<meta http-equiv='refresh' content='5'/>"
    "<title>Ethercard LED</title>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"),
  http_OK,
  (word)1,LedURL[1],LedURL[1][1]?"ON":"OFF",
  (word)2,LedURL[2],LedURL[2][2]?"ON":"OFF",
  (word)3,LedURL[3],LedURL[3][3]?"ON":"OFF",
  (word)4,LedURL[4],LedURL[4][4]?"ON":"OFF",
  (word)5,LedURL[5],LedURL[5][5]?"ON":"OFF");
}
...
Logged

~Tom~

Leeds, UK
Offline Offline
Edison Member
*
Karma: 80
Posts: 1726
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So finally lets put it all together:

Code:
#include <EtherCard.h>

#define STATIC 0  // set to 1 to disable DHCP (adjust myip/gwip values below)

#if STATIC
// ethernet interface ip address
static byte myip[] = {
  192,168,1,200 };
// gateway ip address
static byte gwip[] = {
  192,168,1,1 };
#endif

// ethernet mac address - must be unique on your network
static byte mymac[] = {
  0x74,0x69,0x69,0x2D,0x30,0x31 };

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


#define numberOfLeds 5
int LED[numberOfLeds] = { 2,3,4,5,6}; //This would use digital2 to digital6, but you could choose any
char LedURL[numberOfLeds][numberOfLeds+1] ={ "10000", "01000", "00100", "00010", "00001"}; //All leds begin off, so the LEDs in the array are off except for the one which a given hyperlinks would turn on.

void setup(){
  for(byte i = 0; i < numberOfLeds; i++){
    pinMode(LED[i],OUTPUT); //LEDs are outputs
    digitalWrite(LED[i],LOW); //Off to begin with
  }

  Serial.begin(57600);
  Serial.println("\n[backSoon]");

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
    Serial.println( "Failed to access Ethernet controller");
#if STATIC
  ether.staticSetup(myip, gwip);
#else
  if (!ether.dhcpSetup())
    Serial.println("DHCP failed");
#endif

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip); 
  ether.printIp("DNS: ", ether.dnsip); 
}
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>";

void homePage(){
  //$F represents p string, $D represents word or byte, $S represents string.
  //There are 5 leds, so 5 hyperlinks.
  bfill.emit_p(PSTR("$F"
    "<meta http-equiv='refresh' content='5'/>"
    "<title>Ethercard LED</title>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"),
  http_OK,
  (word)1,LedURL[1],LedURL[1][1]?"ON":"OFF",
  (word)2,LedURL[2],LedURL[2][2]?"ON":"OFF",
  (word)3,LedURL[3],LedURL[3][3]?"ON":"OFF",
  (word)4,LedURL[4],LedURL[4][4]?"ON":"OFF",
  (word)5,LedURL[5],LedURL[5][5]?"ON":"OFF");
}

void loop(){
  // DHCP expiration is a bit brutal, because all other ethernet activity and
  // incoming packets will be ignored until a new lease has been acquired
  if (!STATIC &&  ether.dhcpExpired()) {
    Serial.println("Acquiring DHCP lease again");
    ether.dhcpSetup();
  }
  // wait for an incoming TCP packet, but ignore its contents
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  if (pos) {
    // write to LED digital output

    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 {
      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] == ' ') { //Check if the home page, i.e. no URL
          homePage();
        } else if (!strncmp("?led=",data,5)){ //Check if a url which changes the leds has been recieved
          data += strcspn (data,"01"); //Move to the start of the URL
          char tempURL[numberOfLeds+1] = {0};
          strncpy(tempURL, data, numberOfLeds); //Extract the recieved URL to the temporary string
          for(byte i = 0; i < numberOfLeds ; i++){ //Check through each of the LEDs URLs
            if(!strcmp(tempURL,LedURL[i])){
              //The recieved URL matches the one required to turn this LED on, so we will turn it on.
              digitalWrite(LED[i],(tempURL[i] == '1')?HIGH:LOW); //Set the led state to match the URL.
              //Now we need to toggle the state of this LED in all of the URLs, so that all the hyperlinks can be corrected to match this state.
              for(byte j = 0; j < 5; j++){
                LedURL[j][i] = (tempURL[i] == '1')?'0':'1'; //Notice how we toggle the 'i'th led in each url.     
              }
              //The URL was found, so we don't need to check any others.
              break; //Exit the for loop.
            }         
          }
          bfill.emit_p(http_Found);
        } else { //Otherwise, page isn't found
          // Page not found
          bfill.emit_p(http_Unauthorized);
        }
      }

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



I haven't tested this as I don't have an ethernet sheild. But let me know what happens when you run it, and if it doesn't work I will try and help fix it.
Logged

~Tom~

Hyderabad, India.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hey thanks tom that was really long post and you also helped me understand it, i guess its not working whenever i click on any of the buttons only the 2nd one changes i mean it is /?led=00000

when i press any of buttons hyperlink changes to /?led=01000 and again if i press any of the buttons it changes to /?led=000000


also all the buttons display as ON, none of the buttons change when pressed

« Last Edit: July 10, 2012, 03:48:52 pm by kiriti » Logged

Leeds, UK
Offline Offline
Edison Member
*
Karma: 80
Posts: 1726
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
...
      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] == ' ') { //Check if the home page, i.e. no URL
          homePage();
        } else if (!strncmp("?led=",data,5)){ //Check if a url which changes the leds has been recieved
          data += strcspn (data,"01"); //Move to the start of the URL
          char tempURL[numberOfLeds+1] = {0}; 
          Serial.print("temp = ");
          Serial.println(tempURL); //Just some quick logging
          strncpy(tempURL, data, numberOfLeds); //Extract the recieved URL to the temporary string
          for(byte i = 0; i < numberOfLeds ; i++){ //Check through each of the LEDs URLs
            if(!strcmp(tempURL,LedURL[i])){
              //The recieved URL matches the one required to turn this LED on, so we will turn it on.
              digitalWrite(LED[i],(tempURL[i] == '1')?HIGH:LOW); //Set the led state to match the URL.
              //Now we need to toggle the state of this LED in all of the URLs, so that all the hyperlinks can be corrected to match this state.
              for(byte j = 0; j < 5; j++){
                LedURL[j][i] = (tempURL[i] == '1')?'0':'1'; //Notice how we toggle the 'i'th led in each url.
                Serial.print("LedURL = "); 
                Serial.println(LedURL[j]); //Just some quick logging
              }
              //The URL was found, so we don't need to check any others.
              break; //Exit the for loop.
            }         
          }
       //   bfill.emit_p(http_Found);
          homePage(); //I forgot to add this to send the new URLs back...............
        }...


See if that change works, and if not, click the buttons 1 by 1 and tell me what the Serial monitor returns. I realised that I forgot to add the line which calls the homePage() funtion to send the new URL back.
Logged

~Tom~

Hyderabad, India.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

with your new code i got this outputs on serial monitor, pressed each button twice starting from led1 to led 5
Code:
temp =
LedURL = 10000
LedURL = 00000
LedURL = 00100
LedURL = 00010
LedURL = 00001
temp =
LedURL = 11000
LedURL = 01000
LedURL = 01100
LedURL = 01010
LedURL = 01001
temp =
LedURL = 11000
LedURL = 01000
LedURL = 01000
LedURL = 01010
LedURL = 01001
temp =
LedURL = 10000
LedURL = 00000
LedURL = 00000
LedURL = 00010
LedURL = 00001
temp =
LedURL = 10000
LedURL = 00000
LedURL = 00000
LedURL = 00000
LedURL = 00001
temp =
LedURL = 11000
LedURL = 01000
LedURL = 01000
LedURL = 01000
LedURL = 01001
temp =
LedURL = 11000
LedURL = 01000
LedURL = 01000
LedURL = 01000
LedURL = 01000
temp =
LedURL = 10000
LedURL = 00000
LedURL = 00000
LedURL = 00000
LedURL = 00000
temp =
temp =
Logged

Hyderabad, India.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hey tom my cousin helped me put to gether this code and it works smiley-grin



Code:
#include <EtherCard.h>

#define STATIC 0  // set to 1 to disable DHCP (adjust myip/gwip values below)

#if STATIC
// ethernet interface ip address
static byte myip[] = {
  192,168,1,200 };
// gateway ip address
static byte gwip[] = {
  192,168,1,1 };
#endif

// ethernet mac address - must be unique on your network
static byte mymac[] = {
  0x74,0x69,0x69,0x2D,0x30,0x31 };
#define LED 6  // define LED pin
bool ledStatus = false;
bool ledStatus2= false;

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

void setup(){
  Serial.begin(57600);
  Serial.println("\n[backSoon]");

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
    Serial.println( "Failed to access Ethernet controller");
#if STATIC
  ether.staticSetup(myip, gwip);
#else
  if (!ether.dhcpSetup())
    Serial.println("DHCP failed");
#endif

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip); 
  ether.printIp("DNS: ", ether.dnsip); 
}
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>";

void homePage()
{
  bfill.emit_p(PSTR("$F"
    "<meta http-equiv='refresh' content='5'/>"
    "<title>Ethercard LED</title>"
    "ledStatus: <a href=\"?led=$F\">$F</a><br>ledStatus2: <a href=\"?led2=$F\">$F</a>"),
  http_OK,
  ledStatus?PSTR("off"):PSTR("on"),
  ledStatus?PSTR("ON"):PSTR("OFF"),
  ledStatus2?PSTR("off"):PSTR("on"),
  ledStatus2?PSTR("ON"):PSTR("OFF"));
}

void loop(){
  // DHCP expiration is a bit brutal, because all other ethernet activity and
  // incoming packets will be ignored until a new lease has been acquired
  if (!STATIC && ether.dhcpExpired()) {
    Serial.println("Acquiring DHCP lease again");
    ether.dhcpSetup();
  }
  digitalWrite(LED, !ledStatus);
  Serial.print(!ledStatus);
  Serial.print(!ledStatus2);
  Serial.println("");
  // wait for an incoming TCP packet, but ignore its contents
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  if (pos) {
    // write to LED digital output

    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("?led=off ", data, 9) == 0) {
        ledStatus=false;   
        bfill.emit_p(http_Found);
      }
      else if (strncmp("?led=on ", data, 8) == 0) {

        ledStatus=true; 


        bfill.emit_p(http_Found);
      }
      else if (strncmp("?led2=off ", data, 10) == 0) {

        ledStatus2=false; 


        bfill.emit_p(http_Found);
      }
      else if (strncmp("?led2=on ", data, 9) == 0) {

        ledStatus2=true; 
        bfill.emit_p(http_Found);
      }
      else {
        // Page not found
        bfill.emit_p(http_Unauthorized);
      }
    }

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

}
Logged

Leeds, UK
Offline Offline
Edison Member
*
Karma: 80
Posts: 1726
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm glad you found a soloution, but if you want a solution that can do more than two leds, I think i have fixed the code I posted.

Code:
#include <EtherCard.h>

#define STATIC 0  // set to 1 to disable DHCP (adjust myip/gwip values below)

#if STATIC
// ethernet interface ip address
static byte myip[] = {
  192,168,1,200 };
// gateway ip address
static byte gwip[] = {
  192,168,1,1 };
#endif

// ethernet mac address - must be unique on your network
static byte mymac[] = {
  0x74,0x69,0x69,0x2D,0x30,0x31 };

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


#define numberOfLeds 5
int LED[numberOfLeds] = { 2,3,4,5,6}; //This would use digital2 to digital6, but you could choose any
char LedURL[numberOfLeds][numberOfLeds+1] ={ "10000", "01000", "00100", "00010", "00001"}; //All leds begin off, so the LEDs in the array are off except for the one which a given hyperlinks would turn on.

void setup(){
  for(byte i = 0; i < numberOfLeds; i++){
    pinMode(LED[i],OUTPUT); //LEDs are outputs
    digitalWrite(LED[i],LOW); //Off to begin with
  }

  Serial.begin(57600);
  Serial.println("\n[backSoon]");

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
    Serial.println( "Failed to access Ethernet controller");
#if STATIC
  ether.staticSetup(myip, gwip);
#else
  if (!ether.dhcpSetup())
    Serial.println("DHCP failed");
#endif

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip); 
  ether.printIp("DNS: ", ether.dnsip); 
}
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>";

void homePage(){
  //$F represents p string, $D represents word or byte, $S represents string.
  //There are 5 leds, so 5 hyperlinks.
  bfill.emit_p(PSTR("$F"
    "<meta http-equiv='refresh' content='5'/>"
    "<title>Ethercard LED</title>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"
    "Turn LED$D <a href=\"?led=$S\">$S</a>"),
  http_OK,
  (word)1,LedURL[0],(LedURL[0][0]=='1')?"ON":"OFF",
  (word)2,LedURL[1],(LedURL[1][1]=='1')?"ON":"OFF",
  (word)3,LedURL[2],(LedURL[2][2]=='1')?"ON":"OFF",
  (word)4,LedURL[3],(LedURL[3][3]=='1')?"ON":"OFF",
  (word)5,LedURL[4],(LedURL[4][4]=='1')?"ON":"OFF");
  //I forgot in these that we are checking for '1' and '0', not 1 and 0. I also got the indecies wrong
  //(I was using MATLAB prior to writing this and they use 1 indexing not 0 indexing so I got confused :S
}

void loop(){
  // DHCP expiration is a bit brutal, because all other ethernet activity and
  // incoming packets will be ignored until a new lease has been acquired
  if (!STATIC &&  ether.dhcpExpired()) {
    Serial.println("Acquiring DHCP lease again");
    ether.dhcpSetup();
  }
  // wait for an incoming TCP packet, but ignore its contents
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  if (pos) {
    // write to LED digital output

    delay(1);   // necessary for my system
    bfill = ether.tcpOffset();
    char *data = (char *) Ethernet::buffer + pos;
    if (strncmp("GET /", data, 5) != 0) { //I also accidentally copied this bit in twice (though that shouldn't be an issue)
      // Unsupported HTTP request
      // 304 or 501 response would be more appropriate
      bfill.emit_p(http_Unauthorized);
    } else {
        data += 5;
        if (data[0] == ' ') { //Check if the home page, i.e. no URL
          homePage();
        } else if (!strncmp("?led=",data,5)){ //Check if a url which changes the leds has been recieved
          data += strcspn (data,"01"); //Move to the start of the URL
          char tempURL[numberOfLeds+1] = {0};
          strncpy(tempURL, data, numberOfLeds); //Extract the recieved URL to the temporary string
          Serial.print("temp = ");
          Serial.println(tempURL); //Just some quick logging
          for(byte i = 0; i < numberOfLeds ; i++){ //Check through each of the LEDs URLs
            if(!strcmp(tempURL,LedURL[i])){
              //The recieved URL matches the one required to turn this LED on, so we will turn it on.
              digitalWrite(LED[i],(tempURL[i] == '1')?HIGH:LOW); //Set the led state to match the URL.
              //Now we need to toggle the state of this LED in all of the URLs, so that all the hyperlinks can be corrected to match this state.
              for(byte j = 0; j < numberOfLeds ; j++){
                if(j==i){
                  LedURL[j][i] = (tempURL[i] == '1')?'0':'1'; //Notice how we toggle the 'i'th led in each url.
                  Serial.print("led = ");
                  Serial.println(LedURL[j]);
                  continue;
                }
                LedURL[j][i] = tempURL[i]; //Notice how we toggle the 'i'th led in each url.
                Serial.print("led = ");
                Serial.println(LedURL[j]);     
              }
              //The URL was found, so we don't need to check any others.
              break; //Exit the for loop.
            }         
          }
          bfill.emit_p(http_Found);
        } else { //Otherwise, page isn't found
          // Page not found
          bfill.emit_p(http_Unauthorized);
        }
      }

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

I tested a version modified to not use the ethernet, and it appears to work, so It *should* work for you.
Logged

~Tom~

Pages: [1] 2   Go Up
Jump to: