Cours:TPS 2103 tp servoMoteur : Différence entre versions
(Page créée avec « =Servomoteur= Les servomoteurs possèdent généralement un connecteur à 3 contacts qui sont : * rouge : VCC (ici et en général +5V) * noir : GND * jaune : signal de c... ») |
|||
(20 révisions intermédiaires par le même utilisateur non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
+ | [[Fichier:ArduinoPinout.png|600px|droite]] | ||
+ | |||
+ | <big>{{Rouge|******************************************}}</big> | ||
+ | <big>{{Rouge|*** Apporter la malette d'informatique ***}}</big> | ||
+ | <big>{{Rouge|******************************************}}</big> | ||
+ | |||
+ | {{EnTeteTdInfoS2|InfoS2_tdMli_corrige}} | ||
+ | |||
+ | {{Rouge|<big><big>[[Media:Atmega328p.pdf|datasheet atmega328p]]</big></big>}} | ||
+ | |||
+ | [[Cours:TPS_2103_tp_servoMoteurProf|{{Vert|Correction, enseignants}}]] | ||
+ | |||
+ | Nous allons créer une sorte de télécommande pour voiture de modélisme. | ||
+ | |||
+ | Les actionneurs pour avion/voitures radiocommandées sont souvent des servomoteurs ou se comportent comme tel. | ||
+ | |||
+ | Nous ne ferons pas ici de transmission sans fil mais nous verrons le principe de communication entre l'émetteur et le récepteur en utilisant une liaison série. | ||
+ | |||
=Servomoteur= | =Servomoteur= | ||
Ligne 18 : | Ligne 36 : | ||
Remarquons que le rapport cyclique ne devra varier que dans une certaine plage, et non de 0% à 100%. | Remarquons que le rapport cyclique ne devra varier que dans une certaine plage, et non de 0% à 100%. | ||
− | {{ | + | On utilisera le timer1 pour générer ce signal MLI. Prenez la datasheet pages 131 et suivantes. |
+ | |||
+ | La fréquence de la MLI est donnée par Fmli= Fcpu / (P * ICR1), avec P le prédiviseur (1/8/64/256/1024) et ICR1<65535 (2^16). | ||
+ | |||
+ | {{Todo|Choisir des valeurs pour P et ICR1}} | ||
− | ' | + | Le rapport cyclique sera réglé par : |
− | + | *OCR1A pour la broche OC1A | |
− | + | *OCR1B pour OC1B | |
− | + | ||
− | + | Sa valeur est : rapportCyclique=OCR1A/ICR1 | |
− | + | ||
− | + | {{Question|Ecrire le programme pour générer cette MLI, et vérifier la fréquence à l'oscilloscope}} | |
+ | |||
+ | <source lang=cpp> | ||
+ | int main() | ||
+ | { | ||
+ | // broche en sortie | ||
+ | |||
+ | // timer1 en mode 14 | ||
+ | |||
+ | // valeur du prédiviseur | ||
+ | |||
+ | // générer le signal MLI sur la broche OC1A ou OC1B (bits COM1xx dans le registre TCCR1A) | ||
+ | |||
+ | // valeur du rapport cyclique | ||
+ | |||
+ | while(1) | ||
+ | { | ||
+ | // on peut changer le rapport cyclique régulièrement ici | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | [[Image:Can_atmega328.png|droite|vignette]] | ||
+ | |||
+ | {{Question|Modifier votre programme pour faire varier la position du servomoteur entre ses positions extrêmes.}} | ||
==Potentiomètre== | ==Potentiomètre== | ||
− | |||
Nous souhaitons maintenant commander la position du servomoteur au travers d'un potentiomètre. | Nous souhaitons maintenant commander la position du servomoteur au travers d'un potentiomètre. | ||
On reliera bien évidemment ce potentiomètre sur une entrée analogique du µcontrôleur. | On reliera bien évidemment ce potentiomètre sur une entrée analogique du µcontrôleur. | ||
+ | |||
+ | Remarquons que nous utilisons un CAN 10bits, qui donnera donc une valeur entre 0 et 1023. | ||
{{Question|Écrire un programme répondant au cahier des charges}} | {{Question|Écrire un programme répondant au cahier des charges}} | ||
− | |||
− | + | Vous utiliserez l'un des 2 canevas ci-dessous pour l'utilisation du CAN, l'un utilisant les interruptions, l'autre non : | |
+ | |||
+ | {| | ||
+ | |- | ||
+ | | {{Rouge|Par interruption}} || {{Rouge|Par scrutation}} | ||
+ | |- | ||
+ | | | ||
+ | <source lang=c> | ||
+ | volatile int16_t n; | ||
+ | ISR(ADC_vect) | ||
+ | { | ||
+ | n=ADC; | ||
+ | .... | ||
+ | //relancer une nouvelle conversion (bit ADSC) | ||
+ | } | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | // mettre en route CAN (ADEN) | ||
+ | |||
+ | // choisir la tension de référence (AVCC) | ||
+ | |||
+ | // vitesse du CAN (ADPS..) | ||
+ | |||
+ | // choisir l'entrée (MUX...) | ||
+ | |||
+ | // autoriser interruption CAN (ADIE) | ||
+ | // et lancer une conversion (ADSC) | ||
+ | |||
+ | while(1) | ||
+ | { | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | </source> | ||
+ | || | ||
+ | <source lang=c> | ||
+ | int main() | ||
+ | { | ||
+ | // mettre en route CAN (ADEN) | ||
+ | |||
+ | // choisir la tension de référence (AVCC) | ||
+ | |||
+ | // vitesse du CAN (ADPS..) | ||
+ | |||
+ | // choisir l'entrée (MUX...) | ||
+ | |||
+ | while(1) | ||
+ | { | ||
+ | // lancer une conversion (ADSC) | ||
+ | |||
+ | // attendre fin de conversion : | ||
+ | // le bit ADSC reste à 1 jusqu'à la fin de la conversion | ||
+ | // donc : attendre que le bit passe à 0 ! | ||
+ | // (utiliser loop_until_bis_is... ) | ||
− | + | // lire la valeur | |
+ | int16_t n=ADC; | ||
+ | .... | ||
+ | } | ||
+ | } | ||
− | + | </source> | |
+ | |} |
Version actuelle datée du 17 mars 2023 à 15:09
****************************************** *** Apporter la malette d'informatique *** ******************************************
Pensez à mettre sur la 1ère ligne de votre code : // Compiler: Avrgcc device: nomDuMicrocontroleur
Nous allons créer une sorte de télécommande pour voiture de modélisme.
Les actionneurs pour avion/voitures radiocommandées sont souvent des servomoteurs ou se comportent comme tel.
Nous ne ferons pas ici de transmission sans fil mais nous verrons le principe de communication entre l'émetteur et le récepteur en utilisant une liaison série.
Servomoteur
Les servomoteurs possèdent généralement un connecteur à 3 contacts qui sont :
- rouge : VCC (ici et en général +5V)
- noir : GND
- jaune : signal de consigne/commande
Les servomoteurs utilisés ici sont commandés en position, c'est à dire que suivant la consigne, le moteur tourne jusqu'à la valeur désirée.
Il existe également des commandes en vitesse, et dans ce cas c'est la vitesse de rotation qui est fonction de la commande.
Le signal de consigne est tel qu'indiqué sur la figure ci-dessous :
MLI
On constate sur la figure qu'il est nécessaire de générer un signal MLI (ou PWM) dont la fréquence (ou période) est indiquée sur la figure.
Remarquons que le rapport cyclique ne devra varier que dans une certaine plage, et non de 0% à 100%.
On utilisera le timer1 pour générer ce signal MLI. Prenez la datasheet pages 131 et suivantes.
La fréquence de la MLI est donnée par Fmli= Fcpu / (P * ICR1), avec P le prédiviseur (1/8/64/256/1024) et ICR1<65535 (2^16).
Choisir des valeurs pour P et ICR1
Le rapport cyclique sera réglé par :
- OCR1A pour la broche OC1A
- OCR1B pour OC1B
Sa valeur est : rapportCyclique=OCR1A/ICR1
Ecrire le programme pour générer cette MLI, et vérifier la fréquence à l'oscilloscope
int main()
{
// broche en sortie
// timer1 en mode 14
// valeur du prédiviseur
// générer le signal MLI sur la broche OC1A ou OC1B (bits COM1xx dans le registre TCCR1A)
// valeur du rapport cyclique
while(1)
{
// on peut changer le rapport cyclique régulièrement ici
}
}
Modifier votre programme pour faire varier la position du servomoteur entre ses positions extrêmes.
Potentiomètre
Nous souhaitons maintenant commander la position du servomoteur au travers d'un potentiomètre.
On reliera bien évidemment ce potentiomètre sur une entrée analogique du µcontrôleur.
Remarquons que nous utilisons un CAN 10bits, qui donnera donc une valeur entre 0 et 1023.
Écrire un programme répondant au cahier des charges
Vous utiliserez l'un des 2 canevas ci-dessous pour l'utilisation du CAN, l'un utilisant les interruptions, l'autre non :
Par interruption | Par scrutation |
volatile int16_t n;
ISR(ADC_vect)
{
n=ADC;
....
//relancer une nouvelle conversion (bit ADSC)
}
int main()
{
// mettre en route CAN (ADEN)
// choisir la tension de référence (AVCC)
// vitesse du CAN (ADPS..)
// choisir l'entrée (MUX...)
// autoriser interruption CAN (ADIE)
// et lancer une conversion (ADSC)
while(1)
{
}
}
|
int main()
{
// mettre en route CAN (ADEN)
// choisir la tension de référence (AVCC)
// vitesse du CAN (ADPS..)
// choisir l'entrée (MUX...)
while(1)
{
// lancer une conversion (ADSC)
// attendre fin de conversion :
// le bit ADSC reste à 1 jusqu'à la fin de la conversion
// donc : attendre que le bit passe à 0 !
// (utiliser loop_until_bis_is... )
// lire la valeur
int16_t n=ADC;
....
}
}
|