「お帰りなさい!」家族の帰りを知らせる おぶ兄(obni(z))さん
Obniz IoTコンテスト2021が只今開催中で、沢山の方が参加されているようです。私もobnizという面白いガジェットに触れて、少々寝不足気味です。
Obniz OSは、よく考えられていて、公式サイトの例のように簡単にリモート操作できるようなシステムができてしまいます。
これには正直ビックリ!
ただ、ちょっと凝ったことをしようとすると、最低でもJava Scriptが必要なようです。
JavaScript初心者な私が、小手調べに、今、困っていることを解決するためObnizを活用したシステムを頑張って製作してみましたので、ご紹介します。
デモ動画
材料
部品 | 個数 | 値段 | 購入先 |
---|---|---|---|
obniz Board 1Y | 1 | ¥6,930 | スイッチサイエンスなど |
FeliCa リーダー・ライター RC-S620S | 1 | ¥3,666 | スイッチサイエンス |
FeliCa RC-S620S/RC-S730 ピッチ変換基板のセット(フラットケーブル付き) | 1 | ¥550 | スイッチサイエンス |
Arduino MEGA 2560 R3 | 1 | ¥5,937 | スイッチサイエンス |
※上記の他、基板同士を接続するリード線とNode.jsのプログラムを動かすためのPC(Ubuntu 20.04.1 LTS)、Obniz Board 1Y用の電源コード(USB-C)、Arduino MEGA用の電源コード(USB B若しくは、ACアダプタ)、インターネットに接続するためのWifiルーター(ネット環境)が必要です。
配線図
RC-S620/Sとピッチ変換基板を繋ぐフラットケーブルは、挿しづらく抜けやすいので、しっかりしたピンセットや先の細いプライヤーでないと差し込めません。
また、向きは、フラットケーブルの青い板が上を向くように差し込みます。くれぐれもご注意ください。
ソースコード
本当は、obniz Board 1Yに直接接続したかったのですが、何分Java ScriptやNode.jsは今回初チャレンジなので、使ったことのあるArduinoでFelicaをデコードして、シリアルでobnizへ転送するようにしました。
Arduino向けRC-S620/S制御ライブラリをダウンロードして、Arduino IDE上でライブラリをインクルードしてください。
プログラムを書き込む際、RC-S620/Sが繋がっていると、失敗する可能性が高いので、外しておくとよいです。
今回は、シリアルポートが複数あるArduino MEGAを使いましたが、他のArduinoでは、RC-S620/S制御ライブラリがそのままでは動かない可能性がありますので、ご注意ください(試していませんが、MEGAの互換機なら問題ないでしょう)。
FelicaのIDをデコードしてobnizにシリアル転送する例(ArduinoIDE用)
//適当なファイル名(***.ino)で保存してね!
//[Arduino向けRC-S620/S制御ライブラリ] http://blog.felicalauncher.com/?p=2677 必須
//上記ライブラリ中RCS620S.cppに記述されている「#include "Wprogram.h"」→「#include "Arduino.h"」に書き換える必要があります。2021.4.14追記
#include <RCS620S.h>
#include <inttypes.h>
#include <string.h>
#define COMMAND_TIMEOUT 400
#define POLLING_INTERVAL 2000
#define LED_PIN 13
RCS620S rcs620s;
int waitCardReleased = 0;
void setup() {
int ret;
pinMode(LED_PIN, OUTPUT); // for Polling Status
digitalWrite(LED_PIN, LOW);
Serial.begin(115200); // シリアル初期化 RFID通信用
Serial1.begin(115200); // シリアル初期化 obniz通信用
// initialize RC-S620/S
ret = rcs620s.initDevice();
while (!ret) {} // blocking
}
void loop() {
int ret, i;
// Polling
digitalWrite(LED_PIN, HIGH);
rcs620s.timeout = COMMAND_TIMEOUT;
ret = rcs620s.polling();
if (!ret){
if(waitCardReleased){
waitCardReleased= 0;
}
} else if(!waitCardReleased) {
for(i = 0; i < 7; i++)
{
if(rcs620s.idm[i] / 0x10 == 0) Serial1.print(0);
Serial1.print(rcs620s.idm[i], HEX);
}
if(rcs620s.idm[7] / 0x10 == 0) Serial1.print(0);
Serial1.print(rcs620s.idm[7], HEX);
}
rcs620s.rfOff();
digitalWrite(LED_PIN, LOW);
delay(POLLING_INTERVAL);
}
Obniz Board 1Yを動作させるのに、Node.jsを使っています(下記)。
スマートに運用したくて、Java Scriptでもチャレンジしたのですが、LINE Notifyへのやりとりがうまくいかず、仕方なく、サーバー寄りのNode.jsにしました。
今回のコンテストは、あくまでObnizが主役なので、ある程度Obnizにも仕事をさせつつ、他の機器を使ってObnizを引き立てるということを考えながら実験した所、今の落としどころとなりました。
今回の目玉の1つであるLINE Notifyを使うには、アクセストークンの取得が必要です。こちらのサイトに詳しく書かれておりますので、ご参照ください。
単にLINE Notifyを送るだけでは、公式サイトの真似になってしまいますので、RFIDだけでなく、「パパお帰りなさい」と喋らせることにしました。
私は、Linux(Ubuntu)でOpen JTalkをインストールし、使っています。
Node.jsでOpen JTalkを動かすモジュールがあるようなのですが、うまくいかなかったので、仕方なく、Node.js上でシェルコマンドを送ることで強引に喋らせるという荒業を使いました。
Open JTalkの設定方法については、こちらで詳しく解説されていますよ。
obnizからLINE_Notifyを送る
//適当なファイル名(***.js)で保存してね!
const request = require('request'),
Obniz = require('obniz'),
slp= require('sleep'),
execSync = require('child_process').execSync;
const TOKEN = '自分のトークンをここに記載';
//パパ用 LINEステッカー付
const OPTIONS1 = {
url:'https://notify-api.line.me/api/notify',
method: 'POST',
headers: {
'Content-Type' : 'application/x-www-form-urlencoded',
Authorization : 'Bearer ' + TOKEN
},
json: true,
form: {
message: "パパが帰ってきたよ",
'stickerPackageId': 11539,
'stickerId': 52114130
}
}
//ママ用 LINEステッカー付
const OPTIONS2 = {
url:'https://notify-api.line.me/api/notify',
method: 'POST',
headers: {
'Content-Type' : 'application/x-www-form-urlencoded',
Authorization : 'Bearer ' + TOKEN
},
json: true,
form: {
message: "ママが帰ってきたよ",
'stickerPackageId': 11539,
'stickerId': 52114118
}
}
//子供用を作る場合は、上記のパパ用、若しくはママ用の箇所をコピペし、const OPTION3…などの連番にすると、後で分かりやすくていいかも。
function textCount(haystack,needle){
//ID判定用
if (needle.length == 0){
return haystack.length + 1;
} else {
return haystack.split(needle).length - 1;
}
}
let obniz = new Obniz('OBNIZ_ID_HERE');
obniz.onconnect = async function(){
//Obnizと接続したら、シリアルの設定を行う。
obniz.io2.output(false); //ここをアースへ落とすことにして、Obniz Boardでも使用できるようにしている。
uart = obniz.getFreeUart();
uart.start({rx:0 ,tx:1 ,baud:115200});
obniz.onloop = async function() {
if (uart.isDataExists()){
//UARTの受信が完了したら実行
Rcv = uart.readText();
console.log(Rcv); //スマホのナンバーをターミナル上に表示
if (textCount(Rcv, '自分のナンバー') == 1 ){
//パパID判定用
request(OPTIONS1, function(error, response, body) {
console.log(body); //Line Notifyを送った際の返り値を表示する
});
console.log('パパ');
//↓女性の声
stdout = execSync('echo パパ、おかえりなさい | open_jtalk -x /var/lib/mecab/dic/open-jtalk/naist-jdic -m /usr/share/hts-voice/mei/mei_normal.htsvoice -r 1.0 -ow test.wav');
slp.msleep(3000);
stdout = execSync('aplay test.wav');
obniz.display.clear();
obniz.display.print(Rcv);
obniz.wait(30000);
obniz.display.clear();
} else {
if(textCount(Rcv, '自分のナンバー') == 1 ){
//ママID判定用
request(OPTIONS2, function(error, response, body) {
console.log(body); //Line Notifyを送った際の返り値を表示する
});
console.log('ママ');
//↓男性の声
stdout = execSync('echo ママ、おかえりなさい | open_jtalk -x /var/lib/mecab/dic/open-jtalk/naist-jdic -m /usr/share/hts-voice/nitech-atr503-m001/nitech_atr503_m001.htsvoice -r 1.0 -ow test.wav');
slp.msleep(3000);
stdout = execSync('aplay test.wav');
obniz.display.clear();
obniz.display.print(Rcv);
obniz.wait(30000);
obniz.display.clear();
}
else{
//子供用に追加する場合は、ここに「if(textCount(Rcv, '自分のナンバー') == 1 ){…} else{ }と続け、else{ }の中に下記の「console.log('Unknown!!');」を移します。
console.log('Unknown!!');
}
}
}
}
}
言葉足らずなので補足です~
今回のプログラムを動かすには、Node.jsのインストールを行った後、下記のようなおまじないを行う必要があります。適宜自由なフォルダーでプロジェクトを作成してください。
npm init
npm install obniz
npm install request
npm install require
npm install sleep
上記のソースのままでは、いつまで経ってもLINE Notifyからお知らせが来ませんので、使用するスマホのIDを知る必要があります。
上記のプログラム(js)を動かすと、Obniz Board 1Yのディスプレイ上(30秒)及びターミナル上にIDが表示されますので、それで調べることが可能です。一旦プログラムを止めて、調べたIDを上のソースファイルに書いてくださいね。
投稿者の人気記事
-
kipopytokyo
さんが
2021/04/12
に
編集
をしました。
(メッセージ: 初版)
-
kipopytokyo
さんが
2021/04/14
に
編集
をしました。
(メッセージ: 動画追加、Arduino用コードに追記。)
-
kipopytokyo
さんが
2022/01/04
に
編集
をしました。
ログインしてコメントを投稿する