Ceci est une ancienne révision du document !
La carte SD21 permet de commander 21 servo-moteurs analogiques à partir d'une liaison i2C grace au PIC 18F2220 monté sur la carte. Il est également possible d'installer d'autres microcontrolleurs (BX-24, PICAXE, BS2P…) pour contrôler directement les servo-moteurs.
Nous utiliserons la carte SD21 avec une ARDUINO UNO en utilisant la liaison i2C.
Pour chaque servo, il est possible d'indiquer la position à atteindre et la vitesse du mouvement. 3 registres sont réservés pour chaque servo-moteurs : 1 pour la vitesse et 2 pour la position. Ces registres sont mis à jour via la liaison i2c.
La position est la largeur de l'impulsion en µs. En général, l'impulsion est comprise entre 1000 et 2000 us mais cet intervalle dépend de la référence du servo-moteur.
La vitesse du mouvement est obtenue grace à l'equation suivante : time for move = ((Target_position – start_ position) / speed) * 20 ms.
Il est nécessaire de mettre 2 résistances de pull-up sur SDA et SCL. La datasheet indique la valeur minimale de ces résistances : Rp = (Vcc-0.4V) / 3mA
Dans notre cas, on a Vcc = 5V donc Rp = (5-0.4)/0.003 = 1533 ohm. On prendra donc une résistance de 1.8 Kohm.
On souhaite une vitesse de communication de 100KHz. L'ATMEGA de la carte ARDUINO est cadencé à 16 MHz.
SCLfreq = CPUfreq / (16+2*TWBR*presc) donc TWBR*presc = (CPUfreq-16*SCLfreq)/(2*SCLfreq) = 16MHz – 16 * 100KHz) / (2 * 100KHz) = 72
avec presc = 1, on a TWBR = 72
Les registres contenant la vitesse ou la position de chaque un servo-moteur sont numerotés de 0 à 62.
Registre | Servo | Fonction |
---|---|---|
0 | 1 | Vitesse |
1 | 1 | Position (LSB) |
2 | 1 | Position (MSB) |
3 | 2 | Vitesse |
4 | 2 | Position (LSB) |
5 | 2 | Position (MSB) |
…
Pour chaque modification, il faut envoyer l'adresse de la carte SD21 (0xC2), le numéro du registre et la donnée.
La fonction twi_write_2_bytes() permet d'envoyer 2 octets. Dans notre cas, le numéro du registre et la donnée (vitesse ou position). Les autres fonctions twi sont expliquées ici
void twi_write_2_bytes(unsigned char slave_address, unsigned char data1, unsigned char data2) { twi_start(); twi_address(slave_address); twi_data(data1); twi_data(data2); twi_stop(); }
La fonction sd21_send() envoie la vitesse et la position pour le servo choisi.
#include "twi.h" #define SD21_ADDRESS 0xC2 /* envoie les commandes a la carte SD21 * servo est le numero du servo (de 1 a 21) * vitesse est la vitesse du mouvement * position est la largeur de l'impulsion en µs (de 1000 a 2000) * */ void sd21_send(unsigned char servo, unsigned char vitesse, unsigned int position) { unsigned char registre = (servo - 1) * 3; twi_write_2_bytes(SD21_ADDRESS, registre, vitesse); twi_write_2_bytes(SD21_ADDRESS, registre+1, position); twi_write_2_bytes(SD21_ADDRESS, registre+2, position>>8); } int main(void) { twi_master_initialise(72, 0); //SCLfreq = 100 KHz while (1) { sd21_send(6, 1, 2000); } return 1; }