先日の調査で、M5StickCとSDカードリーダーをつなぎ、センサで採取したデータを、SDカードに書き込むことができました(記事は こちら)。
今回は、SDカードに保存されているファイルを、Webサーバーに送信してみたいと思います。
こちら のページに、画像データをサーバーに送信する方法が書かれていたので、これを参考にさせていただきました。
まずは、Webサーバーに、以下のPHPプログラム「writefile.php」を設置し、同じ場所に「data_files」というフォルダをつくっておきます。
データを受信したら、「data_files」フォルダの下に、「<UNIX Time>.txt」という名前でファイル保存するプログラムです。
<?php $data = file_get_contents('php://input'); $filename = "data_files/" .time() .".txt"; file_put_contents($filename, $data); ?>
M5StickCに書き込むスケッチは以下のとおりです。
#include <M5StickC.h> #include <WiFi.h> #include "SD.h" #include "esp_http_client.h" SPIClass SPI2; File file; const char* ssid = "XXXXXXXX"; const char* password = "XXXXXXXX"; char file_name[20] = "/test1.txt"; void setup() { M5.begin(); M5.Lcd.setRotation(3); M5.Lcd.setCursor(0, 0, 2); M5.Lcd.printf("Connecting to %s ", ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); M5.Lcd.print("."); } M5.Lcd.println(" CONNECTED"); SPI2.begin(0, 36, 26, -1); // SPI初期化 if(!SD.begin(-1, SPI2)) { // SDカード初期化 M5.Lcd.println("Card Mount Failed"); return; } } void loop() { M5.update(); if(M5.BtnA.wasPressed()) { file = SD.open(file_name, FILE_READ); M5.Lcd.fillScreen(BLACK); M5.Lcd.setCursor(0, 0, 2); M5.Lcd.print("FILE SIZE : "); M5.Lcd.println(file.size()); char tmp_var[file.size()] = ""; while(file.available()) { sprintf(tmp_var, "%s%c", tmp_var, char(file.read())); } file.close(); esp_http_client_config_t config = {0}; config.url = "http://XXXXXXXX/writefile.php"; config.method = HTTP_METHOD_POST; esp_http_client_handle_t client = esp_http_client_init(&config); esp_http_client_set_post_field(client, (const char *)tmp_var, strlen(tmp_var)); esp_http_client_perform(client); M5.Lcd.fillScreen(BLACK); M5.Lcd.setCursor(0, 0, 2); M5.Lcd.println("FINISH"); esp_http_client_cleanup(client); } }
最初にWi-Fiネットワークに接続し、SDカードの初期化を行います。
ボタンを押すと、SDカード内の「test1.txt」ファイルを開き、その内容を指定したURLに送信します。
データ送信には「esp_http_client.h」というライブラリを使っています。
ほとんど理解できておらず、上記のサイトを参考に、見よう見まねでつくっているのですが、
- esp_http_client_init()
- → esp_http_client_set_post_field()
- → esp_http_client_perform()
- → esp_http_client_cleanup()
という手順でデータを送信することができるようです。
このスケッチを試してみたところ、小さいファイルは問題なく送信できたのですが、ファイルサイズが大きくなると送信できませんでした(5000バイト程度が上限)。
そのため、スケッチを以下のように変更しました。
#include <M5StickC.h> #include <WiFi.h> #include "SD.h" #include "esp_http_client.h" SPIClass SPI2; File file; const char* ssid = "XXXXXXXX"; const char* password = "XXXXXXXX"; char file_name[20] = "/test3.txt"; int var_size = 2000; void setup() { M5.begin(); M5.Lcd.setRotation(3); M5.Lcd.setCursor(0, 0, 2); M5.Lcd.printf("Connecting to %s ", ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); M5.Lcd.print("."); } M5.Lcd.println(" CONNECTED"); SPI2.begin(0, 36, 26, -1); // SPI初期化 if(!SD.begin(-1, SPI2)) { // SDカード初期化 M5.Lcd.println("Card Mount Failed"); return; } } void loop() { M5.update(); if(M5.BtnA.wasPressed()) { file = SD.open(file_name, FILE_READ); M5.Lcd.fillScreen(BLACK); M5.Lcd.setCursor(0, 0, 2); M5.Lcd.print("FILE SIZE : "); M5.Lcd.println(file.size()); char tmp_var[var_size+1] = ""; esp_http_client_config_t config = {0}; config.url = "http://XXXXXXXX/writefile.php"; config.method = HTTP_METHOD_POST; esp_http_client_handle_t client = esp_http_client_init(&config); esp_http_client_open(client, file.size()); while(file.available()) { sprintf(tmp_var, "%s%c", tmp_var, char(file.read())); if(strlen(tmp_var)>=var_size) { esp_http_client_write(client, (const char *)tmp_var, strlen(tmp_var)); sprintf(tmp_var, ""); M5.Lcd.print("*"); } } esp_http_client_write(client, (const char *)tmp_var, strlen(tmp_var)); M5.Lcd.fillScreen(BLACK); M5.Lcd.setCursor(0, 0, 2); M5.Lcd.println("FINISH"); esp_http_client_close(client); esp_http_client_cleanup(client); file.close(); } }
ボタンを押すと、SDカード内の「test3.txt」ファイルを開き、その内容を送信します。
このスケッチでは、
- esp_http_client_init()
- → esp_http_client_open()
- → esp_http_client_write()
- → esp_http_client_close()
- → esp_http_client_cleanup()
という手順でデータを送信します。「esp_http_client_write()」を複数回繰り返すことで、ファイルサイズの大きなファイルも送信できます。
このスケッチを試してみたところ、250Kバイト程度のファイルを送信することができました。
なお、私がM5Stack、M5StickCの使い方を習得するのにあたっては、以下の書籍を参考にさせていただきました。
ごく基本的なところから、かなり複雑なスケッチや、ネットワーク接続など、比較的高度なものまで、つまづかずに読み進めていけるような構成になっており、大変わかりやすい本です。
このサイトで書いている、M5Stackシリーズ(M5Stack、M5StickCなど)に関するブログ記事を、「さとやまノート」という別のブログページに、あらためて整理してまとめました。
他のM5Stackシリーズの記事にも興味のある方は「さとやまノート」をご覧ください。