最近、Pythonでラズパイ側からArduino側へシリアル通信で情報を送るプログラムを作る機会があったので、その方法を紹介します。

環境

今回使用するデバイスと言語

Raspberry Pi3 => Python3
Arduino Leonardo => Arduino

流れ

  1. STEP.1Pythonライブラリのインストール

    Pythonで使用するserialをインストールします。

    pip

    pip3 install serial
    
  2. STEP.2Pythonプログラム

    上記でインストールしたserialライブラリを使用してシリアル通信します。
    ここでシリアル通信するにあたってのビットレートを指定する必要があるので、送信するデータ量にあわせて考えて置く必要があります。
    基本的に何も考えてない状態であれば、9600で問題ないと思います。

    今回のサンプルプログラムは、文字列を送信しエコーされた文字列を受け取って表示します。

  3. STEP.3Arduinoプログラム

    Arduinoサイドのプログラムは単純にシリアルデータを受け取るだけです。
    終了符号を付けて書く必要があります。
    タイムアウトでも可能ですが時間がかかってしまって効率が悪いので終了符号をつける方法を取ります。

    今回のサンプルプログラムは、受け取った文字列をエコーします。

  4. STEP.4ACM0の権限を変える

    ここが以外とハマってしまうポイントになっています。

    ディレクトリ

    /dev/ttyACM0
    

    Adruinoをラズパイ側に接続するとこのマウントポイントからArduino側にシリアル通信する事が可能です。
    ですが権限がroot:rootになっているため、一般ユーザが実行するとパーミッションエラーを吐かれます。

    そのため、chgrpやchownで自分へのパーミッションを空けておく必要があります。

  5. STEP.5プログラムの起動

    これでうまく動くはずです。

ソースコード

Python3

Python3
import serial

def send():
    with serial.Serial('/dev/ttyACM0',9600) as ser:

        str=bytes("AIUEO;",'utf-8')
        ser.write(str)
        #エコーされた文字を出力
        print(ser.readline())
        ser.close()

if __name__ == "__main__":
    send()

Arduino

Arduino
void setup() {
  Serial.begin(9600);
}

String serialRead() {
  String str;
  if (Serial.available() > 0) {
    str = Serial.readStringUntil(';');
  }
  return str;
}

void loop() {
  String cmd = serialRead();
  //cmdが受け取ったシリアルデータをエコーする
  Serial.println(cmd);
}