Introduction
In this tutorial we will check how to setup a simple Flask server on the Raspberry Pi and send HTTP POST requests to it from the ESP32. Then, we will access the body of the request on the Raspberry Pi.
The Python version used on this tutorial was 3.5.3 and it was tested on a Raspberry Pi 3 model B+, running version 4.9 of Raspbian, installed using NOOBS. Additionally, a DFRobot’s ESP32 module integrated in a ESP32 development board was used.
The Python code
The Python code for this tutorial is very similar to what we have been covering before. As usual, we start by importing the Flask class from the flask module, to setup the whole HTTP server.
Additionally, we will need to import the request object from the flask module, so we can later access the body of the request sent by the client.
After the imports, we need to create an instance of the Flask class.
from flask import Flask, request app = Flask(__name__)
Now that we have our app object, we can proceed with the configuration of the routes of the server. We will have a single route called “/post”, since we are going to test it against POST requests. Naturally, you can call it what you want, as long as you use the endpoint you defined in the client code.
Additionally, we will also limit the actual HTTP methods that this route accepts. You can check a more detailed guide on how to do it on this previous post.
This will ensure that the route handling function will only be executed when the client makes a POST request.
@app.route('/post', methods = ["POST"]) def post():
The route handling function will be very simple. We will just access the body of the request to print it and then return an empty answer to the client. Note that it is common that the answer of a POST request does not contain any content, since a success HTTP response code is, in many cases, enough for the client to know the operation was executed.
So, to get the actual request body, we simple need to access the data member of the request object. We will simply print the result so we can later confirm it matches the content sent by the client.
After that, as already mentioned, we return the response to the client, with an empty body.
print(request.data) return ''
To finalize and to start listening to incoming requests, we need to call the run method on our app object. As first input we pass the ‘0.0.0.0’ IP, to indicate the server should be listening in all the available IPs of the Raspberry Pi, and as second input we pass the port where the server will be listening.
The full Python code for the Raspberry Pi is shown below.
from flask import Flask, request app = Flask(__name__) @app.route('/post', methods = ["POST"]) def post(): print(request.data) return '' app.run(host='0.0.0.0', port= 8090)
The Arduino code
We start with the includes of the libraries we will need to both connect the ESP32 to a wireless network and also to make the HTTP POST requests. These are the Wifi.h and the HTTPClient.h libraries, respectively.
We will also need to declare the credentials to connect to the WiFi network, more precisely the network name and the password.
Then, in the Arduino setup function, we take care of connecting the ESP32 to the WiFi network.
#include <WiFi.h> #include <HTTPClient.h> const char* ssid = "yourNetworkName"; const char* password = "yourNetworkPassword"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi.."); } Serial.println("Connected to the WiFi network"); }
The HTTP POST requests will be performed on the Arduino main loop function. To be able to perform the requests, we will need an object of class HTTPClient.
HTTPClient http;
http.begin("http://192.168.1.92:8090/post");
http.addHeader("Content-Type", "text/plain");
int httpResponseCode = http.POST("POSTING from ESP32");
Serial.println(httpResponseCode);
http.end(); //Free resources
#include <WiFi.h> #include <HTTPClient.h> const char* ssid = "yourNetworkName"; const char* password = "yourNetworkPassword"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi.."); } Serial.println("Connected to the WiFi network"); } void loop() { if(WiFi.status()== WL_CONNECTED){ //Check WiFi connection status HTTPClient http; http.begin("http://192.168.1.92:8090/post"); http.addHeader("Content-Type", "text/plain"); int httpResponseCode = http.POST("POSTING from ESP32"); //Send the actual POST request if(httpResponseCode>0){ Serial.println(httpResponseCode); }else{ Serial.println("Error on sending POST"); } http.end(); //Free resources }else{ Serial.println("Error in WiFi connection"); } delay(10000); //Send a request every 10 seconds }
Testing the code
Figure 1 – HTTP status code returned by the server to the ESP32.
If you go back to the Python prompt where the Flask server is running, you should get a result similar to figure 2, where it shows the messages sent by the ESP32 getting printed.
Figure 2 – ESP32 messages printed on the Flask server, running on the Raspberry Pi.