Introduction to HTTP Communication with ESP32

In this comprehensive guide, you'll learn how to implement HTTP GET and POST requests using the ESP32 microcontroller with Arduino IDE. These communication methods are essential for IoT projects that need to exchange data with web servers, APIs, or cloud services.

ESP32-ESP-IDF-Web-server-control-LED

The Hypertext Transfer Protocol (HTTP) functions as a client-server request-response system. Here's a typical scenario:

Note: This tutorial assumes you have basic knowledge of ESP32 programming and Arduino IDE. If you're new to ESP32, check out our Getting Started with ESP32 guide first.

Understanding HTTP GET vs POST Methods

HTTP GET: Retrieving Data from Resources

HTTP GET is designed specifically for requesting data from a specified resource. It's commonly used when you need to retrieve values from APIs or query parameters from a server. When using GET requests, any data you send becomes part of the URL itself.

GET /update-sensor?temperature=24.5&humidity=45

GET requests can also retrieve simple values or complex JSON objects without sending parameters:

GET /get-sensor-data

HTTP POST: Sending Data to Servers

HTTP POST is fundamentally different—it's used to send data to a server to create or update resources. This method is ideal for publishing sensor readings, submitting form data, or any operation that modifies data on the server.

POST /update-sensor HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded api_key=your_key&sensor=living_room&temperature=24.5

For structured data, POST requests often use JSON format:

POST /update-sensor HTTP/1.1 Host: example.com Content-Type: application/json {"api_key": "your_key", "temperature": 24.5, "humidity": 45}
Feature HTTP GET HTTP POST
Primary Use Retrieve data Send data to server
Data Location URL parameters Request body
Data Visibility Visible in URL Hidden in body
Security Less secure for sensitive data More secure (with HTTPS)
difference_between_get_and_post_method_http

Prerequisites and Setup

Essential Requirements

  • Arduino IDE with ESP32 Support: Latest Arduino IDE with ESP32 board package
  • Arduino_JSON Library: Install via Library Manager
  • WiFi Library: Built-in WiFi.h for ESP32
  • HTTPClient Library: Built-in HTTPClient.h for ESP32

1 Install Required Libraries

Open Arduino IDE and navigate to Sketch > Include Library > Manage Libraries. Search for and install the following libraries:

  • Arduino_JSON by Arduino
arduino-json

Implementing ESP32 HTTP GET Requests

2 Basic HTTP GET Request Structure

Here's a complete example of an ESP32 making HTTP GET requests to a server:

#include <WiFi.h> #include <HTTPClient.h> const char* ssid = "YOUR_WIFI_SSID"; const char* password = "YOUR_WIFI_PASSWORD"; String serverName = "http://your-server.com/update-sensor"; unsigned long lastTime = 0; unsigned long timerDelay = 5000; // 5 seconds void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while(WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("Connected to WiFi"); } void loop() { if ((millis() - lastTime) > timerDelay) { if(WiFi.status() == WL_CONNECTED) { HTTPClient http; String serverPath = serverName + "?temperature=24.37"; http.begin(serverPath.c_str()); int httpResponseCode = http.GET(); if (httpResponseCode > 0) { Serial.print("HTTP Response code: "); Serial.println(httpResponseCode); String payload = http.getString(); Serial.println("Response: " + payload); } else { Serial.print("Error code: "); Serial.println(httpResponseCode); } http.end(); } lastTime = millis(); } }

3 GET Request with Dynamic Data

In real applications, you'll send dynamic sensor data. Here's how to modify the GET request:

// Add sensor reading function float readTemperature() { // Replace with actual sensor reading code return 22.5 + (rand() % 100) / 10.0; } // Modified loop() section void loop() { if ((millis() - lastTime) > timerDelay) { if(WiFi.status() == WL_CONNECTED) { float temperature = readTemperature(); HTTPClient http; // Dynamic query string String serverPath = serverName + "?temperature=" + String(temperature); http.begin(serverPath.c_str()); int httpResponseCode = http.GET(); if (httpResponseCode > 0) { Serial.print("Temperature: "); Serial.print(temperature); Serial.print("°C | HTTP Response: "); Serial.println(httpResponseCode); } http.end(); } lastTime = millis(); } }
HTTP-GET-ESP32-Get-Sensor-Value-Plain-Text-OK

Implementing ESP32 HTTP POST Requests

4 Basic HTTP POST with URL-encoded Data

HTTP POST requests are essential for sending larger amounts of data. Here's a URL-encoded example:

#include <WiFi.h> #include <HTTPClient.h> void loop() { if ((millis() - lastTime) > timerDelay) { if(WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin(serverName.c_str()); // Specify content-type http.addHeader("Content-Type", "application/x-www-form-urlencoded"); // Prepare POST data String httpRequestData = "api_key=your_api_key&sensor=living_room"; httpRequestData += "&temperature=24.5&humidity=45&pressure=1013"; // Send HTTP POST request int httpResponseCode = http.POST(httpRequestData); if (httpResponseCode > 0) { Serial.print("HTTP POST Response code: "); Serial.println(httpResponseCode); String response = http.getString(); Serial.println("Server response: " + response); } http.end(); } lastTime = millis(); } }

