やもりの技術ブログ

日々の生活で行った技術的な活動や日頃感じたことを書きます。

UberEats到着通知BOX~M5stickCとToFセンサから検知しLINEで知らせる~

こんにちは、ヤモリテックです。

(一刻も早く)あたたかいご飯が食べたかったので、UberEats到着通知BOXを作りました。具体的には、UberEats向けに、ご飯の到着(荷台に置かれたこと)をM5stickCとToFセンサから検知してLINEで知らせるシステムを作りました。

完成版

 

動機

私はUberEatsを利用しています。UberEatsはご飯の持ち帰り代行サービスですが、それゆえに受け取る頃にはご飯が冷たくなる傾向にあります。もちろん、配達員の方々はできるだけ早く届けてくださいますし、UberEatsアプリにも【宅配完了通知】機能があります。

それでも「あたたかいご飯が食べたい」時、届いた瞬間にご飯を受けとりたい…!場合に、少し物足りない時間差が生まれるので、家にあったガジェットでその時間差を埋めるシステムを作ってみました。

システム概要

M5stickCとToF、ダンボール、モバイルバッテリを組み合わせて、荷台を作りました。この上に荷物が置かれると、ToFセンサの値をベースに荷物が置かれたことを検知して、WiFiを経由してLINEに通知するようにしました。

システム概要図

荷台の中身

 

実装に関しては、Arduino IEDのサンプルをベースに、以下のサイトを参考にさせていただきました。ありがとうございました。

M5Stack | WiFiを使ってLINE NotifyでLINEに通知を送る | ゆるっとでんしこうさく

M5Stack/M5StickcからのLINE Notify通知を少し改良してみた - Qiita

M5Stack is the innovator of modular IoT development platform.

m5-docs

LINE Notify

(他にも拝見させていただいたのですが、リンクをメモし忘れました。。また見つけたら追記します。)

 

開発環境

MaC OS: Monterey

・M5stickC

・ToF Unit

ダンボール(from ソーセージを買ったときのやつ)

・ガムテープ

ソースコード

機能ごとにソースコードの一部を公開します。基本的には以下の組み合わせで動くようになります。

M5stickCからToFの数値を得る

ほぼサンプルのままです。

// please install vl53l0x lib first (https://github.com/pololu/vl53l0x-arduino)
// lib in Sketch->Includ Library->Library Manager, search for vl53l0x, Author: pololu

#include "M5StickC.h"
#include <Wire.h>
#include <VL53L0X.h>

VL53L0X sensor;
TFT_eSprite img = TFT_eSprite(&M5.Lcd); 

void setup() {
  Serial.begin(115200);
  Wire.begin(0, 26, 100000U); 
  
  M5.begin();

  img.createSprite(160, 80);
  img.fillSprite(BLACK);
  img.setTextColor(WHITE);
  img.setTextSize(2);

  sensor.setTimeout(500);
  if (!sensor.init()) {
    img.setCursor(10, 10);
    img.print("Failed");
    img.pushSprite(0, 0);
    Serial.println("Failed to detect and initialize sensor!");
    while (1) {}
  }
  // Start continuous back-to-back mode (take readings as
  // fast as possible).  To use continuous timed mode
  // instead, provide a desired inter-measurement period in
  // ms (e.g. sensor.startContinuous(100)).
  sensor.startContinuous();
}

void loop() {
  uint16_t distance = sensor.readRangeContinuousMillimeters();
  Serial.print(distance);
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  Serial.println();
  img.fillSprite(BLACK);
  img.setCursor(10, 10);
  img.print(distance);
  img.pushSprite(0, 0);
}

M5stickCからWiFi接続とLINEへ通知

こちらもほぼネットのサンプルのままですが、私の環境では動かなかったので、少し修正しています。sendLineNotifyをloop関数から呼び出します。

