Carte Romeo
De Wiki Arobose
(→Commande des moteurs) |
m (→Commande à distance) |
||
Ligne 21 : | Ligne 21 : | ||
==== Langage C ==== | ==== Langage C ==== | ||
+ | ===== Fonctions PWM ===== | ||
Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A pour E1 et le timer 4D pour E2. | Pour générer un signal PWM, le microcontroleur a besoin d'un timer interne. Il utilise le timer 3A pour E1 et le timer 4D pour E2. | ||
Ligne 95 : | Ligne 96 : | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | ===== Fonctions moteur ===== | ||
Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255). | Nous avons ensuite créer des fonctions qui permettent au robot d'avancer, reculer et tourner en précisant la vitesse (de 0 à 255). | ||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
+ | |||
/* stop */ | /* stop */ | ||
void | void | ||
stop(void) | stop(void) | ||
{ | { | ||
+ | PORTD &= ~(1 << PORT4); /* E1 (PD4) = 0 */ | ||
+ | PORTE &= ~(1 << PORT6); /* E2 (PE6) = 0 */ | ||
pwm_4D_write(0); | pwm_4D_write(0); | ||
pwm_3A_write(0); | pwm_3A_write(0); | ||
Ligne 108 : | Ligne 113 : | ||
* speed from 0 to 255 */ | * speed from 0 to 255 */ | ||
void | void | ||
− | advance( | + | advance(uint8_t m1_speed, uint8_t m2_speed) |
{ | { | ||
PORTD |= (1 << PORT4); /* E1 (PD4) = 1 */ | PORTD |= (1 << PORT4); /* E1 (PD4) = 1 */ | ||
PORTE |= (1 << PORT6); /* E2 (PE6) = 1 */ | PORTE |= (1 << PORT6); /* E2 (PE6) = 1 */ | ||
− | + | pwm_3A_write(m1_speed); | |
− | + | pwm_4D_write(m2_speed); | |
} | } | ||
Ligne 119 : | Ligne 124 : | ||
* speed from 0 to 255 */ | * speed from 0 to 255 */ | ||
void | void | ||
− | back_off( | + | back_off(uint8_t m1_speed, uint8_t m2_speed) |
{ | { | ||
PORTD &= ~(1 << PORT4); /* E1 (PD4) = 0 */ | PORTD &= ~(1 << PORT4); /* E1 (PD4) = 0 */ | ||
PORTE &= ~(1 << PORT6); /* E2 (PE6) = 0 */ | PORTE &= ~(1 << PORT6); /* E2 (PE6) = 0 */ | ||
− | + | pwm_3A_write(m1_speed); | |
− | + | pwm_4D_write(m2_speed); | |
} | } | ||
Ligne 130 : | Ligne 135 : | ||
* speed from 0 to 255 */ | * speed from 0 to 255 */ | ||
void | void | ||
− | turn_left( | + | turn_left(uint8_t m1_speed, uint8_t m2_speed) |
{ | { | ||
PORTD &= ~(1 << PORT4); /* E1 (PD4) = 0 */ | PORTD &= ~(1 << PORT4); /* E1 (PD4) = 0 */ | ||
PORTE |= (1 << PORT6); /* E2 (PE6) = 1 */ | PORTE |= (1 << PORT6); /* E2 (PE6) = 1 */ | ||
− | + | pwm_3A_write(m1_speed); | |
− | + | pwm_4D_write(m2_speed); | |
+ | |||
} | } | ||
Ligne 141 : | Ligne 147 : | ||
* speed from 0 to 255 */ | * speed from 0 to 255 */ | ||
void | void | ||
− | turn_right( | + | turn_right(uint8_t m1_speed, uint8_t m2_speed) |
{ | { | ||
PORTD |= (1 << PORT4); /* E1 (PD4) = 1 */ | PORTD |= (1 << PORT4); /* E1 (PD4) = 1 */ | ||
PORTE &= ~(1 << PORT6); /* E2 (PE6) = 0 */ | PORTE &= ~(1 << PORT6); /* E2 (PE6) = 0 */ | ||
− | + | pwm_3A_write(m1_speed); | |
− | + | pwm_4D_write(m2_speed); | |
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Pour finir, | + | Pour finir, la fonction principale main() et les fonctions setup() qui définissent l'état des pins (entrée ou sortie) et active les modules PWM. |
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
− | |||
void | void | ||
− | + | motor_setup(void) | |
{ | { | ||
/* Motor controller */ | /* Motor controller */ | ||
− | DDRD = (1 << PORTD4); /* PD4 as output pin */ | + | DDRD = (1 << PORTD4); /* E1 (PD4) as output pin */ |
− | DDRE = (1 << PORTE6); /* PE6 as output pin */ | + | DDRE = (1 << PORTE6); /* E2 (PE6) as output pin */ |
− | + | ||
− | |||
− | |||
− | |||
− | |||
pwm_3_setup(); | pwm_3_setup(); | ||
pwm_4_setup(); | pwm_4_setup(); | ||
+ | |||
pwm_3A_enable(); | pwm_3A_enable(); | ||
pwm_4D_enable(); | pwm_4D_enable(); | ||
+ | } | ||
+ | |||
+ | void | ||
+ | setup(void) | ||
+ | { | ||
+ | motor_setup(); | ||
} | } | ||
Ligne 201 : | Ligne 208 : | ||
USART_1_setup(void) | USART_1_setup(void) | ||
{ | { | ||
− | + | DDRD &= ~(1 << PD2); /* initialize pin PD2 (RX) as input pin */ | |
− | + | DDRD |= (1 << PD3); /* initialize pin PD3 (TX) as output pin */ | |
UBRR1 = 103; /* 9600 Baud at 16MHz */ | UBRR1 = 103; /* 9600 Baud at 16MHz */ | ||
Ligne 315 : | Ligne 322 : | ||
} | } | ||
return 0; | return 0; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Conversion analogique / numérique == | ||
+ | |||
+ | Les capteurs que nous utilisons retourne généralement une information (tension) sous forme analogique. Pour exploiter cette information, le microcontroleur doit la convertir en signal numérique. | ||
+ | |||
+ | Le convertisseur analogique / numérique de l'ATMEGA32U4 est un convertisseur 10 bits soit une précision de 1024 points. En se basant sur une tension de référence (généralement la tension d'alimentation), il va, par approximation successive, définir la valeur numérique correspondante à la tension. | ||
+ | |||
+ | Dans un premier temps, nous allons configurer le convertisseur. Le microcontroleur a 6 entrées analogiques sur le port F qu'il faut configurer en entrée. La tension de référence pour effectuer la conversion est la tension d'alimentation Vcc = 5V. | ||
+ | <syntaxhighlight lang="c"> | ||
+ | /* Voltage reference : Vcc | ||
+ | * Right adjust result | ||
+ | * and with clock prescaled to system clock divided by 1024 */ | ||
+ | void | ||
+ | adc_setup(void) | ||
+ | { | ||
+ | /* initialize PORTF pins as input pin */ | ||
+ | DDRF = 0x00; | ||
+ | |||
+ | /* set ADC prescale factor to 1024 */ | ||
+ | ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); | ||
+ | |||
+ | /* Vcc is reference voltage */ | ||
+ | ADMUX |= (1 << REFS0); | ||
+ | |||
+ | /* Set ADC to Free-Running Mode */ | ||
+ | ADCSRB = 0; | ||
+ | |||
+ | /* adc enable */ | ||
+ | ADCSRA |= (1 << ADEN); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Ensuite, nous allons lire la valeur de chaque entrée en démarrant la conversion. | ||
+ | <syntaxhighlight lang="c"> | ||
+ | void | ||
+ | adc_start_conversion(uint8_t pin) | ||
+ | { | ||
+ | //adc_enable(pin); | ||
+ | ADMUX = (1 << REFS0) | pin; | ||
+ | DIDR0 = (1 << pin); | ||
+ | ADCSRA |= (1 << ADSC); // adc start conversion | ||
+ | } | ||
+ | |||
+ | uint16_t | ||
+ | adc_read(uint8_t pin) | ||
+ | { | ||
+ | uint8_t low; | ||
+ | adc_start_conversion(pin); | ||
+ | while (ADCSRA & (1 << ADSC)) | ||
+ | ; // wait for result | ||
+ | low = ADCL; // must read LSB first | ||
+ | return (ADCH << 8) | low; // must read MSB only once! | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
[[Category:Produits]] | [[Category:Produits]] |