6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Arduino と PC でシリアルポート通信する

Last updated at Posted at 2018-08-27

概要

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();
})();
6
2
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
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?