Hello,
I’m new to using Render. I am hosting a python, FastAPI server which should accept HTTP POST requests.
My goal is to be able to send POST from ESP32. This is my code:
#include <ArduinoJson.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include "DFRobot_BloodOxygen_S.h"
// Wi-Fi settings
const char *ssid = "...";
const char *password = "...";
// API server data
const char *serverAddress = "https://scir-api-server.onrender.com";
const int serverPort = 443;
// Initialize WiFi client
//WiFiClient client;
WiFiClientSecure client;
// I2C communication settings
#define I2C_ADDRESS 0x57
DFRobot_BloodOxygen_S_I2C MAX30102(&Wire ,I2C_ADDRESS);
// Define pin for LED signaling
#define LED_PIN 2
void setup() {
Serial.begin(115200); // Serial port for monitoring
delay(100);
//client.setInsecure();
// Connect to Wi-Fi
WiFi.begin(ssid, password);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
Serial.println(".");
}
Serial.println("Connected to Wi-Fi");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Initialize the sensor
while (false == MAX30102.begin()) {
Serial.println("Sensor initialization failed!");
delay(1000);
}
Serial.println("Sensor initialization successful!");
Serial.println("Start measuring...");
MAX30102.sensorStartCollect();
}
void loop() {
// Check Wi-Fi connection
if (WiFi.status() == WL_CONNECTED) {
// Take measurements
MAX30102.getHeartbeatSPO2();
// Check if SPO2 and HR values are within the appropriate ranges
if (MAX30102._sHeartbeatSPO2.SPO2 >= 40 && MAX30102._sHeartbeatSPO2.SPO2 <= 100 && // Extended range for adults (realistically, values are always 94-100)
MAX30102._sHeartbeatSPO2.Heartbeat >= 10 && MAX30102._sHeartbeatSPO2.Heartbeat <= 200) { // Extended range for adults (realistically, values are always 70-130)
// Prepare the data to send in JSON format - create the document
StaticJsonDocument<200> jsonDocument;
// Add sensor ID and measurement results to the document
// Statistically assigned sensor ID for the project
jsonDocument["sensor_id"] = "ABC123";
jsonDocument["HR"] = MAX30102._sHeartbeatSPO2.Heartbeat;
jsonDocument["SPO2"] = MAX30102._sHeartbeatSPO2.SPO2;
// Additionally, get the temperature measured by the sensor - not very useful in raw form
// because it measures the body surface temperature, not the core temperature
jsonDocument["Temperature"] = MAX30102.getTemperature_C();
String jsonString;
serializeJson(jsonDocument, jsonString);
Serial.println("JSON to send:");
Serial.println(jsonString); // Added for debugging
// Create HTTP client
HTTPClient http;
// Create the message
http.begin(client, serverAddress, serverPort, "/endpoint_api");
http.addHeader("Content-Type", "application/json");
// Send the created message - POST request with data in JSON format
int httpCode = http.POST(jsonString);
// Check server response
if (httpCode > 0) {
// Print the server response code to the terminal
Serial.printf("[HTTP] POST... code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
Serial.println(payload);
}
} else {
// Print the server response code to the terminal (error)
Serial.printf("[HTTP] POST... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
} else {
// Print to the terminal that the data from the sensor is incorrect - not sending it
Serial.println("Incorrect data. Measurement was not sent.");
}
}
// Sensor needs four seconds for one measurement
delay(4000);
}
However all I get when sending a POST is 400 Bad Request. In logs of the render’s server I don’t see any form of trying to get to server by ESP32.
When I do a CURL, for example:
curl -X POST "https://scir-api-server.onrender.com/endpoint_api" -H "Content-Type: application/json" -d "{ \"id_czujnika\": \"ABC123\", \"HR\": 75, \"SPO2\": 98, \"Temperatura\": 36.5 }"
I can see that it works in logs of the web service.
For ESP32 i think that payload is OK so I started wondering if it’s because of some certificates and HTTPS problems… Any suggestions?
Thanks
Natalia