Help us understand the problem. What is going on with this article?

ESP32とLINE Notifyを使ってナースコール的なのを作る

ESP32とLINE Notifyを使ってナースコール的なのを作る

esp32_overview.png

はじめに

トイレなど見守りが必要に急になってしまいました。
そこで、介護が必要になってしまった両親のために作りました。
ナースコールみたいにボタンが押したら近くにいなくてもわかるようになったらいいかなぁっていうところから始めました。

構成

ナースコールに相当する押しボタン、ESP32LINE Notifyを使って自分のLINEに通知します。

overall.png

試作

まず試作として、M5Stackを利用してボタンを押したらLINEに通知をできるようにしました。

試作1:Wi-Fiアクセスポイントに接続する

インターネットに接続するために、まずはWi-Fiアクセスポイント(以下AP)に接続をまずしてみます。
includeに下記の2つを追加しました。

#include <WiFi.h>
#include <WiFiMulti.h>

AP接続するコードを作りました。関数化してあとで流用しやすいようにします。

const char* ssid = "ssid";
const char* password = "password";
void wifiConnect() {
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);  // Wi-Fi接続
  while (WiFi.status() != WL_CONNECTED) {  // Wi-Fi 接続待ち
    delay(100);
    Serial.printf(".");
  }
  Serial.println("\nwifi connect ok");
}

最後にsetup()内に先ほどのAP接続するコードを追加し、起動したらすぐに実行されるようにします。

// The setup() function runs once each time the micro-controller starts
void setup() {
  // init lcd, serial, not init sd card
  M5.begin(true, false, true);

  wifiConnect();

これでM5Stackに書き込みし実行するとAPに接続できました。

試作2:LINE Notifyに通知してみる。

「猫の食生活」を超音波距離センサーでLINEに通知してみた─にゃんてっく☆やせないアイツ【vol5】の記事で使われていたこちらのコードを使わせていただきました。

私の方で通知するメッセージを書き換えたかったので少しだけ改良しました。
includeに下記の3つを追加しました。

#include <ssl_client.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>

通知するコードは次の通りです。引数に文字列を渡せるようにしました。

void send(String message) {
  const char* host = "notify-api.line.me";
  const char* token = "hogehoge_token";
  WiFiClientSecure client;
  Serial.println("Try");
  //LineのAPIサーバに接続
  if (!client.connect(host, 443)) {
    Serial.println("Connection failed");
    return;
  }
  Serial.println("Connected");
  //リクエストを送信
  String query = String("message=") + message;
  String request = String("") +
               "POST /api/notify HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Authorization: Bearer " + token + "\r\n" +
               "Content-Length: " + String(query.length()) +  "\r\n" + 
               "Content-Type: application/x-www-form-urlencoded\r\n\r\n" +
                query + "\r\n";
  client.print(request);

  //受信終了まで待つ 
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    Serial.println(line);
    if (line == "\r") {
      break;
    }
  }

  String line = client.readStringUntil('\n');
  Serial.println(line);
}

上記サンプルコードでは、トークンを hogehoge_token としていますが、実際はLine Notifyページにてトークンを発行した文字列に置き換えてください。

通知するコードは出来上がったのでloop()内でボタン押下をチェックして通知してみることにしました。

M5Stackサンプルスケッチ(BASIC>Button)をベースに下記のように書き換えました。(書き換えた場所のみ記載してあります。)

// Add the main program code into the continuous loop() function
void loop() {
  M5.update();

  // if want use Releasefor; suggest use Release in press event
  if (M5.BtnA.wasReleased()) {
    M5.Lcd.print('A');
    send("A Button");
  } else if (M5.BtnB.wasReleased()) {
    M5.Lcd.print('B');
    send("B Button");
  } else if (M5.BtnC.wasReleased()) {
    M5.Lcd.print('C');
    send("C Button");
                ︙

これをM5Stackに書き込み実行すると各ボタンを押すとLINEに通知されました。

実際に作る

ESP8266で作ろとしましたが、どうしても同じように作っても通知できませんでした。(ボタンを数個しかつけないのでこれで十分なのですが・・・)
ということで、M5Stackと同じESP32を使うことにしました。

プルアップ配線

ボタンなどのスイッチのON/OFFの状態をマイコンで取得するにはプルアップ配線をしてあげる必要があります。

google検索してみたら意外と知られていない?INPUT_PULLUP | スイッチサイエンス マガジンを記事を見つけました。

記事中に下記のように記載されていました。

INPUTキーワードの代わりにINPUT_PULLUPキーワードを使ってみましょう。このキーワードを使うと、そのピンがINPUTモードになると共に、マイコンチップ内部のプルアップ抵抗が有効になります
(意外と知られていない?INPUT_PULLUP | スイッチサイエンス マガジンより引用)

今回はこちらを活用したいと思います。
なのでスイッチの一方をGNDへ、もう一方をGPIOに接続してあげます。
秋月電子で購入したESP32-DevKitC ESP-WROOM-32開発ボードを使い、GPIO12,14,27を使いました。

まずは、setup()INPUT_PULLUP を指定します。
今回は、GPIO12,14,27にスイッチを配線します。

#define SWITCH1 12
#define SWITCH2 14
#define SWITCH3 27

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  Serial.println("setup start");
  pinMode(SWITCH1, INPUT_PULLUP);
  pinMode(SWITCH2, INPUT_PULLUP);
  pinMode(SWITCH3, INPUT_PULLUP);

  wifiConnect();
}

ボタン検出とLINEへの通知

loop()内で、ボタンの押下状態を取得し、押下されていればLINEに通知します。

void loop() {
  // put your main code here, to run repeatedly:
  if (digitalRead(SWITCH1) == LOW) {
    send("白色ボタン");
  } else if (digitalRead(SWITCH2) == LOW) {
    send("黄色ボタン");
  } else if (digitalRead(SWITCH3) == LOW) {
    send("呼び出しボタン");
  }
}

実行してみると狙い通り通知されました。

Line_Timeline.png

最後に

今回は、スイッチに エルパ にぎり押ボタンスイッチ を使いました。
他にも押しボタンスイッチをつけました。

実機の写真

TAKACHI TW5-3-9にいれましたが、もう少し大きい方がいいと思いました。

esp32_top.png
esp32_back.png

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした