ArduinoとRaspberry Piは全く異なる製品ですが、どちらも熱心なハッカーやメーカーのニーズに応えています。ArduinoをRaspberry Piに接続し、入力に反応してPython経由でRaspberry Piに出力を送信するスレーブデバイスとして使えたらどうでしょうか?
Arduinoは本格的なコンピューターではありませんが、内蔵ADCチップによるアナログ-デジタル変換など、いくつかの点でコンピューターより優れています。ArduinoをRaspberry Piに接続するには、専用のソフトウェアが必要になります。このチュートリアルはそこから始めます。
Raspberry PiをArduinoで使用するためのソフトウェア設定
Pythonコードを書く前に、Linux ARM 32ビット版Arduino IDEをダウンロードしてインストールする必要があります。インストールが完了したら、 Arduinoにデータを送信するために、ユーザー「pi」を適切なグループに追加する必要があります。piをグループに追加するには、ターミナルを開いて以下を入力します。
$ sudo usermod -a -G dialout pi
次に進む前に、Raspberry Piを再起動してください。Piを再起動したら、Arduino IDEを開き、「ファイル」>「例」>「基本」>「Blink」を選択し、「ツール」>「ボード」でボードを選択してください。テストではArduino Unoを使用しました。
次に、「ツール」>「ポート」に移動し、ボードのポートが選択されていることを確認します。「スケッチ」>「アップロード」(またはメニューの矢印をクリック)をクリックして、コードをArduinoにアップロードします。数秒後、Arduino内蔵のLEDがゆっくりと点滅するはずです。これでArduinoが動作していることがわかります。
テストが完了したら、ArduinoとPythonで通信するための特別なスケッチを書き込みます。「File > Examples > Firmata > StandardFirmata」と選択し、このスケッチをArduinoに書き込みます。書き込みが完了したら、Arduino IDEを閉じてください。pyFirmataライブラリをインストールするには、新しいターミナルを開き、以下を入力します。
$ sudo pip3 install pyfirmata
Raspberry PiでArduinoを使ってHello Worldプロジェクトをプレイ
ArduinoがPythonで動作するかテストするために、Arduinoの12番ピンに接続されたLEDを点灯させる簡単なスクリプトを作成します。接続については図をご覧ください。
Tom's Hardware の最高のニュースと詳細なレビューをあなたの受信箱に直接お届けします。
Arduinoを接続し、ターミナルに以下のコードを入力します。ttyUSB0やttyACM0などのUSBデバイスを探します。先に進む前にメモしておいてください。
$ dmesg
お好みのPython 3エディタ(IDLE、Thonny、nano、Vim)を使って新規ファイルを作成し、LED_test.py という名前を付けます。このファイルにPythonコードを記述します。まず、pyFirmataライブラリから2つのクラスをインポートします。これにより、Arduinoに接続できるようになります。次に、timeライブラリからsleep関数をインポートします。
from pyfirmata import Arduino, util
from time import sleep
次のステップは、 Raspberry PiからArduinoへの接続となる「board」というオブジェクトを作成することです。そのためには、dmesgから取得したUSBデバイス情報を使用する必要があります。今回の場合、ArduinoはttyUSB0に接続していました。
board = Arduino('/dev/ttyUSB0')
LEDという変数は、Arduinoのピン番号を格納するために使用されます。この変数を作成するには、以下の行を追加します。
led = 12
while Trueループの中に、0.2秒ごとにLEDのオン/オフを切り替えるコードを記述します。オブジェクトboardを呼び出し、ピンをデジタル値(0,1)で制御するクラスを定義し、ピンに1を書き込んでLEDを点灯させます。ピンを識別するために変数ledを使用していることに注意してください。その後、0.2秒間スリープし、その後ピンをオフして再びスリープします。
while True:
board.digital[led].write(1) sleep(0.2) board.digital[led].write(0) sleep(0.2)
コードを保存し、エディターから実行します (IDLE 実行 > モジュール実行/Thonny 実行 > 現在のスクリプト実行)。数秒後に Arduino に接続された LED が点滅し、接続が機能していることが証明されます。
最終的な Python スクリプトは次のようになります。
from pyfirmata import Arduino, util
from time import sleep
board = Arduino('/dev/ttyUSB0')
led = 12
while True: board.digital[led].write(1) sleep(0.2) board.digital[led].write(0)
sleep(0.2)
Raspberry PiとArduinoでLEDライトを点滅させる
では、新しいプロジェクトを作りましょう。これは点滅するLEDですが、点滅間隔はポテンショメータというアナログ電子部品で制御します。Raspberry Piでは通常、ポテンショメータはADC(アナログ-デジタル変換)ボードなしでは使えません。
Arduinoから返される値を使って、LEDの点滅速度を制御できます。先ほど構築・テストした既存のLEDテスト回路にポテンショメータを追加します。詳細については、下の図をご覧ください。
このプロジェクトのコードは、新しい空のファイルで開始し、同じ行を使用して、Arduino で使用されているピンをインポートおよび構成します。
from pyfirmata import Arduino, util from time import sleep board = Arduino('/dev/ttyUSB0') led = 12
Arduinoからアナログ値を読み取るには、メインコードを中断せずに実行されるスレッドを作成する必要があります。スレッドを開始する前に、 itというオブジェクトを作成し、Arduinoに接続する必要があります。
it = util.Iterator(board) it.start() board.analog[0].enable_reporting()
コードの本体はwhile Trueループで、ポテンショメータに接続されたアナログピン0の現在の値を読み取り、その値をvalueという変数に格納します。この値はPythonシェルに表示されます。
while True: value = board.analog[0].read() print(value)
条件付きテストが変数 valueに適用されます。値にデータがない場合、none が返され、コードがクラッシュします。そのため、if条件で値をチェックし、none の場合は 0 に変更します。
if value == None: value = 0
これをテストするためのもう一つの条件は、値が0.05より大きい場合、返されるアナログ値は0.0から1.0の間であるということです。値が0.05より大きい場合、LEDは点灯し、コードを一時停止してLEDのオン/オフを維持するために使用されるスリープ間隔は、値によって制御されます。
elif value > 0.05: board.digital[led].write(1) sleep(value) board.digital[led].write(0) sleep(value)
最後のコード行はelse条件で、値が0.05未満の場合にLEDを消灯します。コードを保存して実行してください。ポテンショメータを回してLEDが点灯するのを確認してください。最終的なPythonコードは以下のようになります。
from pyfirmata import Arduino, util from time import sleep board = Arduino('/dev/ttyUSB0') led = 12 it = util.Iterator(board) it.start() board.analog[0].enable_reporting()
while True: value = board.analog[0].read() print(value) if value == None: value = 0 elif value > 0.05: board.digital[led].write(1) sleep(value) board.digital[led].write(0) sleep(value)
この記事はもともと Linux Format Magazine 260 号に掲載されたものです。