Need help with LED ethernet project

Hi Gang,

I need some help to understand a feel things on a project I’m working on it.
I have a couple of Duemilenove boards and a couple of Nueletronic’s Ethernet shield, running arduino version 0022 with all needed libraries. I have been able to play with the examples provided but I would like to take the next step.

As a reminder Im have very little experience programming but I have a fair understanding of programming logic, Im just trying to put things in place.

One of Nueletronic examples is a web-based LED control:

This is a great example and show how can you do things “online”.

I would like to make this work with 6 LEDs so I started poking around the code to see how could I adapt to my needs. Turns out I got somewhere but not even close to my ideal.

Here’s My questions and explanations:

  • I manage to control 5 LED’s using the cmd=# in the code. For some reason I don’t understand “cmd” will only accept single digits variables (1,2,3-9), when I try send the code with cmd=10 it wont work at all (i need that to activate the 6th LED);

  • I still don’t understand how to build the web page showing all 6 LED with its status and the button to turn on and off. I was poking the code but I just don’t get it, maybe someone could help me find my way.

I am attaching the code with the changes I made.
Thank you all in advance and any help will be welcome.

Cheers
PC

You'll need to take an HTML tutorial for details on how to build the interface. check out w3schools.

Can we see that example code?

_t analyse_cmd(char *str)
{
        int8_t r=-1;
     
        if (find_key_val(str,"cmd")){
                if (*strbuf < 0x3a && *strbuf > 0x2f){
                        // is a ASCII number, return it
                        r=(*strbuf-0x30);
                }
        }
        return r;

is the bit that is failing - OK, other procedures may be failing, too, but analyse_cmd definitly is - this function translates the ASCII “0” to the binary 0, and the ASCII “9” to the value 9, and the numbers between acordingly. It does not even consider if it is a twoletter/digit parameter passed (like “10”). I am not sure the strbuf-pointer and the str-pointer being passed are correlated correctly (I havn’t examined the find_key_val procedure in detail)

The values passed to the Arduino, in the cmd=n arguments do not have to correspond to pin numbers. You could put the pin numbers in an array, and pass indexes to the Arduino. The cmd=0 argument would turn on the pin that was in the first ([0]) position in the array. The cmd=4 argument would turn on the pin that was in the fifth ([4]) position in the array.

baum:
You’ll need to take an HTML tutorial for details on how to build the interface.
check out w3schools.

Can we see that example code?

Hello baum,

the HTML itself it’s not the problem, I am familiar and have been using html, asp, php, etc for a while now, but the issue is how the example build the thml code around the variables, and that was my question.

The code is attached to the original message, but I will post it here too, maybe you can see something I couldnt:

plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"));
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<center><p><h1>LED Controller</h1></p> "));
         
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<hr>
<form METHOD=get action=\""));
        plen=es.ES_fill_tcp_data(buf,plen,baseurl);
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("\">"));
    
    // Beginning Relay 3 ================================================   
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<h2> LED 1 is  </h2> "));
 				plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<h1><font color=\"#00FF00\"> "));
         
        if(on_off)
        	plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("ON"));
        else 
        	plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("OFF"));
        
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("  </font></h1>
 ") );
        
        if(on_off){
        	plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=hidden name=cmd value=2>"));
        	plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=submit value=\"Switch off\">"));
        }
        else {
        	plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=hidden name=cmd value=1>"));
        	plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=submit value=\"Switch on\">"));
        }
        // End Relay 3 ====================================================
        
        
        
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</form>"));
        plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</center><hr> <p> V1.2 by PC"));

This code works to show 1 LED, question is how would I be able to make to all 6.

thnak you anyway :slight_smile:

Msquare: is the bit that is failing - OK, other procedures may be failing, too, but analyse_cmd definitly is - this function translates the ASCII "0" to the binary 0, and the ASCII "9" to the value 9, and the numbers between acordingly. It does not even consider if it is a twoletter/digit parameter passed (like "10"). I am not sure the strbuf-pointer and the str-pointer being passed are correlated correctly (I havn't examined the find_key_val procedure in detail)

Hi Square,

thank you for your answer I have to be honest that I understand what you said but I dont know where to change. Would you help me with the values to allow me to be able to use from 0 to, lets say, 50, this way I would be able to setup intensities among other things.

than you again for your information PC

PaulS: The values passed to the Arduino, in the cmd=n arguments do not have to correspond to pin numbers. You could put the pin numbers in an array, and pass indexes to the Arduino. The cmd=0 argument would turn on the pin that was in the first ([0]) position in the array. The cmd=4 argument would turn on the pin that was in the fifth ([4]) position in the array.

Hello PaulS,

I know that, if you look the code you will see that cmd=1 activate pin3, cmd=2 deactivate pin3, etc.

if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){
                plen=print_webpage(buf, on_off);
            goto SENDTCP;
         }
        cmd=analyse_cmd((char *)&(buf[dat_p+5]));
        
        if (cmd==1){
                on_off=1;
            digitalWrite(PCPin3, HIGH);  // switch on LED
        }
        else if (cmd==2){
                on_off=0;
            digitalWrite(PCPin3, LOW);  // switch off LED
        }
        else if (cmd==3){
                on_off=1;
            digitalWrite(PCPin4, HIGH);  // switch on LED
        }
        else if (cmd==4){
                on_off=0;
            digitalWrite(PCPin4, LOW);  // switch off LED
        }
        else if (cmd==5){
                on_off=1;
            digitalWrite(PCPin5, HIGH);  // switch on LED
        }
        else if (cmd==6){
                on_off=0;
            digitalWrite(PCPin5, LOW);  // switch off LED
        }
        else if (cmd==7){
                on_off=1;
            digitalWrite(PCPin6, HIGH);  // switch on LED
        }
        else if (cmd==8){
                on_off=0;
            digitalWrite(PCPin6, LOW);  // switch off LED
        }
        else if (cmd==9){
                on_off=1;
            digitalWrite(PCPin7, HIGH);  // switch on LED
        }
        else if (cmd==10){
                on_off=0;
            digitalWrite(PCPin7, LOW);  // switch off LED
        }
        else if (cmd==11){
                on_off=1;
            digitalWrite(PCPin8, HIGH);  // switch on LED
        }
        else if (cmd==12){
                on_off=0;
            digitalWrite(PCPin8, LOW);  // switch off LED
        }

