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.

  • 1: 31250 Hz – Silencieux mais la plupart des moteurs auront un couple faible et vont chauffer
  • 2: 3906 Hz – Non recommandé, bruit très aigu et couple faible
  • 3: 977 Hz – Non recommandé, trop de bruit
  • 4: 488 Hz – Non recommandé, trop de bruit
  • 5: 244 Hz – Non recommandé, trop de bruit
  • 6: 122 Hz – Par défaut – Bon couple, bruit faible
  • 7: 31 Hz – Meilleur couple mais plus de vibration
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 :

Documentation de pigpio

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

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *