On-Board-MCU

Der Robot HAT ist mit einem AT32F415CBT7 Mikrocontroller von Artery ausgestattet. Es handelt sich um einen ARM Cortex-M4 Prozessor mit einer maximalen Taktfrequenz von 150MHz. Der Mikrocontroller verfügt über 256KB Flash-Speicher und 32KB SRAM.

Das Onboard-PWM und ADC werden vom Mikrocontroller gesteuert. Die Kommunikation zwischen dem Raspberry Pi und dem Mikrocontroller erfolgt über die I2C-Schnittstelle. Die für die Kommunikation verwendete I2C-Adresse ist 0x14 (7-Bit-Adressformat).

Einführung

Der RESET-Pin des Onboard-MCU ist mit dem Raspberry Pi GPIO 5 oder MCURST für robot_hat.Pin verbunden. Der MCU verwendet die 7-Bit-Adresse 0x14.

ADC

Registeradressen sind 3 Byte, von 0x170000 bis 0x140000 sind es ADC-Kanäle 0 bis 3. Die ADC-Präzision beträgt 12 Bit, und der Wert liegt zwischen 0 und 4095. Weitere Einzelheiten finden Sie in robot_hat.ADC.

Adresse

Beschreibung

0x170000

ADC-Kanal 0

0x160000

ADC-Kanal 1

0x150000

ADC-Kanal 2

0x140000

ADC-Kanal 3

0x130000

ADC-Kanal 4 (Batteriestand)

Beispiel:

ADC-Wert des Kanals 0 lesen:

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 hat ein 1-Byte-Register mit 2-Byte-Werten.

Ändern der PWM-Frequenz

Die Frequenz wird mit Vorwähler und Periode definiert.

Um die Frequenz einzustellen, müssen Sie zuerst die gewünschte Periode definieren. Wie bei Arduino ist dies normalerweise 255, oder wie bei PCA9685 4095.

Die CPU-Taktfrequenz beträgt 72 MHz. Dann können Sie den Vorwähler aus Ihrer gewünschten Frequenz berechnen

Vorwähler = 72MHz / (Periode + 1) / Frequenz - 1

Wenn Ihnen die Periode egal ist, gibt es eine Möglichkeit, sowohl die Periode als auch den Vorwähler aus der Frequenz zu berechnen. Siehe robot_hat.PWM.freq().

Pulsbreite

Die Kontrolle der Pulsbreite des Kanals ist recht einfach, schreiben Sie einfach den Wert in das Register.

Aber was ist der Wert? Wenn Sie die PWM auf eine 50%-Pulsbreite einstellen möchten, müssen Sie genau wissen, was die Periode ist. Basierend auf der oben genannten Berechnung, wenn Sie die Periode auf 4095 einstellen, dann entspricht das Setzen des Puls-Wertes auf 2048 ungefähr einer 50%-Pulsbreite.

Adresse

Beschreibung

0x20

PWM-Kanal 0 Einschaltwert einstellen

0x21

PWM-Kanal 1 Einschaltwert einstellen

0x22

PWM-Kanal 2 Einschaltwert einstellen

0x23

PWM-Kanal 3 Einschaltwert einstellen

0x24

PWM-Kanal 4 Einschaltwert einstellen

0x25

PWM-Kanal 5 Einschaltwert einstellen

0x26

PWM-Kanal 6 Einschaltwert einstellen

0x27

PWM-Kanal 7 Einschaltwert einstellen

0x28

PWM-Kanal 8 Einschaltwert einstellen

0x29

PWM-Kanal 9 Einschaltwert einstellen

0x2A

PWM-Kanal 10 Einschaltwert einstellen

0x2B

PWM-Kanal 11 Einschaltwert einstellen

0x2C

Geschwindigkeit von Motor 2 Einschaltwert einstellen

0x2D

Geschwindigkeit von Motor 1 Einschaltwert einstellen

Vorteiler

Register ab 0x40 dienen zur Einstellung des PWM-Vorteilers. Der Bereich umfasst 0~65535. Es gibt nur 4 Timer für alle 14 Kanäle. Siehe PWM Timer(WICHTIG)

Adresse

Beschreibung

0x40

Timer 0 Vorteiler einstellen

0x41

Timer 1 Vorteiler einstellen

0x42

Timer 2 Vorteiler einstellen

0x43

Timer 3 Vorteiler einstellen

Periode

Register ab 0x44 dienen zur Einstellung der PWM-Periode. Der Bereich umfasst 0~65535. Es gibt nur 4 Timer für alle 14 Kanäle. Siehe PWM Timer(WICHTIG)

Adresse

Beschreibung

0x44

Timer 0 Periode einstellen

0x45

Timer 1 Periode einstellen

0x46

Timer 2 Periode einstellen

0x47

Timer 3 Periode einstellen

PWM-Timer(WICHTIG)

Was ist ein PWM-Timer? Der PWM-Timer ist ein Werkzeug, um den PWM-Kanal für Sie ein- und auszuschalten.

Der MCU hat nur 4 Timer für PWM: Das bedeutet, Sie können die Frequenz nicht für verschiedene Kanäle mit demselben Timer einstellen.

Beispiel: Wenn Sie die Frequenz auf Kanal 0 einstellen, werden die Kanäle 1, 2, 3 beeinflusst. Wenn Sie die Frequenz von Kanal 2 ändern, werden die Kanäle 0, 1, 3 überschrieben.

Dies geschieht beispielsweise, wenn Sie sowohl einen passiven Summer (der ständig die Frequenz ändert) als auch einen Servo (der eine feste Frequenz von 50 Hz benötigt) steuern möchten. Dann sollten Sie diese auf zwei verschiedene Timer aufteilen.

Timer

PWM-Kanal

Timer 0

0, 1, 2, 3

Timer 1

4, 5, 6, 7

Timer 2

8, 9, 10, 11

Timer 3

12, 13 (für Motoren)

Beispiel

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 zurücksetzen

Derzeit liest die Firmware einen festen 3-Byte-Wert, dann kann sie ADC-Werte zurückgeben oder PWM steuern. Deshalb benötigt das ADC-Register 3 Byte, wobei die letzten 2 Byte 0 sind.

Wenn Ihr Programm mitten in der Kommunikation unterbrochen wird, kann die Firmware hängen bleiben und die Daten verschieben. Selbst wenn wir ein Timeout beim Warten auf 3-Byte-Daten haben.

Wenn dies der Fall ist, müssen Sie den MCU zurücksetzen. Um ihn zurückzusetzen, können Sie den Befehl robot_hat verwenden:

robot_hat reset_mcu

Oder Sie können es in Ihrem Python-Code tun:

from robot_hat import reset_mcu
reset_mcu()

Oder Sie können einfach den Reset-Pin (GPIO 5) für 10 ms herunterziehen und dann für weitere 10 ms wieder hochziehen, denn das ist es, was reset_mcu macht.

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)