IPDL - 12: TCP/UDP Server for Sensor Data
ESP32 TCP Sensor Data Server
Objective
To develop a basic IoT system in which an ESP32 reads sensor data and sends the requested data to a laptop over a TCP connection using a Wi-Fi router.
The system uses a DHT11 and an LDR as example sensors. The same basic TCP server can be extended to integrate any other sensor supported by the ESP32.
Introduction to TCP
TCP (Transmission Control Protocol) is a communication protocol used to exchange data reliably between two devices over a network.
TCP works using a client-server model:
- The server waits for a connection.
- The client connects to the server.
- The client sends a request.
- The server processes the request and sends a response.
In this project:
- ESP32 = TCP Server
- Laptop = TCP Client
- Wi-Fi Router = Network
- DHT11 and LDR = Sensors
The ESP32 and laptop are connected to the same Wi-Fi router. The ESP32 gets an IP address from the router and starts a TCP server on a specific port.
How Will It Work?
The ESP32 first connects to the existing Wi-Fi router. Once connected, it starts a TCP server. The laptop is also connected to the same router. A Python program running on the laptop connects to the ESP32 using its IP address and TCP port.
The Python program asks the user which sensor data is required. If the user selects 1 (DHT11), the laptop sends: DHT The ESP32 receives the command, reads the DHT11 and sends the temperature and humidity back to the laptop.
If the user selects 2 (LDR), the laptop sends: LDR The ESP32 reads the LDR through its analog input and sends the LDR value back. Therefore, the basic communication is:
User → Laptop → TCP → ESP32 → Sensor → ESP32 → TCP → Laptop
The important point is that the sensor is not directly connected to the laptop. The ESP32 acts as the sensor interface and TCP server. This architecture can be extended by connecting additional sensors to the ESP32 and defining additional commands for them.
ESP32 as a TCP Server
The ESP32 creates a TCP server on port 5000:
WiFiServer server(5000);
Explanation
WiFiServer creates a TCP server object.
The number 5000 is the TCP port on which the ESP32 waits for incoming connections.
The ESP32 first connects to the Wi-Fi router:
WiFi.begin(ssid, password);
After connecting, its IP address can be obtained using:
WiFi.localIP()
This IP address is required by the laptop to connect to the ESP32.
The TCP server is then started using:
server.begin();
Checking for a TCP Client
The ESP32 continuously checks whether a laptop has connected:
<syntaxhighlight lang="cpp"> WiFiClient client = server.available(); </syntaxhighlight>
If a client is connected, the ESP32 can receive commands and send sensor data through the client object.
Receiving the Sensor Command
The ESP32 waits for a command from the laptop:
<syntaxhighlight lang="cpp"> String command = client.readStringUntil('\n');
command.trim(); command.toUpperCase(); </syntaxhighlight>
Explanation
The laptop sends a text command such as:
<syntaxhighlight lang="text"> DHT </syntaxhighlight>
or:
<syntaxhighlight lang="text"> LDR </syntaxhighlight>
readStringUntil('\n') reads the command until the newline character.
trim() removes unnecessary spaces or line-ending characters.
toUpperCase() makes the command easier to process regardless of whether the user enters uppercase or lowercase text.
Reading DHT11 Data
When the received command is DHT, the ESP32 reads the DHT11:
<syntaxhighlight lang="cpp"> float temperature = dht.readTemperature(); float humidity = dht.readHumidity(); </syntaxhighlight>
The values are then sent to the laptop:
<syntaxhighlight lang="cpp"> client.print("Temperature: "); client.print(temperature, 1); client.print(" C");
client.print(" | Humidity: "); client.print(humidity, 1); client.print(" %"); </syntaxhighlight>
The laptop may receive:
<syntaxhighlight lang="text"> Temperature: 27.0 C | Humidity: 61.0 % </syntaxhighlight>
Reading LDR Data
When the received command is LDR, the ESP32 reads the analog value:
<syntaxhighlight lang="cpp"> int ldrValue = analogRead(LDR_PIN); </syntaxhighlight>
The value is then sent to the laptop:
<syntaxhighlight lang="cpp"> client.print("LDR Value: "); client.println(ldrValue); </syntaxhighlight>
The laptop may receive:
<syntaxhighlight lang="text"> LDR Value: 1847 </syntaxhighlight>
The actual value changes depending on the amount of light falling on the LDR.
Python TCP Client
The laptop runs a Python program that creates a TCP socket:
<syntaxhighlight lang="python"> import socket
ESP32_IP = "192.168.1.9" PORT = 5000
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) </syntaxhighlight>
Explanation
The socket module provides the networking functionality.
ESP32_IP contains the IP address displayed by the ESP32.
PORT must match the TCP server port running on the ESP32.
The following statement establishes the connection:
<syntaxhighlight lang="python"> client.connect((ESP32_IP, PORT)) </syntaxhighlight>
The laptop is now connected to the ESP32 TCP server.
Selecting the Sensor
The Python program provides a simple menu:
<syntaxhighlight lang="python"> print("Select sensor:") print("1. DHT11") print("2. LDR") print("3. Exit")
choice = input("Enter your choice: ") </syntaxhighlight>
The selected option is converted into a TCP command:
<syntaxhighlight lang="python"> if choice == "1":
command = "DHT"
elif choice == "2":
command = "LDR"
elif choice == "3":
break
</syntaxhighlight>
The command is sent to the ESP32:
<syntaxhighlight lang="python"> client.send((command + "\n").encode()) </syntaxhighlight>
Receiving the Sensor Data
After sending the command, the Python client waits for the ESP32 response:
<syntaxhighlight lang="python"> response = client.recv(1024).decode()
print("ESP32:", response.strip()) </syntaxhighlight>
For example:
<syntaxhighlight lang="text"> Enter your choice: 1
ESP32: Temperature: 27.0 C | Humidity: 61.0 % </syntaxhighlight>
or:
<syntaxhighlight lang="text"> Enter your choice: 2
ESP32: LDR Value: 1847 </syntaxhighlight>
Extending the Project
The DHT11 and LDR are only example sensors.
The same architecture can be used to integrate other sensors such as:
- Ultrasonic sensor
- Any other sensor supported by the ESP32
For a new sensor, the basic approach is:
- Connect the sensor to the ESP32.
- Write the sensor-reading code.
- Define a command for that sensor.
- Check the command received from the TCP client.
- Read the sensor.
- Send the sensor data back through TCP.
Thus, the TCP communication framework remains the same, while the sensor-reading section can be modified or expanded as required.
Conclusion
This project demonstrates how an ESP32 can act as a TCP-based sensor server and provide sensor data to a computer over a Wi-Fi network.
The project combines:
ESP32 + Sensors + Wi-Fi + TCP + Python
The command-based design makes the system simple to understand and easy to expand with additional sensors.