Groveのモジュールには水センサというののがあるので、それで雨をスマホにお知らせしてくれる仕組みを作ってみました。
Groveの水センサー(電極部分に水が触れると出力がLOWになります。押しボタンスイッチのGroveの様に扱えます。)
#プログラム
プログラムは水センサが反応したらIFTTTのWebHookにPOSTするようになってます。センサが反応しない状態から反応している状態に変わった時だけ反応するONエッジ検出という方法で反応を見ています。且つセンサが誤作動しないように10回連続で反応しないと検出しない様に工夫しています。
Wio LTEはD38のみGroveコネクタの電源端子が常にONになっていますが、それ以外はプログラムでONにしないと使えません。例えば、D20のコネクタに接続する場合は、次のプログラムの様にします。
#include <WioLTEforArduino.h>
#include <stdio.h>
#define APN "soracom.io"
#define USERNAME "sora"
#define PASSWORD "sora"
#define WEBHOOK_EVENTNAME "NotifyRain"
#define WEBHOOK_KEY "-- key --"
#define WEBHOOK_URL "https://maker.ifttt.com/trigger/"WEBHOOK_EVENTNAME"/with/key/"WEBHOOK_KEY
#define WATER_SENSOR_PIN (WIOLTE_D20) // I2Cの場合はPB8、UARTの場合はPB7とする
#define INTERVAL (100)
#define WATER_SENSOR_OFF 0
#define WATER_SENSOR_ON 1
#define WATER_SENSOR_ERR -1
WioLTE Wio; // D38以外に接続する場合は記述する
void connectLTE()
{
SerialUSB.println("### Power supply ON.");
Wio.PowerSupplyLTE(true);
delay(5000);
SerialUSB.println("### Turn on or reset.");
if (!Wio.TurnOnOrReset()) {
SerialUSB.println("### ERROR! ###");
return;
}
SerialUSB.println("### Connecting to \""APN"\".");
delay(5000);
if (!Wio.Activate(APN, USERNAME, PASSWORD)) {
SerialUSB.println("### ERROR! ###");
return;
}
}
void setup()
{
pinMode(WATER_SENSOR_PIN, INPUT);
Wio.Init(); // D38以外に接続する場合は記述する
Wio.PowerSupplyGrove(true); // D38以外に接続する場合は記述する
connectLTE();
}
void loop()
{
static int beforeWaterSensorStatus = WATER_SENSOR_OFF;
int waterSensorStatus = getWaterSensorStatus();
if(waterSensorStatus != WATER_SENSOR_ERR ) {
if((waterSensorStatus == WATER_SENSOR_ON)
&&(beforeWaterSensorStatus == WATER_SENSOR_OFF)) {
char data[100];
int status;
SerialUSB.println("### Post.");
sprintf(data, "{\"value1\":\"It started to rain\"}");
SerialUSB.print("Post:");
SerialUSB.print(data);
SerialUSB.println("");
if (!Wio.HttpPost(WEBHOOK_URL, data, &status)) {
SerialUSB.println("### ERROR! ###");
}
SerialUSB.print("Status:");
SerialUSB.println(status);
}
beforeWaterSensorStatus = waterSensorStatus;
}
delay(INTERVAL);
}
// 水センサーの値を取得
int getWaterSensorStatus()
{
int waterSensorStatus = digitalRead(WATER_SENSOR_PIN); // 現在の値を取得(基準)
delay(100);
// 10回同じ値であれば正常
for(int i=0;i<10;i++) {
int nowWaterSensorStatus = digitalRead(WATER_SENSOR_PIN); // 現在の値を取得
if( waterSensorStatus != nowWaterSensorStatus ){
return WATER_SENSOR_ERR;
}
delay(100);
}
if(waterSensorStatus == LOW) return WATER_SENSOR_ON;
return WATER_SENSOR_OFF;
}
また、I2CのGroveコネクタに接続する場合はPB8、UARTの場合はPB7とします。
#IFTTTからスマホへ
IFTTTにはスマホ用のアプリがあり、出力側のサービスで「Notifications」を使えばスマホのアプリで受け取って表示することができます。スマホのアプリはストアでIFTTTで検索すれば見つかると思います。
#実用時の注意点
雨に反応させた際にそのまま乾いてしまうと雨の成分が残ってしまい、反応したままになってしまいます。そのため、晴れた時は拭き取るか、センサを斜めにして、流れ落ちる様にする工夫が必要です。
#最後に
執筆中のKindle書籍のWio LTE本(Groveリファレンス編)はこの様なノウハウをまとめてます。出版まで少々お待ちを!
目次や書籍に関する情報は以下を参照ください