Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

ESP32(Arduino)で画像をPOST するサンプル

More than 1 year has passed since last update.

ESP32 で SDカード内のファイルをPOSTするサンプルコード

Github

esp32-post-image

構成

Adafruit ESP32 Feather

マイクロSDカードスロットDIP化キット

SPI接続

Adafruit ESP32 Feather と マイクロSDカードスロットDIP化キット を SPI接続する

-- ESP32 SDカード
SPI_SCL 5 2
SPI_MOSI 18 3
3V3 -- 4
SPI_CS_SD 16 5
GND -- 6
SPI_MISO 19 7

開発環境

PlatformIO IDE for VSCode

環境でビルドとESP32へ書き込みができるのでリンクを参考にインストールする。

コード

multipart/form-data で サーバにPOSTするコード

ImagePost.cpp
bool ImagePost::postImage(File *file, FUNC_POST_IMAGE_CALLBACK callback){
...
    //boundary 作成
    randomSeed(micros() + analogRead(A0));
    for (int i = 0; i < 3; i++) {
      ltoa(random(0x7FFFFFF), boundary + strlen(boundary), 16);
    }
    strcpy(contentType, "multipart/form-data; boundary=");
    strcat(contentType, boundary);

    String payloadHeaderFormat = ""
                     "--%s\r\n"
                     "Content-Disposition: form-data; name=\"image\"; filename=\"%s\"\r\n"
                     "Content-Type: application/octet-stream\r\n"
                     "Content-Transfer-Encoding: binary\r\n"
                     "\r\n"
                     ;
    //body 部分上部 boundary と下部 boundary データを作成
    char payloadHeader[200] = {0};
    sprintf(payloadHeader,
                payloadHeaderFormat.c_str(),
                boundary,
                file->name());

    char payloadFooter[50] = {0};
    sprintf(payloadFooter, "\r\n--%s--\r\n", boundary);

...

    if (client.connect(API_HOST,API_PORT)){
        client.printf("POST %s HTTP/1.1\n",API_PLANTER_IMAGE);
        client.print(F("Host: "));client.println(API_HOST);
        client.println(F("Accept: application/json"));
        client.println(F("Connection: close"));
        client.print(F("Content-Type: "));client.println(contentType);
        client.print(F("Content-Length: "));client.println(contentLength);        
        client.println();
        client.print(bodyHeader.c_str());
        client.flush();

        size_t w = 0;
        while (file->available()) {
            w += client.write(file->read());            
            if((w % API_POST_IMAGE_FLASH_SIZE) == 0){
                client.flush();
            }
        }
        client.flush();
        client.print(bodyFooter.c_str());
        client.flush();

        //レスポンス タイムアウト
        int timeout = millis() + (API_POST_IMAGE_RESPONSE_TIMEOUT_SEC * 1000);
        bool isTimeout = false;
        while (client.available() == 0) {
            if (timeout - millis() < 0) {
                Serial.println(">>> Client Timeout !");
                isTimeout = true;
                break;
            }
        }
        if(isTimeout == false){         
            String line = "";
            while(client.available()){
                line = client.readStringUntil('\r');
                response += line;
            }
        }
        client.stop();        
    }
    //コールバック
    callback(response.c_str());
    return true;
}

画像受け取りサーバ

server ディレクトリで node app.js を実行する
ESP32から POST されると /uploads/ ディレクトリにファイルが作成される

$node app.js 
Example app listening at http://192.168.100.140:8080
t_furu
1980年鹿児島県霧島市生まれ 東京の中小IT企業にて物流システム開発に従事。その他通信関連企業経験を経てフリーランスとなり、ソフトウェアだけでなくハードウェア系込みのサービス開発に取り組み、現在に至る。 鹿児島初の モノづくりスペース TUKUDDO を運営中してましたが、移転閉店。 現在は 秋葉原にて ベンチャー企業に所属して Webサービスを開発中。
http://tf-web.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away