#はじめに
「M5Stack UnitV2で顔認識して、一定時間その人が現れなかったらお知らせ」を作ります。「一定時間その人が現れなかったら」の部分はenebularを使って、一定時間が任意に遠隔で変更できるようにします。
#M5Stack UnitV2の準備
ラズベリーパイとM5Stack UnitV2をUSBケーブルでつなぐ。
ラズベリーパイのブラウザChromiumを立ち上げて、http://10.254.239.1/
にアクセス。
なお、今回使用する人物写真は、photoACのAI人物素材(ベータ版)で、AIが生み出した実在しないモデルです。
https://www.photo-ac.com/main/genface
この実在しない6人のモデルの顔を、Face Recognition modeで、学習させた。
#Firebaseの準備
田中正吾さんの記事「M5StackとFirebaseを使ってenebularとつないでみよう」
https://blog.enebular.com/firebase/m5stack-firebase-enebular-collaboration/
を参考に Firebaseを設定する。
Google Developerログインを済ませて、Firebaseにアクセス。
コンソールに移動する。
プロジェクトを追加を押してプロジェクト作成。
プロジェクトに名前をつける。
ウェブアプリに Firebase を追加する。
アプリニックネームを入力
この画面の赤四角部分 https://xxxxxxxxxxxxxxxxxxxxxx-default-rtdb.firebaseio.com/
をコピペで保管しておく。
#M5StickCの準備
M5StickCに以下のスケッチを書き込み、M5Stack UnitV2とM5StickCをGroveケーブルでつなぐ。
書き込む前の準備として、必要なライブラリをインストールする。
- Firebaseライブラリをインストール。
https://github.com/ArtronShop/IOXhop_FirebaseESP32
からZIPをダウンロードして、ArduinoIDEにインストールする。
2.ArduinoJsonはバージョン6.18.5が最新である(2021.12.16現在)が、バージョン6では動かないので、バージョン5.13.5をライブラリマネージャーから、インストールする。
3.プログラムをM5StickCに書き込む。
プログラムは以下の3つの記事を参考にした。
Takahiro MITSUOKAさんの記事「M5UnitV2の検出結果をAmbientに送信するメモ」
https://zenn.dev/tmitsuoka0423/articles/15fcd13dc5334365e7ab
田中正吾さんの記事「M5StackとFirebaseを使ってenebularとつないでみよう」
https://blog.enebular.com/firebase/m5stack-firebase-enebular-collaboration/
スラニューさんの記事「M5StickCからFirebase Realtime Databaseに値を書き込んじゃうよ。」
https://slanew.com/news/819
//これはArduinoJsonはVer5を使用する
#include <IOXhop_FirebaseESP32.h>
#include <M5StickC.h>
#include <ArduinoJson.h>
#include <WiFi.h>
#include <Ambient.h>
WiFiClient client;
const char *ssid = "xxxxxxx";
const char *password = "xxxxxxxxxxxxx";
Ambient ambient;
unsigned int channelId = xxxxx; // CHANNEL ID
const char *writeKey = "xxxxxxxxxxxxx";
#define FIREBASE_DATABASE_URL "xxxxxxxxxxxxxxxxxxxx-default-rtdb.firebaseio.com"
int lastSendTime = 0;
//DynamicJsonDocument doc(1024);
DynamicJsonBuffer jb;
float x;
void setup(){
M5.begin();
Serial.begin(115200);
Serial2.begin(115200, SERIAL_8N1, 33, 32);
M5.Lcd.setRotation(3);
M5.Lcd.fillScreen(BLACK);
// connect to wifi.
WiFi.begin(ssid, password);
Serial.print("connecting");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println();
// WiFi Connected
Serial.println("\nWiFi Connected.");
Serial.println(WiFi.localIP());
M5.Lcd.println("WiFi Connected.");
M5.Lcd.println("");
Firebase.begin(FIREBASE_DATABASE_URL);
Firebase.stream("/M5Stack/message", [](FirebaseStream stream) {
String eventType = stream.getEvent();
eventType.toLowerCase();
Serial.print("event: ");
Serial.println(eventType);
if (eventType == "put") {
String path = stream.getPath();
String data = stream.getDataString();
Serial.print("data: ");
Serial.println(stream.getDataString());
}
});
Firebase.setString("/M5Stack/message", "start");
ambient.begin(channelId, writeKey, &client);
}
void loop()
{
if (Serial2.available())
{
String receiveString = Serial2.readStringUntil('\n');
// JSONをデシリアライズ
//deserializeJson(doc, receiveString);
JsonObject& obj = jb.parseObject(receiveString);
if (!obj.success()) {
Serial.println("parseObject() failed");
return;
}
// こんな感じで中身を取り出せる
String name = obj["face"][0]["name"];
Serial.println(name);
if(name == "sato"){
x=1;
M5.Lcd.fillRect(0,20,160,60,BLACK);
M5.Lcd.setCursor(20,20);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.print("sato");
// Firebaseへ送信
Firebase.setInt("/M5Stick/personID", 1);
}
else if (name == "suzuki"){
x=2;
M5.Lcd.fillRect(0,20,160,60,BLACK);
M5.Lcd.setCursor(20,20);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.print("suzuki");
// Firebaseへ送信
Firebase.setInt("/M5Stick/personID", 2);
}
else if (name == "takahashi"){
x=3;
M5.Lcd.fillRect(0,20,160,60,BLACK);
M5.Lcd.setCursor(20,20);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.print("takahashi");
// Firebaseへ送信
Firebase.setInt("/M5Stick/personID", 3);
}
else if (name == "tanaka"){
x=4;
M5.Lcd.fillRect(0,20,160,60,BLACK);
M5.Lcd.setCursor(20,20);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.print("tanaka");
// Firebaseへ送信
Firebase.setInt("/M5Stick/personID", 4);
}
else if (name == "ito"){
x=5;
M5.Lcd.fillRect(0,20,160,60,BLACK);
M5.Lcd.setCursor(20,20);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.print("ito");
// Firebaseへ送信
Firebase.setInt("/M5Stick/personID", 5);
}
else if (name == "watanabe"){
x=6;
M5.Lcd.fillRect(0,20,160,60,BLACK);
M5.Lcd.setCursor(20,20);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.print("watanabe");
// Firebaseへ送信
Firebase.setInt("//M5Stick/personID", 6);
}
else if (name == "unidentified"){
x=7;
M5.Lcd.fillRect(0,20,160,60,BLACK);
M5.Lcd.setCursor(20,20);
M5.Lcd.setTextSize(1);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.print("unidentified");
// Firebaseへ送信
Firebase.setInt("/M5Stick/personID", 7);
}
delay(2000);
M5.Lcd.fillRect(0,20,160,60,BLACK);
M5.Lcd.setCursor(20,20);
M5.Lcd.setTextSize(1);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.print("no person");
// Firebaseへ送信
Firebase.setInt("/M5Stick/personID", 8); //when no person, send 8
delay(1000);
Serial.println(x);
// 一定間隔でAmbientに送信
if (millis() - lastSendTime > 60000)
{
ambient.begin(channelId, writeKey, &client);
ambient.set(1, x);
//ambient.send();
lastSendTime = millis();
}
}
}
#人物認識結果を確認
M5Stack UnitV2とM5StickCをGroveケーブルで接続して、M5StackUnitV2のカメラで人物写真を写す。
その認識結果を以下の3か所で確認する。
#enebularを準備する。
Firebaseのデータをenebularで取得します。
「Firebaseにデータ連携できるノード」https://blog.enebular.com/nodes/firebase-nodes/
を読んで、node-red-contrib-firebase-data を使います。
以下にアクセス(プロジェクト名を入れる)。
https://console.firebase.google.com/u/0/project/`[your-project]`/settings/serviceaccounts/adminsdk
左上のプロジェクトの概要の右にある歯車ボタンを押して、プロジェクトの設定→サービスアカウントタブでもこの画面に行けます。
新しい秘密鍵の生成ボタンを押す。
!
生成してダウンロードした秘密キーの中で、 "private_key", "client_email" の部分を次のAdd Firebaseノード内で入力します。
enebularのパレットの管理から node-red-contrib-firebase-data という名前のノードを追加する。
node-red-contrib-line-messaging-api ノードも追加する。
一定時間現れないとお知らせ部分は、triggerノードとswitchノードを組み合わせる。
フローの初めはinjectノードで2秒ごとにAdd Firebaseノードを刺激
Add Firebaseノードの中のFirebaseCertificateノード
上述のFirebaseで生成してダウンロードした秘密キーの中で、 "private_key", "client_email" の部分をコピペする。
triggerノード
ここで一定時間を指定する。この図では、48時間と設定している。
これで、satoさんが初回現れてから48時間現れないと、satoさんが現れないというメッセージがpayloadとLINE Notifyノードに流れる。
#動作確認
satoさんとsuzukiさんが一定時間現れないと、LINE Notifyにお知らせがきた。
これで、一定時間現れなかったらLINEにお知らせ、さらに、enebularを使って一定時間を任意に遠隔で変更できて、ガッツポーズ。