So you're a Noob? Post your questions here until you graduate! Don't be shy.

User avatar
By Narfel
#71858 Hi folks, I'm still not positive on the basic interaction between my arduino code and the web. In the simplified example below i have a simple pushbutton hooked up to a GPIO and I serve a htmlbutton hooked to a javascript function. What i'd like to do is have the hardware pushbutton invoke the javascript function exactly as if i'd pressed the htmlbutton on the page. It's probably easier than i think or impossible because of a reason i'm not aware of... :?

Code: Select all#include <Arduino.h>
#include <ESP8266WebServer.h>
#define BUTTON 4

const char *website =
R"0(
  <!DOCTYPE html>
  <html>
  <head><meta charset="UTF-8">
    <script>function buttonClick(){ console.log("webbutton pressed"); };</script>
  </head>
  <body><button type="button" onclick="buttonClick();">Button</button></body>
  </html>
)0";

const char* ssid = "xxxxxx";
const char* password = "xxxxxx";
ESP8266WebServer server(80);

void handleRoot() {
        server.send(200, "text/html", website);
};
void handleButton() {
        --- tell javascript to invoke its function buttonClick()
};

void setup() {
        pinMode(BUTTON, INPUT_PULLUP);

        Serial.begin(115200);
        WiFi.begin(ssid, password);
        while (WiFi.status() != WL_CONNECTED) {
                delay(500);
                Serial.println(".");
        }
        Serial.println(WiFi.localIP());
        server.on("/", handleRoot);
        server.begin();
}

void loop() {
        handleButton();
        server.handleClient();
}
User avatar
By rudy
#71871 I have done very little with javascript or web page stuff. What I think is that you would need either Ajax or websockets to pass things to the javascript. It has been a long day so instead of trying to do something with your code I decided to modify the websocket example I posted in one of your previous posts. I hope it will help you to do what you want. The communications is there. Presentation can be changed.

I didn't know how to do this, I just thought I would be able to figure it out, and I did. I have a board with a couple of relays and two switches, that I wanted to implement the manual switch input. So I now only have to take the code and make it handle the second relay and switch. But not today.

The websocket program had an on and an off button and LED text that would change color to match the state of the led. It also handled multiple connections and would keep them in sync. I took this and added a button input.

As I am tired I used a button library to take care of that. It is set to cause a change on a button release.
I used GPIO0 as the button input as that has a switch on my boards.
I used the onboard led to show the output state so the state of the led is inverted. Easy to fix. Or use a different output with high == on.

Take a look at handleButton(). This changes the led state and sends an update to the webpages.

Code: Select all/*
   ESP8266 Web server with Web Socket to control an LED.

   The web server keeps all clients' LED status up to date and any client may
   turn the LED on or off.

   For example, clientA connects and turns the LED on. This changes the word
   "LED" on the web page to the color red. When clientB connects, the word
   "LED" will be red since the server knows the LED is on.  When clientB turns
   the LED off, the word LED changes color to black on clientA and clientB web
   pages.

   References:

   https://github.com/Links2004/arduinoWebSockets

*/

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <Hash.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

extern "C" {
#include "user_interface.h"
}

const int LEDPIN = 2;                             //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
// Current LED status
bool ledState;
//boolean ledState;          //A variable that keeps the current LED status
//-----------------------------------------------------------------
// Fill in your WiFi router SSID and password

const char* ssid = "ssid";
const char* password = "pass";

//---------------------------------------------------
#include <Button.h>        // https://github.com/JChristensen/Button          //$$$$$$$$$$$$$$$$$$$$$$$$$$

#define BUTTON 0                     //         //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

#define PULLUP true        //To keep things simple, we use the Arduino's internal pullup resistor.
#define INVERT true        //Since the pullup resistor will keep the pin high unless the
//switch is closed, this is negative logic, i.e. a high state
//means the button is NOT pressed. (Assuming a normally open switch.)
#define DEBOUNCE_MS 20     //A debounce time of 20 milliseconds usually works well for tactile button switches.

Button myBtn(BUTTON, PULLUP, INVERT, DEBOUNCE_MS);    //Declare the button

//---------------------------------------------------
//-----------------------------------------------------------------
MDNSResponder mdns;

static void writeLED(bool);

ESP8266WiFiMulti WiFiMulti;

ESP8266WebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);

//----------------------------------------------------------------------
static const char PROGMEM INDEX_HTML[] = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta name = "viewport" content = "width = device-width, initial-scale = 1.0, maximum-scale = 1.0, user-scalable=0">
<title>ESP8266 WebSocket Demo</title>

<body style="background-color: #808080; font-family: Arial, Helvetica, Sans-Serif; Color: #000000;">

