今回は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で制御するロボットについて以下の記事でまとめていますので、あわせてご覧ください。
それでは、また次の記事でお会いしましょう。
コメント