純粋なPythonの記事ではありませんが、トラブルが解決できた事例ができましたので記事にしました。
私はArduino(アルドゥイーノ)が好きで、ロボット制御や簡単なIoTシステムを構築しています。
「Pythonで顔認識したらサーボモータでカメラを顔の方に向けたい」と考え、調査中にサーボモータの制御でつまづきました笑。
Arduino UNO R4 MINIMAでSG90サーボを使用する際、エラーが出てしまいました。
以前、UNO R3で遊んでいた時はできたのに、なぜだろう?と調べた結果、一つの解決策がヒットしましたので公開します。
あくまで一つの解決策であり、誰しも当てはまる事例ではないかもしれませんが、お役に立てれば幸いです。
また、動作確認としてPythonのinputメソッドからサーボの回転角度を指示するスクリプトを使用しています。
実行環境
まず、私の環境を簡単に紹介しておきます。
- Windows10/11
- Arduino IDE 2.2.1
- Arduino本体 UNO R4 MINIMA
- サーボ:SG90
- Python 3.11
上記は現時点の最新バージョンです。
UNO R3とUNO R4 MINIMAの違い
この記事の重要なファクターとなる両者の違いについて理解する必要があります。
基本情報
Arduino UNO R4 MINIMAは、Arduino UNO R3の後継モデルとして設計され、いくつかの重要な技術的進歩を含んでいます。
UNO R3からUNO R4 MINIMAへの変更点のうち、今回のトラブルに関する内容に絞って説明します。
マイクロコントローラの変更
UNO R3は8-bitのATMega328Pマイコンを搭載していましたが、UNO R4 MINIMAは32-bitのルネサス RA4M1マイコンを搭載しています。
この変更により、マイコンの性能が大幅に向上し、クロック速度、メモリ、およびフラッシュストレージがそれぞれ3~16倍に増加しています。
この変更は「WindowsPCのCPUがIntelのcore i3からcore i7になった」というような同じ製品のアップグレードの話ではなく、「MacのCPUがIntel系からM1チップ(Appleシリコン)に切り替わった」ほどの違いです。
以前のマイコンでできたことが、今後もいろいろできなくなったり変更されるのかもしれません。
今回のトラブルの原因は、まさにこのマイコンの変更が原因となっています。
トラブルの状況
Arduino UNO R3では問題なくできるのに、UNO R4 MINIMAではエラーが出てしまう状況です。
R4 MINIMAで実行したときのエラーはこちら。
警告:ライブラリServoはアーキテクチャavr, megaavr, sam, samd, nrf52, stm32f4, mbed, mbed_nano, mbed_portenta, mbed_rp2040に対応したものであり、アーキテクチャrenesas_unoで動作するこのボードとは互換性がないかもしれません。
In file included from C:\papa3\pythonarduino\servotest\servotest.ino:1:0:
C:\Users\papa3\AppData\Local\Arduino15\libraries\Servo\src/Servo.h:77:2: error: #error "This library only supports boards with an AVR, SAM, SAMD, NRF52 or STM32F4 processor."
#error "This library only supports boards with an AVR, SAM, SAMD, NRF52 or STM32F4 processor."
^~~~~
exit status 1
Compilation error: exit status 1
このエラーについて詳しく解説すると、以下の通りです。
難しいので要約すると、
ということになります。
*ルネサスアーキテクチャ=renesas_uno
これを解決しましょう。
解決策
これまで使用していたServoライブラリが古いために起きるエラーです。
つまり、ServoライブラリをアップデートまたはインストールすればOKです。
ライブラリをインストール(アップデート)するには、
ライブラリマネージャーを開き、
検索ボックスに「servo」と入力すると候補が表示されるので、
一番上に表示される「Servo」ライブラリのインストール(またはアップデート)をクリックし、
Servoライブラリが「installed」になれば完了。
この状態でサーボを利用するためのArduinoコードをコンパイル(検証)または書き込みを実行すると、問題なく実行できます。
上はUNO R4に書き込みが完了した図。
もちろん、UNO R3でもこれまで通り書き込みできます。
実行したコードの公開
今回のテストで使用したコードを公開しておきます。
これは、Pythonのinputメソッドでサーボの角度を入力すると、その値がArduinoに送られるというものです。
使用しているサーボはSG90というArduinoではメジャーなものです。
ただし、このサーボの可動域は0度から180度のため、Python側で制限をかけています。
Arduinoのコード
本体の9番ピンに接続したサーボを制御する設定です。
Pythonから受け取ったシリアルデータ(0~180の値)を受け取り、それをサーボの角度に指定するだけのものです。
#include <Servo.h>
Servo myServo; // サーボモータのインスタンスを作成
void setup() {
Serial.begin(9600); // シリアル通信の開始
myServo.attach(9); // ピン9にサーボモータを接続
}
void loop() {
if (Serial.available() > 0) { // シリアルデータが利用可能な場合
String angleStr = Serial.readString(); // シリアルデータを読み取る
int angle = angleStr.toInt(); // 文字列を整数に変換する
myServo.write(angle); // サーボモータを指定された角度に移動する
}
}
最初にこれをArduino本体に書き込んでおく必要があります。
この時点でエラーが出る場合、他の問題が考えられます。
Pythonのスクリプト
今回の目的はinputメソッドで値を入力し、その値をArduinoにシリアル値として渡すことです。
ただし、SG90サーボは0~180度の範囲しか動作しないため、故障を防ぐためにPython側で範囲をチェックしています。
範囲外の角度を入力した場合、elseによって警告を出しています。
また、プログラムはwhile Trueにより常に実行されるため、終了したいときはctrl+cで終了することができるようになっています。
import serial
# COMポートを開く
print("Open Port")
ser = serial.Serial('COM6', 9600)
while True:
try:
# 0~180の範囲内で角度を入力する
angle = input("Enter angle between 0 and 180: ")
# 角度が範囲内にあるかどうかを確認する
if 0 <= int(angle) <= 180:
ser.write(angle.encode()) # 角度を送信する
else:
print("Invalid angle! Please enter a value between 0 and 180.") # 無効な角度を警告する
except KeyboardInterrupt:
break # Ctrl + Cが押された場合、ループを抜ける
# ポートを閉じる
print("Close Port")
ser.close()
上記はWindowsにおいてArduinoを接続したUSBポートが「COM6」の場合の書き方です。
これはお使いの環境によって異なるため、確認してください。
なお、Macの場合はWindowsと異なり、「ser = serial.Serial(‘/div/ttyUSB0’, 9600)」のようになります。
※手元にmacがなかったので、画面キャプチャは紹介できませんでした。
また、上記はPySerialというライブラリを利用してArduinoと接続しています。
詳しくはこちらの記事を参照してください。
まとめ
今回は、Arduino UNO R4 MINIMAでSG90サーボを使用するときにエラーが出た場合の解決方法について解説しました。
もし、この記事の内容でも解決できないという場合、コメントやフォームにてご質問ください。
今後もPythonを中心としたプログラミングの情報をお届けします。
以下のメルマガにご登録頂くと、不定期に配信をお届けします。
ぜひ購読してください!
それでは、ステキなPythonライフを!