Skip to content
Snippets Groups Projects
test_webpage_sensors.ino 10.86 KiB
/*********
 https://randomnerdtutorials.com/esp32-async-web-server-espasyncwebserver-library/
*********/

// Import required libraries
#include <Arduino.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
#include <Stepper.h>
#include <AccelStepper.h>
#include <MultiStepper.h>

// Replace with your network credentials
const char* ssid = "Connectify-ESP32 Boot";
const char* password = "temp_pass1234";

const char* input_parameter1 = "output";
const char* input_parameter2 = "state";

#define PRESSUREPIN1 34
#define PRESSUREPIN2 35
#define motorIN1 33
#define motorIN2 32
#define motorIN3 26
#define motorIN4 27

#define PRESSURE1GOAL 1000
#define PRESSURE2GOAL 2034

Stepper motor(200, motorIN1, motorIN2, motorIN3, motorIN4);
//AccelStepper motor(AccelStepper::FULL4WIRE, motorIN1, motorIN2, motorIN3, motorIN4);

// current temperature & humidity, updated in loop()
int pressure1 = 0.0;
int pressure2 = 0.0;
float motor1Speed = 0.0;
String pressure1status = "NOT YET...";
String pressure2status = "NOT YET...";
String motor1status = "Not running";

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;    // will store last time DHT was updated

// Updates DHT readings every 10 seconds
const long interval = 1;  

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <style>
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 3.0rem; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .sensorlabel{
      font-size: 1.5rem;
      vertical-align:center;
      padding-bottom: 15px;
    }
    .statuslabel { font-size: 1.3rem; }
    button2 {background-color: #555555;}
    body {max-width: 600px; margin:0px auto; padding-bottom: 25px;}
    .switch {position: relative; display: inline-block; width: 120px; height: 68px} 
    .switch input {display: none}
    .slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 6px}
    .slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 3px}
    input:checked+.slider {background-color: #b30000}
    input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
  </style>
</head>
<body>
  <h2>Remotely Adjustable Boot</h2>
  <p>
    <i class="fas fa-thermometer-half" style="color:#4a32a8;"></i> 
    <span class="sensorlabel">Pressure LEFT</span> 
    <br>
    <span id="pressure1">%PRESSURE1%</span>
    <sup class="units">mmHg</sup>
  </p>
  <p>
    <span class="sensorlabel">Status:</span>
    <span id="pressure1status" class="statuslabel">%PRESSURE1STATUS%</span>
  </p>
  <p>
    <i class="fas fa-thermometer-half" style="color:#4a32a8;"></i> 
    <span class="sensorlabel">Pressure RIGHT</span> 
    <span id="pressure2">%PRESSURE2%</span>
    <sup class="units">mmHg</sup>
  </p>
  <p>
    <span class="sensorlabel">Status:</span>
    <span id="pressure2status" class="statuslabel">%PRESSURE2STATUS%</span>
  </p>
  <p>
    <i class="fas fa-wrench" style="color:#4a32a8;"></i> 
    <span class="sensorlabel">Motor Status</span>
    <span id="motor1status">%MOTOR1STATUS%</span>
    <sup class="units">torque</sup>
  </p>
  %BUTTONPLACEHOLDER%
  <script>function toggleCheckbox(element) {
    var xhr = new XMLHttpRequest();
    if(element.checked){ xhr.open("GET", "/update?output="+element.id+"&state=1", true); }
    else { xhr.open("GET", "/update?output="+element.id+"&state=0", true); }
    xhr.send();
  }
  </script>
</body>
<script>
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("pressure1").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/pressure1", true);
  xhttp.send();
}, 1000 ) ;

setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("pressure1status").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/pressure1status", true);
  xhttp.send();
}, 1000 ) ;

setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("pressure2").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/pressure2", true);
  xhttp.send();
}, 1000 ) ;

setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("pressure2status").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/pressure2status", true);
  xhttp.send();
}, 1000 ) ;

setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("motor1status").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/motor1status", true);
  xhttp.send();
}, 1000 ) ;
</script>
</html>)rawliteral";

String outputState(int output){
  if(digitalRead(output)){
    return "checked";
  }
  else {
    return "";
  }
}