// ------------------------------------------------------------
// ライブラリインクルード部 Library include section.
// ------------------------------------------------------------
#include "M5StickC.h"
#include <functional>
#include <WiFi.h>
#include <Update.h>
#include <WiFiUdp.h>
#include <WiFiClientSecure.h>
#include <ssl_client.h>
#include <HTTPClient.h>

// ------------------------------------------------------------
// 定数/変数 定義部 Constant / variable definition section.
// ------------------------------------------------------------ 
const char* ssid = "xxxx"; // 自分のWi-FiルータのSSID 
const char* password = "xxxx"; // 自分のWi-Fiルータのパスワード

// LCD設定
TFT_eSprite img = TFT_eSprite(&M5.Lcd); 

//Line通知
void sendLineNotify() {
  const char* host = "notify-api.line.me";
  const char* token = "xxxx"; //発行したtokenを使う
const char* message = "ウーバーきたよ%f0%9f%8d%9a"; //ごはんの絵文字をURLエンコードしたもの WiFiClientSecure client; // initialized for line notify(これ書かないと動かなかった、Connection failed になる) client.setInsecure(); Serial.println("Try"); //LineのAPIサーバに接続 if (!client.connect(host, 443)) { Serial.println("Connection failed"); return; } Serial.println("Connected"); //リクエストを送信 String query = String("message=") + String(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'); if (line == "\r") { break; } } String line = client.readStringUntil('\n'); Serial.println(line); } // ------------------------------------------------------------ // Setup 関数 Setup function. // ------------------------------------------------------------ void setup() { // M5StickCの初期化と動作設定 Initialization and operation settings of M5StickC. M5.begin(); // 開始 // シリアルコンソールの開始 Start serial console. Serial.begin(115200); delay(500); // Wi-Fi接続 We start by connecting to a WiFi network Serial.println(); // シリアルポート経由でPCのシリアルモニタに出力 Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); // setup img(LCD) img.createSprite(160, 80); img.fillSprite(BLACK); img.setTextColor(WHITE); img.setTextSize(2); // 画面に表示 img.fillSprite(BLACK); img.setCursor(10, 10); img.print("Connecting to "); img.print(ssid); img.pushSprite(0, 0); WiFi.begin(ssid, password); // Wi-Fi接続開始 // Wi-Fi接続の状況を監視(WiFi.statusがWL_CONNECTEDになるまで繰り返し while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } // Wi-Fi接続結果をシリアルモニタへ出力 Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); // 画面に表示 img.fillSprite(BLACK); img.setCursor(0, 10); img.println("WiFi connected"); img.println("IP: "); img.println(WiFi.localIP()); img.pushSprite(0, 0); } void loop() { delay(1000); sendLineNotify(); // 画面に表示 img.fillSprite(BLACK); img.setCursor(0, 10); img.println("WiFi OK!"); img.pushSprite(0, 0); if (WiFi.status() == WL_CONNECTED) { //Wi-Fiからの切断 Serial.println("Disconnect from WiFi"); WiFi.disconnect(); // Wi-Fi接続の状況を監視(WiFi.statusがWL_DISCONNECTEDになるまで繰り返し while (WiFi.status() !=WL_DISCONNECTED) { delay(500); Serial.print("."); } // Wi-Fi切断結果をシリアルモニタへ出力 Serial.println(""); Serial.println("WiFi disconnected"); img.fillSprite(BLACK); img.setCursor(40, 10); img.println("WiFi disconnected"); img.pushSprite(0, 0); } }

システムの動作検証

上から見ると穴が空いていますが、ToFセンサの場所です。この上に冒頭のようにものが置かれるとLINEに通知が来ます。

荷台を上から見たとき

LINEの内容

まだテスト動作の確認のみなので、実際にUberEatsを頼んでみようとう思います!はたして、あたたかいご飯が食べられるのか。。

<後日検証結果を追記予定>

 

利用ガジェットの紹介リンク

M5StickC ToF Hat(VL53L0X搭載)

M5StickC ToF Hat(VL53L0X搭載)

  • スイッチサイエンス
Amazon