Send Sensor Data to a Web Server via ESP8266

Difficulty Level: Intermediate

Project Overview

This project demonstrates how to send sensor data to a web server using an ESP8266 and display the data on a web page. It’s an excellent starting point for IoT projects that require remote monitoring of environmental conditions, such as home automation, weather stations, or greenhouse management.

In this project, we will:

- Use an ESP8266 microcontroller to read temperature and humidity data from a DHT11 sensor.

- Send the collected data to a web server using HTTP POST requests.

- Process and validate the incoming data on the server side using PHP.

- Visualize the real-time data on a web page with JavaScript and Chart.js for an interactive user experience.

This setup provides a practical introduction to IoT concepts like sensor interfacing, network communication, and data visualization.

Components Required

- 1 x ESP8266 (ESP-01 or NodeMCU recommended)

- 1 x DHT11 or DHT22 Temperature and Humidity Sensor (DHT22 offers higher accuracy)

- 1 x 10kΩ pull-up resistor (for stabilizing the DHT data line)

- Jumper wires

- Breadboard

- Optional: USB-to-Serial adapter (e.g., FTDI module) for programming ESP-01

Setting Up the ESP8266

Before diving into the code, ensure your ESP8266 is ready:

1. Install the ESP8266 Board Manager in the Arduino IDE:

  - Go to File > Preferences, add http://arduino.esp8266.com/stable/package_esp8266com_index.json to the "Additional Boards Manager URLs."

  - Open Tools > Board > Boards Manager, search for "ESP8266," and install it.

2. Install Required Libraries:

  - ESP8266WiFi (pre-installed with the board package).

  - DHT by Adafruit (install via Sketch > Include Library > Manage Libraries).

  - ArduinoJson (for JSON data handling).

3. Update Firmware: Use the ESP8266 Flasher tool if your module’s firmware is outdated.

4. Configure Arduino IDE: Select your ESP8266 board (e.g., "NodeMCU 1.0" or "Generic ESP8266 Module") and the correct COM port.

Wiring Diagram

For the DHT Sensor:

- VCC: Connect to the 3.3V pin on the ESP8266 (5V may damage the sensor).

- GND: Connect to the GND pin on the ESP8266.

- DATA: Connect to GPIO2 (D4 on NodeMCU) with a 10kΩ pull-up resistor between VCC and DATA.

Note: Double-check connections to avoid erratic readings or sensor damage.

Arduino Code

Below is the optimized Arduino code to read sensor data and send it to the web server:

#include <ESP8266WiFi.h>
#include <DHT.h>
#include <ArduinoJson.h>

#define DHTPIN 2        // Pin where the DHT sensor is connected (GPIO2)
#define DHTTYPE DHT11   // Use DHT11 or DHT22 depending on your sensor

DHT dht(DHTPIN, DHTTYPE);

const char* ssid = "Your_SSID";          // Replace with your Wi-Fi SSID
const char* password = "Your_PASSWORD";  // Replace with your Wi-Fi password
const char* server = "your_server_ip";   // Replace with your server IP or domain

WiFiClient client;

void setup() {
  Serial.begin(115200);
  dht.begin();
  
  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  float temp = dht.readTemperature();  // Read temperature in Celsius
  float hum = dht.readHumidity();      // Read humidity in percentage
  
  if (isnan(temp) || isnan(hum)) {
    Serial.println("Failed to read from DHT sensor!");
    delay(2000);
    return;
  }

  if (client.connect(server, 80)) {
    Serial.println("Connected to server");

    // Create JSON object
    StaticJsonDocument<200> jsonDoc;
    jsonDoc["temp"] = temp;
    jsonDoc["hum"] = hum;
    String postData;
    serializeJson(jsonDoc, postData);
    
    // Send HTTP POST request
    client.println("POST /api/receive-data.php HTTP/1.1");
    client.println("Host: " + String(server));
    client.println("Content-Type: application/json");
    client.print("Content-Length: ");
    client.println(postData.length());
    client.println();
    client.println(postData);
    
    // Wait for server response (optional for debugging)
    while (client.available()) {
      String line = client.readStringUntil('\r');
      Serial.print(line);
    }
    
    client.stop();
    Serial.println("Data sent to server: " + postData);
  } else {
    Serial.println("Connection to server failed");
  }

  delay(10000);  // Send data every 10 seconds
}
        

Tips:

- Replace your_server_ip with your server’s IP address or domain (e.g., 192.168.1.100 or example.com).

- Adjust delay(10000) to change the data-sending frequency.

Server-Side Code (PHP)

This PHP script securely receives and processes the JSON data from the ESP8266:

<?php
header("Content-Type: application/json");

// Get raw POST data
$data = json_decode(file_get_contents("php://input"));

if (!isset($data->temp) || !isset($data->hum)) {
    echo json_encode(["status" => "error", "message" => "Invalid data"]);
    exit();
}

// Sanitize input
$temp = filter_var($data->temp, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
$hum = filter_var($data->hum, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

if ($temp === false || $hum === false) {
    echo json_encode(["status" => "error", "message" => "Invalid temperature or humidity values"]);
    exit();
}

// Log data to a file (optional)
$log_entry = date('Y-m-d H:i:s') . " | Temp: $temp °C | Hum: $hum %\n";
file_put_contents("sensor_data.log", $log_entry, FILE_APPEND);

// Optional: Save to a database (e.g., MySQL)
// $conn = new mysqli("localhost", "username", "password", "database");
// $conn->query("INSERT INTO sensor_data (temperature, humidity, timestamp) VALUES ($temp, $hum, NOW())");

// Return response to ESP8266
echo json_encode(["status" => "success", "temp" => $temp, "hum" => $hum]);
?>
        

Notes:

- Place this file (e.g., receive-data.php) in your server’s /api/ directory.

- Uncomment and configure the MySQL code if you want to store data persistently.

JSON API for Data Handling

To serve data for visualization, create a separate PHP file (e.g., get-data.php):

<?php
header("Content-Type: application/json");

// Simulate fetching latest data (replace with database query if applicable)
$latest_data = [
    "status" => "success",
    "temp" => 25.5,  // Example value
    "hum" => 60.2    // Example value
];

echo json_encode($latest_data);
?>
        

Data Visualization

Use this HTML/JavaScript code to display real-time data with Chart.js:

<!DOCTYPE html>
<html>
<head>
    <title>Sensor Data Dashboard</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
    <canvas id="sensorChart" width="400" height="200"></canvas>
    <script>
        const ctx = document.getElementById('sensorChart').getContext('2d');
        const chart = new Chart(ctx, {
            type: 'line',
            data: {
                labels: [],
                datasets: [{
                    label: 'Temperature (°C)',
                    data: [],
                    borderColor: 'red',
                    fill: false
                }, {
                    label: 'Humidity (%)',
                    data: [],
                    borderColor: 'blue',
                    fill: false
                }]
            },
            options: { scales: { y: { beginAtZero: true } } }
        });

        function fetchData() {
            fetch('/api/get-data.php')
                .then(response => response.json())
                .then(data => {
                    const time = new Date().toLocaleTimeString();
                    chart.data.labels.push(time);
                    chart.data.datasets[0].data.push(data.temp);
                    chart.data.datasets[1].data.push(data.hum);
                    if (chart.data.labels.length > 20) {
                        chart.data.labels.shift();
                        chart.data.datasets[0].data.shift();
                        chart.data.datasets[1].data.shift();
                    }
                    chart.update();
                });
        }

        setInterval(fetchData, 10000); // Update every 10 seconds
        fetchData(); // Initial fetch
    </script>
</body>
</html>
        

Upload and Test

1. Upload the Arduino code to your ESP8266 via the Arduino IDE.

2. Host the PHP scripts on a web server (e.g., XAMPP, a Raspberry Pi, or a cloud server).

3. Open the Serial Monitor (Ctrl+Shift+M) to verify Wi-Fi connection and data transmission.

4. Visit your web page (e.g., http://your_server_ip/dashboard.html) to see the live chart.

Troubleshooting:

- No data on the server? Check the IP address and ensure port 80 is open.

- Sensor errors? Verify wiring and pull-up resistor placement.

Enhancements & Next Steps

- Database Storage: Use MySQL or SQLite to log data for historical trends.

- MQTT Protocol: Replace HTTP with MQTT for faster, bidirectional communication.

- Alerts: Add email/SMS notifications via services like Twilio or SMTP when thresholds are crossed.

- Cloud Integration: Connect to AWS IoT, Google Cloud, or Firebase for scalability.

- Mobile App: Build a simple app using Flutter or React Native to view data on the go.

Conclusion

This project showcases a complete IoT workflow: collecting sensor data with an ESP8266, sending it to a web server, and visualizing it in real time. It’s a versatile foundation for countless applications, from smart homes to industrial monitoring systems.

FAQ

Q: Can I use a different sensor instead of DHT11?

A: Yes! The DHT22 offers better accuracy, or you could use a BME280 for temperature, humidity, and pressure. Adjust the code accordingly.

Q: Why isn’t my ESP8266 connecting to Wi-Fi?

A: Ensure the SSID and password are correct, and check if your router is on the 2.4 GHz band (ESP8266 doesn’t support 5 GHz).

Q: How do I make the data update faster?

A: Reduce the delay() value in the Arduino code, but avoid overwhelming the server with too many requests.

Q: Can I host this on a free server?

A: Yes, platforms like Heroku or 000webhost support PHP hosting, though you may need to tweak the setup for external requests.

Q: What if my server isn’t accessible from outside my network?

A: Use port forwarding on your router or a service like Ngrok to expose your local server to the internet.

Further Reading for Engagement

Want to dive deeper? Check out these topics on our site:

Getting Started with IoT: A Beginner’s Guide

How to Set Up a Local Web Server with XAMPP

Exploring MQTT: Lightweight Messaging for IoT

Building a Weather Station with ESP8266

Chart.js Tutorials: Advanced Data Visualization

Resources

Libraries

ESP8266WiFi

DHT Sensor Library

ArduinoJson

Tools

Arduino IDE

Chart.js Documentation

Tutorials

ESP8266 Pinout Reference

Setting Up a Server with Apache

Hardware

Buy ESP8266 on Amazon

DHT11/DHT22 Sensors

Contact Us

If you have any questions or inquiries, feel free to reach out to us at Microautomation.no@icloud.com .

Follow our Socials for the newest updates!