Pages: 1 [2]   Go Down
Author Topic: multiple led webserver help  (Read 7767 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

man works awesome, ill need to find 5 leds now smiley-grin

i sincerely thank you for your help smiley
Logged

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

It should be easy to adjust it to however many LEDs you need. Just change these lines:
Code:
#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"};

void homePage(){
...
}

For example, this would do 4:
Code:
#define numberOfLeds 4
int LED[numberOfLeds] = { 2,3,4,5}; //This would use digital2 to digital5, but you could choose any
char LedURL[numberOfLeds][numberOfLeds+1] ={ "1000", "0100", "0010", "0001"};

void homePage(){
  //There are 4 leds, so 4 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>"),
  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");
}

Glad it works smiley-grin
Logged

~Tom~

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good jobs man..its work.. Thank u very much..
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 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.

Hi,

Just to let you know, that I registered myself at this forum only to be able to say:

Thank you!

Sincerely,
Tiago
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So finally lets put it all together: ...

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.

I can't tell how much glad I am to found this thread, and this post! I wanted to do something similar, but instead of controlling leds, I wanted to control actuator motors to lock or release door. I am coming from C# .NET, so I am not familiar with pointers, built-in string functions, program memory, etc. I made my first program using String objects, only using ram. I made for and while cycles to search for parts in strings, and terrible solutions like these. When I finished, I ran out of memory, and get strange errors from different places. I even ordered a Mega 2560 after UNO because of the more ram.  smiley-grin
But thanks to your code, I could understand how should I build an app like this, and get my project working properly, and much-much more simple! Thank you all again!

One part should be modified for later solutions when somebody want to control something what takes more time than blink a led: When the browser sends a request to do something, It does not wait much time to get the Ok response. It repeats the same request again, and maybe again.
In that case, when you get to the point when you decided what to control, you should call bfill.emit_p() and ether.httpServerReply(bfill.position())  before start doing anything time consuming. But be careful! If you still need data from the request string, you need to store it from data, because bfill replaces it with the outgoing message, and everything get lost what was in the buffer before.

That's all.
Logged

Pages: 1 [2]   Go Up
Jump to: