Jump to content

IPDL - 12: TCP/UDP Server for Sensor Data

From cognifront

ESP32 TCP Sensor Data Acquisition Using DHT11 and LDR

Project Overview

This project demonstrates how an ESP32can acquire sensor data and make that data available to a computer over a TCP connection.

The ESP32 connects to an existing Wi-Fi router and operates as a TCP server. A laptop connected to the same Wi-Fi network runs a Python TCP client. The user can select which sensor data is required from the laptop terminal.

The project uses two sensors:

  • DHT11 — measures temperature and relative humidity.
  • Light-dependent resistor |LDR — measures the intensity of light as an analog value.

The communication is based on a simple command-response mechanism.

The laptop sends either: 1 (for DHT) or 2 (for LDR)

The ESP32 reads the corresponding sensor and sends the result back to the laptop.

Objectives

The main objectives of this project are:

  • To understand TCP client-server communication.
  • To connect an ESP32 to an existing Wi-Fi network.
  • To configure an ESP32 as a TCP server.
  • To acquire temperature and humidity using a DHT11 sensor.
  • To acquire analog light-level data using an LDR.
  • To send sensor data from the ESP32 to a computer over TCP.
  • To develop a Python TCP client.
  • To understand a simple request-response communication model.

System Architecture

<syntaxhighlight lang="text">

                      Wi-Fi Router
                   ┌────────────────┐
                   │                │
                   │  Local Network │
                   │                │
                   └───────┬────────┘
                           │
            ┌──────────────┴──────────────┐
            │                             │
          Wi-Fi                         Wi-Fi
            │                             │
     ┌──────▼──────┐               ┌──────▼──────┐
     │    ESP32    │               │   Laptop    │
     │ TCP Server  │               │ TCP Client  │
     │ Port 5000   │               │   Python    │
     └──────┬──────┘               └─────────────┘
            │
      ┌─────┴─────┐
      │           │
   ┌──▼──┐      ┌─▼──┐
   │DHT11│      │ LDR│
   └─────┘      └────┘

</syntaxhighlight>

The router provides the local network connection. The ESP32 and laptop must be connected to the same network.

Internet access is not required for the actual sensor-data communication. The router only needs to provide connectivity between the ESP32 and laptop.

Communication Model

The project follows a request-response model.

<syntaxhighlight lang="text"> Laptop

  │
  │  TCP connection
  ▼

ESP32 TCP Server

  │
  │  "DHT"
  ▼

DHT11

  │
  │  Temperature + Humidity
  ▼

ESP32

  │
  │  TCP response
  ▼

Laptop Terminal </syntaxhighlight>

For the LDR:

<syntaxhighlight lang="text"> Laptop

  │
  │  "LDR"
  ▼

ESP32 TCP Server

  │
  │  analogRead()
  ▼

LDR

  │
  │  Analog value
  ▼

ESP32

  │
  │  TCP response
  ▼

Laptop Terminal </syntaxhighlight>

Hardware Requirements

Component Quantity

Sensor Connections

DHT11 Connection

The DHT11 data pin is connected to GPIO 4 of the ESP32.

DHT11

The program defines the DHT11 connection as:

<syntaxhighlight lang="cpp">

  1. define DHTPIN 4
  2. define DHTTYPE DHT11

</syntaxhighlight>

LDR Connection

The LDR is connected as a voltage divider, with the divider output connected to GPIO 34.

LDR circuit

The program defines:

<syntaxhighlight lang="cpp">

  1. define LDR_PIN 34

</syntaxhighlight>

GPIO 34 is used as an analog input.

Software Requirements

ESP32 Software

The ESP32 program requires:

  • Arduino IDE
  • ESP32 board support package
  • WiFi library
  • DHT sensor library

The ESP32 program creates a TCP server on port 5000.

Laptop Software

The laptop requires:

  • Python 3
  • Python socket module

The Python program uses the built-in Python `socket` module, so an additional networking package is not required.

Network Setup

The ESP32 and laptop must be connected to the same Wi-Fi router.

For example:

<syntaxhighlight lang="text"> Router IP: 192.168.1.1

ESP32 IP: 192.168.1.9

Laptop IP: 192.168.1.10 </syntaxhighlight>

The ESP32 IP address is displayed in the Arduino Serial Monitor after it successfully connects to the router.

The ESP32 program uses:

<syntaxhighlight lang="cpp"> WiFi.begin(ssid, password); </syntaxhighlight>

After connection, the program displays:

<syntaxhighlight lang="text"> Wi-Fi connected! ESP32 IP Address: 192.168.1.x TCP Server started Port: 5000 Waiting for TCP client... </syntaxhighlight>

Step 1 — Configure the ESP32 Wi-Fi

Open the ESP32 program in Arduino IDE.

Enter the Wi-Fi network name and password:

<syntaxhighlight lang="cpp"> const char* ssid = "YOUR_WIFI_NAME"; const char* password = "YOUR_WIFI_PASSWORD"; </syntaxhighlight>

Do not publish real Wi-Fi credentials in project documentation.

Select the appropriate ESP32 board and COM port and upload the program.

Step 2 — Obtain the ESP32 IP Address

Open the Arduino Serial Monitor.

Set the baud rate to:

<syntaxhighlight lang="text"> 115200 </syntaxhighlight>

After the ESP32 connects to the router, the Serial Monitor displays its IP address.

For example:

<syntaxhighlight lang="text"> Wi-Fi connected! ESP32 IP Address: 192.168.1.9 TCP Server started Port: 5000 Waiting for TCP client... </syntaxhighlight>

Record this IP address.

The IP address may be different every time the ESP32 connects to the router.

Step 3 — Configure the Python TCP Client

Open the Python TCP client program.

Change the ESP32 IP address to the IP displayed in the Serial Monitor.

For example:

<syntaxhighlight lang="python"> ESP32_IP = "192.168.1.9" PORT = 5000 </syntaxhighlight>

The Python client creates a TCP socket:

<syntaxhighlight lang="python"> client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) </syntaxhighlight>

It then connects to the ESP32:

<syntaxhighlight lang="python"> client.connect((ESP32_IP, PORT)) </syntaxhighlight>

Step 4 — Run the Python Client

Open Command Prompt or Terminal in the directory containing the Python file.

Run:

<syntaxhighlight lang="text"> python tcp-client-esp-data-receiver.py </syntaxhighlight>

The client establishes a TCP connection with the ESP32.

The terminal displays:

<syntaxhighlight lang="text"> Connected to ESP32

ESP32 Sensor Server Available commands: DHT or LDR </syntaxhighlight>

Step 5 — Select the Sensor

The Python client displays a menu:

<syntaxhighlight lang="text"> Select sensor: 1. DHT11 2. LDR 3. Exit

Enter your choice: </syntaxhighlight>

Selecting DHT11

Enter:

<syntaxhighlight lang="text"> 1 </syntaxhighlight>

The Python program converts this selection into the command:

<syntaxhighlight lang="text"> DHT </syntaxhighlight>

The command is transmitted to the ESP32 through the TCP connection.

The ESP32 reads the DHT11 and sends the temperature and humidity.

Example:

<syntaxhighlight lang="text"> ESP32: Temperature: 27.0 C | Humidity: 61.0 % </syntaxhighlight>

Selecting LDR

Enter:

<syntaxhighlight lang="text"> 2 </syntaxhighlight>

The Python program sends:

<syntaxhighlight lang="text"> LDR </syntaxhighlight>

The ESP32 reads the analog value from GPIO 34.

Example:

<syntaxhighlight lang="text"> ESP32: LDR Value: 1847 </syntaxhighlight>

The exact LDR value depends on the light falling on the sensor and the voltage-divider circuit.

Exiting

Enter:

<syntaxhighlight lang="text"> 3 </syntaxhighlight>

The Python client closes the TCP connection.

Command Protocol

The project uses two application-level commands.

Command ESP32 action

The commands are transmitted as text followed by a newline.

For example:

<syntaxhighlight lang="text"> DHT\n </syntaxhighlight>

or:

<syntaxhighlight lang="text"> LDR\n </syntaxhighlight>

The ESP32 reads the command using:

<syntaxhighlight lang="cpp"> String command = client.readStringUntil('\n'); </syntaxhighlight>

The command is then trimmed and converted to uppercase.

ESP32 TCP Server Operation

The ESP32 creates a TCP server:

<syntaxhighlight lang="cpp"> WiFiServer server(5000); </syntaxhighlight>

The server is started using:

<syntaxhighlight lang="cpp"> server.begin(); </syntaxhighlight>

The program continuously checks whether a client has connected:

<syntaxhighlight lang="cpp"> WiFiClient client = server.available(); </syntaxhighlight>

When a client connects, the ESP32 sends a welcome message:

<syntaxhighlight lang="cpp"> client.println("ESP32 Sensor Server"); client.println("Available commands: DHT or LDR"); </syntaxhighlight>

The ESP32 then waits for a command.

DHT11 Data Acquisition

When the ESP32 receives the `DHT` command, it reads:

<syntaxhighlight lang="cpp"> float temperature = dht.readTemperature(); float humidity = dht.readHumidity(); </syntaxhighlight>

The values are sent to the TCP client:

<syntaxhighlight lang="cpp"> client.print("Temperature: "); client.print(temperature, 1); client.print(" C");

client.print(" | Humidity: "); client.print(humidity, 1); client.println(" %"); </syntaxhighlight>

If the DHT11 reading fails, the ESP32 sends:

<syntaxhighlight lang="text"> ERROR: DHT11 read failed </syntaxhighlight>

LDR Data Acquisition

When the ESP32 receives the `LDR` command, it reads the analog input:

<syntaxhighlight lang="cpp"> int ldrValue = analogRead(LDR_PIN); </syntaxhighlight>

The result is transmitted to the laptop:

<syntaxhighlight lang="cpp"> client.print("LDR Value: "); client.println(ldrValue); </syntaxhighlight>

Complete Data Flow

The complete operation can be summarized as:

<syntaxhighlight lang="text"> 1. Power ON ESP32

       ↓

2. ESP32 connects to Wi-Fi router

       ↓

3. Router assigns IP address

       ↓

4. ESP32 starts TCP server

       ↓

5. Laptop connects to same Wi-Fi

       ↓

6. Python TCP client starts

       ↓

7. Python client connects to ESP32

       ↓

8. User selects DHT11 or LDR

       ↓

9. Python sends command

       ↓

10. ESP32 receives command

       ↓

11. ESP32 reads selected sensor

       ↓

12. ESP32 sends sensor data

       ↓

13. Laptop displays result </syntaxhighlight>

Example Terminal Session

A typical session may look like:

<syntaxhighlight lang="text"> Connected to ESP32

ESP32 Sensor Server Available commands: DHT or LDR

Select sensor:

1. DHT11 2. LDR 3. Exit

Enter your choice: 1

ESP32: Temperature: 27.0 C | Humidity: 61.0 %

Select sensor:

1. DHT11 2. LDR 3. Exit

Enter your choice: 2

ESP32: LDR Value: 1847

Select sensor:

1. DHT11 2. LDR 3. Exit

Enter your choice: 3

Connection closed </syntaxhighlight>

Troubleshooting

ESP32 does not connect to Wi-Fi

Check:

  • Wi-Fi SSID.
  • Wi-Fi password.
  • Whether the router is operating normally.
  • Whether the ESP32 is within Wi-Fi range.

Laptop cannot connect to ESP32

Check:

  • ESP32 and laptop are connected to the same router.
  • The ESP32 IP address in the Python program matches the address shown in Serial Monitor.
  • TCP port `5000` is being used.
  • The laptop firewall is not blocking the Python connection.

DHT11 data is not received

Check:

  • DHT11 VCC connection.
  • DHT11 GND connection.
  • DHT11 DATA connection to GPIO 4.
  • DHT11 library installation.
  • Sensor wiring and power supply.

LDR value does not change

Check:

  • LDR voltage-divider wiring.
  • Connection of the divider output to GPIO 34.
  • 10 kΩ resistor connection.
  • Whether the LDR is exposed to different light levels.

Project Concepts Demonstrated

This project combines several concepts:

Concept

Project Architecture from an IoT Perspective

The project can be viewed as a basic IoT data-acquisition system:

<syntaxhighlight lang="text">

            SENSOR LAYER
         ┌─────────────────┐
         │ DHT11     LDR   │
         └────────┬────────┘
                  │
                  ▼
            DEVICE LAYER
         ┌─────────────────┐
         │      ESP32      │
         │ Sensor Reading  │
         │   TCP Server    │
         └────────┬────────┘
                  │
                  │ Wi-Fi / TCP
                  ▼
            NETWORK LAYER
         ┌─────────────────┐
         │   Wi-Fi Router  │
         └────────┬────────┘
                  │
                  ▼
         APPLICATION LAYER
         ┌─────────────────┐
         │ Python TCP      │
         │ Client          │
         │                 │
         │ User Interface  │
         └─────────────────┘

</syntaxhighlight>

Learning Outcome

After completing this project, the learner should be able to:

  • Configure an ESP32 for Wi-Fi networking.
  • Identify the IP address assigned to an ESP32.
  • Create a TCP server on an ESP32.
  • Create a TCP client using Python.
  • Establish TCP communication over a local Wi-Fi network.
  • Send commands from a computer to an ESP32.
  • Read DHT11 sensor data.
  • Read analog LDR data.
  • Implement a basic request-response protocol.
  • Understand the relationship between sensors, embedded devices, networks, and client applications.

Conclusion

This project demonstrates a simple networked sensor system in which an ESP32 acquires data from a DHT11 and LDR and provides the data to a laptop through TCP.

The design separates the system into three main components:

  1. Sensor acquisition using ESP32.
  1. Network communication using Wi-Fi and TCP.
  1. User interaction and data display using a Python client.

The command-based design also provides a simple foundation for extending the project with additional sensors or commands.

Source Code

The project consists of two programs:

  • ESP32 TCP sensor server — runs on the ESP32.
  • Python TCP client — runs on the laptop.

The Python client uses Python's `socket` module to establish the TCP connection and provides the DHT11/LDR selection menu.