// Replaces placeholder with DHT values
String processor(const String& var){
  //Serial.println(var);
  if(var == "PRESSURE1"){
    return String(pressure1);
  }
  else if (var == "PRESSURE1STATUS"){
    return String(pressure1status);
  }
  else if(var == "PRESSURE2"){
    return String(pressure2);
  }
  else if (var == "PRESSURE2STATUS"){
    return String(pressure2status);
  }
  else if(var == "MOTOR1STATUS"){
    return String(motor1status);
  }
  else if(var == "BUTTONPLACEHOLDER"){
    String buttons = "";
    buttons += "<h4>Output - GPIO 2</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"2\" " + outputState(2) + "><span class=\"slider\"></span></label>";

    return buttons;
  }
  return String();
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);
  
  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  Serial.println("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println(".");
  }

  // Print ESP8266 Local IP Address
  Serial.println(WiFi.localIP());

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });
  server.on("/pressure1", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(pressure1).c_str());
  });
  server.on("/pressure1status", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(pressure1status).c_str());
  });
  server.on("/pressure2", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(pressure2).c_str());
  });
  server.on("/pressure2status", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(pressure2status).c_str());
  });
  server.on("/motor1status", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(motor1status).c_str());
  });

  server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage1;
    String inputMessage2;
    // GET input1 value on <ESP_IP>/update?output=<inputMessage1>&state=<inputMessage2>
    if (request->hasParam(input_parameter1) && request->hasParam(input_parameter2)) {
      inputMessage1 = request->getParam(input_parameter1)->value();
      inputMessage2 = request->getParam(input_parameter2)->value();
      digitalWrite(inputMessage1.toInt(), inputMessage2.toInt());
    }
    else {
      inputMessage1 = "No message sent";
      inputMessage2 = "No message sent";
    }
    Serial.print("GPIO: ");
    Serial.print(inputMessage1);
    Serial.print(" - Set to: ");
    Serial.println(inputMessage2);

    if (inputMessage2.toInt() == 1){
      motor1status="running!!!"; // doesn't work idk why
//      motor.setSpeed(120);
//      motor.setCurrentPosition(0);
//      motor.setAcceleration(10);
//
//      motor.moveTo(2000);
//
//      while(motor.distanceToGo() <= 1000) {
//        motor.setSpeed(80);
//        motor.runToPosition();
//      }
      motor.setSpeed(60);
      motor.step(500);
      motor.setSpeed(0);
//     motor1status = "motor stop";
    }
    
    request->send(200, "text/plain", "OK");
  });

  // Start server
  server.begin();
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);
}
 
void loop(){
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    
    previousMillis = currentMillis;
    
    int intervals1[7] = {0,0,0,0,0,0,0};
    int intervalValues1[7] = {0,0,0,0,0,0,0};
    int intervals2[7] = {0,0,0,0,0,0,0};
    int intervalValues2[7] = {0,0,0,0,0,0,0};
    
     for(int counter = 0; counter < 10; counter ++) {
      int a1 = analogRead(PRESSUREPIN1);
      int a2 = analogRead(PRESSUREPIN2);
      int aModulus1 = int (a1 / (600));
      int aModulus2 = int (a2 / (600));
      intervals1[aModulus1] += 1;
      intervalValues1[aModulus1] += int(a1 % 600);

      intervals2[aModulus2] += 1;
      intervalValues2[aModulus2] += int(a2 % 600);

      delay(10);
     }
          
     int maxIntervalSize1 = intervals1[0];
     int maxIntervalIndex1 = 0;
     for (int index = 1; index < 7; index ++) {
      if (intervals1[index] > maxIntervalSize1) {
        maxIntervalIndex1 =  index;
        maxIntervalSize1 = intervals1[index];
      }
     }
     int maxIntervalSize2 = intervals2[0];
     int maxIntervalIndex2 = 0;
     for (int index = 1; index < 7; index ++) {
      if (intervals2[index] > maxIntervalSize2) {
        maxIntervalIndex2 =  index;
        maxIntervalSize2 = intervals2[index];
      }
     }
     pressure1 = (intervalValues1[maxIntervalIndex1]/maxIntervalSize1)+ maxIntervalIndex1*600;
     pressure2 = (intervalValues2[maxIntervalIndex2]/maxIntervalSize2)+ maxIntervalIndex2*600;

    if (((float)abs(pressure1 - PRESSURE1GOAL)/(float)PRESSURE1GOAL) <= 0.15){
      pressure1status = "LEFT GOAL REACHED";
    }
    else {
      pressure1status = "not yet...";
    }

    if (((float)abs(pressure2 - PRESSURE2GOAL)/(float)PRESSURE2GOAL) <= 0.15){
      pressure2status = "RIGHT GOAL REACHED";
    }
    else {
      pressure2status = "not yet...";
    }
    
  }
}