-->
Page 1 of 1

Sample Sketch for ESP-12 w/ Integral Web Page Full Function

PostPosted: Thu Oct 29, 2015 2:22 pm
by JoseAngel
This Project is an Depuration and improvement of few similar projects I saw Here and There that hepme to learn ESP-Arduino. :idea:

It's Aimed at ESP8266-12 Dev Board (the One with Photo Resistors, Leds, and a bunch of GPIOs).

This Project lets you Control 4 Outputs from "buttons" on a web page, as well Continuously Monitor 2 Inputs and the ADC Input.

To monitor Inputs, its uses AJAX (javascript/html), so its hyper-efficient on bandwidt, no need to call to Comcast for Broader Internet, don worry its supported by most Phones and Every PC build from 1995 :o


:arrow: Works Well ( I debugged most of other project's pitfails :geek: :geek: ), Just Customize to your application.

I'm here learning as you, don't see me as a Guru, just promise me to doit better and share your work. :mrgreen:

Code: Select all/*
 * I just started with ESP8266 since I have few urgent IoT needs to fulfill, and its ideal for my purposes, but I find no useful samples
 * to help me for such simple IoT solution I pursuit.
 * then reading here and there I gathered the blocks to build my IoT ESP-12
 * I home many people here sharing this need could find this project useful
 * Dont give me credits, I Just Improved what I've find puting toghether in an single project which could be an
 * start point for many others with similar need
 *
 * This work is an improvement on previous tutorials published here ot other webs
 * Particular thanks to Rui Santos and its Arduino-Ethernet Shield tutorials from which tis the base for this work (and the CSS styleSheet is used here)
 * Visit: http://randomnerdtutorials.com for more details
 *
 * Also the "Garage Door Opener V2 by SWilson http://www.esp8266.com/viewtopic.php?f=29&t=2696 provided most of the help
 * very useful info needed to handle ajax html and other WEB-Related technologies can be found at http://www.w3schools.com/js/default.asp
 *
 * Fell free to copy/improve/etc onle compensation wanted is you share your ESP8266 projects here
 *
 * WARNING: this project is released "as is"  with no warranty, you are responsible for it, use it as learning tool not as part for a commercial
 * or production device.
 *
 * LICENSE: MIT (which means you can copy and if you like to share it again as you like, no snake GPL viral clauses.
 *
 * this project for testing uses an css style sheet read from Rui SantosÅ› examples "ethernetcss.css" you can find it at its Arduino-Ethernet sample
 * my safety suggestion if you decide to use an CSS style sheet derived or no from 'santos, is you should host it at your own controlled server,
 * this way minimizes DDoS Attacks or other Attacks on your IoT network.
 * Preferable to use ths solution on an Intranet with VPN access from the exterior and not allow the IoT modules to receive externa connexions.
 *
 * I'don't speak English natively, I do may best effort to express here, sorry for any error
 *
 * Thanks
 * J.A. Acosta
 *
 */
#include <ESP8266WiFi.h>
#define serverPort 80
// define (map) GPIO to HTML Fields (buttons/Indicators), note: not using 0 as base index deliberately

#define input1 16
#define input2 14

#define statusLEDr 15
#define statusLEDg 12
#define statusLEDb 15

#define output1 4
#define output2 5
#define output3 2
#define output4 0

WiFiServer server(serverPort);

//*-- IoT Information
const char* _SSID = "yourNetworkSSID";
const char* _PASS = "yourNetworkPass";
const char* _passcode = "1234";//note: the field "passcode in the html form "frm1" must match the passcode lenght
char passcodeOK='0';//start Code is blank...
String readString;
int analogReadOut = 0;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
   
  pinMode(output1, OUTPUT); 
  pinMode(output2, OUTPUT); 
  pinMode(output3, OUTPUT); 
  // avoid using pin0 while on development, cause is more difficult to upload code since ESP_COMM must be connected before owncode start
  //pinMode(output4, OUTPUT); //uncomment to control output #4 
  pinMode(statusLEDr, OUTPUT);
  pinMode(statusLEDg, OUTPUT);
  pinMode(statusLEDb, OUTPUT);
   
  pinMode(input1, INPUT); 
  pinMode(input2, INPUT);
   
  delay(50);
  Serial.print("Connecting to ");
  Serial.println(_SSID);
  WiFi.begin(_SSID, _PASS);
   
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected to:");
  Serial.println(_SSID);
  delay(1000);
  ESP.wdtEnable(WDTO_4S);
  //Start the server
  server.begin();
  Serial.println("Server started");

  //Print the IP Address
  Serial.print("Use this URL to connect: ");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.print(":");
  Serial.print(serverPort);
  Serial.println("/");
  delay(1000);
}


