概要
- ドアの施開錠履歴をできるだけ安価な仕組みで取得したい。
- 既存のものではサムターンに被せるタイプのスマートロックがあるが、高価である。
- 例えば高齢者の安否確認にスマートロックは必要ない。施開錠履歴のみあれば十分ではないか。
用意するもの
- M5StickC
- Arduino IDEが動くPC (Mac/Windows)
環境構築
(1)Arduino IDEをインストール
https://www.arduino.cc/en/main/software
(2)M5StickC関連のライブラリをインストール
スケッチ→ライブラリをインクルード→ライブラリを管理
M5StickCを検索
プログラミング
- M5StickCの6軸センサーを使い、どの軸が上を向いているかを検出する
- ディスプレイにはOPEN/CLOSEと表示する。
- Wifi経由でAmbientに送信し可視化する(1:OPEN 0:CLOSE)
lockstate.ino
#include <M5StickC.h>
#include "Ambient.h"
#define POSE_P_X 0
#define POSE_M_X 1
#define POSE_P_Y 2
#define POSE_M_Y 3
#define POSE_P_Z 4
#define POSE_M_Z 5
uint8_t pose = POSE_P_X;
uint8_t prev_pose = POSE_P_X;
WiFiClient client;
Ambient ambient;
const char* ssid = "xxxxxxxxxxxxxx";
const char* password = "xxxxxxxxxxxx";
unsigned int channelId = "xxxxx"; // AmbientのチャネルID
const char* writeKey = "xxxxxxxxxxxxxxxx"; // ライトキー
// 加速度
float accX_g = 0;
float accY_g = 0;
float accZ_g = 0;
float accX_mpss = 0;
float accY_mpss = 0;
float accZ_mpss = 0;
// 角速度
float gyroX_dps = 0;
float gyroY_dps = 0;
float gyroZ_dps = 0;
boolean near_p_g(float value){
if(8.0 < value && value < 12.0){
return true;
}else{
return false;
}
}
boolean near_m_g(float value){
if(-12.0 < value && value < -8.0){
return true;
}else{
return false;
}
}
boolean near_zero(float value){
if(-2.0 < value && value < 2.0){
return true;
}else{
return false;
}
}
void setup() {
// Initialize the M5StickC object
M5.begin();
M5.MPU6886.Init();
M5.Lcd.setRotation(1);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextSize(1);
WiFi.begin(ssid, password); // Wi-Fi APに接続
while (WiFi.status() != WL_CONNECTED) { // Wi-Fi AP接続待ち
delay(500);
Serial.print(".");
}
Serial.print("WiFi connected\r\nIP address: ");
Serial.println(WiFi.localIP());
ambient.begin(channelId, writeKey, &client); // チャネルIDとライトキーを指定してAmbientの初期化
}
void loop() {
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextSize(3);
// 加速度取得
M5.MPU6886.getAccelData(&accX_g,&accY_g,&accZ_g);
accX_mpss = accX_g * 9.8;
accY_mpss = accY_g * 9.8;
accZ_mpss = accZ_g * 9.8;
// 角速度取得
M5.MPU6886.getGyroData(&gyroX_dps,&gyroY_dps,&gyroZ_dps);
if(near_zero(accX_mpss) && near_p_g(accY_mpss) && near_zero(accZ_mpss)){
pose = POSE_P_Y;
}else if(near_p_g(accX_mpss) && near_zero(accY_mpss) && near_zero(accZ_mpss)){
pose = POSE_P_X;
}else if(near_zero(accX_mpss) && near_zero(accY_mpss) && near_p_g(accZ_mpss)){
pose = POSE_P_Z;
}else if(near_zero(accX_mpss) && near_m_g(accY_mpss) && near_zero(accZ_mpss)){
pose = POSE_M_Y;
}else if(near_m_g(accX_mpss) && near_zero(accY_mpss) && near_zero(accZ_mpss)){
pose = POSE_M_X;
}else if(near_zero(accX_mpss) && near_zero(accY_mpss) && near_m_g(accZ_mpss)){
pose = POSE_M_Z;
}
// 姿勢に変化があった場合にのみ描画する
if(prev_pose != pose){
M5.Lcd.fillScreen(BLACK);
switch(pose){
case POSE_M_X:
M5.Lcd.setRotation(3);
M5.Lcd.setCursor(56, 16);
M5.Lcd.print("CLOSE");
// 施錠の情報をAmbientに送信する
ambient.set(1, 0);
ambient.send();
delay(500);
break;
case POSE_P_Y:
M5.Lcd.setRotation(3);
M5.Lcd.setCursor(56, 16);
M5.Lcd.print("OPEN");
// 解錠の情報をAmbientに送信する
ambient.set(1, 1);
ambient.send();
delay(500);
break;
default:
;
}
}
prev_pose = pose;
delay(100);
}
注意点
- サムターンの操作性を損なわないような取り付け方を工夫する必要がある。
- 何らかの電源(モバイルバッテリー等)で給電しておく必要がある。
その他
- 画面表示の明るさ、表示時間を調整すれば節電できる。
- アプリを構築しAPIに送信するようにすれば複数箇所の対応、アラートメールを送信する等機能を増やせる。
- ドアの施解錠以外の用途にも応用できるかもしれない。