<script>
var websock;
function start() {
  websock = new WebSocket('ws://' + window.location.hostname + ':81/');
  websock.onopen = function(evt) { console.log('websock open'); };
  websock.onclose = function(evt) { console.log('websock close'); };
  websock.onerror = function(evt) { console.log(evt); };
  websock.onmessage = function(evt) {
    console.log(evt);
    var e = document.getElementById('ledState');
    if (evt.data === 'ledon') {
      e.style.color = 'red';
    }
    else if (evt.data === 'ledoff') {
      e.style.color = 'black';
    }
    else {
      console.log('unknown event');
    }
  };
}
function buttonclick(e) {
  websock.send(e.id);
}
</script>
</head>
<body onload="javascript:start();">
<h1>ESP8266 WebSocket Demo</h1>
<div id="ledState"><b>LED</b></div>
<button id="ledon"  type="button" onclick="buttonclick(this);">On</button>
<button id="ledoff" type="button" onclick="buttonclick(this);">Off</button>
</body>
</html>
)rawliteral";



//----------------------------------------------------------------------
void handleButton() {
    myBtn.read();                    //Read the button

    if (myBtn.wasReleased()) {       //If the button was released, change the LED state
        ledState = !ledState;

      if (ledState == true) { 
        writeLED(true);
           webSocket.broadcastTXT("ledon");
           Serial.println("led on");
      }
      else
      {
        writeLED(false);
           webSocket.broadcastTXT("ledoff");
           Serial.println("led off");
      }

    }
}

//----------------------------------------------------------------------
// Commands sent through Web Socket
const char LEDON[] = "ledon";
const char LEDOFF[] = "ledoff";

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
  Serial.printf("webSocketEvent(%d, %d, ...)\r\n", num, type);
  switch(type) {
    case WStype_DISCONNECTED:
      Serial.printf("[%u] Disconnected!\r\n", num);
      break;
    case WStype_CONNECTED:
      {
        IPAddress ip = webSocket.remoteIP(num);
        Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\r\n", num, ip[0], ip[1], ip[2], ip[3], payload);
        // Send the current LED status
        if (ledState) {
          webSocket.sendTXT(num, LEDON, strlen(LEDON));
        }
        else {
          webSocket.sendTXT(num, LEDOFF, strlen(LEDOFF));
        }
      }
      break;
     
    case WStype_TEXT:
      Serial.printf("[%u] get Text: %s\r\n", num, payload);

      if (strcmp(LEDON, (const char *)payload) == 0) {
        writeLED(true);
      }
      else if (strcmp(LEDOFF, (const char *)payload) == 0) {
        writeLED(false);
      }
      else {
        Serial.println("Unknown command");
      }
      // send data to all connected clients
      webSocket.broadcastTXT(payload, length);
    printf("[%u]   payload- %s\n", num, payload);         // $$$$$$$$$$$$$$$$$$$$
      break;
     
    case WStype_BIN:
      Serial.printf("[%u] get binary length: %u\r\n", num, length);
      hexdump(payload, length);

      // echo data back to browser
      webSocket.sendBIN(num, payload, length);
      break;
     
    default:
      Serial.printf("Invalid WStype [%d]\r\n", type);
      break;
  }
}

void handleRoot()
{
  server.send(200, "text/html", INDEX_HTML);
}

void handleNotFound()
{
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}

//-------------------------------------------------
static void writeLED(bool LEDonState)
{
  ledState = LEDonState;

  if (LEDonState) {
    digitalWrite(LEDPIN, 1);
  }
  else {
    digitalWrite(LEDPIN, 0);
  }
}

//=================================================
void setup()
{
  pinMode(LEDPIN, OUTPUT);
  writeLED(false);

  Serial.begin(115200);

  //Serial.setDebugOutput(true);

  Serial.println();
  Serial.println();
  Serial.println();

  for(uint8_t t = 4; t > 0; t--) {
    Serial.printf("[SETUP] BOOT WAIT %d...\r\n", t);
    Serial.flush();
    delay(1000);
  }

  WiFiMulti.addAP(ssid, password);

  while(WiFiMulti.run() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }


  Serial.println("");
  Serial.println("ESPWebSock.ino");
 
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

      Serial.print(WiFi.SSID());
      Serial.print(" (");
      Serial.print(WiFi.RSSI());
      Serial.println(")");     

  if (mdns.begin("com22-101", WiFi.localIP())) {
//  if (mdns.begin("espWebSock", WiFi.localIP())) {
    Serial.println("MDNS responder started");
    mdns.addService("http", "tcp", 80);
    mdns.addService("ws", "tcp", 81);
  }
  else {
    Serial.println("MDNS.begin failed");
  }

  Serial.print("Connect to http://espWebSock.local or http://");
  Serial.println(WiFi.localIP());

  server.on("/", handleRoot);
  server.onNotFound(handleNotFound);

  server.begin();

  webSocket.begin();
  webSocket.onEvent(webSocketEvent);
}

//=================================================
void loop()
{
  webSocket.loop();
  server.handleClient();
  handleButton();
}