Browser based input: howto trigger event from client (browser)

Hi, I’m new here. Already searched for this but could not find it.

How can I trigger on Arduino if a user checked a checkmark to initiate some action? I append a part of the code of main loop that shows what I mean:

...
  Client client = server.available();      // listen for incoming clients
  if (client) {
    boolean currentLineIsBlank = true;    // an http request ends with a blank line
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();          //read HTTP request char by char 
        if (readString.length() < 100)           //store characters to string
          readString = readString + c; 
        if(readString.indexOf("chkLED=ON") > -1) 
          bLEDon = false;
        else
          bLEDon = true;
        
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          client.println("<h2>Arduino</h2>
");

          // output values of analog input pins
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            client.print("A"); client.print(analogChannel); client.print("=");
client.print(analogRead(analogChannel));
            client.println("

");
          }
          client.print("<form method='GET'>");
          client.print("<input type='checkbox' name='chkLED' value='ON'>LED ON</input>");
          client.println("</form>");

          break;
        }
        if (c == '\n') { // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') { // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    delay(1);          // give the web browser time to receive the data
    readString="";      //clearing string for next read
    client.stop();      // close the connection:
  }
...

I’ve read anywhere on net that

if(readString.indexOf("chkLED=ON") > -1)

should check the marker. It obviously does because if I omit checked in chkLED line it sets my LED to low.

But how can I trigger the input from browser.

Any directions are highly welcome.

rob*

AFAIK the client has to POST the form before the Arduino can do anything. Setting the mark just happens in the browser most of the time...

Thanks for reply.

Any practical insights for me how this is done?

rob*

ok as I found it, I am answering myself for those who may search for the same odd thing.

Here the code for the main loop:

void loop(void) {
  if ( !bLEDon ) {
    if (ledState == HIGH) digitalWrite(ledPin, LOW); // if on then switch to off
  } else {
    toggleLED();
  }
  Client client = server.available();    // listen for incoming clients
  if (client) {
    boolean currentLineIsBlank = true;   // an http request ends with a blank line
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();          //read char by char HTTP request    
        if (readString.length() < 100)   //store characters to string
          readString = readString + c; 

        // if you've gotten to the end of the line (received a newline character) and the line is blank,
        //  the http request has ended, so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          
          client.println("HTTP/1.1 200 OK");  // send a standard http response header
          client.println("Content-Type: text/html");
          client.println();

          client.println("<h2>Arduino,</h2>
");

          // values of analog input pins
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            client.println("<p>");
            client.print("A("); client.print(analogChannel); client.print(")="); client.print(analogRead(analogChannel));
            client.println("</p>");
          }
          client.print("<form method=\"get\" action=\"1\">");
          client.print("<input type='checkbox' name='chkLED' value='ON' checked>&nbsp;LED ON</input>");
          client.print("
<input type=\"submit\" name=\"update\" value=\"OK\"></input>");
          client.println("</form>");
          break;
        }
        if (c == '\n') { // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') { // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    Serial.println(readString);
    if(readString.indexOf("chkLED=ON") > -1 ) {
      bLEDon = true;
      Serial.println("     => LED ON");
    }
    else if ( !(readString.indexOf("GET /favicon.ico") > -1) ) { // at least Chrome: It requests favicon
      bLEDon = false;
      Serial.println("  !! => LED OFF");
    }
    delay(1);          // give the web browser time to receive the data
    readString="";      //clearing string for next read
    client.stop();      // close the connection:
  }
}

Explanation:
The code prints out on HTML page values of analog ports, adds a checkmark to disable LED blinking. When unchecked and OK is pressed this submits

GET /1?chkLED=ON&update=OK HTTP/1.1

I first did not recognize that everytime the browser requeries, it also requests for favicon. As this is the second reply it must be filtered. Otherwise the chkLED=ON is not detected (that is the if clause behind else).

BTW: Anyone managed to deliver a simple favicon.ico. Would be nice :wink:

LOG of Debug Code (Note: not mentioned above)

Opened: cfg.ip
cfg.ip: 192.168.10.177

100GET / HTTP/1.1
Host: 192.168.10.177
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh;
  !! => LED OFF
[0]..client stopped.

GET /favicon.ico HTTP/1.1
Host: 192.168.10.177
Connection: keep-alive
Accept: */*
User-Agent: Mo
[1]..client stopped.

GET /1?chkLED=ON&update=OK HTTP/1.1
Host: 192.168.10.177
Connection: keep-alive
Referer: http://1
     => LED ON
[2]..client stopped.

GET /favicon.ico HTTP/1.1
Host: 192.168.10.177
Connection: keep-alive
Accept: */*
User-Agent: Mo
[3]..client stopped.
  if ( !bLEDon ) {
    if (ledState == HIGH) digitalWrite(ledPin, LOW); // if on then switch to off
  } else {
    toggleLED();
  }

Given that first comment, what does toggleLED() do? Change the state of the pin AND the state of the variable at the same time? Shouldn't you always be doing that?

BTW: Anyone managed to deliver a simple favicon.ico. Would be nice ;-) ...

The icon can reside on another server. You can simply return a link to it.

Not sure just what your issue is, but below is some simple server code that can make an arduino pin high/low

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
Server server(84); //server port

String readString; 
 
 //////////////////////

void setup(){

pinMode(4, OUTPUT);
//start Ethernet
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();

//enable serial data print 
Serial.begin(9600); 
Serial.println("servertest1"); // so I can keep track of what is loaded
}

void loop(){
// Create a client connection
Client client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();

//read char by char HTTP request
if (readString.length() < 100) {

//store characters to string 
readString += c; 
//Serial.print(c);
} 

//if HTTP request has ended
if (c == '\n') {

///////////////
Serial.println(readString);

  //now output HTML data header

  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println();

client.println("<HTML>");
   client.println("<HEAD>");
     client.println("<TITLE>Arduino GET test page</TITLE>");
   client.println("</HEAD>");
   client.println("<BODY>");
    
    client.println("<H1>HTML form GET example</H1>");

    client.println("<FORM ACTION=\"http://192.168.1.102:84\" method=get >");

    client.println("Pin 4 \"on\" or \"off\": <INPUT TYPE=TEXT NAME=\"LED\" VALUE=\"\" SIZE=\"25\" MAXLENGTH=\"50\">
");

        client.println("<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"Change Pin 4!\">");

    client.println("</FORM>");
    
client.println("
");

   client.println("</BODY>");
client.println("</HTML>");

  delay(1);
  //stopping client
client.stop();

/////////////////////
if(readString.indexOf("on") >0)//checks for on
           {
             digitalWrite(4, HIGH);    // set pin 4 high
             Serial.println("Led On");
             }
if(readString.indexOf("off") >0)//checks for off
           {
             digitalWrite(4, LOW);    // set pin 4 low
             Serial.println("Led Off");
             }
//clearing string for next read
readString="";
  
}}}}}