5 POST Request with JSON Data

JSON has become the standard format for API communication. Here's how to send JSON data:

#include <ArduinoJson.h> void sendJSONData(float temperature, float humidity, float pressure) { if(WiFi.status() == WL_CONNECTED) { // Create JSON document StaticJsonDocument<200> jsonDocument; jsonDocument["api_key"] = "your_api_key_here"; jsonDocument["sensor_name"] = "living_room_sensor"; jsonDocument["temperature"] = temperature; jsonDocument["humidity"] = humidity; jsonDocument["pressure"] = pressure; // Serialize JSON to string String jsonString; serializeJson(jsonDocument, jsonString); HTTPClient http; http.begin(serverName.c_str()); // Set content-type to JSON http.addHeader("Content-Type", "application/json"); // Send POST request int httpResponseCode = http.POST(jsonString); if (httpResponseCode > 0) { Serial.print("JSON POST Response code: "); Serial.println(httpResponseCode); String response = http.getString(); Serial.println("Response: " + response); } http.end(); } }
Important: When working with JSON data, make sure to allocate sufficient memory for your JSON documents using StaticJsonDocument<size>. The size should be large enough to hold your complete JSON structure.
HTTP-GET-ESP32-Get-Sensor-Value-Plain-Text-OK

Integrating with Popular APIs and Services

The principles you've learned apply to virtually any web service. Here are examples for popular platforms:

ThingSpeak API Example

String thingSpeakURL = "http://api.thingspeak.com/update"; String apiKey = "YOUR_CHANNEL_API_KEY"; String postData = "api_key=" + apiKey + "&field1=" + String(temperature) + "&field2=" + String(humidity);

IFTTT Webhooks Example

String iftttURL = "http://maker.ifttt.com/trigger/event_name/with/key/YOUR_KEY"; String jsonData = "{\"value1\":\"" + String(temperature) + "\",\"value2\":\"" + String(humidity) + "\",\"value3\":\"" + String(pressure) + "\"}";

Troubleshooting Common Issues

Connection Problems

Wi-Fi Connection Fails: Double-check credentials and ensure ESP32 is within router range.

Server Unreachable: Verify server address, port, and firewall settings.

SSL Certificate Issues: For HTTPS, you may need to handle certificate verification.

Request/Response Problems

Timeout Errors: Increase timeout using http.setTimeout().

Incorrect Data Format: Ensure data matches server expectations.

Memory Issues: Large JSON documents can exhaust memory. Increase buffer size if needed.

HTTP-GET-ESP32-Get-Sensor-Value-Plain-Text-OK

Complete IoT Sensor Project Example

Here's a complete project that reads from sensors and sends data to a server:

#include <WiFi.h> #include <HTTPClient.h> #include <ArduinoJson.h> #include "DHT.h" #define DHTPIN 4 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); const char* ssid = "YOUR_WIFI"; const char* password = "YOUR_PASSWORD"; String serverURL = "http://your-server.com/api/sensor-data"; unsigned long lastReadingTime = 0; const long readingInterval = 30000; // 30 seconds void setup() { Serial.begin(115200); dht.begin(); connectToWiFi(); } void loop() { if (millis() - lastReadingTime >= readingInterval) { float temperature = dht.readTemperature(); float humidity = dht.readHumidity(); if (!isnan(temperature) && !isnan(humidity)) { sendSensorData(temperature, humidity); } else { Serial.println("Failed to read from DHT sensor"); } lastReadingTime = millis(); } } void sendSensorData(float temp, float humidity) { if (WiFi.status() != WL_CONNECTED) { connectToWiFi(); return; } StaticJsonDocument<256> doc; doc["device_id"] = "esp32_01"; doc["temperature"] = temp; doc["humidity"] = humidity; doc["timestamp"] = millis(); String jsonPayload; serializeJson(doc, jsonPayload); HTTPClient http; http.begin(serverURL.c_str()); http.addHeader("Content-Type", "application/json"); int httpCode = http.POST(jsonPayload); if (httpCode > 0) { Serial.printf("Data sent. Response: %d\n", httpCode); } else { Serial.printf("POST failed, error: %d\n", httpCode); } http.end(); }
Pro Tip: For battery-powered projects, implement deep sleep between readings and minimize transmission frequency to conserve power. Always use HTTPS for sensitive data and implement proper authentication for your endpoints.

Congratulations! You've mastered HTTP GET and POST requests with the ESP32. These skills open up endless possibilities for IoT projects that interact with web services, APIs, and cloud platforms.