That part is clear. :)

Right now I would like to be able to control all 6 LED's I have so far and be able to present the status and the buttons on the web page. If i change the cmd at the URL bar I can go all the way to the 5th LED (turn on 5th led only tough)

thank you anyway for your suggestion

PC

PaulS: The values passed to the Arduino, in the cmd=n arguments do not have to correspond to pin numbers. You could put the pin numbers in an array, and pass indexes to the Arduino. The cmd=0 argument would turn on the pin that was in the first ([0]) position in the array. The cmd=4 argument would turn on the pin that was in the fifth ([4]) position in the array.

Hello again,

I was thinking about what you said and I would like to ask if would be possible to, instead of using numbers, use letters. eg. cmd=a

This way I would have all needed variables to control 6 LED's

If that's possible, what would I have to change in order to make it happen

thank you again

PC

I am sorry - that is a 300 line program :roll_eyes:. Still, we all have to start somewhere.

Lets take the most obvious piece, this "senseless" repeating of code

    :
        else if (cmd==7){
                on_off=1;
            digitalWrite(PCPin6, HIGH);  // switch on LED
        }
    :

Any long repeating if-then-else should at least be replaced with a switch-case construction. As this code deos the same for all cases, we can do one better; As PaulS pointed out, use an array. Initialize so index 0 contains the pin number of the pin that controls the "0"th LED.

byte LEDpins[] = { PCPin3, PCPin4, ... PCPin8 } ; // This will be 6 elements [0] to [5] long

The code now simply is the "cmd" value you have is the pin to turn on or off. We decide which way, by testing if the number is even (bitwise AND with 1 is TRUE/nonzero if it is odd). Otherwise the cmd divided by 2 and ignore fractions is the index value

 if (cmd&1 == 0) digitalWrite(LEDPins[cmd/2],HIGH) ; else digitalWrite(LEDPins[cmd/2],LOW) ;

Minor problem, the cmd==1 and cmd==2 do not divide to the same number, so this will work if cmd==0 turns first LED on and cmd==1 turns it off. Fix and adjust whichever is easier.

There we've just 48 lines of code with a few lines (you can add spacing and 8 space indentation if you want ;) )

Really you should now be able to see PaulS' suggestion: Instead of the single digit numeric parameter (which we could fix) just use a single character and in analyse_cmd return the "a" as binary 0... and we're ready to do 13 LEDs.

Really you should now be able to see PaulS' suggestion: Instead of the single digit numeric parameter (which we could fix) just use a single character and in analyse_cmd return the "a" as binary 0... and we're ready to do 13 LEDs.

Hi again Msquare.

I will be honest. I do understand what you said, but Im a newbie and Im trying to work around an example to make something out of it, but there is so much I can do with so little knowledge. Believe me Im not happy knowing that I have no ideia about how to start the changes and, right now, Im just trying to make it work with the 6 leds. After that I still have to figure out how how to build the html code to show all 6 led button to change the led status using the webpage.

Could you give me a light about using a,b,c's instead of number to turn the leds on and off????

thank you for your help I will do some research about the switch-case

PC

The analyze_cmd() function is finding the character following the equal sign, and converting that character to an integer, by subtracting the equivalent of '0' from the character ('3' - '0' = 3).

You could, if you were so inclined, change analyze_cmd to return a character instead of an int. Or, you could clone analyze_cmd, and call is analyze_state. Rename analyze_cmd to analyze_pin. In analyze_pin, change "cmd" to "pin". In analyze_state, change "cmd" to "state".

Then, invoke the server using: http://someUrl/?pin=6&state=0 This would let you set pin 6 to off. Make it state=1 to turn pin 6 on.

You could use led instead of pin, to control which LED instead of explicitly which pin, to set.

The possibilities are limitless.

Hi PC.

Just incase you still in this project. Do you use andrewdlindsay' library ? ( http://blog.thiseldo.co.uk/?p=504 ) If so .. take a look at the DNS lookup included example.

It's about html form and how to search for a key in request.

If you still need some other basic example, let me know .. i'll post my code. I use this code to provide web based configuration interface for my Arduino Project.

Sincerely -bino-