注釈
こんにちは、SunFounderのRaspberry Pi & Arduino & ESP32愛好家コミュニティへようこそ!Facebook上でRaspberry Pi、Arduino、ESP32についてもっと深く掘り下げ、他の愛好家と交流しましょう。
Why Join?
エキスパートサポート:コミュニティやチームの助けを借りて、販売後の問題や技術的な課題を解決します。
学び&共有:ヒントやチュートリアルを交換してスキルを向上させましょう。
独占的なプレビュー:新製品の発表や先行プレビューに早期アクセスしましょう。
特別割引:最新製品の独占割引をお楽しみください。
祭りのプロモーションとギフト:ギフトや祝日のプロモーションに参加しましょう。
👉 私たちと一緒に探索し、創造する準備はできていますか?[here]をクリックして今すぐ参加しましょう!
オンボードMCU
Robot HATは、ArteryのAT32F415CBT7マイクロコントローラーを搭載しています。これは、最大クロック周波数が150MHzのARM Cortex-M4プロセッサーです。マイクロコントローラーには、256KBのフラッシュメモリと32KBのSRAMがあります。
オンボードのPWMとADCは、マイクロコントローラによって駆動されます。Raspberry Piとマイクロコントローラ間の通信は、I2Cインターフェイスを通じて確立されます。通信に使用されるI2Cアドレスは0x14(7ビットアドレス形式)です。
紹介
オンボードMCUのRESETピンは、Raspberry PiのGPIO 5、または robot_hat.Pin
の MCURST
に接続されています。MCUは7ビットアドレスの 0x14
を使用しています。
ADC
レジスタアドレスは3バイトで、0x170000から0x140000までがADCチャンネル0から3です。ADCの精度は12ビットで、値は0から4095までです。robot_hat.ADC
で詳細を確認してください。
アドレス |
説明 |
---|---|
|
ADCチャンネル0 |
|
ADCチャンネル1 |
|
ADCチャンネル2 |
|
ADCチャンネル3 |
|
ADCチャンネル4(バッテリーレベル) |
例:
チャンネル0のADC値を読む:
from smbus import SMBus
bus = SMBus(1)
# smbus only support 8 bit register address, so write 2 byte 0 first
bus.write_word_data(0x14, 0x17, 0)
msb = bus.read_byte(0x14)
lsb = bus.read_byte(0x14)
value = (msb << 8) | lsb
PWM
PWMは1バイトのレジスタと2バイトの値を持っています。
PWM周波数の変更
周波数はプリスケーラと周期で定義されます。
周波数を設定するには、まず設定したい周期を定義する必要があります。Arduinoでは通常255、PCA9685では4095です。
CPUクロックは72MHzです。そこから、希望の周波数に応じたプリスケーラを計算できます
プリスケーラ = 72MHz / (周期 + 1) / 周波数 - 1
周期にこだわらない場合は、周波数から周期とプリスケーラの両方を計算する方法があります。 robot_hat.PWM.freq()
を参照してください。
パルス幅
チャンネルのパルス幅を制御するのは簡単で、値をレジスタに書き込むだけです。
しかし 値とは何か?PWMを50%のパルス幅に設定したい場合、周期が正確に何であるかを知る必要があります。上記の計算に基づき、周期を4095に設定した場合、パルス値を2048に設定すると、約50%のパルス幅になります。
アドレス |
説明 |
---|---|
|
PWMチャンネル0 オン値 を設定 |
|
PWMチャンネル1 オン値 を設定 |
|
PWMチャンネル2の オン値 を設定 |
|
PWMチャンネル3の オン値 を設定 |
|
PWMチャンネル4の オン値 を設定 |
|
PWMチャンネル5の オン値 を設定 |
|
PWMチャンネル6の オン値 を設定 |
|
PWMチャンネル7の オン値 を設定 |
|
PWMチャンネル8の オン値 を設定 |
|
PWMチャンネル9の オン値 を設定 |
|
PWMチャンネル10の オン値 を設定 |
|
PWMチャンネル11の オン値 を設定 |
|
モーター2の速度 オン値 を設定 |
|
モーター1の速度 オン値 を設定 |
プリスケーラー
0x40から始まるレジスタはPWMプリスケーラーを設定するためのもので、範囲は0〜65535です。全14チャンネルに対してタイマーは4つのみです。 PWMタイマー(重要) を参照してください。
アドレス |
説明 |
---|---|
|
タイマー0の プリスケーラー を設定 |
|
タイマー1の プリスケーラー を設定 |
|
タイマー2の プリスケーラー を設定 |
|
タイマー3の プリスケーラー を設定 |
周期
0x44から始まるレジスタはPWM周期を設定するためのもので、範囲は0〜65535です。全14チャンネルに対してタイマーは4つのみです。 PWMタイマー(重要) を参照してください。
アドレス |
説明 |
---|---|
|
タイマー0の 周期 を設定 |
|
タイマー1の 周期 を設定 |
|
タイマー2の 周期 を設定 |
|
タイマー3の 周期 を設定 |
PWMタイマー(重要)
PWMタイマーとは何ですか?PWMタイマーは、PWMチャンネルをオン・オフするためのツールです。
MCUにはPWM用のタイマーが4つしかありません:つまり、同じタイマーで異なるチャンネルの周波数を設定することはできません。
例:チャンネル0に周波数を設定すると、チャンネル1、2、3に影響が及びます。チャンネル2の周波数を変更すると、チャンネル0、1、3が上書きされます。
これは、常に周波数を変更するパッシブブザーと固定周波数50Hzが必要なサーボを同時に制御したい場合のような状況です。この場合、それらを2つの異なるタイマーに分けるべきです。
タイマー |
PWMチャンネル |
---|---|
タイマー0 |
0, 1, 2, 3 |
タイマー1 |
4, 5, 6, 7 |
タイマー2 |
8, 9, 10, 11 |
タイマー3 |
12, 13(モーター用) |
例
from smbus import SMBus
bus = SMBus(1)
# Set timer 0 period to 4095
bus.write_word_data(0x14, 0x44, 4095)
# Set frequency to 50Hz,
freq = 50
# Calculate prescaler
prescaler = int(72000000 / (4095 + 1) / freq) - 1
# Set prescaler
bus.write_word_data(0x14, 0x40, prescaler)
# Set channel 0 to 50% pulse width
bus.write_word_data(0x14, 0x20, 2048)
MCUをリセット
現在のファームウェアは固定3バイトの値を読み取り、その後ADC値を返すかPWMを制御できます。そのためADCレジスタは最後の2バイトが0の3バイトが必要です。
そして、通信の途中でプログラムが中断されると、ファームウェアが固まってデータがずれる可能性があります。3バイトのデータ待ちにはタイムアウトも設定しています。
そのような場合は、MCUをリセットする必要があります。リセットするには、robot_hatコマンドを使用できます:
robot_hat reset_mcu
または、Pythonコードで行うこともできます:
from robot_hat import reset_mcu
reset_mcu()
あるいは、リセットピン(GPIO 5)を10ms引き下げてから、さらに10ms引き上げるだけで、それが reset_mcu
が行うことです。
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(5, GPIO.OUT)
GPIO.output(5, GPIO.LOW)
time.sleep(0.01)
GPIO.output(5, GPIO.HIGH)
time.sleep(0.01)