みなさん、こんにちは。 トドお父さんです。
家庭菜園の自動水やりシステム、EasyIoTとの連携の説明が3回でも終りませんでしたので、
今回 4回目です。 ながながとお付きあい、有難うございます。
ようやく、ESP8266のプログラムコードの説明に進めますね。 (仕事みたいでつorz)
前のブログから、説明が続いてますので併せて見てくださいねー。
前回のブログ
[電子工作]Part4 家庭菜園の自動水やりシステムの作成再開!(EasyIoTとの連携 Ⅲ)
前々回のブログ、
[電子工作]Part3 家庭菜園の自動水やりシステムの作成再開!(EasyIoTとの連携 Ⅱ)
前々々回のブログ、
[電子工作]Part2 家庭菜園の自動水やりシステムの作成再開!(EasyIoTとの連携)
また、もとネタのインストラクタブルの下記の記事も併せて参照してくださいね。
ESP8266 Smart Plant Irrigation System
この記事にある、Githubに登録されたコードをベースに私のシステムに合わせて修正しました。
プログラムはこのプロジェクト初回の下記レスで説明した、Arduino IDEを使って作りました。
Arduinoの統合環境、使いやすいです。 ESP8266チップでLチカまでできれば確認はOKですよー。
[電子工作]家庭菜園の自動水やりシステムの作成再開!(Part1ESP8266 Wifiチップ)
【プログラムの説明】
今回作ったプログラムは本家と同様に、GitHubに登録しました。
GitHubまで使うことになるとは、半年前までは思いもつきませんでしたね。
この年でも、だんだん進化しております、トドお父さん (自画自賛 乙)
My ESP8266 Vegitable gardem iIrigation System
このプロジェクトのプログラムは、一番上の ESP8266_mqtt_irrigator_Aug09a というフォルダです。
その下は、前回説明した回路図と部品リスト(BOMリスト)を登録しています。
Readmeは、従来プログラムの先頭にコメントととして入れていた内容を書き込んでいます。
プログラムは、HTMLでコピーして貼り付けるのでしたね、やってみましょう。
おぅっ、結構、きれいに貼りつけましたね。
<Head> </Head>タグの間に入れるCSSで<Pre> </pre>タグのスタイルを制御できれば、
縦・横の大きさを固定でオーバーする部分はスクロールバーでスクロールできるのですが、ここは
初心者向けのアメブロ、そんな機能はありませんので、プログラムを分割して部分ごとに説明しますね。
1、プログラム 定義部
#include <ESP8266WiFi.h>#include <MQTT.h>#include <EEPROM.h>#define DEBUG#define AP_SSID "xxxxxx" #define AP_PASSWORD "xxxxxx"#define EIOTCLOUD_USERNAME "xxxxx"#define EIOTCLOUD_PASSWORD "xxxxx"// create MQTT object#define EIOT_CLOUD_ADDRESS "cloud.iot-playground.com"#define PIN_PUMP 13 //BUILTIN_LED //D0 // nodemcu built in LED#define PIN_BUTTON 12 // D3 // nodemcu flash button#define PIN_HUM_ANALOG A0 // humidity pin#define MAX_ANALOG_VAL 925 // 2017.8.10 changed from 956#define MIN_ANALOG_VAL 225 // 2017.8.10 changed from 250#define IRRIGATION_TIME 10 // irrigation time in sec#define IRRIGATI ON_PAUSE_TIME 300 // irrigation pause time in sec - only for auto irrigator// irrigator statetypedef enum { s_idle = 0, // irrigation idle s_irrigation_start = 1, // start irrigation s_irrigation = 2, // irrigate s_irrigation_stop = 3, // irrigation stop} e_state;
まずは、先頭部。
ESP8266内蔵のWifiととEEPROMを制御するライブラリのインクルードです。
MQTTはEasyIoT Cloudとの情報のPublish(データ出力)とSubscribe(データ入力)を制御
するライブラリですね。Adafruutなんかにも、似たようなライブラリがありますが、間違わない
ようにしてくださいね。
つづく #define はプログラム内で使用する定数の値の設定になります。
wifi のSSID、パスワード、EasyIot Cloudに登録した皆さんのIDとパスワードを入力します。
#define DEBUG はDEBUG用のSWコントロールで、使用しないときは//でコメントアウトにします。
つぎはハード的な設定です。ここは皆さんの環境や好みで変更できます。
#define PIN_PUMP 13 ⇒ ポンプ(水バルブ)の出力ピン IO13
#define PIN_BUTTON 12 ⇒ 手動でポンプON/OFFをするスイッチの入力ピン IO12
#define PIN_HUM_ANALOG A0 // ESP8266 はアナログ入力が1個しかありません。TOUTピン
// 0V~1Vが 0~1024変換されます。(3.3Vの場合は分圧)
#define MAX_ANALOG_VAL 925 // 2017.8.10 changed from 956 乾燥センサのMAX値
#define MIN_ANALOG_VAL 225 // 2017.8.10 changed from 250 乾燥センサのMIN値
// この2つは乾燥センサで実際にテストして決めます。
#define IRRIGATION_TIME 10 // irrigation time in sec ON時にポンプが働く時間 10秒
#define IRRIGATION_PAUSE_TIME 3000 // 自動動作のときにポンプが再開する間隔 50分間
つぎのtypedef enum{ 以降は、この基板の動作状態を判断するステートを4種類定義しています。
enum型宣言ということですが、詳しくはググって勉強して下さいね。
2、プログラム 定義部 続き
// define ESP8266 parameter#define CONFIG_START 0#define CONFIG_VERSION "v01"struct StoreStruct { // This is for mere detection if they are your settings char version[4]; // The variables of your settings uint moduleId; // module id} storage = { CONFIG_VERSION, // The default module 0 0,};#define PARAM_HUMIDITY_TRESHOLD "/Sensor.Parameter1"#define PARAM_MANUAL_AUTO_MODE "/Sensor.Parameter2"#define PARAM_PUMP_ON "/Sensor.Parameter3"#define PARAM_HUMIDITY "/Sensor.Parameter4"#define MS_IN_SEC 1000 // 1S MQTT myMqtt("", EIOT_CLOUD_ADDRESS, 1883);
つぎはEEPROMに収納するパラメータの一群です。
初回に、EasyIoT Cloudと通信して、作成した新規モジュールのパラメータが構造体のなかの
配列に入ります。 2回目以降は読みだすでけですので、デバッグ時はEEPROMを初期化する
必要があります。(自分はeap8266_flasher.exeを使用して、ファームを上書きします)
最後のMQTT myMqtt(“”, EIOT_CLOUD_ADDRESS, 1883); はMQTTライブラリのコンストラクタで
MQTTライブラリ(クラス)のmyMqtt というインスタンスを作成します。(意味不明?すまそです)
3、プログラム 定義部 続き
// intvariablesint state;bool stepOk = false;int soilHumidityThreshold;bool autoMode;String valueStr("");String topic("");boolean result;int lastAnalogReading;bool autoModeOld;int soilHumidityThresholdOld;unsigned long startTime;int soilHum;int irrigatorCounter;
プログラムで使う変数の定義です。 変数なのでESP8266のRAMに入ります。
4、プログラム 初期化処理 1(変数の初期設定とWif接続)
void setup() { state = s_idle; pinMode(PIN_PUMP, OUTPUT); pinMode(PIN_BUTTON, INPUT); autoMode = false; stepOk = false; soilHumidityThresholdOld = -1; startTime = millis(); soilHum = -1; Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(AP_SSID, AP_PASSWORD); Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(AP_SSID); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }; Serial.println("WiFi connected"); Serial.println("Connecting to MQT T server"); EEPROM.begin(512); loadConfig();
初期化で最初の状態を定義します。
enumで定義した4つのステートは 初期ではs_idle アイドル状態
ピンモードでpin13をPIN_PUMP出力に、pin12をPIN_BUTTON入力に設定
自動モード OFF,100mSタイマー、乾燥度 -1、現在時刻=millis();
wifi設定とWifi初期接続、EEPROM初期化までを終了します。
5、プログラム 初期化処理2 (MQTTサーバー接続)
//set client id // Generate client name based on MAC address and last 8 bits of microsecond counter String clientName; //clientName += "esp8266-"; uint8_t mac[6]; WiFi.macAddress(mac); clientName += macToStr(mac); clientName += "-"; clientName += String(micros() & 0xff, 16); myMqtt.setClientId((char*) clientName.c_str()); Serial.print("MQTT client id:"); Serial.println(clientName); // setup callbacks myMqtt.onConnected(myConnectedCb); myMqtt.onDisconnected(myDisconnectedCb); myMqtt.onPublished(myPublishedCb); myMqtt.onData(myDataCb); //////Serial.println("connect mqtt..."); myMqtt.setUserPwd(EIOTCLOUD_USERNAME, EIOTCLOUD_PASSWORD); myMqtt.connect(); delay(500); Serial.print("ModuleId: "); Serial.println(storage.moduleId);
上はMQTTサーバと接続するための一意のClient名を生成しています。
wifiのmacアドレスを文字列に変換して、その末尾にランダムなマイクロ秒値の下位8ビットを
取り出して、16進数に変換した値を文字に変換して最後にnullを入れて終端しています。
生成したClientName文字列がMQTT Client IDとなり、MQTTサーバのClientIDとして
設定します。
その他のMQTTのメンバ関数の設定もここで行っています。
MQTTサーバーへの接続の実施
myMqtt.setUserPwd(EIOTCLOUD_USERNAME, EIOTCLOUD_PASSWORD); myMqtt.connect();
myMqtt.connect();
なんか、ここまでの説明で力尽きました。
いやー、会社の仕事より疲れましたよ、プログラムの説明。
自分が初心者だから、今のうちに理解しないと、って頑張りすぎたみたいですね。
今日、一日で説明が終わりませんでした。
いや~疲れました。
このへんで、カンベンしてやろう!(勘弁してね!)って捨て台詞で今日は終わりにします。
次回 Part6 EasyIoTとの連携Ⅴ でプログラムは完結する予定です。
続きを乞うご期待!
それでは、おやすみなさい