※当サイトはアフィリエイト広告(Amazonアソシエイト含む)を掲載しています。

おばあちゃんが心配|見守り装置を自作しよう①

Electronics

こんにちはAsoBotです。
実家で一人暮らしのおばあちゃんが心配。どうすればいいかな?

そうだ!!見守り装置を作ろう!!
ということで自作見守り装置を作っていきます。

装置の構想を考える

最後の受信はやっぱりスマホがいい。さらに言うなら使い慣れたLINEがいい。
あとは赤外線センサーからスマホまでをどうやって繋いでいくかということを考えると次のような構成が扱いやすいと思います。

  • マイコンはWifiが扱えてコストもお手軽なXIAO ESP32-C6
  • センサーは検出範囲の広い赤外線センサー
  • LINEへの発信は無料で使えるLINE Messeging API
  • センサーからLINEへはGAS (Google Apps Script)で中継

これで簡単無料で便利な見守りシステムが構成できます。

部品リスト

使う部品は少なく こちら

部品名品番特徴
マイコンSeeed Studio
XIAO ESP32C6
親指サイズ
2.4 GHz Wi-Fi 6
BLE 5.0
ZigBee対応
赤外線センサーSR602検知範囲が広い
(最大5m程度)
電圧: 3.3V〜15V

今回はデバッグ用に次の拡張ボードを使用します。

XIAO 用拡張ボードベース

XIAO 用拡張ボードベース | Seeed Studio Wiki
Seeed Studio XIAO 拡張ボード

手順① WiFiに接続する&データを送信(ESP32C6プログラム)

まずは、センサーが反応した時に、ESP32C6からデータを発信します。
発信したデータはWiFiを経由してスプレッドシートに書き込まれます。

事前に準備が必要なものは下の2つ

  • WiFiのネットワーク名のSSIDPassword ※WiFiの機器に記載があります
  • スプレッドシートを作成するためのGAS(Google Apps Script)を利用したウェブアプリURL

これらを含めたEPS32C6のプログラムは以下です。
Arduino IDEで書き込みます。

#include <WiFi.h>
#include <HTTPClient.h>
#include <time.h>
#include <U8g2lib.h>
#include <Wire.h>

// Wi-Fi / GAS設定
const char* ssid = "(WiFiのSSIDを入力してください)";
const char* password = "(WiFiのパスワードを入力してください)";
const char* gas_url = "(GASで設定したウェブアプリURL)";

// ピン設定
const int SENSOR_PIN = 1; // Expansion BoardのD1

// OLED設定 (Expansion Board搭載のもの)
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

// 時刻設定
const char* ntpServer = "ntp.nict.jp";
const long  gmtOffset_sec = 9 * 3600;

void setup() {
  Serial.begin(115200);
  pinMode(SENSOR_PIN, INPUT);

  // OLED開始
  u8g2.begin();

  // Wi-Fi接続
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_6x10_tf);
  u8g2.drawStr(0, 10, "Connecting WiFi...");
  u8g2.sendBuffer();

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  // 時刻同期
  configTime(gmtOffset_sec, 0, ntpServer);
}

void loop() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Failed to obtain time");
    return;
  }

  // --- 液晶表示処理 ---
  char time_str[20];
  sprintf(time_str, "%02d:%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
  
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB14_tr);
  u8g2.drawStr(0, 20, "Current Time:");
  u8g2.drawStr(10, 45, time_str);
  u8g2.setFont(u8g2_font_6x10_tf);
  u8g2.drawStr(0, 60, "Sensor: Waiting...");
  u8g2.sendBuffer();

  // --- デバッグ用:即時発出ロジック ---
  // 本番では if (timeinfo.tm_hour >= 4 && !hasDetectedToday) などの条件を加える
  if (digitalRead(SENSOR_PIN) == HIGH) {
    u8g2.drawStr(0, 60, "Sensor: DETECTED!");
    u8g2.sendBuffer();

    char msg_time[20];
    sprintf(msg_time, "%02d時%02d分", timeinfo.tm_hour, timeinfo.tm_min);
    String message = String(msg_time) + " 活動を開始しました(Debug)";
    
    Serial.println(message);
    sendToGAS(message);

    // デバッグ中の連続送信を防ぐため、検知後は5秒待機
    delay(5000); 
  }

  delay(500);
}

void sendToGAS(String msg) {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin(gas_url);
    http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
    http.addHeader("Content-Type", "application/json");

    String jsonPayload = "{\"message\":\"" + msg + "\"}";
    int httpResponseCode = http.POST(jsonPayload);
    
    if (httpResponseCode > 0) {
      Serial.println("Success: " + http.getString());
    } else {
      Serial.println("Error: " + String(httpResponseCode));
    }
    http.end();
  }
}

手順② GASでデータを受信(スプレッドシートプログラム)

GAS(ガス)は、Googleが提供する「Google Apps Script」の略で、スプレッドシート、Gmail、カレンダーなどGoogleの各種サービスを自動化・連携させることができます。

プログラムは「拡張機能」→「Apps Script」で書き込みます。

function doPost(e) {
  // 受信データの解析
  var jsonString = e.postData.getDataAsString();
  var data = JSON.parse(jsonString);
  var message = data.message;
  
  // 1. スプレッドシートに記録(任意)
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[0];
  sheet.appendRow([new Date(), message]);
  
  // 2. LINEに通知(LINE Notifyを使う場合)
  // sendLineNotify(message); 
  
  // マイコンへのレスポンス
  return ContentService.createTextOutput(
    JSON.stringify({"result": "success", "received": message})
  ).setMimeType(ContentService.MimeType.JSON);
}

// LINE通知用の関数(使いたい場合はトークンを取得して有効化してください)
function sendLineNotify(message) {
  var token = "(あなたのLINE_NOTIFY_TOKEN)"; 
  var options = {
    "method"  : "post",
    "payload" : {"message": message},
    "headers" : {"Authorization": "Bearer " + token}
  };

どうでしたか?物体検出してスプレッドシートの更新表示まで出来ましたか?
途中の説明は省略しているので、別の機会に書き加えていきたいと思います。

ここまで来たら次はデータをLINEで送っていきます。
まだまだ先は長いので、今日はここまで、次回に続く。。。