前回汎用トリガーの接点1入力版を紹介しました。
- ブログ内記事:『スマートホーム向け汎用トリガーを作る(ESP32使用) - 接点1入力版』
ところで使用しているESP32モジュールボード『DOIT ESP32 DEVKIT
V1』はIOピンがたくさんあるので(今回使用している30ピン版モジュールボードでも24個のIOピンを装備)、1入力しか使わないのは損ですよね😅。
そこで複数入力に対応できるようにプログラム(スケッチ)を書き換えました。
今回はスマートホーム向け汎用トリガー(接点多入力版)の紹介です。
■スマートホーム向け汎用トリガーを作る(ESP32使用):接点多入力版
以下は『汎用トリガー(多入力版)の作成と、IFTTTでの動作確認(ルームライトの点灯・消灯)まで』です。
使用するESP32ボードは前回と同じ『DOIT ESP32 DEVKIT V1』です。
●汎用トリガー(接点多入力版)の作成
1. 回路 - 汎用トリガー(接点多入力版)
汎用性を出すために接点入力部分については、
- 入力接点の極性対応(Lアクディブだけでなく、Hアクディブへの対応)
- 入力電圧幅を増加
回路図(汎用トリガー(接点多入力版))【画像をクリックすると高精細な画像を表示できます】 |
実装例(汎用トリガー(接点多入力版):動作確認用ブレッドボード) |
1-1. 接点入力(入力ポート)
ESP32ボードのIOポート22(D22)とIOポート21(D21)をセンサーの接点の入力ポートとして使用します。
センサーの出力は以下の2種類のケースが考えられます。
- センサーが検知した時の出力がLOW電圧(Lアクティブ)
- センサーが検知した時の出力がHigh電圧(Hアクティブ)
Lアクティブの方が一般的な出力だと思いますが、ここで作成するトリガーは汎用性を重視していますので、Hアクティブ出力のセンサーにも対応できるようにしました。
(対応可能なセンサーの出力仕様(電圧等)は上記回路図、または下記仕様書(データシート)を参照ください。)
1-2. LED表示(出力ポート)
ESP32ボードのIOポート23(D23)とLED表示用の出力ポートとして使用します。
ポートとGNDの間にLEDと電流制限抵抗(220Ω)を接続します。
Arduinoの出力は3.3V、LED(緑)のVFは2V程度なので、LEDに流れる電流は(3.3V ー
2V) ÷ 220Ω =
6mAとなります(LEDの明るさを変えるにはこの抵抗値を調整してください)。
- 【参考】ボードの電源
ボードに元からついているmicro
USBコネクタ(プログラム書き込み・シリアル通信用)を使います。
スケッチ(プログラム)書き込んだ後はこのmicro
USBコネクタにUSB電源(USB充電器等)を接続して動作させることができます(動作確認済み。但し、この場合PCとは繋がっていないので当然ですがシリアル通信は機能しません)。
2. プログラム(スケッチ) - 汎用トリガー(接点多入力版)
参照元のプログラム(スケッチ)は経過時間のオーバーフローに対応していないので、その部分を追加しています(オーバーフローまでに約50日間かかるのでまだ動作確認はできていません😅)。
また多入力に対応するために、サブルーチン化、変数の配列化など大幅に変更しています。
プログラム(スケッチ)の動き:
- LED表示:
- 起動後、Wi-Fiに接続するまではLEDを点滅。接続が完了したらLEDは消灯。
- 接点信号を検出したらLEDは点灯
- シリアル通信:
- 起動後、Wi-Fiに接続が完了したらその旨をPCに送信
- 接点信号を検出したらその旨をPCに送信
- Webhooks:
- 接点信号を検出したら、Webhooksに任意のテキスト(プログラムで設定可能)を発行。
(以下のサンプルプログラム中の” WiFi_ssid ”と” Password ”は接続するWi-FiネットワークのSSIDとパスワードに書き換えてください。
そして、" Private_key "はWebhooksのプライベートキーに書き換えてください(Webhooksについてとプライベートキーの取得方法は下で紹介しています)。
またWebhooksに発行するテキスト(イベント名)は任意に設定可能です。)
このプログラム(スケッチ)は2入力版ですが、以下の4箇所を書き換えることによって容易に3入力以上に変更可能です。
※① 入力チャンネル数
※② Webhooksで発行するテキスト(イベント名)
※③ 入力ポートの設定
※④ 入力のノイズ排除時間の判定基準時間
今回はプログラム(スケッチ)内のコメントも接点1入力版から大幅に更新しています。
ーーーサンプルプラグラム(汎用トリガー(接点多入力版))ーーー
(" // ... "と" /* ... */ "の部分(黄色)はコメントです。)
/**
*
* ー スマートホーム向け汎用トリガー(接点多入力版) ー
*
*
* このスケッチを使用するためには
* ・Wi-FiのSSIDおよびパスワード
* ・Webhooksのプライベートキー
* の設定が必要です。
*
*
*
引用元によると、このスケッチのWi-Fi接続およびスイッチ入力認識は
* Arduino IDEのサンプルを使っているそうです
* ★引用元:
* "CONNECT MAKER TO ANYTHING - IFTTT"
*
https://bigjungle.net/blog/2015/6/26/connect-maker-to-anything-ifttt
*
*
* 入力チャンネル数を増やすにはプログラム中の以下の4箇所(※印)を変更する
* ※① 入力チャンネル数
* ※② Webhooksで発行するテキスト(イベント名)
* ※③ 入力ポートの設定
* ※④ 入力のノイズ排除時間の判定基準時間
*
*/
#include <WiFi.h> // ヘッダファイル"WiFi.h"はArduino
IDEに標準であるようです(別途インストール不要)
// Wi-Fi接続先の設定
const char *ssid = "WiFi_ssid"; // WiFi_ssidには接続するWi-FiのSSIDを設定
const char *password = "Password"; // Passwordには接続するWiFiのパスワードを設定
// Webhooks(IFTTT)の設定
const char *host = "maker.ifttt.com"; // WebhooksのホストURL
const char *privateKey = "Private_key"; // Private_keyにはWebhooksのあなたのプライベートキーを設定
// 入力チャンネル数
// ※①
入力チャンネル数を変更するにはこの数字を変える
const int nInput = 2;
// Webhooksに発行するテキスト(イベント名)
// ※②
入力チャンネル数を変更するには、このテキストをチャンネル数用意する
const char *event_name[nInput] = {
"input0_sensed", // 入力チャンネル0のテキスト
"input1_sensed" // 入力チャンネル1のテキスト
};
// ハードウェアの設定
// ※③
入力チャンネル数を変更するには、この入力ポートをチャンネル数用意する
const int buttonPin[nInput] = {22, 21}; // 入力(接点)を割り当てるポート
const int ledPin = 23;
// LEDを割り当てるポート
// 変数の定義
int buttonState[nInput]; // 入力ポートの今回状態
int lastButtonState[nInput];
// 入力ポートの前回状態
//
以下はタイマーとして使う変数で、代入するmillis()と同じ型の"unsigned
long"で定義
unsigned long lastDebounceTime[nInput]; // 入力ポートの状態が切り替わってからのタイマー
// ※④ 入力チャンネル数を変更するには、この判定基準時間をチャンネル数用意する
unsigned long debounceDelay[nInput] = {50,50}; // 入力ポートの切り替わりがノイズか否か?
の判定基準時間(50m秒)
/**
* セットアップルーチン setup():
* ー スケッチ実行時の最初に1回だけ実行 ー
*/
void setup() {
// IOポートのモード設定
for(int i=0; i < nInput; i++){
pinMode(buttonPin[i], INPUT); // 入力ポートの設定
};
pinMode(ledPin, OUTPUT);
// 出力ポート(LED)の設定
// シリアル通信のデータ転送レートの設定
Serial.begin(115200);
delay(10);
// ボタンの前回状態(lastButtonState)の初期化
for(int i=0; i < nInput; i++){
lastButtonState[i] = LOW;
};
//
タイマー(lastDebounceTime)の初期化(入力チャンネル毎)
for(int i=0; i < nInput; i++){
lastDebounceTime[i] = 0;
};
// Wi-Fi接続の開始
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
// Wi-Fi接続確立中はLEDが点滅
int led = HIGH;
while (WiFi.status() != WL_CONNECTED) {
delay(200);
digitalWrite(ledPin, led);
led = !led;
}
// Wi-Fi接続が確立したらLEDは消灯
digitalWrite(ledPin, LOW);
// Wi-Fi接続が確立したらシリアル通信でIPアドレスを送信
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
/**
* メインルーチン loop():
* ー スケッチ実行時にsetup()実行後、繰り返し実行
ー
*/
void loop() {
for(int i=0; i < nInput; i++){
sense_button(i);
// 入力チャンネル毎に入力の有無を確認
};
}
/**
* サブルーチン sense_button():
* ー 入力の有無を確認 ー
*/
void sense_button(const int buttonNumber) {
// スイッチの現状の読み込み
int reading = digitalRead(buttonPin[buttonNumber]);
//
millis()がオーバーフローしたらタイマーをリセットします
if (lastDebounceTime[buttonNumber] > millis()) {
// タイマーのリセット
lastDebounceTime[buttonNumber] = millis();
}
//
以下はスイッチの現状(reading)を監視して、信号がノイズか本当の
// 押下かの判定
//
スイッチの現状(reading)が前回状態(lastButtonState)からすぐに
//
変わってしまったらノイズと見なしてタイマーをリセットします
if (reading != lastButtonState[buttonNumber]) {
// タイマーのリセット
lastDebounceTime[buttonNumber] = millis();
}
//
スイッチの現状(reading)が判定基準時間以上前回状態(lastButtonState)
// 変化がない場合はノイズではないと見なします
if ((millis() - lastDebounceTime[buttonNumber]) >
debounceDelay[buttonNumber]) {
//
入力チャンネル毎のボード入力の状態をシリアル通信で送信
if (reading != buttonState[buttonNumber]) {
Serial.print("Input");
Serial.print(buttonNumber);
Serial.print(" now ");
Serial.println(HIGH == reading ? "HIGH" :
"LOW");
buttonState[buttonNumber] = reading;
//
スイッチの今回状態(buttonState)がLOWの場合はスイッチ
// 押下とみなしてWebhooksを発行する
if (buttonState[buttonNumber] == LOW) {
send_event(buttonNumber);
}
}
}
//
スイッチの前回状態(lastButtonState)に現状(reading)を保存する
lastButtonState[buttonNumber] = reading;
}
/**
* サブルーチン send_event():
* ー
Webhooksにテキスト(イベント名)を発行 ー
*/
void send_event(const int buttonNumber) {
// Webhooksにテキスト発行中はLEDを点灯する
digitalWrite(ledPin, HIGH);
//
Webhooksにテキスト発行中はシリアル通信で接続したホストを送信
Serial.print("Connecting to ");
Serial.println(host);
// TCP接続を行うためにWiFiClientを使用する
WiFiClient client;
const int httpPort = 80;
//
接続が失敗した場合にはその旨をシリアル通信で送信する
if (!client.connect(host, httpPort)) {
Serial.println("Connection failed");
return;
}
// Webhooks発行用のURLを作成する
String url = "/trigger/";
url += event_name[buttonNumber];
url += "/with/key/";
url += privateKey;
Serial.print("Requesting URL: ");
Serial.println(url);
// 指定したURLにHTTP GETリクエストを送信する
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " +
host + "\r\n" +
"Connection:
close\r\n\r\n");
//
サーバーからの全ての返信データをシリアル通信で送信する
//
サーバーからの全ての返信データを受信したら接続を終了(切断)する
while(client.connected()) {
if(client.available()) {
String line =
client.readStringUntil('\r');
Serial.print(line);
} else {
//
サーバーからのデータがまだあるかも知れないので少し待つ
delay(50);
};
}
// すべてが完了したらその旨をシリアル通信で送信する
Serial.println();
Serial.println("closing connection");
client.stop();
// シリアル通信が完了したらLEDを消灯する
digitalWrite(ledPin, LOW);
}
ーーーサンプルプラグラム [おわり]ーーー
※ このプログラムはヘッダファイル『 WiFi.h 』を使用していますが、この『 WiFi.h 』はArduino
IDEに標準で用意されているようです。別途用意する必要はありませんでした。
- 【参考】Webhooksについて(プライベートキーの取得)
Webhooksはアプリではありません。IFTTTのトリガー用にIFTTTが提供しているサービスのひとつです。IFTTTに登録されていないアプリ・サービスをIFTTTのトリガーにするためには必要不可欠なサービスです。
上記のプログラム(スケッチ)でこのサービスを利用するにはプライベートキーの取得が必要になります。以下に紹介します(事前にIFTTTの登録が必要です)。
IFTTTのPC版ページにあるWebhooksのページを開き『Documentation』を選択します。
以上です。
3. 動作確認用のIFTTTアプレット
3-1. 接点0検出時のアプレット
このアプレットは『Webhooksに発行されるテキスト(イベント名)"input0_sensed"受け取ったら、Nature
Remo経由でルームライトをONにする』という内容です。
トリガー(IF)としてはWebhooksを選択し、『Event
Name』には上記プログラム(スケッチ)でWebhooksに発行されるテキスト(イベント名)『input0_sensed』を入力します。
以上で、接点1検出時のアプレットは完了です。
3-2. 接点1検出時のアプレット
以上でIFTTTアプレットの設定は完了で、全ての準備が完了です。
4. 動作確認 - 汎用トリガー(接点多入力版)
以下の動作確認はESP32ボードをPCとUSB接続した状態で行います(シリアル通信を確認するためです)。
4-1. Wi-Fi接続確立時
4-2. 接点信号検出時
- 接点0検出時
発行されたWebhooksのテキスト(今回の場合は"input0_sensed")に応じて④IFTTTのアプレットが実行されます(今回の場合、上記のアプレットの通りにNature
Remo経由でライトが点灯します。)
- 接点1検出時
発行されたWebhooksのテキスト(今回の場合は"input1_sensed")に応じて④IFTTTのアプレットが実行されます(今回の場合、上記のアプレットの通りにNature
Remo経由でライトが消灯します。)
●汎用トリガー(接点多入力版)の仕様書(データシート)
今回作成した汎用トリガーの仕様書を作ってみました。
汎用トリガー(接点多入力版)仕様書(データシート) |
【おまけ情報】
上記回路図および仕様書において、Hアクティブの時のOFF電圧(LOW電圧)を0.2V以下と定義していますが、これは使用しているデジタルトランジスタのデータを杓子定規に引用しているだけで、現実的には1V程度以下でOFFすると思います。
『汎用トリガー(接点多入力版)』の説明は以上になります。
苦手😅なコーディングはこれにて再び封印します😋。
今後はこの汎用トリガーにセンサー等を付けて実際に使ってみますね。
はじめまして。『汎用トリガー(接点多入力版)』の記事、私も似た様なものを作ってみようと思っていたので興味深く拝見しました。大変恐縮ですが、もし可能であれば、『汎用トリガー(接点多入力版)』の回路図の解像度が高いものをご提供願えないでしょうか。部品を集めて作ってみたいと考えております。ご面倒をお掛けしますが宜しくお願いします。
返信削除コメントありがとうございます。
削除回路図をクリックしていただくと解像度の高い回路図が表示されるようにしているのですがご確認いただけましたでしょうか。
(一応、文字もなんとか読める程度の解像度にしたつもりなのですが…。)
お手数おかけしますが今一度ご確認いただけますでしょうか。
いかがでしょうか。まだ画像が荒いでしょうか?
削除