Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8899

Arduino×Discordでお手軽IoTを実現してみた話

$
0
0

ドアセンサーを作ってみる

 自室のドアが開閉した際にスマホ/PCで通知を受け取れたら面白いのでは、と思い作ってみました。

今回使うあれそれ

【必須】
・Arduino(要Wi-Fiモジュール)
・Discordアカウント
・リードスイッチ

【任意】
・C#でHTTPサーバーを用意できる((根気||知識)&&サーバー機)



 ログの保存/閲覧のためにわざわざ何かこしらえるのは面倒なので、既存のチャットツールへBotに投稿させその履歴をログとします。SlackやLINEなんかもBotがあるらしいんですが今回はDiscordで実装します。

 HTTPサーバーはArduinoとDiscordの仲介を担います。Arduinoから直接Discordへ投げてもいいんですが、後々の拡張性を考えて間に自前サーバーを挟んでます。

簡略図

2019-11-14_15h17_53.png

実装

Arduino

 今回はWi-FiモジュールとArduino互換機が合体した「ESP-12E」を使いました。ESP8266が搭載されています。
 画像ではUNOになってますがそのあたりは心の目で見てください。

2019-11-14_21h36_28.png
 スイッチがアナログピンに繋がっているのは完全に気まぐれです。特にこれといった理由はありません。それからESP-12Eはボード上に書かれた番号とGPIOの番号が一致しないので使う場合はそのあたり気を付けましょう。

ESP.ino
#include <ESP8266WiFi.h>
#include <Switches.h>
boolisOpen=true;// Wi-Fi(5GHzには非対応)constchar*ssid="SSID";constchar*password="パスワード";// Serverconstchar*host="192.168.0.16";//サーバー機のローカルIPconstinthttpPort=80;constchar*path="/Hoge";WiFiClientclient;//インジケータLED(フルカラー)用のピンを指定intpinR=5;intpinG=4;voidsetup(){pinMode(pinR,OUTPUT);//D1ピンpinMode(pinG,OUTPUT);//D2ピンSerial.begin(115200);WIFIconnecting();}voidWIFIconnecting(){// WIFI_AP, WIFI_STA, WIFI_AP_STA or WIFI_OFFWiFi.mode(WIFI_STA);WiFi.begin(ssid,password);while(WiFi.status()!=WL_CONNECTED){delay(500);Serial.print(".");}Serial.println("");Serial.println("WiFiに接続しました。");Serial.print("IPアドレス: ");Serial.println(WiFi.localIP());Serial.print("ゲートウェイ: ");Serial.println(WiFi.gatewayIP());Serial.print("サブネットマスク: ");Serial.println(WiFi.subnetMask());}voidloop(){intval=analogRead(0);boolcurrent=val==1024?false:true;if(isOpen!=current){Serial.println(!isOpen);isOpen=!isOpen;post();}switch(isOpen){//インジケータ用LEDの点灯。カソードコモン/アノードコモンで適宜書き換えcasetrue:digitalWrite(pinR,LOW);digitalWrite(pinG,HIGH);Serial.println("OPEN");break;casefalse:digitalWrite(pinR,HIGH);digitalWrite(pinG,LOW);Serial.println("CLOSE");}delay(200);}voidpost(){path=isOpen?"/open":"/close";if(true){Serial.println("送信中");if(!client.connect(host,httpPort)){Serial.println("サーバーへのアクセスに失敗しました。");return;}inthttpcode=client.print(String("POST ")+path+" HTTP/1.1\r\n"+"Host: "+host+"\r\n"+"Content-Length:"+"0"+"\r\n"+"Connection: close\r\n\r\n"+"piyo");Serial.println(httpcode);unsignedlongtimeout=millis();while(client.available()==0){if(millis()-timeout>10000){Serial.println(">>> タイムアウトしました。");return;}}Serial.println("送信成功");//    while (client.available()) {//      //char c = client.read();//      //Serial.print("OK");//    }Serial.println("");}}

 ググって出て来たコードを切り貼りして書き足したものです。

 フルカラーLED楽しいです。



最終的にはこんな感じで取り付けます。
2019-11-14_23h01_04.png

Discord

 こちらの記事を参考にウェブフック用のURLを取得してください。POSTリクエストでJSON投げるだけでBotがテキストチャンネルにメッセージを投稿してくれるようになります。
 DiscordにWebhookでいろいろ投稿する

 
 

HTTPサーバー

 上記で取得したURLを使います。postToDiscord()メソッド内にコピペしましょう。

Program.cs
usingSystem;usingSystem.IO;usingSystem.Net;usingSystem.Net.Http;usingSystem.Text;classProgram{staticasyncSystem.Threading.Tasks.TaskMain(string[]args){try{HttpListenerlistener=newHttpListener();listener.Prefixes.Add("http://192.168.0.16:80/");listener.Start();while(true){HttpListenerContextcontext=listener.GetContext();HttpListenerRequestrequest=context.Request;HttpListenerResponseres=context.Response;Console.WriteLine(request.RawUrl);awaitpostToDiscord(request.RawUrl);res.StatusCode=200;byte[]content=Encoding.UTF8.GetBytes("HELLO");res.OutputStream.Write(content,0,content.Length);res.Close();}}catch(Exceptionex){Console.WriteLine("Error: "+ex);}}staticasyncSystem.Threading.Tasks.TaskpostToDiscord(stringstr){// POSTする対象のURLstringurl="ウェブフック用URL";// POSTメソッドで渡すパラメータvarjson="{ \"content\" : \"hoge\"}";switch(str){case"/open":json="{ \"content\" : \"OPEN!!\"}";break;case"/close":json="{ \"content\" : \"CLOSE...\"}";break;default:json="{ \"content\" : \"UNKNOWN_MESSAGE\"}";break;}using(varclient=newHttpClient()){varcontent=newStringContent(json,Encoding.UTF8,"application/json");varresponse=awaitclient.PostAsync(url,content);}}}

完成

こんな感じで動いてくれます。
【プロトタイプ】



【完成品】

うまく動かないときのあれこれ

開発環境やプログラムが管理者権限で動いていない

 サーバープログラム起動時にエラーが発生します。

サーバー機のファイアウォールが邪魔している

 サーバーが稼働しているのにリクエストがはじかれる場合はFWの設定を疑いましょう。

ローカルIPが固定されていない

 動いてたのに再起動したら動かなくなったぞ、とかいう場合はたぶんIPの不一致が原因です。

おまけ

 今回VS2019で始めて実行ファイルを生成しようとしたんですがVS2010とかと違って勝手に生えてこないんですね。泣きそうになりながら.exeを探してました。メニューの[ビルド]から発行とやらを選択する必要があるようで。いやぁ知らんかった。

おまけ2

今回のきったねえ配線で最後を飾りたいと思います。お疲れ様でした。


Viewing all articles
Browse latest Browse all 8899

Trending Articles