====== 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;
}