今回はRaspberry PiとArduino UNOを接続してシリアル通信を行う方法について解説します。
Raspberry Piは高いクロックで動作するARMコアを搭載しており、画像処理や機械学習に使用することが可能ですが、一方でリアルタイム処理は苦手としています。
Arduinoはシングルタスクではありますが、タイマー割り込みが手軽に実装できたりと、ハードウェアの制御が得意です。
この2つのボードを組み合わせて動作させるための、ボード間シリアル通信の方法を紹介します。
また、Raspberry Piに関する記事を以下のページでまとめていますので、あわせてご覧ください。

Raspberry PiとArduino UNO R3のハードウェアを接続する方法
Raspberry PiとArduino UNO間のハードウェア接続はUSBケーブルで行います。
Raspberry Pi側がType-A、Arduino側がType-Bコネクタとなります。

ケーブルはArduino書き込み用のものがある場合はそのまま使用できます。
私の場合はロボットで使用したかったため、以下のような短めのUSBケーブルを購入しました。
COMポートの接続を確認する
Raspberry PiにUSBケーブルでArduinoを接続することで、Raspberry Pi側からはCOMポートとして認識されます。
接続の確認を行うため、Raspberry Piのターミナルで以下のコマンドを実行してください。
ls -l /dev/ | grep tty以下のようにデバイス一覧が表示されます。
crw–w—- 1 root tty 4, 8 Dec 5 14:05 tty8
crw–w—- 1 root tty 4, 9 Dec 5 14:05 tty9
crw-rw—- 1 root dialout 166, 0 Dec 5 14:05 ttyACM0
crw——- 1 root root 5, 3 Dec 5 14:05 ttyprintk
crw-rw—- 1 root tty 7, 0 Dec 5 14:05 vcs
crw-rw—- 1 root tty 7, 1 Dec 5 14:05 vcs1
crw-rw—- 1 root tty 7, 2 Dec 5 14:05 vcs2
以下の行が表示されれば、Arduinoと接続されています。
crw-rw—- 1 root dialout 166, 0 Dec 5 14:05 ttyACM0
COMポートを使ったシリアル通信を行うソースコード
ここからは実際にCOMポートを使用してシリアル通信を行うための、それぞれのボードのコードの実装方法について解説します。
Arduino側のプログラム
Arduino UNO R3側のスケッチのコードです。
プログラムが実行されるとHello, Raspberry Piという文字列のデータが2秒間隔で送信されます。
void setup() {
  // シリアル通信を9600bpsで開始
  Serial.begin(9600);
}
void loop() {
  // "Hello, Raspberry Pi"を送信
  Serial.println("Hello, Raspberry Pi");
  // 2秒待機
  delay(2000);
}Raspberry Pi側のデータを受信したい場合は?
逆に受信を行いたい場合はSerial.readString関数を使用するだけで取得できます。
    // シリアルからデータを読み取り、Stringとして格納
    String receivedStr = Serial.readString();基本的に文字列データでのやり取りとなりますので、数値を扱いたい場合は受信後にキャストしてください。
Raspberry Pi側のプログラム
Raspberry Pi側のコードの作成方法を解説します。
ライブラリのインストール
まずPythonのシリアル通信ライブラリをインストールします。
sudo apt-get update
sudo apt-get install python3-serial作成したPythonコード
続いてこちらがArduino側とシリアル通信をするPythonのコードです。
Arduino側から送られたデータを受信し、コンソールに表示します。
import serial
import time
# Arduinoが接続されているシリアルポートとボーレートを設定
serial_port = '/dev/ttyACM0'
baud_rate = 9600
try:
    # シリアルポートを開く
    ser = serial.Serial(serial_port, baud_rate)
    print("シリアルポートを開きました: " + serial_port)
    while True:
        # データが利用可能であれば読み取る
        if ser.in_waiting > 0:
            line = ser.readline().decode('utf-8').rstrip()
            print("受信データ: " + line)
except KeyboardInterrupt:
    # Ctrl+Cが押されたら終了
    print("プログラムを終了します")
    ser.close()
except Exception as e:
    # その他のエラー
    print("エラーが発生しました: " + str(e))
    ser.close()
Arduino側に送信したい場合は?
Arduino側に送信したい場合はser.writeメソッドの引数に送りたいデータを設定するだけです。
        # 整数を送信
        ser.write(str(value).encode())実行結果
まず、Arduino側を起動後に、Raspberry Pi側のPythonコードを実行します。
すると以下のようにArduino側から送信された文字列を、Raspberry Pi側のコンソールで表示することができました。

まとめ
今回はRaspberry PiとArduinoを接続し、シリアル通信を行う方法を解説しました。
2つのボードを組み合わせることで、処理の並列化やIOの拡張も可能ですので、ぜひ試してみてください。
また、Arduinoで制御するロボットについて以下の記事でまとめていますので、あわせてご覧ください。

それでは、また次の記事でお会いしましょう。

					
					
					
					
					
	









コメント