Posting Data to a Server from the ESP32 in Arduino IDE

Mailboxes

A Sketch for the basic outline for any ESP32 project using the Arduino IDE that needs to send text or a file to a server on the internet

Like many things with this hobby, it’s easy when you know how!

#include "esp_http_client.h"
#include <WiFi.h>
#include "Arduino.h"

const char* ssid = "NSA";
const char* password = "Orange";

const char *post_url = "http://your-webserver.net/yourscript.php"; // Location to send POSTed data
const char *post_data = "field1=value1&field2=value2";  // Post data can be name value, or just value

bool internet_connected = false;

void setup()
{
  Serial.begin(115200);

  if (init_wifi()) { // Connected to WiFi
    internet_connected = true;
    Serial.println("Internet connected");
  }
}

bool init_wifi()
{
  int connAttempts = 0;
  Serial.println("\r\nConnecting to: " + String(ssid));
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED ) {
    delay(500);
    Serial.print(".");
    if (connAttempts > 10) return false;
    connAttempts++;
  }
  return true;
}


esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
  switch (evt->event_id) {
    case HTTP_EVENT_ERROR:
      Serial.println("HTTP_EVENT_ERROR");
      break;
    case HTTP_EVENT_ON_CONNECTED:
      Serial.println("HTTP_EVENT_ON_CONNECTED");
      break;
    case HTTP_EVENT_HEADER_SENT:
      Serial.println("HTTP_EVENT_HEADER_SENT");
      break;
    case HTTP_EVENT_ON_HEADER:
      Serial.println();
      Serial.printf("HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
      break;
    case HTTP_EVENT_ON_DATA:
      Serial.println();
      Serial.printf("HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
      if (!esp_http_client_is_chunked_response(evt->client)) {
        // Write out data
        // printf("%.*s", evt->data_len, (char*)evt->data);
      }
      break;
    case HTTP_EVENT_ON_FINISH:
      Serial.println("");
      Serial.println("HTTP_EVENT_ON_FINISH");
      break;
    case HTTP_EVENT_DISCONNECTED:
      Serial.println("HTTP_EVENT_DISCONNECTED");
      break;
  }
  return ESP_OK;
}

static esp_err_t post_something()
{
  esp_err_t res = ESP_OK;

  esp_http_client_handle_t http_client;
  
  esp_http_client_config_t config_client = {0};
  config_client.url = post_url;
  config_client.event_handler = _http_event_handler;
  config_client.method = HTTP_METHOD_POST;

  http_client = esp_http_client_init(&config_client);
  
  esp_http_client_set_post_field(http_client, post_data, strlen(post_data));

  // esp_http_client_set_header(http_client, "Content-Type", "image/jpg"); // sending a jpg file

  esp_err_t err = esp_http_client_perform(http_client);
  if (err == ESP_OK) {
    Serial.print("esp_http_client_get_status_code: ");
    Serial.println(esp_http_client_get_status_code(http_client));
  }

  esp_http_client_cleanup(http_client);
}

void loop()
{
  if (condition met) { 
    post_something();
  }
}

On the server side assuming you are using PHP you use this code to name and save files:

$received = file_get_contents('php://input');
$fileToWrite = "upload - ".time().".jpg";
file_put_contents($fileToWrite, $received);

This code below will send a received file to your email address. You need to update the email address in lines 6 and 27. If you are not sending a JPG you need to change line 20 to reflect the content type.

$received = file_get_contents('php://input');
$timeNow = date("F j, Y, g:i a");
$subject = "Email Subject - ".time();

$bound_text = "----*%$!$%*";
$bound = "--".$bound_text."\r\n";
$bound_last = "--".$bound_text."--\r\n";

$headers = "From: [email protected]\r\n";
$headers .= "MIME-Version: 1.0\r\n" .
"Content-Type: multipart/mixed; boundary=\"$bound_text\""."\r\n" ;
$message =
'Content-Type: text/html; charset=UTF-8'."\r\n".
'Content-Transfer-Encoding: 7bit'."\r\n\r\n".
'
&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;'."\n\n".
$bound;

$message .= "Content-Type: image/jpeg; name=\"filename.jpg\"\r\n"
."Content-Transfer-Encoding: base64\r\n"
."Content-ID: &lt;filename.jpg&gt;\r\n"
."\r\n"
.chunk_split(base64_encode($received))
.$bound_last;

echo mail('[email protected]', $subject, $message, $headers);

Similar code is used in the time-lapse project here: https://robotzero.one/time-lapse-esp32-cameras/

References

Digital Ocean Droplet: https://m.do.co/c/801f9f581abd  Cheapest way to get a PHP server. Supposedly this link gives a $100 in credit over 60 days
Email code: https://stackoverflow.com/questions/30295587/sending-email-with-inline-image
IDF version: https://github.com/espressif/esp-idf/blob/master/examples/protocols/esp_http_client/main/esp_http_client_example.c
Mailbox image: Mathyas Kurmann on Unsplash

19 Replies to “Posting Data to a Server from the ESP32 in Arduino IDE”

  1. Peter Grüner says:

    Hello,

    how can i send a Picture with post_data ?
    I know i can get the Buffer by camera_fb_t *pic = esp_camera_fb_get() and pic->buf, pic->len.

    greets
    Peter

    1. WordBot says:

      Hi, check the Upload Capture to a Server part of this tutorial – https://robotzero.one/time-lapse-esp32-cameras/ for how to send a picture.

    2. B Flat says:

      Hello,
      Thank you for posting your hard work. I have a question regarding the file uploads.
      How do I attach a file (.wav or .jpg or .mp4) to this script for upload to a server?

      Uploading Text works fine:
      const char *post_data = “field1=value1&field2=value2”; // Post data can be name value, or just value
      esp_http_client_set_post_field(http_client, post_data, strlen(post_data)); // Uploads text to php script on server and creates a txt file without problems.

      Uploading .wav/.jpg File:
      I cannot see how you attach a file stored in the esp32 (LittleFS or SPIFFS.) into your script,
      esp_http_client_set_header(http_client, “Content-Type”, “audio/x-wav”); // sending a wav file
      esp_http_client_set_header(http_client, “Content-Type”, “image/jpg”); // sending a jpg file

      Your line of code details the headers. How do you attach the jpg/wav file content?
      #include “LITTLEFS.h” // Little File system replacing SPIFFS.
      filetoupload = LITTLEFS.open(SerenadeForStringsOpus48.wav, FILE_READ);

      Please share your thoughts on this.
      Flat

      1. WordBot says:

        Hi,
        Does this help – https://github.com/robotzero1/esp32cam-timelapse/blob/master/timelapse-server.ino ?
        IF the file isn’t small you might have to chunk upload. I don’t really remember well how I did this but this might help – https://github.com/robotzero1/esp32cam-telegram

  2. Hans Middelbeek says:

    HI!

    Thanks for this, I am completely new in this area, so a lot of questions will come up….
    My first problem now is that when I compile I get an error in the following line

    esp_http_client_set_post_field(client, post_data, strlen(post_data));

    And the error is ‘client’ was not declared in this scope

    What can be the problem??

    1. WordBot says:

      Argg… was a typo.. ‘client’ should have been ‘http_client’

  3. Nicole says:

    Hello,
    I am having this problem since I want to upload taken photos to Custom Vision (Microsoft Azure service). Can anyone help me how to do this? 🙂

    Taking picture…
    E (41498) esp-tls: couldn’t get hostname for :www.customvision.ai:
    E (41498) esp-tls: Failed to open new connection
    E (41498) TRANS_SSL: Failed to open a new connection
    E (41502) HTTP_CLIENT: Connection failed, sock < 0
    HTTP_EVENT_DISCONNECTED

  4. R.Tugrul says:

    Could you please demostrate a sample that contains image file upload from sd card.
    Thanks

    1. WordBot says:

      If you want to upload a specific image you have to have some sort of file manager on the ESP32. I have a tutorial in the works for this but it will be a few weeks probably.

  5. JC says:

    how equivalent is this with AsyncTCP, that works on arduino framework ?

    1. WordBot says:

      In what way? This tutorial uses the Espressif IDF in the Arduino IDE but it will only work on ESP32 based devices.

      1. jc says:

        I am indeed speaking only about ESP32. AsyncTcp lib can be sometime quite unstable, and offers … async tcp connection. As IDF allows the same thing ‘out of the box’ I will get rid of AsyncTcp to use your example and the pure idf solution…

  6. James McCallum says:

    Hi
    I get the following response in the serial monitor
    Taking picture…
    E (2341653) HTTP CLIENT: Connection failed, soc < 0
    HTTP_EVENT DISCONNECTED
    then it just repeats.

    I'm running the timelapse-server program you developed. Any pointers or help would be great. Thanks Jim

    1. WordBot says:

      Hi, I seems like the ESP32 can’t connect to your server.

  7. nur ahmad dwi wibowo says:

    hello mr zero, nice to meet u
    i’ve tried to post image to my php web, but nothing happened.

    preview image not showing the image, neither the view image when i right click on the blank image

    1. WordBot says:

      Do you have access to an error log on your server?

  8. nur ahmad dwi wibowo says:

    Hi mr Bot
    no issue on log server. i use 000webhost for hosting the web.

    but when i try using the localhost, its work. what happened? thanks before sir 🙂

  9. kiske says:

    i am trying to send data by making a post request to a https website from esp32 can someone explain me how it can be done?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

scroll to top