ESP8266 Live Sensor Data (Without IoT)

 


Hey, welcome, my friend! Today in this post, I’m going to show you how to create a super simple and useful live sensor data reader using an ESP8266 as a Soft Access Point (AP) Wi-Fi on a web server. There are many ways in this world to send data from one source to another, usually requiring an internet connection, a concept known as the Internet of Things (IoT). However, in this project, we don’t need the internet. We will simply send data or readings from the NodeMCU to browser devices using Wi-Fi.

Parts Require:-

ESP8266 Node MCU x1

Ultrasonic Sensor x1

Rotary Encoder x1

LM35 Temperature Sensor x1

Please note that the sensors I used in this project are my personal choices. You are free to choose any other sensors or components, but you will need to modify the code accordingly.
 Circuit Diagram:-



Code:-

Here is the complete code for the Arduino IDE. Just copy it from here and paste it into your Arduino IDE. Then, select the port and COM board, and upload the code.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

const int trigPin = D1;
const int echoPin = D2;
const int lm35Pin = A0;
const int rotaryPinA = D5;
const int rotaryPinB = D6;
const int buttonPin = D7;

ESP8266WebServer server(80);

volatile int encoderValue = 0;
volatile bool buttonPressed = false;
int lastEncoded = 0;

long duration;
int distance;
float temperature;

void IRAM_ATTR handleRotary() {
  int MSB = digitalRead(rotaryPinA); // MSB = most significant bit
  int LSB = digitalRead(rotaryPinB); // LSB = least significant bit

  int encoded = (MSB << 1) | LSB; // converting the 2 pin value to single number
  int sum = (lastEncoded << 2) | encoded; // adding it to the previous encoded value

  if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue++;
  if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue--;

  encoderValue = constrain(encoderValue, 0, 360);

  lastEncoded = encoded; // store this value for next time
}

void IRAM_ATTR handleButtonPress() {
  buttonPressed = true;
}

void handleRoot() {
  String html = "<!DOCTYPE html><html><head>";
  html += "<meta charset='UTF-8'>";
  html += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
  html += "<style>";
  html += "body { font-family: 'Arial', sans-serif; background-color: #f0f0f0; margin: 0; padding: 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; }";
  html += ".box { width: 90%; max-width: 300px; height: 150px; margin: 10px; border-radius: 20px; text-align: center; font-size: 24px; color: #ffffff; display: flex; align-items: center; justify-content: center; }";
  html += ".distance-box { background-color: #3498db; border: 4px solid #2c3e50; }";
  html += ".temperature-box { background-color: #2ecc71; border: 4px solid #27ae60; }";
  html += ".progress-container { position: relative; width: 200px; height: 200px; margin-top: 20px; }";
  html += ".progress { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 24px; color: #333; background: conic-gradient(#3498db 0deg, #2ecc71 360deg); }";
  html += ".progress::after { content: ''; width: 180px; height: 180px; border-radius: 50%; background: #f0f0f0; position: absolute; }";
  html += ".progress span { position: relative; z-index: 1; }";
  html += ".boom { animation: boomAnimation 1s ease-in-out infinite; color: red; font-size: 36px; font-weight: bold; }";
  html += "@keyframes boomAnimation { 0% { transform: scale(1); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } }";
  html += "</style>";
  html += "</head><body>";
  html += "<div class='box distance-box' id='distanceBox'><span id='distance'>Loading...</span></div>";
  html += "<div class='box temperature-box' id='temperatureBox'><span id='temperature'>Loading...</span></div>";
  html += "<div class='progress-container'><div class='progress' id='progress'><span id='encoderValue'>Loading...</span></div></div>";
  html += "<script>";
  html += "function fetchData() {";
  html += "fetch('/getDistance').then(response => response.json()).then(data => {";
  html += "document.getElementById('distance').innerText = 'Distance: ' + data.distance + ' CM';";
  html += "document.getElementById('distanceBox').style.backgroundColor = getDistanceColor(data.distance);";
  html += "});";
  html += "fetch('/getTemperature').then(response => response.text()).then(data => {";
  html += "document.getElementById('temperature').innerText = 'Temperature: ' + data + ' °C';";
  html += "document.getElementById('temperatureBox').style.backgroundColor = getTemperatureColor(parseFloat(data));";
  html += "});";
  html += "fetch('/getEncoder').then(response => response.text()).then(data => {";
  html += "let progressElem = document.getElementById('progress');";
  html += "let encoderValueElem = document.getElementById('encoderValue');";
  html += "if (data === 'BOOM!') {";
  html += "encoderValueElem.innerHTML = '<span class=\"boom\">BOOM!</span>';";
  html += "progressElem.style.background = 'conic-gradient(red 0deg, red 360deg)';";
  html += "} else {";
  html += "encoderValueElem.innerText = data + '°';";
  html += "progressElem.style.background = 'conic-gradient(hsl(' + data + ', 100%, 50%) 0deg, hsl(' + data + ', 100%, 50%) ' + data + 'deg, #eee ' + data + 'deg 360deg)';";
  html += "}";
  html += "});";
  html += "}";
  html += "function getDistanceColor(value) {";
  html += "var hue = 120 - (value * 1.2);"; // Adjust the hue calculation to start with red and transition to green
  html += "return 'hsl(' + hue + ', 100%, 50%)';"; // Create color in HSL format
  html += "}";
  html += "function getTemperatureColor(temp) {";
  html += "var hue = temp > 45 ? 270 : temp < 11 ? 240 : 240 + (temp - 11) * 2.7;";
  html += "return 'hsl(' + hue + ', 100%, 50%)';";
  html += "}";
  html += "setInterval(fetchData, 100);";
  html += "</script>";
  html += "</body></html>";

  server.send(200, "text/html", html);
}


void handleGetDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = duration * 0.034 / 2;
  String json = "{\"distance\":" + String(distance) + "}";
  server.send(200, "application/json", json);
}

float readTemperature() {
  int rawValue = analogRead(lm35Pin);
  float voltage = (rawValue / 1023.0) * 3.3; // Calculate voltage (0-3.3V)
  float temperatureCelsius = voltage * 100.0; // Convert voltage to temperature in Celsius
  return temperatureCelsius;
}

void handleTemperature() {
  temperature = readTemperature();
  server.send(200, "text/plain", String(temperature));
}

void handleEncoder() {
  if (buttonPressed) {
    server.send(200, "text/plain", "BOOM!");
    buttonPressed = false;
  } else {
    server.send(200, "text/plain", String(encoderValue));
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(lm35Pin, INPUT);
  pinMode(rotaryPinA, INPUT);
  pinMode(rotaryPinB, INPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  
  attachInterrupt(digitalPinToInterrupt(rotaryPinA), handleRotary, CHANGE);
  attachInterrupt(digitalPinToInterrupt(rotaryPinB), handleRotary, CHANGE);
  attachInterrupt(digitalPinToInterrupt(buttonPin), handleButtonPress, FALLING);

  const char* ssid="ESP8266 Live Data"; //SSID of this device 
  const char* password="12345678"; // Password of this Device
  
  // Set up the ESP8266 as a Wi-Fi Access Point
  WiFi.softAP(ssid, password);

  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);

  server.on("/", handleRoot);
  server.on("/getDistance", handleGetDistance);
  server.on("/getTemperature", handleTemperature);
  server.on("/getEncoder", handleEncoder);
  server.begin();
  Serial.println("HTTP server started");
}

void loop() {
  server.handleClient();
}

We have integrated three sensors in this project:

  1. Ultrasonic Sensor: Measures the distance of an object from the sensor. The measured distance is displayed on the web page, and the background color of the display box changes based on the distance.
  2. LM35 Temperature Sensor: Measures the ambient temperature. The temperature is displayed in degrees Celsius, with the background color of the display box changing based on the temperature.
  3. Rotary Encoder: Captures the rotation angle, which is displayed on a circular progress bar. If the encoder’s button is pressed, a “BOOM!” message is shown with an animation.

The data from these sensors is refreshed every 100 milliseconds, providing a real-time update on the web page.

How to Use

  1. Setup: Connect the ESP8266 NodeMCU to your computer and upload the provided code using the Arduino IDE.
  2. Power Up: Once the code is uploaded, power the ESP8266. It will create a Wi-Fi network named "ESP8266 Live Data" with the password "12345678".
  3. Connect: Use your smartphone or computer to connect to the "ESP8266 Live Data" Wi-Fi network.
  4. Access the Web Server: Open a web browser and navigate to the IP address 192.168.4.1. You will see a web page displaying the live sensor data.
  5. Observe the Data: Place objects at varying distances from the ultrasonic sensor, observe temperature changes around the LM35 sensor, and rotate the rotary encoder to see real-time updates on the web page.

 Please Share this project with your friends and Subscribe my YouTube Channel.

Comments