Open O2giriOC opened 1 year ago
I2Cの場合はI2Cでの通信が必要となりますが、申し訳ございませんが現在opnizはI2Cをサポートしておりません…
ちなみにENV3はこちらの製品でしょうか? 上記の製品でしたらArduinoライブラリが用意されていますでの、opnizで実装する場合はopniz Node.js SDKおよびopniz Arduino Libraryを拡張実装することでArduinoライブラリで用意されている関数をNode.js SDKから使用できるようになります。
拡張実装に関する詳細なドキュメントも用意できておらず恐縮ですが、参考までに「opnizでつくる「CO2センサ(MH-Z19C)データのGoogle Spreadsheetsロギングシステム」」という記事にてArduinoライブラリを用いてopnizを拡張実装した例をご紹介しています。
そのセンサーで間違いないです!説明不足ですみません… なるほど!クラスを実装するイメージですかね? とりあえず記事を参考にさせてもらいます! またしてもありがとうございます!!
拡張用ベースクラスを用意していますのでそれを拡張していただくかたちになります! Arduino LibraryのREADMEにはちょろっと書いていましたがNode.js SDK側に拡張方法に関する記載がなかったので、別途解説記事を書いておこうと思います!
opnizの拡張実装解説記事を書きました! ご参考になれば幸いです!
わざわざありがとうございます! ちょうど手詰まっていたところなので、助かりました。 丁寧な解説本当にありがとうございます!!
お久しぶりです、パソコンを修理に出していまして連絡が遅れてしまいすみません。 現在クラスを実装してとりあえずLEDを点滅させようとしたのですが、下のメッセージが表示され、LEDが点滅していない状況です。
Node.jsとの接続自体はできているとは思うのですが、どこか至らないところがあるのでしょうか。 教えていただければ幸いです。
お久しぶりです! JSONメッセージが表示されているのでしたら正常に接続、通信は行なえています! drawpixメソッドでLEDが点滅しないとなるとJSONメッセージに対応したハンドラーが存在しないことが考えられます。
おそらくですがクラス拡張された際にEsp32クラスをベースクラスに使用されているのではないかと思います。 drawpixメソッドはM5Atomクラス側で定義されているので、M5Atomクラスをベースクラスとすればdrawpixメソッドも使用できるようになるかと思います。
ありがとうございます!! 言われた通りESP32クラスを使用していました笑。
https://www.youtube.com/watch?v=7n0_f7Z5mFQ 上記の動画のようにブラウザからM5Atomliteを制御したいと考えているのですが、これはopniz-severを使用してwebsocketで動かしているのでしょうか?
この動画ではM5ATOMとNode.js間をopnizで繋ぎ、Node.jsとHTMLを別途WebSocketで繋いでいます。 イメージとしてはHTML上のボタンが押されたときにHTMLからNode.jsへWebSocketでイベントを送り、Node.js側でイベントを受けたらopnizのメソッドを実行する感じです。
理想としてはHTMLから直接opnizメソッドを実行したいところなのですが、恐縮ですがこちらも現在対応できていない状況です… (現状のopniz Node.js SDKからWebSocket Server機能と関連ライブラリを外せばブラウザ上でもopnizが動く想定です)
opnizがブラウザ対応できれば、おっしゃる通りopniz-serverを介してHTMLからM5ATOMとやりとりが行えるようになります。
ありがとうございます! この場合M5ATOMを動かすNode.jsとWebsocketでM5ATOMとブラウザを繋ぐNode.jsの2つを用意するということでしょうか?
ひとつのNode.js内でM5ATOMを制御するopnizのコードと、HTMLとやりとりするWebSocketのコードを組み合わせます。 イメージとしてはNode.js側は以下のようなコードになります。
const opniz = new Opniz.M5Atom({ port: opnizPort })
await opniz.connectWait()
const wss = new WebSocketServer({ port: wsPort })
wss.on("connection", async ws => {
// HTMLからWebSocketメッセージを受けてM5ATOMを制御
ws.on("message", async message => {
switch(message.toString()) {
case "green":
await opniz.drawpix(0, "#00ff00"); break
case "blue":
await opniz.drawpix(0, "#0000ff"); break
case "red":
await opniz.drawpix(0, "#ff0000"); break
case "off":
await opniz.drawpix(0, "#000000"); break
}
})
// M5ATOMからの情報を受けてHTMLへWebSocketメッセージを送信
opniz.onbutton = () => {
ws.send(JSON.stringify({ button: true }))
}
})
HTML側のWebSocketからgreen
やblue
といったメッセージを受け取ると対応するopniz.drawpix
メソッドを実行します。
またopniz.onbutton
メソッドにてws.send
でHTML側にメッセージを送信すればM5ATOMのボタンイベントの発火をHTML側に伝えられます。
ありがとうございます! websocketとそのように組み合わせればいいんですね!! わざわざサンプルコードまで教えていただきまして、本当に感謝しかありません!! ありがとうございます!!
お久しぶりです。 ENVⅢのクラスを拡張でき、実際にNode.js SDKで動かすことができました。 今現在、上記のコードを参考にしてHTMLからwebsocket経由でatomliteを動かそうとしているのですが、websocketハンドシェイクが完了したタイミングでatomliteとの接続が切れてしまいます。 ポート番号を一緒にしているのが問題かなと思い変更してみたのですが、特に変わらず「Opniz Error: Connection timeout.」と表示されました。 他の原因が思いつかず、また質問させていただきました。回答していただければ幸いです。
お久しぶりです。
確かに同じポート番号だとだめなのですが、その場合はError: listen EADDRINUSE
といったポート番号が使用済みというエラーとなるはずなので問題は別にありそうですね…
ひとまず以下をチェックしてみてもらえますでしょうか。
回答ありがとうございます。とりあえずチェックしてみました。
・クライアント側(opnizデバイス、ブラウザ)のポート番号も重複しないものになっているか 両サイドのポート番号を別の値にしましたが同じようにopnizとの接続ができないという結果でした。また一緒な番号にしたとしても「listen EADDRINUSE」とは出ませんでした。
・opnizのコード単体で動作するか READMEのようなサンプルコードのように、opnizのコードだけが書かれたjsファイルを動かしたのですが、正常に動きました。Lチカは勿論、クラス拡張を行ったENVⅢも動いたので特に問題はないように思えます。
・WebScoketのコード単体で動作するか こちらもwebsocketでhtmlとNode.jsサーバの双方向通信を行うコード単体を動かしました。こちらも特に問題なく動きました。
もしかしたらですが、expressモジュールを使ってサーバ構築を行っているのに問題があるのでしょうか。
ご確認ありがとうございます! それぞれ単体で動いているのであれば組み合わせ方の問題ですかね…
もしかしたらですが、expressモジュールを使ってサーバ構築を行っているのに問題があるのでしょうか。
expressもポートが絡みますがEADDRINUSE
が出ていないなら(ポート番号を分けているなら)ポートの問題ではなさそうですね…
opniz、WebSocket、Expressそれぞれのlistenタイミングも少し気になるので可能であればソース共有できそうでしょうか?
const WebSocketServer = require("ws").Server;
const http = require("http");
const express = require("express");
const app = express();
const {Opniz} = require("opniz");
const Opniz_PORT = process.env.PORT || 4000;
const Server_PORT = process.env.PORT || 3000;
//M5Atomクラスを追加
class ExtendOpniz extends Opniz.M5Atom{
async getTmp(){
return Number( await this.exec("getTmp") )
}
}
const opniz = new ExtendOpniz({Opniz_PORT});
//HTML
app.get("/", (req,res)=>{
res.sendFile(__dirname + "/views/index.html");
});
//WebScoket起動
const server = http.createServer(app);
const wss = new WebSocketServer({server:server});
//opniz接続
const connect = async()=>{
console.log("opniz start");
while (!(await opniz.connectWait())) console.log("connect...")
console.log("[connect]");
await opniz.dis.drawpix(0, 0x0ff000);
}
//websocket
wss.on("connection", async (ws)=>{
console.log("CONNECT");
//確立したらopniz開始
connect();
//ブラウザを閉じたとき
ws.on("close",()=>{
console.log("END");
});
//メッセージを受けたとき
ws.on("message", async (msg)=>{
console.log("message:"+ msg);
ws.send(msg.toString()); //toString()で文字列に変換
});
});
//サーバの構築
server.listen(Server_PORT,()=>{
console.log(Server_PORT);
});
jsのコードは今の所このような感じです。見づらくてすみません。 動作の流れとしては サーバの構築 → HTMLの表示&WebSocket開始 → opniz開始 といったものを想定しています。
ありがとうございます! ひとまずopnizのポート指定部分を以下のように変更してみてください!
// const opniz = new ExtendOpniz({Opniz_PORT});
const opniz = new ExtendOpniz({ port: Opniz_PORT });
言われた通りに変更したら実行できました!! 文法を間違えていたのですか... 別にサーバを構築?するときにはポート番号の指定が大事ということがわかりました! ありがとうございます!!
お久しぶりです、また質問失礼します。 今ENV3センサを使用していまして、センサ値が受信される26番ピンをanalogreadしていたのですが、0としか表示されません。 ENV3は湿度、気圧、温度を測定していて、I2C通信なので、専用の関数じゃないと値を取得できないということでしょうか。 また教えていただければ幸いです。