Envoyer des commandes au contrôleur T’REX
Nous avons déjà vu comment récupérer des informations depuis le contrôleur T’REX. Ici nous allons voir comment envoyer des commandes pour changer la vitesse des moteurs et modifier la position des servomoteurs.
Protocole de communication avec le T’REX
Le bus I²C nous permet d’echanger une serie d’octet entre 2 cartes, mais ne propose pas de protocole de communication à proprement parler. Le code d’exemple du T’REX propose un protocole pour l’envoi de commande.
Le T’REX peut recevoir 27 octets contenant :
- La fréquence de la PWM du pont en H
- La vitesse des 2 moteurs (les moteurs de chaque côté sont cablés en parallèle pour se comporter comme un moteur unique)
- La position des 6 servomoteurs
- La sensibilité du détecteur d’impact
- La tension minimale de coupure
- Les paramètres propres à l’I²C
Certaines de ces informations sont contenues sur 16 bits. Nous devons combiner deux octets pour envoyer la valeur.
Octet | Nom | Position | Description |
---|---|---|---|
1 | Start byte | Cet octet doit être 0x0F (15 décimal) | |
2 | PWM frequency |
Pour controler la vitesse des moteurs, le pont en H va envoyer une PWM ou signal carré. La fréquence de la PWM joue sur le couple des moteurs, leur échauffement ou le bruit si la fréquence est audible par l’oreille humaine.
|
|
3 | Left motor speed | High byte | Un entier entre +255 et -255. Une valeur négative signifie un changement de sens |
4 | Low byte | ||
5 | Left motor brake | 0 ou 1 En mode freinage, la valeur absolue de la vitesse du moteur est utilisée pour freiner la roue. +255 ou -255 sur la vitesse du moteur correspond à un freinage à 100%. |
|
6 | Right motor speed | High byte | Un entier entre +255 et -255. Une valeur négative signifie un changement de sens |
7 | Low byte | ||
8 | Right motor brake | 0 ou 1 En mode freinage, la valeur absolue de la vitesse du moteur est utilisée pour freiner la roue. +255 ou -255 sur la vitesse du moteur correspond à un freinage à 100%. |
|
9 | Servo 0 position | High byte | Un entier entre 1000 et 2000 qui détermine l’angle de l’axe. Sur les servomoteurs standards, un paramètre de valeur 1000 µs est la position extrême dans un sens (vers 0°), 2000 est la position extrême dans le sens inverse (vers 180°) et 1500 est au milieu (vers 90°). En fait, de nombreux fabricants ne respectent pas ces standards très précisément et les servomoteurs obéissent à des valeurs entre 700 et 2300. N’hésitez-pas à repousser ces valeurs limites tant que le servomoteur continue à se positionner. Noter cependant qu’essayer de positionner un servomoteur à ces positions extrêmes (souvent manifesté par un son grondant) entraîne une intensité élevée, et doit être évité Une valeur négative va positionner le servomoteur dans la même position à l’exception que le sens de direction sera inversé Une valeur de 0 indique qu’il n’y a pas de servomoteur connecté, et aucune pulsation ne sera envoyée. |
10 | Low byte | ||
11 | Servo 1 position | High byte | |
12 | Low byte | ||
13 | Servo 2 position | High byte | |
14 | Low byte | ||
15 | Servo 3 position | High byte | |
16 | Low byte | ||
17 | Servo 4 position | High byte | |
18 | Low byte | ||
19 | Servo 5 position | High byte | |
20 | Low byte | ||
21 | Accelerometer de-vibrate | Entier entre 0 et 255 – Par défaut 50 Après un impact, le châssis peut continuer à vibrer un court instant ce qui peut déclencher des faux positifs d’impact. Ce paramètre permet de désactiver temporairement la détection d’impact pendant une période de 2ms x valeur. La valeur par défaut de 50 correspond à un arrêt de 100ms. |
|
22 | Impact sensitivity | High byte | Entier supérieur à 0. 50 par défaut. Ajuste la sensibilité du détecteur d’impact pour éviter les faux positifs. La valeur maximale n’est pas indiquée dans la documentation :/ |
23 | Low byte | ||
24 | Low battery | High byte | Le contrôleur peut se couper automatiquement si la tension devient trop faible pour préserver la batterie. Une valeur de 550 arrêtera le contrôleur si la tension est inférieure à 5.5V. En sélectionnant une valeur supérieure à la tension de la batterie, on peut provoquer un arrêt forcé. |
25 | Low byte | ||
26 | I²C address | De 0 à 127. Par défaut 7 L’adresse par défaut est 0x07 (7 décimal) mais peut être changée à n’importe quel moment. La nouvelle adresse sera stoquée dans la mémoire EEPROM est sera conservée au redémarrage. |
|
27 | Clock frequency | 0=100kHz, 1=400kHz. Après un reset du contrôleur, la fréquence redevient 100kHz par défaut. |
Source :
http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.ServowriteMicroseconds
Communication avec Python
Je fais ici la suite de l’article sur la lecture des informations depuis le contrôleur T’REX. Je réutilise la libraire pigpio dont toutes les étapes d’installation se trouvent sur le précédent article.
Le code
#!/usr/bin/python3 # -*- coding: utf-8 -*- from __future__ import division # Pour division float from pprint import pprint import pigpio import time # Cablage TREX_ADDRESS = 0x07 SDA=2 # Pin no 3 SCL=3 # Pin no 5 # Connexion de pigpiod pigpio = pigpio.pi() def trex_command(): ''' Envoi une requete de commande au T'REX ''' # Verification de la connexion de pigpiod if not pigpio.connected: exit(0) # Preparation de la requete Bit Bang pigpio.bb_i2c_open(SDA, SCL, baud=100000) # Preparation des donnees right_motor_bytes = right_motor_speed.to_bytes(2, byteorder='big', signed=True) left_motor_bytes = left_motor_speed.to_bytes(2, byteorder='big', signed=True) servo_0_bytes = (0).to_bytes(2, byteorder='big'); servo_1_bytes = (0).to_bytes(2, byteorder='big'); servo_2_bytes = (0).to_bytes(2, byteorder='big'); servo_3_bytes = (0).to_bytes(2, byteorder='big'); servo_4_bytes = (0).to_bytes(2, byteorder='big'); servo_5_bytes = (0).to_bytes(2, byteorder='big'); impact_bytes = (50).to_bytes(2, byteorder='big'); battery_bytes = (550).to_bytes(2, byteorder='big'); # Envoi de la requete pigpio.bb_i2c_zip(SDA, [ 4, TREX_ADDRESS, # Set I2C adress to TREX_ADDRESS 2, # Start condition 7, 27, # Write 27 bytes of data 0x0F, # 1. Start byte 0x06, # 2. PWM frequency -> 122Hz left_motor_bytes[0], left_motor_bytes[1], # 3-4. Left motor speed 0x00, # 5 Left motor brake right_motor_bytes[0], right_motor_bytes[1], # 6-7. Right motor speed 0x00, # 8. Right motor brake servo_0_bytes[0], servo_0_bytes[1], # 9-10. Servo 0 position servo_1_bytes[0], servo_1_bytes[1], # 11-12. Servo 1 position servo_2_bytes[0], servo_2_bytes[1], # 13-14. Servo 2 position servo_3_bytes[0], servo_3_bytes[1], # 15-16. Servo 3 position servo_4_bytes[0], servo_4_bytes[1], # 17-18. Servo 4 position servo_5_bytes[0], servo_5_bytes[1], # 19-20. Servo 5 position 0x32, # 21. Accelerometer de-vibrate -> 50 impact_bytes[0], impact_bytes[1], # 22-23. Impact sensitivity battery_bytes[0], battery_bytes[1], # 24-25. Low battery TREX_ADDRESS, # 26. I2C address 0x00, # 27. Clock frequency 3, # Stop condition 0 # No more commands ]) # Fin de la requete Bit Bang pigpio.bb_i2c_close(SDA) if __name__ == '__main__': left_motor_speed = 0 right_motor_speed = 0 # Acceleration marche avant for i in range(0,256): left_motor_speed = i right_motor_speed = i trex_command() time.sleep(0.001) # Deceleration marche avant for i in range(255,-1, -1): left_motor_speed = i right_motor_speed = i trex_command() time.sleep(0.001) # Acceleration marche arriere for i in range(0,256): left_motor_speed = -i right_motor_speed = -i trex_command() time.sleep(0.001) # Deceleration marche arriere for i in range(255,-1, -1): left_motor_speed = -i right_motor_speed = -i trex_command() time.sleep(0.001) # Deconnexion de pigpiod pigpio.stop()
Source :
Troubleshooting
Can’t connect to pigpio at localhost(8888)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Can't connect to pigpio at localhost(8888) Did you start the pigpio daemon? E.g. sudo pigpiod Did you specify the correct Pi host/port in the environment variables PIGPIO_ADDR/PIGPIO_PORT? E.g. export PIGPIO_ADDR=soft, export PIGPIO_PORT=8888 Did you specify the correct Pi host/port in the pigpio.pi() function? E.g. pigpio.pi('soft', 8888) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
le daemon n’est pas démarré. Démarrez le avec sudo pigpiod
ou au démarrage du système avec sudo systemctl enable pigpiod
pigpio.error: ‘GPIO already in use’
Il n’y a pas eu de bb_i2c_close(SDA)
Il faut kill le daemon avec sudo killall pigpiod
, puis le relancer avec sudo pigpiod