void loop() {
  //reset code for re-validation
  passcodeOK='0';
  // Create a client connection
  WiFiClient 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;
        }
        // HTTP request has ended
        if (c == '\n') {   
          if (readString.indexOf(String("sensorupdrq"))>0){//this branch purpose is to discriminate ajax update request from standad web request to, if you dont need
            Serial.println("\r\najax sensor upd req:"); //comment the entire branch all '//<<<' lines
            Serial.print(readString);//<<<
            client.println("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: keep-alive"); // <<<
            readInputs(client);//<<<
          }//<<<
          else//<<<
          {
            Serial.println("web request:");
            Serial.print(readString);
            if (readString.indexOf(String("passcode="))>0){
              if (readString.indexOf(String(_passcode))>0) {
                passcodeOK='1';
                Serial.println("Password OK");
                digitalWrite(statusLEDg, HIGH);
                digitalWrite(statusLEDr, LOW);
            }else{
                passcodeOK='0';
                Serial.println("Password NotOK");
                digitalWrite(statusLEDg, LOW);
                digitalWrite(statusLEDr, HIGH);
              }
            }
            client.println("HTTP/1.1 200 OK\r\nContent-Type: text/html");
            client.println("\r\n<HTML>");
            client.println("<HEAD>");
            client.println("<meta name=\"viewport\" content=\"width=380\">");
// Important, edit the Following line to match your CSS style sheet location, I suggest you to host at your own controlled server
            client.println("<link rel='stylesheet' type='text/css' href='http://--PATH TO YOUR CSS--/ethernetcss.css' />");
            client.println("<TITLE>FULL ESP8266-12 CONTROL DEMO</TITLE>");
            // simple javascritp code to intercept anchor clientick and trick HREF field with the Button (or action) ID and add the password from the input field
            client.println("\r\n<script>\r\nfunction SndCommand( obx,swtchNO ){ \r\nobx.href=\"button\"+swtchNO+\"&passcode=\"+document.getElementById(\"frm1\").elements[0].value;\r\n}\r\n</script>\r\n");
            // not so simple script to allow sensor data to be automatically updated
            client.println("\r\n<script>\r\nfunction GetSensorUpd() {\r\nnocache = \"&nocache=\" + Math.random() * 1000000;");
            client.println("var ajaxreq = new XMLHttpRequest();");
            client.println("ajaxreq.open(\"GET\", \"sensorupdrq\" + nocache, true);");
            client.println("ajaxreq.onreadystatechange = function() {");
            client.println("if (ajaxreq.readyState == 4 && ajaxreq.status == 200) {");
            client.println("document.getElementById(\"readX\").innerHTML = ajaxreq.responseText;");
            client.println("}\r\n}\r\najaxreq.send();");
            client.println("setTimeout('GetSensorUpd()', 5000);\r\n}\r\n</script>\r\n");//updates each half second

            client.println("</HEAD>");
            client.println("<BODY onload=\"GetSensorUpd()\">");//comment thiss if you do not want automatic sensor update
//            client.println("<BODY>");//uncomment this if yoy do not want auto update
            client.println("<H1>Demo to Control Output<br />and<br />Sensor Read with ESP8266</H1>");
            client.println("<br />"); 
            client.print("<div id=\"passx\"><form id=\"frm1\">Password:<input name=\"passcode\" size=\"5\" maxlength=\"4\" type=\"password\" value=\"");
            if (passcodeOK== '1') client.print(_passcode);
            client.println("\" style='font-size:24pt'></form></div>");
               
            client.print("<div id=\"readX\">");
            readInputs(client); 
            client.println("</div>");

           
            // first ON/OFF Buttons pair
            client.println("<BR /><a href=\"\" onclick=\"SndCommand(this,11)\">Output 1 On</a>");
            //SndCommand is a javascript code running on the clientiet (aka ajax) Parameters are outputIDx and State
            client.println("<a href=\"\" onclick=\"SndCommand(this,10)\">Output 1 Off</a><br /><br />");   
           
            // then repeat for every gpio as output to control
           
            client.println("<a href=\"\" onclick=\"SndCommand(this,21)\">Output 2 On</a>");
            client.println("<a href=\"\" onclick=\"SndCommand(this,20)\">Output 2 Off</a><br /><br />"); 
 
            client.println("<a href=\"\" onclick=\"SndCommand(this,31)\">Output 3 On</a>");
            client.println("<a href=\"\" onclick=\"SndCommand(this,30)\">Output 3 Off</a><br /><br />"); 
           
            client.println("<a href=\"\" onclick=\"SndCommand(this,41)\">Output 4 On</a>");
            client.println("<a href=\"\" onclick=\"SndCommand(this,40)\">Output 4 Off</a><br /><br />");
           
            client.println("</BODY>");
            client.println("</HTML>");
            //Processing client request
            // Button0
            if (readString.indexOf("button11") >0 && passcodeOK== '1'){
              digitalWrite(output1, HIGH);
            }
            if (readString.indexOf("button10")>0 && passcodeOK== '1'){
              digitalWrite(output1, LOW);
            }
            if (readString.indexOf("button21") >0 && passcodeOK== '1'){
              digitalWrite(output2, HIGH);
            }
            if (readString.indexOf("button20")>0 && passcodeOK== '1'){
              digitalWrite(output2, LOW);
            }
            if (readString.indexOf("button31") >0 && passcodeOK== '1'){
              digitalWrite(output3, HIGH);
            }
            if (readString.indexOf("button30")>0 && passcodeOK== '1'){
              digitalWrite(output3, LOW);
            }
            if (readString.indexOf("button41") >0 && passcodeOK== '1'){
              digitalWrite(output4, HIGH);
            }
            if (readString.indexOf("button40")>0 && passcodeOK== '1'){
              digitalWrite(output4, LOW);
            }     
          }
          delay(1);
          client.stop();
          delay(0);
          //clean readString for next read
          readString="";
          digitalWrite(statusLEDg, LOW);
          digitalWrite(statusLEDr, LOW);
        }
      }
    }
  }
}
// send back GPIO Data Refresh
void readInputs(WiFiClient cl) {
  cl.println("\r\n<p>");//dont miss to wrap the request with some tag, mandatory for ajax to work properly
  analogReadOut = analogRead(A0);
  if (analogReadOut < 50){
    cl.print("<p>Analog Reading:<span style='background-color:#00FF00; font-size:18pt'>");
    cl.print(analogReadOut);
    cl.println("</span></p>");
  }else{
    cl.print("<p>Analog Reading:<span style='background-color:#FF0000; font-size:18pt'>");
    cl.print(analogReadOut);
    cl.println("</span></p>");
  } 
  cl.println("<br />");
  if (digitalRead(input1)) {
    cl.println("<p>Input ONE is: <span style='background-color:#00FF00; font-size:18pt'>ON</span></p>");
  }else{
    cl.println("<p>Input ONE is: <span style='background-color:#FF0000; font-size:18pt'>OFF</span></p>");
  }
  cl.println("<br />");
  if (digitalRead(input2)) {
    cl.println("<p>Input TWO is: <span style='background-color:#00FF00; font-size:18pt'>ON</span></p>");
  }else{
    cl.println("<p>Input TWO is: <span style='background-color:#FF0000; font-size:18pt'>OFF</span></p>");
  }
  cl.println("</p>");//this tag completes the request wrap
  Serial.println("ajax sensor upd sent\r\n");
}

Re: Sample Sketch for ESP-12 w/ Integral Web Page Full Funct

PostPosted: Thu Jun 16, 2016 7:52 am
by JBredahl
I would like to see your CSS style sheet file to get an idea of how it should look.