まえがき
「世界中の人に、のあちゃん・えくくん(猫)と遊んでもらいたい」
そんな思いから、世界中のパソコンやスマホを通して、ペットののあちゃん・えくくんとコミュニケーションがとれるものを作ってみました。
本当は猫じゃらしを振り回してもらいたかったのですが、まずはLEDを点灯させるだけの「光をともす」をやってみたいと思います。
↑ のあちゃんとえくくん ↓のあちゃんに光が灯される図
世界中からアクセスできる点については、ESP32を公開Webサーバーにして直接アクセスできるようにしてみたかったのですが、その辺りの知識が全く無く、色々ややこしそうだったので断念。(誰か教えてください)
Webページで入力があった場合にローカルサーバーで検知し、シリアル通信でArduinoを動かすことにしました。
Arduinoにプログラムを書き込む
シリアル通信で"n"が入力されたらLEDが光り、"f"が入力されたらLEDが
消えるというコード。
constbyteLED_PIN=5;voidsetup(){pinMode(LED_PIN,OUTPUT);Serial.begin(9600);}voidloop(){while(Serial.available()>0){charvalue=Serial.read();if(value=='n'){// nはONdigitalWrite(LED_PIN,HIGH);}elseif(value=='f'){// fはOFFdigitalWrite(LED_PIN,LOW);}else{digitalWrite(LED_PIN,LOW);}Serial.println(value);}}
Arduinoをシリアル通信させるNode.jsプログラム
参考にさせていただいた記事
ArduinoでTwitter連携!愛しのぬいぐるみトンピーちゃんに命を吹き込んでみた
https://dotstud.io/blog/arduino-nodejs-twitter-connect/
これでNode.jsでシリアルポートを制御できるようになる。
constSerialPort=require("serialport");constport=newSerialPort("/dev/tty.xxx",{baudRate:9600,});port.on("open",()=>{console.log("Serial open.");setInterval(write,3000);});port.on("data",(data)=>{console.log(`Data from Arduino: ${data}`);});constwrite=()=>{console.log(`Input to Arduino: ${signal}`);port.write(signal,(error)=>{if(error){console.error(`Error: ${error.message}`);}});};
Cloud Firestoreを使ってWebページで入力があった場合にローカルサーバーで検知する
参考にさせていただいた記事
firestore, vue.jsでリアルタイム同期のチャットを実装してみる [チュートリアル形式]
https://qiita.com/ryo2132/items/2881d8223eb2ad3050a1
Cloud Firestoreには、データベースに変更があった場合リアルタイムで分かる便利機能があるらしい。ただ、今回の場合データベースを使う必要は全く無いので、とても無駄な感じがある。
//-----------------------------------------------// firebase Admin関係//----------------------------------------------constadmin=require("firebase-admin");constserviceAccount=require("./xxx.json");admin.initializeApp({credential:admin.credential.cert(serviceAccount),databaseURL:"https://yyy.firebaseio.com",});constdb=admin.firestore();//-----------------------------------------------// firestoreのデータの変更を検知する//----------------------------------------------constdoc=db.collection("users");constobserver=doc.onSnapshot((querySnapshot)=>{querySnapshot.docChanges().forEach(change=>{if(change.type==='added'){constsignal=change.doc.data().signal;}})},(err)=>{console.log(`Encountered error: ${err}`);});
Webページを作ってfirebaseにデプロイする
コードのほとんどはfirebaseが自動的に作ってくれる。主にbodyタグ内を書き換えるだけ。
<!DOCTYPE html><html><head><metacharset="utf-8"><metaname="viewport"content="width=device-width, initial-scale=1"><title>Welcome to Firebase Hosting</title><!-- update the version number as needed --><script defersrc="/__/firebase/8.0.0/firebase-app.js"></script><!-- include only the Firebase features as you need --><script defersrc="/__/firebase/8.0.0/firebase-auth.js"></script><script defersrc="/__/firebase/8.0.0/firebase-database.js"></script><script defersrc="/__/firebase/8.0.0/firebase-messaging.js"></script><script defersrc="/__/firebase/8.0.0/firebase-storage.js"></script><!-- initialize the SDK after all desired features are loaded --><script defersrc="/__/firebase/init.js"></script><!-- Firebase と Cloud Firestore のライブラリをアプリに追加する --><script src="https://www.gstatic.com/firebasejs/7.2.3/firebase-app.js"></script><script src="https://www.gstatic.com/firebasejs/7.2.3/firebase-firestore.js"></script></head><body><div><h2>のあちゃん と えくくんに光をともす</h2><buttonid="on-button"><p>光をともしてあげる</p></button><buttonid="off-button"><p>光を消してあげる</p></button></div><pid="load">Firebase SDK Loading…</p><script>document.addEventListener('DOMContentLoaded',function(){try{letapp=firebase.app();letfeatures=['auth','database','messaging','storage'].filter(feature=>typeofapp[feature]==='function');document.getElementById('load').innerHTML=`Firebase SDK loaded with ${features.join(', ')}`;}catch(e){console.error(e);document.getElementById('load').innerHTML='Error loading the Firebase SDK, check the console.';}});// Initialize Cloud Firestore through Firebasefirebase.initializeApp({apiKey:"XXXXXX",authDomain:"XXXXXX",projectId:"XXXXXX",});constdb=firebase.firestore();document.getElementById("on-button").onclick=function(){constnow=newDate();// コメントをFirestoreへ登録db.collection('users').add({signal:"n",createdAt:now})console.log("ONを追加")};document.getElementById("off-button").onclick=function(){constnow=newDate()// コメントをFirestoreへ登録db.collection('users').add({signal:"f",createdAt:now,})console.log("OFFを追加")};</script></body></html>
さいご
Arduinoへの書き込み、firebaseにwebページのデプロイが終わったら、$ node ファイル名.js
で動かす!
あとがき
これで世界中の人がのあちゃん・えくくんに光を灯すことができるようになりました。