【ラズベリーパイ3+Arduino】シリアル通信で複数のLED点滅

この記事では、RaspberryPi3からシリアル通信でArduinoに文字列を送り、複数のLEDを点滅させる方法をソースコード付きで解説します。

シリアル通信でLED点滅

Raspberry Pi3 (Python)から Arduino経由で11~13番ピンに繋いだLEDを点滅させます。
点滅の合図はシリアル通信で送信する文字列で行いました。
(11~13番ピンをオンにするかオフにするかをカンマ区切りの文字列で送ります)

回路構成

回路構成(配線図)です。

【使用機器】
ラズベリーパイ3 ×1
Arduino UNO ×1
LED ×1
抵抗(470Ω) ×1
ブレッドボード ×1
・ジャンパーワイヤ(メス-オス) 数本

※LEDとピンの間に470kΩ程度の抵抗を入れます。
※LEDをさす際はアノードとカソードの向きに注意してください。

ソースコード

サンプルプログラムのソースコードです。

Arduino側

String cmds[3] = {"\0"}; // 分割された文字列を格納する配列
char data[20];   // 文字列格納用
int i = 0;  // 文字数のカウンタ
int index;
#define PIN1 11
#define PIN2 12
#define PIN3 13

// 文字列分割
int split(String data, char delimiter, String *dst){
    int index = 0;
    int arraySize = (sizeof(data)/sizeof((data)[0]));
    int datalength = data.length();
    for (int i = 0; i < datalength; i++) {
        char tmp = data.charAt(i);
        if ( tmp == delimiter ) {
            index++;
            if ( index > (arraySize - 1)) return -1;
        }
        else dst[index] += tmp;
    }
    return (index + 1);
}

// データ受信
String serialRead(){
  // データ受信したとき
  if (Serial.available()) {
    // 1文字ずつ読み込み
    data[i] = Serial.read();
    // 文字数が10以上 or 終端文字なら終了
    if (i > 20 || data[i] == '\0'){
      // 配列リセット
      for(int j=0;j<index;j++) cmds[j] = "";
      // カンマ区切りで分割
      index = split(data, ',', cmds);
      i = 0;
    }
    else { i++; }

  }
  return String(data);
}

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

void loop() {
  String cmd = serialRead();
  // 受信したデータに応じてLEDを点灯・消灯
  if(cmds[0] == "on") digitalWrite(PIN1, HIGH);
  if(cmds[0] == "off") digitalWrite(PIN1, LOW);
  if(cmds[1] == "on") digitalWrite(PIN2, HIGH);
  if(cmds[1] == "off") digitalWrite(PIN2, LOW);
  if(cmds[2] == "on") digitalWrite(PIN3, HIGH);
  if(cmds[2] == "off") digitalWrite(PIN3, LOW);
}

※何かデータが送られて来たらLEDを点灯

ラズベリーパイ側

ラズベリーパイ側(Python)のコードです。

# -*- coding: utf-8 -*-
import serial

def main():
    ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)
    while True:
        cmd = input()
        cmd = cmd + "\0"
        ser.write(cmd.encode())
        # python2 ver
        #flag = raw_input()
        #ser.write(flag+"\n")
        if(flag == 'q'): # qが入力されたら通信終了
            break
    ser.close()

if __name__ == '__main__':
    main()

■serial.Serial(シリアルポート, 通信速度, timeout=タイムアウト時間[s])

※ArduinoをUSBポートに抜き差しするとArduinoが接続されているシリアルポート「/dev/ttyACM0」が変化することがあります。
「serial.serialutil.SerialException: could not open port」などとエラーが出た場合は、下記事を参考に変化後の値に書き換えて下さい。
【ラズベリーパイ3】dmesgコマンドでArduinoのUSBシリアルポートを確認

実行結果

「on, on, off」と入力→11・12番ピン点灯、13番ピン消灯
「off, off, on」と入力→11・12番ピン消灯、13番ピン点灯

【関連記事】
ラズベリーパイ3で電子工作入門
Arduino入門 サンプル集
Python入門 サンプル集

コメント