Skyway IoT SDKからArduinoに指令を送る


これまで私はWebブラウザからRaspberry Piに接続されたハードウェアを操作する用事がある場合はPusherというWebSocketのSaaSを使ってました。

Pusherはライブラリも豊富で便利なのですが、せっかくのWebSocketなのに太平洋の向こうまでパケットが飛んで行くのにどうも納得行かず、Skyway IoT SDKへの置き換えをしてみることにしました。

Skyway IoT SDKのインストール&動作確認

とりあえず、こちらのページを元にインストール。
https://qiita.com/komasshu/items/5042c1e18eb4589b977a

Raspberry PiからArduinoをコントロール

PCからarduinoにシリアルで文字列「1」を受け取ると1秒だけ光るスケッチを書き込みます。

byte c = 0;

void setup(){
  Serial.begin(9600);
  pinMode(13,OUTPUT);
}

void loop(){
  while (Serial.available()){
    c = (int)Serial.read();
    switch(c){
      case 49://1
        digitalWrite(13,HIGH);
        delay(1000);
        digitalWrite(13,LOW);
        break;
    }
  }
}

次にRaspberry PiにNode.jsのシリアルポート接続ライブラリをインストールします。

公式に記載の通り、sudo npm install serialport --unsafe-perm --build-from-sourceとオプションを付けないと、ちゃんと動かないので注意。

ArduinoをRaspberry Piに挿し替え、こんな感じのサンプルスクリプトで動作確認してください。

serial_test.js
const SerialPort = require('serialport')
const fs = require('fs')
var sp = null
var files = fs.readdirSync('/dev/')
files.forEach(function(file){
  if( file.match(/ttyAC/) ){
    sp = new SerialPort('/dev/'+file, {
      baudRate: 115200
    })
    console.log(file)
  }
})
sp.write('1')

skyway-siru-device/metrics.jsを書き換え

上記の動作確認ではmetrics.jsでRaspberry Pi側のカメラ画像やCPU使用率などを送信してますので、ここにシリアル通信を受信するところを書き足しましょう。

まず、metrics.jsの先頭部分に、さっきのserial_test.jsを書き足します。そして、metrics.jsのdevice.get()がGETを受信したときの動作ということで、ここにシリアルポートへアクセスする文を書き足してみましょう。

metrics.js
device.on('connect', () => {
  device.get('/echo/:mesg', (req, res) => res.send(req.params.mesg))
  startSendMetrics()
  setTerminate()
})

こんな感じに書き換えます

metrics.js
device.on('connect', () => {
  device.get('/echo/:mesg', (req, res) => {
    res.send(req.params.mesg))
    sp.write(req.params.mesg)) // 追記:シリアル通信
  }
  startSendMetrics()
  setTerminate()
})

sample-client.htmlを書き換え

次にブラウザ側です。

ボタンを押した際の処理を

sample-client.html
  btn.addEventListener('click', ev => {
    client.fetch(uuid+'/echo/helloWorld', {method: 'get'})
      .then(res => res.text())
      .then(text => console.log(`echo message: ${text}`))
  })

こんな感じ(helloWorldを「1」に)書き換えます。

sample-client.html
  btn.addEventListener('click', ev => {
    client.fetch(uuid+'/echo/1', {method: 'get'})
      .then(res => res.text())
      .then(text => console.log(`echo message: ${text}`))
  })

これで、ブラウザ上でボタンを押すとRaspberry Piに「1」という文字列が飛び、Raspberry  PiからArduinoに「1」が飛びます。

Arduinoがシリアルを受け取ったら爆発するようにすれば、おしおきだべぇ〜を再現できますね。めでたしめでたし。