編集履歴一覧に戻る
isakonのアイコン画像

isakon が 2020年08月21日10時43分53秒 に編集

筆者を明記した

本文の変更

-

elchika運営です!

+

elchika運営のisakonです!

今回はESP8266と圧力センサーを使って、センサーに圧力が加わっているかどうかを監視し、結果をSlackのメッセージとして投稿するものを作っていこうと思います。 ## 使用したもの - [ESPr® One(Arduino Uno同一形状 ESP-WROOM-02開発ボード)](https://www.switch-science.com/catalog/2620/) - [圧力センサーFSR402](http://akizukidenshi.com/catalog/g/gP-04002/) - [カーボン抵抗 1/4W 10kΩ](http://akizukidenshi.com/catalog/g/gR-25103/) - [Arduino用アクリルベースセット(透明青)](http://akizukidenshi.com/catalog/g/gP-10710/) - [丸ピンIC用ソケット 1×2](http://akizukidenshi.com/catalog/g/gP-00673/) - 熱収縮チューブ - ジャンパー線 Arduino IDEはv1.8.9を使用しています。 ESP8266の後継品としてBluetoothを内蔵しているESP32があるので、そちらを買ったほうが色々なことができます。 ## ESP-WROOM-02にArduino IDEのスケッチを書き込めるように設定する ### 環境設定 ESP-WROOM-02はArduinoマイコンとしても使えるWi-Fiモジュールです。 モジュール自体は400円ほどで買えますが、ブレッドボードなどで扱いやすい2.54mmにピッチ変換されたものも流通しています。 今回はあらかじめArduinoと同一形状の基盤にESP-WROOM-02が搭載されている、スイッチサイエンス様のESPr® Oneを使ってみました。 給電やUSB接続ができるようになっているので、Arduino系のマイコンボードのように使える優れものです。 ただし、動作電圧が $3.3V$ なことには気をつけましょう。 ボードを購入したスイッチサイエンス様で「[ESP-WROOM-02開発ボードをArduino IDEで開発する方法](http://trac.switch-science.com/wiki/esp_dev_arduino_ide)」が公開されているので、参考にしながら設定していきます。 Arduino IDEを起動し、上部のツールバーから「ファイル → 環境設定」を選択します。 環境設定のウインドウが開くので、下部にある「追加のボードマネージャのURL」に`https://arduino.esp8266.com/stable/package_esp8266com_index.json`を追加してOKボタンを押します。 ![環境設定](https://camo.elchika.com/a12d3f04767e8a06841904b1dd86b2874a7fbd03/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30303030303030302d303030302d303030302d303030302d3030303030303030303030302f30393936656533322d316432612d343163352d623761642d616162633231333139326337/) これでボードマネージャにesp8266が出現するようになりました。 ツールバーから「ツール → ボード → ボードマネージャ」を選択します。 ボードマネージャのウインドウが開くので「esp8266」で検索し、出てきたパッケージをインストールします。 ![ボードマネージャ](https://camo.elchika.com/9522733096f1e7c0ece94f28a9bd8fae5020a1a4/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30303030303030302d303030302d303030302d303030302d3030303030303030303030302f35613166396635372d363464662d346534332d616338352d316131626362623232653361/) その後、ツールバーの「ツール → ボード → Generic ESP8266 Module」を選択し、下図のように設定を行いました。 ![ESP-WROOM-02設定](https://camo.elchika.com/16c7941c7cb5d7c8f943bdff4926d4f70760f6fe/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30303030303030302d303030302d303030302d303030302d3030303030303030303030302f63346435376262362d303636342d343636372d393262622d363833656137343637306338/) これでESP-WROOM-02に対してArduino IDEでスケッチを書き込めるようになりました:clap: ### 動作確認 早速動かしてみましょう!試しにESPr® OneのビルトインのLEDをチカチカさせてみます。 ピッチ変換済みモジュールなどを使っている場合は、LEDと抵抗を回路に組み込んでよしなにしてください。 今回は以下のスケッチを書き込みました。 ```arduino:Lチカ #define LED_PIN 14; void setup() { pinMode(LED_PIN, OUTPUT); } void loop() { digitalWrite(LED_PIN, HIGH); delay(1000); digitalWrite(LED_PIN, LOW); delay(1000); } ``` LED1の部分が点滅していればスケッチが書き込めています:bulb: ![ESPr®OneでLチカ](https://camo.elchika.com/dbd602f1b77f65a1a0b478178b37dfa53d18ff3a/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30303030303030302d303030302d303030302d303030302d3030303030303030303030302f35633134643636612d613762632d343564352d383662372d316137326637663132613563/) ## 圧力センサーを使う ### 回路を組む 今回はFSR402という圧力センサーを使います。 圧力センサーは普段は $1 M\Omega$ 程度の抵抗値がありますが、センサー部に指などで圧力をかけると抵抗値が下がっていきます。 購入時に付属してくるデータシートによれば、 $1kg$ の圧力を加えると $1 k\Omega$ 程度の抵抗値になるようです。 圧力センサーですが、このままだとブレッドボードに直接挿したりして使うしかなく、少し扱いづらいです。 そこで、少し取り回しを良くするために丸ピンICソケットとジャンパー線をはんだ付けして、熱圧縮チューブで絶縁したものに圧力センサーを挿して使っています。 以下のような回路を組みました。 ![圧力センサーを組み込んだ回路](https://camo.elchika.com/1ca891c041064e4f484c73cc72579d7ab467b0e8/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30303030303030302d303030302d303030302d303030302d3030303030303030303030302f33646432636464342d356466362d343339382d383535362d653932353362393461373163/) ![](https://camo.elchika.com/cbc423eaf3766cadc0ce304f87b9b6428c7845ce/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30303030303030302d303030302d303030302d303030302d3030303030303030303030302f35643039643637632d333363302d343637352d623537612d396134356563643963383764/) 圧力センサーは $V_{cc}$ に繋ぎ、もう片方は $10 k\Omega$ の抵抗を使ってプルダウンしています。 アナログ入力がA0のみなので、A0ピンと電圧を読み取りたい部分をジャンパー線で繋いでいます。 (ESPr® Oneの場合、入力範囲は $0$ ~ $3.3V$ で、基板上で $0$ ~ $1.0V$ に変換してくれます) オームの法則により電圧降下は抵抗値に比例するので、A0の電圧を $V_{out}$ とすると、 $$ V_{cc} : V_{out} = (R_x + R) : R $$ $$ V_{out} = \frac{ R }{ R_ x + R } V_{cc} $$ $R_x$ が非常に大きい(圧力を加えていないとき)と $V_{out} \fallingdotseq 0$ となり、非常に小さい(十分な圧力を加えているとき)と $V_{out} \fallingdotseq V_{cc}$ と見なせます。 圧力を加えると電流が流れるスイッチのようなイメージです。 ### 動作確認 Arduino IDEのツールバーの[ツール] → [シリアルモニタ]を選択してシリアルモニタを開き、右下の転送速度を115200bpsに合わせます。 その後、次のスケッチを書き込みます。 ```arduino:アナログピンを読み取る void setup() { // ESP8266の転送速度である115200bpsに設定する Serial.begin(115200); } void loop() { int value = analogRead(A0); Serial.println(value); delay(1000); } ``` 圧力センサーを指でつまんだり離したりすると、シリアルモニタに0 ~ 1024(ESP8266だと1023ではないようです)の値が表示されます。 ![圧力センサーを組み込んだ回路](https://camo.elchika.com/8da7c56de48760bfeffb2af586d62e310ab0932d/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30303030303030302d303030302d303030302d303030302d3030303030303030303030302f32326564346234352d373063392d343439362d393733352d326136646331313862363237/) ## Slackにメッセージを送信する センサーと連動してSlackなどのサービスに通知したくなることがあると思います。 ESP8266やESP32などのWi-Fiモジュールを組み込むと、モノの状態をセンサーなどで調べつつ、インターネット経由で状態を送信して知ることができるようになります。 まずはセンサーの回路とつながずに、Slackの特定のチャンネルに通知する方法から考えていきます。 ### Wi-Fiルーターに接続する ESP8266はライブラリを使えば数行を書くだけで簡単にWi-Fiルーターに接続できます。 [ESP8266WiFi library](https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/readme.html#)を読みながら接続の設定をします。 ```arduino:ESP8266でWi-Fiルーターに接続する #include <ESP8266WiFi.h> // 各自設定する static const String WIFI_SSID = "ssid"; static const String WIFI_PASSWORD = "password"; void setupWifi() { WiFi.begin(WIFI_SSID, WIFI_PASSWORD); // 接続に数秒かかるので接続されるまでループする while (WiFi.status() != WL_CONNECTED) { delay(500); } // DHCPによって割り当てられたIPアドレスを出力する Serial.println(WiFi.localIP()); } void setup() { Serial.begin(115200); setupWifi(); } void loop() { // noop } ``` シニアルモニタにIPアドレスが表示されれば接続成功です。 ### SlackのIncoming Webhookの設定 https://slack.com/services/new/incoming-webhook にアクセスします。 投稿したいチャンネルを選択して「Incoming Webhook インテグレーションの追加」を押します。 ![Incoming Webhookの追加](https://camo.elchika.com/7a0d373b7e2bac3417867de3d1c318400e4273a7/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30303030303030302d303030302d303030302d303030302d3030303030303030303030302f61353730626362632d326134612d343366612d626330312d636335353934356337343036/) 遷移先のページにWebhook URLが書いてあるのでこれを後ほど使います。 このURLを知られると他人でもメッセージを送れてしまうので、管理には気をつけましょう。 ![](https://camo.elchika.com/8ad930267cd32aa735a1827a936cb7b8e5951c0e/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30303030303030302d303030302d303030302d303030302d3030303030303030303030302f34653831323039382d666631352d343530362d383265622d633734356631623338636566/) また、このページの下部でSlackで表示される名前やアイコンをカスタマイズできます。 ### メッセージを送信するスケッチを書き込む 先ほど表示されたWebhook URLに対して、POSTリクエストで文字列のJSONを送信すると、指定したチャンネルに投稿されます。 単純なメッセージを送信するだけなら`payload={"text": "送信したいメッセージ"}`の文字列を送信すれば投稿できます。 投稿ごとにユーザー名を変えたければ`username`を、アイコンを変えたければ`icon_emoji`を送信するJSONに含めれば変えられます。 ```arduino:IncomingWebhookでSlackにメッセージを送信する #include <ESP8266WiFi.h> #include <WiFiClientSecure.h> #include <WiFiUdp.h> static const String WIFI_SSID = "ssid"; static const String WIFI_PASSWORD = "password"; static const String SLACK_HOST = "hooks.slack.com"; static const String SLACK_URL = "webhook url"; static const int PORT = 443; // https通信に使うSlackの2021/02/12まで有効な証明書の拇印 // Chromeのアドレスバーの鍵マーク → 証明書 → 詳細タブ → 拇印の行 の値をコピーする static const char* FINGERPRINT = "c10d5349d23ee52ba261d59e6f990d3dfd8bb2b3"; void setupWifi() { WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { delay(500); } Serial.println(WiFi.localIP()); } void submitSlack() { WiFiClientSecure client; client.setFingerprint(FINGERPRINT); if (!client.connect(SLACK_HOST, PORT)) { Serial.println("Slackとの接続に失敗しました"); } String message = "ESP8266からの送信テスト"; String payload = "payload={\"text\": \"" + message + "\"}"; Serial.println(payload.c_str()); String request = "POST " + SLACK_URL + " HTTP/1.1\n" + "Host: " + SLACK_HOST + "\n" + "User-Agent: ESP8266\n" + "Connection: close\n" + "Content-Type: application/x-www-form-urlencoded\n" + "Content-Length: " + payload.length() + "\n\n" + payload; client.println(request); delay(7000); while (client.available()) { // 終端文字まで文字列を読む(終端文字は破棄される) String line = client.readStringUntil('\r'); Serial.print(line); } Serial.println(""); client.stop(); } void setup() { Serial.begin(115200); setupWifi(); submitSlack(); } void loop() { // noop } ``` スケッチを書き込んでしばらくすると、Slackの指定したチャンネルにメッセージが投稿されます。 ![Slackに投稿されたメッセージ](https://camo.elchika.com/d71a47f5b4eb5a59d2ce5a126efece7a4e6cb5ab/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30303030303030302d303030302d303030302d303030302d3030303030303030303030302f38383862643363372d353363312d343065372d386135642d326561656537363464353962/) ## 圧力検知とSlackへの投稿を組み合わせる Wi-Fiルーターがあって給電さえできれば圧力を検知した結果をSlackに送信できるようにします。 圧力センサーを使ったスケッチとSlackにメッセージを送信するスケッチを組み合わせます。 ```arduino:圧力センサーに圧力がかかったときにSlackにメッセージを送信する // 同様の実装なので省略(以下...で既存のコードと同じなので省略の意味) static const int THRESHOLD = 512; boolean isEnabled = false; // ... void submitSlack() { // ... String message = isEnabled ? ":nauseated_face:" : ":face_vomiting:"; // ... } void setup() { Serial.begin(115200); setupWifi(); } void loop() { int value = analogRead(A0); boolean isPressing = value >= THRESHOLD; if (isEnabled != isPressing) { isEnabled = isPressing; submitSlack(); } delay(1000); } ``` これで圧力センサーに一定以上の圧力を加えているときと、圧力を加えるのをやめたときにSlackにメッセージが投稿されます:tada: ![指で圧力をかけてからかけるのをやめたときの投稿](https://camo.elchika.com/322170d31f9746c986193f5d0b5b5260d3c1bbd5/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f30303030303030302d303030302d303030302d303030302d3030303030303030303030302f33353536653830662d373063662d346337322d613831322d633433333537383261636630/)