LoginSignup
2
3

More than 5 years have passed since last update.

nodejsでmindstrom-EV3を制御するev3dev-lang-js入門

Last updated at Posted at 2016-12-30

はじめに

EV3で動くLinux環境ev3devを使って開発します。この記事は、EV3にev3devをインストールし、SSH接続できている状態であることを前提にしています。
環境構築ができていない方はこちらの記事を参考にしてください。

mindstorm-EV3をLinuxで制御しよう! ev3dev OSのインストールととSSH接続

この記事ではnodejsからev3devを制御するライブラリev3dev-lang-jsを、サンプルコードとともに紹介します。

nodejsのインストール

ev3devにnodejsをインストールします。

robot@ev3dev:~$ sudo apt-get update
robot@ev3dev:~$ sudo apt-get install nodejs

ev3dev-lang-jsのインストール

ev3dev-lang-jsはjavascriptを使ってEV3のモーターやLEDの制御、センサー値の取得などを実現するライブラリです。npmでインストールできます。

robot@ev3dev:~$  npm install ev3dev-lang

バッテリー情報を取得

EV3の電源供給系統のデータを取得するにはPowerSupplyクラスを利用します。

battery-metadata.js

battery-metadata.js
var ev3dev = require('ev3dev-lang');

function printBatteryInfo(label, battery) {
    console.log(label + " --------------");

    if(battery.connected) { 
        console.log('  Technology: ' + battery.technology);
        console.log('  Type: ' + battery.type);

        console.log('  Current (microamps): ' + battery.measuredCurrent);
        console.log('  Current (amps): ' + battery.currentAmps);

        console.log('  Voltage (microvolts): ' + battery.measuredVoltage);
        console.log('  Voltage (volts): ' + battery.voltageVolts);

        console.log('  Max voltage (microvolts): ' + battery.maxVoltage);
        console.log('  Min voltage (microvolts): ' + battery.minVoltage);
    }
    else
        console.log("  Battery not connected!");
}

var defaultBattery = new ev3dev.PowerSupply();
printBatteryInfo("Default battery", defaultBattery);

実行結果

robot@ev3dev:~/ev3dev-lang-js-test$ node battery-metadata.js
Default battery --------------
  Technology: Li-ion
  Type: Battery
  Current (microamps): 233333
  Current (amps): 0.233333
  Voltage (microvolts): 8465666
  Voltage (volts): 8.465666
  Max voltage (microvolts): 7500000
  Min voltage (microvolts): 7100000

LEDを制御

EV3のLEDを制御するにはEv3Ledsクラスを利用します。
EV3のLEDは右側と左側がそれぞれ、赤色と緑色のLEDによって構成されています。つまりそれらのLEDの明るさの強弱を変化させて重ね合わせることで黄色やオレンジ色も表現することが可能です。

詳しくはこちらを参考

ev3devでmindstorm-EV3のLEDを制御しよう

fade-led.js

fade-led.js
var ev3dev = require('ev3dev-lang');

console.log('fading LEDs from green to red...');

for (var pct = 0; pct < 100; pct += 1) {
    var brightnessVal = (pct / 100);
    var invertedBrightnessVal = 1 - brightnessVal;

    ev3dev.Ev3Leds.left.setColor([ brightnessVal, invertedBrightnessVal ]);
    ev3dev.Ev3Leds.right.setColor([ brightnessVal, invertedBrightnessVal ]);

    if(pct % 10 == 0)
        console.log(pct + '%');

    {   //Hack to sleep for time
        //    SHOULD NOT BE USED IN PRODUCTION CODE
        var start = new Date().getTime();
        while(new Date().getTime() < start + 100) {
            ;
        }
    }
}

setColorメソッドの第一引数には配列で赤色、緑色LEDの出力の強さを0~1の範囲で指定します。
ev3dev.Ev3Leds.left.setColor([ brightnessVal, invertedBrightnessVal ]);

実行結果

robot@ev3dev:~/ev3dev-lang-js-test$ node fade-leds.js
fading LEDs from green to red...
0%
10%
20%
30%
40%
50%
60%
70%
80%
90%
done

(クリックで動画再生)
YouTube

モーターの回転とLEDの色を同期させてみる

EV3のモーターを制御するにはMotorクラスを利用します。

led-from-motor-speed.js

led-from-motor-speed.js
var ev3dev = require('ev3dev-lang');
var stoppedBlinkInterval = 200;

if(!ev3dev.Ev3Leds.isConnected) {
    console.error("This sample can only run on the EV3 brick. Other platforms are not supported by this script.");
    process.exit(1);
}

var motor = new ev3dev.Motor();

if(!motor.connected) {
    console.error("No valid motor was found. Please connect a tacho motor and try again.");
    process.exit(1);
}

console.log("Connected to motor " + motor.address);
motor.stopAction = motor.stopActionValues.coast;

console.log("Timer running... Rotate the motor and watch the on-board LEDs.");

