❗ このプロジェクトは現在アルファ版です。
opnizとはM5StackデバイスをNode.js(JavaScript / TypeScript)からobnizライクに実装できるオープンソースフレームワークです。
Node.js SDKおよびArduinoライブラリがあり、WebSocketで相互通信を行います。
しくみとしてはM5StackデバイスおよびNode.js SDK間にてJSON形式のRPCメッセージをやりとりし、相互に定義されたメソッドを呼び合います。
本リポジトリはNode.js SDKのリポジトリとなります。
デバイスのRead/Writeを実行したり(Pinも動的に指定可能です)、デバイス側からのイベント(たとえばM5Stack系デバイスのボタン等)を受け取って非同期に処理を実行したりできます。
またM5UnifiedおよびM5Atom Arduino LibraryのAPIもいくつか実装しています。
- M5Stack BASIC
- M5Stack Core2
- M5StickC
- M5ATOM Matrix
- M5ATOM Lite
- M5ATOM Echo
- M5ATOM U
- M5ATOMS3
- M5ATOMS3 Lite
- M5Stamp Pico
- M5Stamp S3
- その他ESP32、ESP32-PICO-D4、ESP32-S3デバイス
npm install opniz
❗ 事前にデバイスへopniz Arduinoライブラリ(M5Unified向けもしくはESP32向け)を書き込んでください。
opniz CLI (npm) を使用するとかんたんにデバイス書き込みできます。
以下のコードは最小限のopnizのJavaScript実装コードです。
opnizインスタンスの生成、opnizデバイスへの接続、デバイスへの操作の3ステップを実行しています。
address
、port
をデバイスのIPアドレスと、任意のポート番号に書き換えて実行してみてください。
const { Opniz } = require("opniz")
const port = 3000 // 任意のポートを指定(opnizデバイスの指定と合わせる)
; (async () => {
const opniz = new Opniz.Esp32({ port }) // opnizインスタンス生成
await opniz.connectWait() // opnizデバイスへ接続
console.log(await opniz.getFreeHeap()) // opnizデバイスのヒープメモリーサイズを取得して表示
})()
実際にデバイスを24時間稼働で実装する場合は以下のようにループ実装します。
const { Opniz } = require("opniz")
const port = 3000 // 任意のポートを指定(opnizデバイスの指定と合わせる)
const opniz = new Opniz.Esp32({ port }) // opnizインスタンス生成
const main = async () => {
// opnizデバイスへ接続
while (!(await opniz.connectWait())) console.log("connect...")
console.log("[connected]")
try {
// 1秒おきにデバイスのヒープメモリーサイズを表示
for (;;) {
console.log(await opniz.getFreeHeap())
await opniz.sleep(1000)
}
// エラー処理
} catch(e) {
console.log("[error]", e.message)
await main()
}
}
main()
❗ 事前にM5ATOM等の内蔵LED搭載デバイスへopniz Arduinoライブラリ(M5Unified向け)を書き込んでください
M5ATOM(内蔵フルカラーLED搭載端末であれば他のM5Stackデバイスでも大丈夫です)でLチカを行ってみます。
以下のコードを実行すると1秒おきにLEDが点滅します。
await opniz.Led.fillpix(color)
が内蔵LEDを制御するメソッドです。
このようにデバイスをArduinoライブラリを用いて実装するのと同じ感覚でNode.jsにて実装できます。
const { Opniz } = require("opniz")
const port = 3000 // 任意のポートを指定(opnizデバイスでの指定と合わせる)
const opniz = new Opniz.M5Unified({ port }) // opnizインスタンス生成
const OFF = "#000000"
const GREEN = "#00ff00"
let state = true
const main = async () => {
// opnizデバイスへ接続
while (!(await opniz.connectWait())) console.log("connect...")
console.log("[connected]")
try {
// 1秒おきに内蔵LEDを点滅
for (;;) {
await opniz.Led.fillpix(state ? GREEN : OFF)
state = !state
await opniz.sleep(1000)
}
// エラー処理
} catch (e) {
console.log("[error]", e.message)
await main()
}
}
main()
次に内蔵LEDではなく、IOに接続したLEDを制御してみましょう。
以下のコードを実行すると21番ピンに接続したLEDが1秒おきに点滅します。
await opniz.digitalWrite(pin, state ? HIGH : LOW)
にて変数pin
に指定したピンをdigitalWriteで制御しています。
このようにNode.js SDKより動的にピンをアサインして制御できます。
const { Opniz } = require("opniz")
const port = 3000 // 任意のポートを指定(opnizデバイスでの指定と合わせる)
const opniz = new Opniz.M5Unified({ port }) // opnizインスタンス生成
const pin = 21 // LEDを繋いだピン番号を指定
const HIGH = 1
const LOW = 0
let state = true
const main = async () => {
// opnizデバイスへ接続
while (!(await opniz.connectWait())) console.log("connect...")
console.log("[connected]")
try {
// 1秒おきに`pin`に接続したLEDを点滅
for (;;) {
await opniz.digitalWrite(pin, state ? HIGH : LOW)
state = !state
await opniz.sleep(1000)
}
// エラー処理
} catch(e) {
console.log("[error]", e.message)
await main()
}
}
main()
次のコードを実行し、デバイスのボタンを押すとコンソールにonClicked!
と表示されます。
opniz.Btn.onClicked = (button, count) => console.log("onClicked!")
のようにonClicked
メソッドを上書くことでボタンイベントを拾い、任意の処理を行います。
このonメソッドはデバイスクラスにて任意に実装可能です。
const { Opniz } = require("opniz")
const port = 3000 // 任意のポートを指定(opnizデバイスでの指定と合わせる)
const opniz = new Opniz.M5Unified({ port }) // opnizインスタンス生成
const main = async () => {
// opnizデバイスへ接続
while (!(await opniz.connectWait())) console.log("connect...")
console.log("[connected]")
// デバイスのボタンが押されたらconsole表示
opniz.Btn.onClicked = (button, count) => console.log("onClicked!")
try {
// 無限ループ
for (;;) {
await opniz.sleep(1000)
}
// エラー処理
} catch (e) {
console.log("[error]", e.message)
await main()
}
}
main()
pin
に指定したピンからアナログ値を読み取ります。
pin
に指定したピンからデジタル値(0 or 1)を読み取ります。
pin
に指定したピンからvalue
に指定したデジタル値(0 or 1)を出力します。
ledcWrite(pin: number, duty: number, channel: number, freq: number, resolutionBits: number): Promise<boolean>
pin
に指定したピンからPWM出力します。
デバイスを再起動します。
現在M5UnifiedライブラリのDisplay
、Button
、IMU
クラスのメソッドをいくつか実装しています。
M5AtomライブラリのLED_Display
クラスを内部インクルードしいくつか実装しています。
opniz Node.js SDKでは以下の通信プロトコルを実装しています。
デフォルトではWebSocket (Server)
が使用されます。
- WebSocket (Server)
- WebSocket (Client)
- TCP (Server/Client同居)
opniz Arduinoライブラリでは以下の通信プロトコルを実装しています。
デフォルトではWebSocket (Client)
が使用されます。
- WebSocket (Client)
- TCP (Server/Client同居)
使用するプロトコルによりopnizのコンストラクタパラメータが変わってきます。
プロトコル | コンストラクタパラメータ | パラメータ内容 |
---|---|---|
WebSocket (Server) | Opniz.Esp32({ port }) |
port : listenするポート番号を指定します |
WebSocket (Client) | Opniz.Esp32({ address, port, id?, protocol?: "WebSocketClient" }) |
address : 接続先のopnizのIPアドレスまたはhostnameを指定しますport : 接続先のopnizのWebSocket Serverポート番号を指定しますid : opniz Serverを経由してopnizデバイスと接続する場合に、opnizデバイスで指定したid と同じ値を指定します(省略可)protocol : "WebSocketClient"プロトコルを指定します(id が指定されている場合は省略可能です) |
TCP (Server/Client同居) | Opniz.Esp32({ address, port, serverPort?, protocol?: "TCP" }) |
address : 接続先のopnizのIPアドレスを指定しますport : 接続先のopnizのTCP Serverポート番号を指定しますserverPort : listenするポート番号を指定します(省略可能で、省略時はport と同じ値となります)protocol : "TCP"を指定します(serverPort が指定されている場合は省略可能です) |
またNode.js SDK同士の接続も可能です。
- opniz Arduino Library for M5Unified
- M5Unified向けArduinoライブラリ
- opniz CLI
- opniz Arduino LibraryのBasicスケッチをコマンドから簡単に書き込めるCLIツール
- opniz Server
- opniz Node.js SDKやopnizデバイスからのJSON RPCメッセージを中継するWebSocketサーバ