概要
Raspberry Pi に似ているが、Raspberry Pi と違って頭脳が無い。
ゆえにむしろ機械制御に集中できる。
デモを作る場合に PC に繋いで制御したい場合に非常に扱いやすい。
PCとシリアルポートの双方向通信ができるので、それで制御するのが良い。
必須インストール/入手
- Arduino IDE
- Arduino 本体 + 必要なセンサー類
実装例
下記の実装で次の動きを実現する。
- PCからLEDのON/OFFを送る。
- Arduinoからタッチセンサーの情報を送る
Arduino
const int LED = 13;
const int TOUCH = 2;
int receiveByte = 0;
String bufferStr = "";
String STR_ON = "ON";
String STR_OFF = "OFF";
void setup() {
pinMode(LED, OUTPUT); // LED(出力)
pinMode(TOUCH , INPUT); // タッチセンサー(入力)
Serial.begin(9600); // シリアルポート通信開始
}
void loop() {
// PCからの受信
bufferStr = "";
while (Serial.available() > 0) {
receiveByte = Serial.read();
if (receiveByte == (int)'\n') break;
bufferStr.concat((char)receiveByte);
}
// 受け取ったデータがあるならスイッチ操作
if (bufferStr.length() > 0) {
if (STR_ON.compareTo(bufferStr) == 0) {
digitalWrite(LED, HIGH);
} else {
digitalWrite(LED, LOW);
}
}
// タッチセンサーが反応したらPCに送る
int touchValue = digitalRead(TOUCH);
if (touchValue == HIGH){
Serial.println("T");
}
// wait
delay(500);
}
PC側(Arduino.js)
const SerialPort = require('serialport');
class Arduino {
/**
* @param {object} config
* @param {string} config.serialPort
* @param {int} config.baudRate
* @param {int} config.waitMsecAfterOpen
*/
constructor(config) {
this.config = config;
this.port = null;
this._onSerialList = [];
}
/**
* 非同期でArduinoを立ち上げる。他のタスクを妨げない。立ち上がってなければなにもしない。
*/
initArduino() {
return new Promise((resolve) => {
this.port = new SerialPort(this.config.serialPort, {
baudRate: this.config.baudRate
});
this.port.on('open', () => {
// すぐだとシリアル通信受け付けないので一定時間遅らせる。
setTimeout(() => resolve(), this.config.waitMsecAfterOpen);
});
const parser = this.port.pipe(new SerialPort.parsers.Readline({delimiter: '\n'}));
parser.on('data', (data) => {
data = data.replace(/\r/, '');
this._onData(data);
});
});
}
_onData(data) {
for (let onSerial of this._onSerialList) {
let matches = data.match(onSerial.condReg);
if (matches) {
onSerial.callback(...matches);
return;
}
}
if (data.match(/^\[log]/)) return;
throw new Error(`未知のデータ: ${data}`);
}
/**
* @callback Arduino_onSerial
* @param {string} data
*/
/**
* @param {Object.<string, Arduino_onSerial>} callbacks
*/
onSerial(callbacks) {
for (let cond of Object.keys(callbacks)) {
let condReg = new RegExp('^' + cond.replace(/\*/g, '.*?') + '$');
this._onSerialList.push({condReg, callback: callbacks[cond]});
}
}
sendToArduino(data) {
this.port.write(new Buffer(data + "\n"), (err, results) => {
if(err) {
throw new Error('Err: ' + err);
}
});
}
}
module.exports = Arduino;
PC側(main.js)
const Arduino = require('./Arduino');
const arduino = new Arduino({serialPort: 'COM5', baudRate: 9600, waitMsecAfterOpen: 2000});
arduino.onSerial({
if (data === 'T') {
console.log('タッチ');
}
});
// 5秒後にLEDをON
setTimeout(() => {
arduino.sendToArduino('ON');
}, 5000);
// 10秒後にLEDをOFF
setTimeout(() => {
arduino.sendToArduino('OFF');
}, 10000);
(async function () {
await lib.Arduino.initArduino();
})();