setInterval(function() {

    if(motor.speed > 1) {
        var rpsSpeed = Math.min(Math.abs(motor.speed) / motor.countPerRot, 1);
        var ledColor = [rpsSpeed, 1 - rpsSpeed];
        ev3dev.Ev3Leds.left.setColor(ledColor);
        ev3dev.Ev3Leds.right.setColor(ledColor);
    }
    else {
        ev3dev.Ev3Leds.left.setColor([0, 1]);
        ev3dev.Ev3Leds.right.setColor([0, 1]);
    }

}, 80);

実行結果

EV3インテリジェントブロックのAポートにLモーターを接続してから実行します。

robot@ev3dev:~/ev3dev-lang-js-test$ node led-from-motor-speed.js
Connected to motor outA
Timer running... Rotate the motor and watch the on-board LEDs.
# モーターを手で回転させてみましょう
# Ctrl-cで終了

(クリックで動画再生)
YouTube

タッチセンサーを使う

EV3のタッチセンサーを制御するにはTouchSensorクラスを利用します。

raw-device-events.js

raw-device-events.js
var ev3dev = require('ev3dev-lang');

var greenANSI = "\033[42m";
var redANSI = "\033[41m";
var resetANSI = "\033[0m";

var touchSensor = new ev3dev.TouchSensor();
if (!touchSensor.connected) {
    console.error("No touch sensor could be found! Please verify that a touch sensor is plugged in and try again.");
    process.exit(1);
}

touchSensor.registerEventCallback(function(error, touchInfo) {
    if(error) throw error;
    console.log("Sensor is " + (touchInfo.lastPressed ? greenANSI + "PRESSED" : redANSI + "RELEASED") + resetANSI);
},
    function(userData) {
        var isPressed = touchSensor.isPressed;
        var changed = isPressed != userData.lastPressed;

        userData.lastPressed = isPressed;
        return changed;
    }, false, { lastPressed: false });

 console.log("Press the touch sensor to trigger the press event.");

registerEventCallbackメソッドの定義は以下のとおりです。コールバック関数内でタッチイベント情報を取得しています。

registerEventCallback

registerEventCallback(
callbackFunction: function,
eventPredicate: function,
firstTriggerOnly?: boolean,
userCallbackData?: any)
: void

実行結果

EV3インテリジェントブロックの1番ポートにタッチセンサーを接続してから実行します。

robot@ev3dev:~/ev3dev-lang-js-test$ node raw-device-events.js
Press the touch sensor to trigger the press event.
# タッチセンサーを押したり離したりしてみましょう
Sensor is PRESSED
Sensor is RELEASED

特定のポートに接続したモーターを制御

接続ポートを指定してモーターを制御する方法です。

run-specific-motor.js

run-specific-motor.js
var ev3dev = require('ev3dev-lang');

var motor = new ev3dev.Motor(ev3dev.OUTPUT_A);
if(!motor.connected) {
    console.error("No motor was found on port A. Please connect a tacho motor to port A and try again.");
    process.exit(1);
}

motor.runForDistance(360 * 10, 500, motor.stopActionValues.brake);

console.log("Running the motor for 180 tacho counts...");

// Prevent Node from exiting until motor is done
var cancellationToken = setInterval(function() {
    if(!motor.isRunning)
        clearInterval(cancellationToken);
}, 200);

Aポートを使用する設定

var motor = new ev3dev.Motor(ev3dev.OUTPUT_A);

runForDistanceメソッドは第一引数に回転角度、第二引数に回転速度、第三引数に動作停止パラメーターを設定します。

motor.runForDistance(360 * 10, 500, motor.stopActionValues.brake);

実行結果

EV3インテリジェントブロックのAポートにLモーターを接続してから実行します。

robot@ev3dev:~/ev3dev-lang-js-test$ node run-specific-motor.js
Running the motor for 180 tacho counts...
# モーターが10回転します

タッチセンサーとモーターを連携

タッチセンサーを押している間、モーターが回転し続けるコードは以下のようになります。

touch-sensor-motor-control.js

touch-sensor-motor-control.js
var ev3dev = require('ev3dev-lang');

var touchSensor = new ev3dev.TouchSensor();
if(!touchSensor.connected) {
    console.error("No touch sensor could be found! Please verify that a touch sensor is plugged in and try again.");
    process.exit(1);
}

var motor = new ev3dev.Motor();
if(!motor.connected) {
    console.error("No valid motor was found. Please connect a tacho motor and try again.");
    process.exit(1);
}

console.log("Connected to touch sensor at address " + touchSensor.address + " and tacho motor at address " + motor.address);
console.log("Press the touch sensor to spin the motor.");

setInterval(function() {
    motor.start(motor.maxSpeed * touchSensor.getValue(0), motor.stopActionValues.hold);
}, 10);

実行結果

robot@ev3dev:~/ev3dev-lang-js-test$ node touch-sensor-motor-control.js
Connected to touch sensor at address in1 and tacho motor at address outA
Press the touch sensor to spin the motor.
# タッチセンサーを押下している間モーターが回転します

(クリックで動画再生)
YouTube

参考

サンプルプログラムはev3dev-lang-jsのサンプルコードを利用しています。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3