センサーの値をFTPサーバーにCSVで送る(ESP-WROOM02)
こんにちは!
今回は、ESP-WROOM-02で取得したセンサーの値を、FTPサーバーを使ってサーバーに送ってみたいと思います!
サーバーなども絡んできて難しいですが、これができるようになると、例えば、センサーの値を定期的にサーバーに送りったり、値を蓄積してデータをとることだってできちゃいます!
更に応用すればスマートフォンなどから遠隔で、好きなタイミングでセンサーの値を取得できちゃったりも可能です^^
まさにIoTですね^^
大まかな流れ↓
1.回路準備
2.開発環境の準備
3.サーバーの準備(Xサーバーで説明を進めさせていただきます)
4プログラミング
5.動作確認・まとめ
です!
では、早速解説に入りたいと思いますがまず、いろいろ準備するものがあります(´;ω;`)
①「回路の準備」
・低損失三端子レギュレーター 3.3V1A TA48033S
・電解コンデンサ 47μF35V(秋月電子で購入すると、3端子レギュレータに付属されています。)
・セラミックコンデンサ 0.1μF(秋月電子で購入すると、3端子レギュレータに付属されています。)
・LED(起動などを確認するためのメッセージ用に使う。なので任意)
・タクトスイッチ(2個)(任意ですがあると便利です)
・ミニブレットボード(あると便利)
ジャンパーワイヤー(オス)
(ブレットボードで回路を組むとき、見栄え良く綺麗に繫げられますのであると便利)
※任意(楽したい方向け)
ESP-WROOM-02開発ボードを使うとすぐに開発ができるよう回路が組まれているため、上記の「ESP-WROOM02」「超小型USBシリアル変換モジュール」「3端子レギュレータ」「電解コンデンサ 47μF35V」「セラミックコンデンサ 0.1μF」「タクトスイッチ」は不要になります!
・次に回路の組み立てに入ります。
組み立てに関してはESP-WROOM02の回路は再び下記サイトさんの
「6.各部品の接続」を参考にしていただければと思います。(とてもわかりやすいです)
WROOM 単体に Arduino スケッチで Wi-Fi ストリーミング
・ESP‐WROOM02本体の接続箇所
pinナンバー | 状態 |
---|---|
GPIO 15(IO15) | LOW |
GPIO 2(IO2) | HIGH |
GPIO 0(IO0) | LOW |
EN | HIGH |
※GPIO 0(IO0)をLOWの状態で起動させるときのみ書き込みモード、
LOWじゃなければ実行モードになります。
なのでGPIO 0とGNDにダクトスイッチをかましとくと後が楽です。
※RST(リセット)もLOWにすることでプログラムのリセットが行えますのでRSTとGNDにダクトスイッチをかましておくと後が楽です。
・完成するとこんな感じになると思います!
※ESP-WROOM-02開発ボードをご使用の方はここからスタート。
②「開発環境の準備」
・まずはArduino IEDでESP-WROOM02を使えるようにします↓
Arduino IDEでESP-WROOM-02(ESP8266)とESP-WROOM-32を使えるようにする!(Windows10)
・次にFTP通信するためのライブラリーを追加します。
Arduinoファイルの中にあります「libraries」の中を開いて頂き、足りないライブラリーを入れていきます!
※もしかしたらデフォルトで入っているかもしれません。
・WiFi
③「サーバーの準備」
・次はサーバーの準備です!
サーバーと聞くだけで私は嫌になってしまうほど苦手分野です(´・ω・`)ショボーン
私が使用しているサーバーはXサーバーというレンタルサーバです!
(※有料です。)
・なので今回はXサーバーを使用して説明させて頂きますがサーバーの設定等は、
他のサイトさんを参考にしていただいたほうが
分かりやすいと思いますのでご参考までに↓
・次にマイPCにFTPクライアントソフトウェアをダウンロード、FTPサーバーと連携させます。
私が使用しているのは学校の授業でも使用したFFFTPというソウトなので、こちらで説明を進めさせて頂きたいと思います。
ここからダウンロードできます↓
・FTPサーバーと連携させる手順は、こちらも
他のサイトさんを参考にしていただいたほうが
分かりやすいと思いますのでご参考までに↓
ここまで、結構大変かと思いますが次からが本番です!
頑張りましょう!
④「プログラミング」
やっとプログラミング!
・まず、Arduino IEDを起動して、こちらのメインコードをコピペしてください↓
(ファイル名は任意で)
メインコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
#include <SoftwareSerial.h> #include <FS.h> #include <ESP8266WiFi.h> // ESP8266用ライブラリ #include <WiFiUdp.h> // UDP通信を行うライブラリ #define PIN_CAM 13 // IO 13(5番ピン)にPch-FETを接続する #define TIMEOUT 2000 // タイムアウト 2秒 #define SSID "***" // 無線LANアクセスポイントのSSID #define PASS "***" // 無線LANアクセスポイントのパスワード #define SENDTO "192.168.0.255" // UDP送信先IPアドレス(変更する必要なし) #define PORT 1024 // UDP送信ポート番号(変更する必要なし) //FTPサーバーと接続するための設定 #define FTP_TO "202.254.23.21" // FTP 送信先のIPアドレス(入力されているのは例です。ご自分のIPに変えてください) #define FTP_USER "***" // FTP ユーザ名 #define FTP_PASS "***" // FTP パスワード #define FTP_DIR "/***" // FTP ディレクトリ #define FILENAME "/spiffs.txt" //FTPサーバーに送るファイル名(保存するファイル名) File file; WiFiUDP udpFtp; // UDP通信用のインスタンスを定義 WiFiServer server(80); // Wi-Fiサーバ(ポート80=HTTP)定義 void setup() { SPIFFS.begin(); Serial.begin(115200); // 動作確認のためのシリアル出力開始 WiFi.mode(WIFI_STA); // 無線LANをSTAモードに設定 WiFi.begin(SSID, PASS); // 無線LANアクセスポイントへ接続 while (WiFi.status() != WL_CONNECTED) { // 接続に成功するまで待つ Serial.print("."); delay(500); // 待ち時間処理 } server.begin(); // サーバを起動する File file = SPIFFS.open(FILENAME, "r"); // 保存のためにファイルを開く if (file == 0) sleep(); // ファイルを開けれなければ戻る file.seek(1, SeekSet); char c = file.read(); Serial.println(""); Serial.print("spiffs:"); Serial.println(c); file.close(); File f = SPIFFS.open(FILENAME, "a"); // 保存のためにファイルを開く(追記モードでオープン) f.println("1234567"); // 文字列の書き込み(書き込みたい文字にしてください) f.close(); //ファイルを閉じる byte ret = doFTP(FILENAME); // FTPで送信する if (ret) { Serial.print("FTP Err :"); Serial.println(ret); delay(3000); } Serial.print("http://"); // デバイス名をシリアル表示 Serial.print(WiFi.localIP()); // 本機のIPアドレスをシリアル表示 Serial.println(FILENAME); // ファイル名をシリアル表示 udpFtp.beginPacket(SENDTO, PORT); // UDP送信先を設定 udpFtp.print(", http://"); // デバイス名を送信 udpFtp.print(WiFi.localIP()); // 本機のIPアドレスを送信 udpFtp.println(FILENAME); // ファイル名を送信 udpFtp.endPacket(); // UDP送信の終了(実際に送信する) } void loop() { Serial.println("finish"); // 終了表示 delay(100000); //finish送信待機時間 } void sleep() { Serial.println("F Err"); // ファイルを呼び出せなかった時のエラー表示 } |
・次にファイルを分割し、新しいファイルにこちらのコードを記載します。(ファイル名は任意で)
やりかたは、Arduino IEDの右上にある ▼ を押してください。
押したら「新規タブ」を押してください。
すると下の方が黄色くなり、新規ファイルの名前と出ますのでそこに
ファイル名を入力してOKを押してください。
そうするとこのように1つファイルが増えます!
(ftp_1 と、更に ftpというファイルを追加しました)
・新しく作ったファイルに下記のFTPコードをコピペしてください↓
FTPコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
#define FTP_WAIT 1 #define BUFFER_SIZE 128 byte doFTP(char *filename){ char ftpBuf[BUFFER_SIZE]; WiFiClient client; WiFiClient dclient; int i; File file = SPIFFS.open(filename,"r"); if(!file){ Serial.println("SPIFFS open fail"); return 11; } Serial.println("SPIFFS opened"); if (client.connect(FTP_TO,21)) { Serial.println("Command connected"); } if(eRcv(client,ftpBuf)) return 21; sprintf(ftpBuf,"USER %s\r\n",FTP_USER); client.print(ftpBuf); delay(FTP_WAIT); Serial.print(ftpBuf); if(eRcv(client,ftpBuf)) return 22; sprintf(ftpBuf,"PASS %s\r\n",FTP_PASS); client.print(ftpBuf); delay(FTP_WAIT); Serial.println("PASS"); if(eRcv(client,ftpBuf)) return 23; client.print("Type I\r\n"); delay(FTP_WAIT); Serial.println("Type i"); if(eRcv(client,ftpBuf)) return 25; client.print("PASV\r\n"); delay(FTP_WAIT); Serial.println("PASV"); delay(100); if(eRcv(client,ftpBuf)) return 26; char *tStr = strtok(ftpBuf,"(,"); if(tStr == NULL) return 27; int array_pasv[6]; for (i = 0; i < 6; i++) { tStr = strtok(NULL,"(,"); array_pasv[i] = atoi(tStr); if(tStr == NULL){ Serial.println("Bad PASV Answer"); return 28; } } unsigned int hiPort,loPort; hiPort = array_pasv[4] << 8; loPort = array_pasv[5] & 255; Serial.print("Data port: "); hiPort = hiPort | loPort; Serial.println(hiPort); if (dclient.connect(FTP_TO,hiPort)) { Serial.println("Data connected"); }else{ Serial.println("Data connection failed"); client.stop(); file.close(); return 31; } sprintf(ftpBuf,"STOR %s%s\r\n",FTP_DIR,filename); client.print(ftpBuf); delay(FTP_WAIT); Serial.print(ftpBuf); if(eRcv(client,ftpBuf)){ dclient.stop(); file.close(); return 32; } Serial.println("Writing"); i=0; while(file.available()){ ftpBuf[i]=file.read(); i++; if(i >= BUFFER_SIZE){ if(!dclient.connected()) break; dclient.write( (byte *)ftpBuf, BUFFER_SIZE); i=0; Serial.print("."); delay(1); } } if(i > 0){ if(dclient.connected()){ dclient.write((byte *)ftpBuf, i); } } dclient.stop(); Serial.println("Data disconnected"); if(eRcv(client,ftpBuf)) return 33; client.print("QUIT\r\n"); delay(FTP_WAIT); Serial.println("QUIT"); if(eRcv(client,ftpBuf)) return 91; client.stop(); Serial.println("Command disconnected"); file.close(); Serial.println("SPIFFS closed"); return 0; } byte eRcv(WiFiClient &client,char *ftpBuf){ byte thisByte,i=0,len=0; while(!client.available()){ delay(FTP_WAIT); if(!client.connected()){ Serial.println("FTP:eRcv:disC"); return 11; } i++; if(i>1000){ // 200ms以上必要 Serial.println("FTP:eRcv:noRes"); return 12; } } while(client.connected()){ if(!client.available()){ delay(FTP_WAIT); if(!client.available()) break; } thisByte = client.read(); if(thisByte==(byte)'\r'); else if(thisByte==(byte)'\n'){ Serial.write('>'); Serial.println(ftpBuf); if(ftpBuf[0] >= '4'){ client.print("QUIT\r\n"); delay(FTP_WAIT); Serial.println("QUIT"); return 1; } if(len>3 && ftpBuf[3] == ' '){ return 0; } len = 0; }else if(len < BUFFER_SIZE - 1 ){ ftpBuf[len] = thisByte; len++; ftpBuf[len] = 0; } } return 0; } void efail(WiFiClient &client){ byte thisByte = 0; client.print("QUIT\r\n"); delay(FTP_WAIT); while(!client.available()){ if(!client.connected()) return; delay(1); } while(client.available()){ thisByte = client.read(); Serial.write(thisByte); } client.stop(); Serial.println("Command disconnected"); } |
以上、まずはこれでビルドが通るか試してみてください!
これでエラーが出なければひとまずOKですね!
※ESP-WROOM-32ではこのプログラムだとエラーが出ます。
プログラムの改良が必要になりますが、まだ解決策は見つけられてないです(;^ω^)
もしわかる方教えて頂けると助かります(;^ω^)
「補足」
・ファイルを書き込むには追記と上書きがあります!
メインプログラムにありますここのヵ所↓
File f = SPIFFS.open(FILENAME, “a”); // “a” は追記
f.println(“1234567”);
の、”a” を ”w” 変えると上書きになります!
また、f.println(“1234567”);
に、センサーの値を入れれば、センサーの値を送れるようになります^^
是非試してみてください^^
※SPIFFSを使うためにファイルシステムのアップローダ
という作業が必要かもしれません!
まだされてないかたはこちらのサイトさんを参考に 参考サイト
⑤「動作確認・まとめ」
・それでは、実際にESP-WROOM02に書き込んでみたいと思います!
書き込みモードにして書き込みスタート!
※ESP-WROOM02側で、GPIO 0(IO0)をLOWの状態で起動させるときのみ書き込みモード、
LOWじゃなければ実行モードになります。
※ビルドをした際に、こんなエラーが出たら書き込みモードになっていないのが原因です。
(GPIO 0(IO0)をLOWの状態で起動させるときのみ書き込みモード、LOWじゃなければ実行モードになります。)
改善されない場合はもう一度①「回路の準備」を読み直してみてください。
・書き込みが成功すると、シリアルモニターにこんな感じで表示されていれば成功です!
※クリックすれば拡大できます。
・最後に、FFFTPソフトを使ってサーバーにちゃんと送られているか確認します!
※クリックすれば拡大できます。
送られてますね!
これで大成功です^^
一発で上手くいかないかもしれませんが、原因を探して頑張ってみてください^^
分らないところがありましたら、どうぞお気軽にコメント下さいませ^^
以上、ご訪問ありがとうございました^^
はじめまして、
記事の投稿ありがとうございます。
すいませんが、質問させてもらえませんか。
そちらでは今でも このページ記載のコードで動作しますか?
この手順を試したところ、掲載されている成功例画像と違って、
実行後で以下の部分のような550の数値のとこでエラーがでました。
なんらか 原因など思い当たるとこがあれば教えてもらえないでしょうか?
STOR /futami_test/spiffs.txt
>550 /futami_test/spiffs.txt: No such file or directory
QUIT
FTP Err :32
※似た文章をすでに送ってしまったかもしれません
電撃さんでしょうか
はじめまして、
以下の記事をみました。
http://toccho.xsrv.jp/2018/07/09/sensor-ftp-csv-esp-wroom02/#comment-107
記事の投稿ありがとうございます。
私は趣味でESPからウェブサーバにcsvやテキスト形式のファイルを送ろうとしています。
すいませんが、質問させてもらえませんか。
そちらでは今でも このページ記載のコードで動作しますか?
この手順を試したところ、掲載されている成功例画像と違って、
実行後で以下の部分のような550の数値のとこでエラーがでました。
なんらか 原因など思い当たるとこがあれば教えてもらえないでしょうか?
STOR /futami_test/spiffs.txt
>550 /futami_test/spiffs.txt: No such file or directory
QUIT
FTP Err :32
それと、この内容をESP32の方でも試されていますか?
お忙しいところすいませんが、よろしくお願いします。
初めまして^^
コメント・ご訪問頂きありがとうございます^^
内容を確認させていただきました^^
いくつか確認させてください^^
1.まず、エラー内容というのはArduino IEDのシリアルモニターで表示された内容ですか?
それともブラウザで表示されたエラーですか?
2.エラー内容はこれがすべてですか?
お手数ですが状況の方をさらに詳しく教えて頂けると幸いです(;^ω^)
その他の質問につきましては、
ESP32ではまだ試していませんが近々試す予定です^^
すいません、返事に気づきませんでした。
ご回答ありがとうございます。
1.については、Arduino IEDのシリアルモニターで表示された内容です。
2. については、以下が 表示されたもの全体です。
STOR以降がうまくいっていないようです
Command connected
>220 FTP Server ready.
USER 「私のユーザ名」
>331 Password required for 「私のユーザ名」
PASS
>230 User 「私のユーザ名」 logged in.
Type i
>200 Type set to I
PASV
>227 Entering Passive Mode (157,112,183,138,234,164).
Data port: 60068
Data connected
STOR /futami_test/spiffs.txt
>550 /futami_test/spiffs.txt: No such file or directory
QUIT
FTP Err :32
http://「私のIPアドレス」/spiffs.txt
finish
追加情報なのですが、
ESP8266が乗っていれば他の形式のマイコンでも動作すると考えて、
以下のESPを使っております
WeMos D1 CH340 WiFi 開発ボード ESP8266
https://www.amazon.co.jp/gp/product/B01D1D0EO4/ref=oh_aui_detailpage_o07_s00?ie=UTF8&psc=1
いえいえ^^
もしかしたらSPIFFSファイルシステムアップローダーという作業が必要だったかもしれません(;^ω^)
まずSPIFFSでファイルの読み書きができるか試してみてください(;^ω^)
下記のサイトが参考になるかと思います⇩
https://tomosoft.jp/design/?p=7814
また、ディレクトリーの位置が間違っている可能性もありますのでこれでも上手くいかないようでしたらディレクトリー確認したいので、
#define FTP_DIR “/***”
のところをどのように記載しているか確認させていただければと思います(;^ω^)
追加情報ありがとうございます^^
触ったことありませんがおっしゃる通りWeMos D1 CH340 WiFi 開発ボード ESP8266でもできるはずです^^
TOCCHO様、
ESP8266NodeMCUで一発で動きました。
※数か所Errorがあるようですが、きちんと、spiffs.txtがFTPサーバに作成されていました。
感動しました。
すみません、ESP32版の作成は可能でございますか??
PAO様、コメント頂きありがとうございます!
返信が遅くなり申し訳ないです(;^ω^)
error申し訳ないです(;^ω^)
ESP32でも同じようにできると思いますが試していないのでわかりません。申し訳ないです(;^ω^)
Hey very nice blog!|