Node.js
Arduino
ArduinoIDE

Arduinoを使ってPCからDCモーター制御(Node.js編)

Arduinoを使ってPCからDCモーター制御(Node.js編)

 Arduinoを使ってDCモーター制御の続きです。モーターを回すことに成功したので、次はモーターを外部からの操作で制御することにチャレンジしてみます。

 外部記事1を参考に、Node.jsを使ってArduinoをコントロール→モーターの制御までやってみました。

 モータの回転をWeb経由で制御する仕組みは以下のようになっています。

image.png

環境

 以下のとおりです。
- PC:Windows 10 Fall Creators Update
- Arduino-UNO
- Arduinoビギナーのためのモーター・リレー・ブザー制御入門

 前回の続きから、引き続きこの基盤を使ってモーターの外部操作を試みます。

下準備

Node.jsのインストール

 Node.jsからダウンロード→インストールでOKです。今回は9.10.1をインストールしました。

Johnny-five のインストール

 コマンドプロンプトより、C:\から"npm install johnny-five"します。
 インストール前に、"npm init"しておき、package.jsonを作成しておくと良いです。
 他のディレクトリからインストールしようとすると、そのディレクトリからの相対パスでnode_modules以下ができてしまうので注意。
 間違った場所にnode_modulesができても、node_modulesごと消して再インストールで良さそうです。

インストール例
C:\Users>cd c:\
c:\>npm install johnny-five

> serialport@6.0.5 install c:\node_modules\firmata\node_modules\serialport
> prebuild-install || node-gyp rebuild

(中略)

c:\node_modules\serialport\build\Release\serialport.node successfully
prebuild-install info install Successfully installed prebuilt binary!
npm WARN saveError ENOENT: no such file or directory, open 'c:\package.json'
npm WARN saveError EPERM: operation not permitted, open 'c:\package-lock.json.769635733'
npm WARN enoent ENOENT: no such file or directory, open 'c:\package.json'
npm WARN !invalid#1 No description
npm WARN !invalid#1 No repository field.
npm WARN !invalid#1 No README data
npm WARN !invalid#1 No license field.

+ johnny-five@0.14.2
added 197 packages in 10.887s

 以下のようなWARNINGが出てしまった場合、package.jsonが生成されていないことが原因なのですが、インストール自体が成功している場合は次の手順に進んでも構いません。

packagel.jsonに関するWARNING
npm WARN saveError ENOENT: no such file or directory, open 'c:\package.json'

Arduinoライブラリ設定

 GitHub - firmata/arduino: Firmata firmware for Arduinoの右上Clone or downloadよりDownload ZIPを選択、ZIPモジュールをダウンロードします。
 Arduino IDEを起動し、スケッチ→ライブラリをインクルード→.ZIP形式のライブラリをインストールのあと、ダウンロードしたZIPモジュールを指定してインストールすれば使えるようになります。

image.png

 その後、スケッチ例→Firmata→StandardFirmataと選択し、StandardFirmataのコードを表示させ、マイコンボードに書き込み準備完了です。
 書き込み完了後、Arduino側でNode.jsからの命令を受け付けるようになります。一度書き込みが済んでしまえば、Arduino側に新しいコードを書き込まなくても色々なことを実行できるのは便利ですね。

Hello wordを試す

 準備ができたら、Johnny-Five Hello Worldを試してみます。
 Windowsの場合ポート指定が必要なため、サイトのソースをそのまま実行できないため注意が必要です。
 サイトの図のように基盤にLEDを指していなくても、基板上のオレンジLEDの点滅を確認できます。

基板上のLED点滅
var five = require("johnny-five");
var board = new five.Board({port:'COM5'});          // Windowsの場合、必ずポートを指定する

board.on("ready", function() {
  console.log("Ready!");
  var led = new five.Led(13);

  led.blink(500);

});

Node.jsでモーター制御

 Johnny-FiveのDCモーターのサンプルコードJavaScript Robotics: Motor - Directionalを例に、モーターを回してみるコードを書いてみます。
 ソースコードはこのような感じになります。モーターを5秒間正回転させ、その後5秒間逆回転し、停止させます。
 環境によってはモーターの制御がうまくいかない場合があるかもしれません。その場合は、pins:の設定を見直してみてください。
 また、この環境だけの可能性がありますが、motor.forward()した後、モーターの回転を止める際にmotor.reverse()→motor.stop()の順で命令を送らないとモーターが止まらないため、ソースコードがそのような記載になっています。

 ちなみに、プログラムによりモーターが一通り動いた後、>>プロンプトに続けてモーター制御のコマンドを入力すると、モーターの正回転・逆回転・停止を直接制御可能です。

コマンドを入力することでモーターの動きを制御
>> motor.reverse(80)
>> motor.stop()

Web経由でモーターの制御をするための準備

 PCからモーターの制御をするところまでできたので、次はWeb経由でモーターの制御をしてみます。
 Webから以下のようにフラグ情報を送ってあげて、Arduino側で受け取ったらフラグに応じた処理をさせてみます。

  • 1:正回転
  • 0:停止
  • -1:逆回転

 Web経由での情報の受け渡しにはGoogle Spreadsheetを使う方法を採用しました。2
 ソースコードはMotorControlTest/MotorControlApp.gsに記載しました。各関数の動きは以下のとおりです。
 コードが一通りできたら「ウェブアプリケーションとして導入」します。

  • doGet(e) : A1セルの値を取得
  • setFlag(e) : A1セルを1⇔-1に切り替える
  • setStopFlag(e) : A1セルに0をセット

 次に以下図のように、図形にスクリプトを割り当てます。図形を押すと、1・0・-1の切替ができるようにしてみます。

image.png

 Node.js側では指定したURLのBodyを取得するコードを実行します。
 上記の公開したアプリのURLを変数として実行させると、A1セルの値が返ってきます。図形をクリックしてA1の値を更新してみます。A1セルの変更がNode.js側でも拾ってこれたので、いよいよWeb経由での制御に進みます。

Web経由でのモータの制御

 ここまで来たら「Node.jsでモーター制御」と「Web経由でモーターの制御をするための準備」を組み合わせて、MotorControlTest/motor_control.js
というコードを書いてモーターの制御をスマホ経由で実施してみました。
 Goole SpreadSheetの図形はアプリからクリックができないようなので、FirefoxのPCモードから対象のスプレッドシートを開いてボタンを押しています。
 スプレッドシートの値の変更と、モーターの回転が連動していることが確認できました!

動かしたときのログ
>node motor_control.js
1522641390473 Connected COM5
1522641392494 Repl Initialized
>>
2018/04/02 12:56:32     Motor Cotroll Start!!
2018/04/02 12:56:32     Motor Stop!!
2018/04/02 12:56:32     Motor Stop!!
2018/04/02 12:56:32     Motor Reverse!!
2018/04/02 12:56:32     Motor Stop!!
2018/04/02 12:56:37Flag:0
2018/04/02 12:56:37     Motor Stop!!
2018/04/02 12:56:37     Motor Reverse!!
2018/04/02 12:56:38     Motor Stop!!

(中略)

2018/04/02 12:57:25Flag:-1
2018/04/02 12:57:25     Motor Stop!!
2018/04/02 12:57:25     Motor Reverse!!
2018/04/02 12:57:25     Motor Start!!

(中略)

2018/04/02 12:58:07Flag:0
2018/04/02 12:58:07     Motor Stop!!
2018/04/02 12:58:07     Motor Reverse!!
2018/04/02 12:58:08     Motor Stop!!

(To exit, press ^C again or type .exit)
>>
1522641489593 Board Closing.

参考文献