====== Présentation ====== La carte [[http://www.robot-electronics.co.uk/htm/sd21tech.htm|SD21]] permet de commander 21 servo-moteurs analogiques à partir d'une liaison [[robotics:computing:communication_twi_entre_atmega|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. ====== Utilisation ====== 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. ===== Position ===== 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. ===== Vitesse ===== La vitesse du mouvement est obtenue grace à l'equation suivante : time for move = ((Target_position – start_ position) / speed) * 20 ms. ====== Implémentation ====== ===== Schéma ===== {{::schema.jpg?400|}} 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. ===== Fréquence SCL ===== 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 ===== Fonctionnement ===== 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. ===== Exemple ===== 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 [[robotics:computing:communication_twi_entre_atmega|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; }