Asservissement moteur CC

Documents pareils
ARDUINO DOSSIER RESSOURCE POUR LA CLASSE

Bien commencer avec un LaunchPad MSP430G et un Breadboard

Durée estimée :1 journée Date de la réalisation : Description Fournisseur Référence Nombre PU HT LM35CZ, LM35AZ LM35DZ

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

Carte ARDUINO UNO Microcontrôleur ATMega328

Mathématiques et petites voitures

Liste des Paramètres 2FC4...-1ST 2FC4...-1PB 2FC4...-1PN 2FC4...-1SC 2FC4...-1CB

Fiche technique CPU 314SC/DPM (314-6CG13)

Alarme intrusion filaire AEI HA zones

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

RÉALISATION D UN BANC D ÉQUILIBRAGE

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Fiche n 14 : Import / Export avec PlanningPME

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

MANUEL D INSTRUCTION

AUTOPORTE III Notice de pose

CARACTERISTIQUE D UNE DIODE ET POINT DE FONCTIONNEMENT

Modules d automatismes simples

Education Delivery Intelligent Tool

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

FONCTION COMPTAGE BINAIRE ET DIVISION DE FRÉQUENCE

IUT GEII MARSEILLE Patrick GUMUCHIAN. Lycée Alphonse Benoit L'Isle sur la Sorgue Marc SILANUS

Une carte pour vos projets

STS SE. FreeRTOS. Programmation réseau WIFI. Programmation réseau. Socket Tcp. FlyPort smart Wi-Fi module

SOMMAIRE MONTAGE DU COMPTEUR ET CAPTEURS...3 LE MOT DU CHEF DE PRODUIT...5 L ORGANISATION DE L ECRAN...5 LES PICTOGRAMMES UTILISES...5 LES BOUTONS...

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

BACCALAUREAT GENERAL MATHÉMATIQUES

ET 24 : Modèle de comportement d un système Boucles de programmation avec Labview.

NOTICE D' UTILISATION CAMWORKS FRAISAGE. Luc Vallée Lycée Blaise Pascal Segré

Logiciel SuiviProspect Version Utilisateur

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

1.6- Génération de nombres aléatoires

Tutoriel sur l enregistrement en classe Janvier Jean-Claude Boudet (académie de Bordeaux) 1. Le matériel

Module de télémétrie MT-021- Guide de démarrage rapide

Manuel d installation du clavier S5

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

Piano Stairs. descriptif de la conception et des programmes associés. Copyright (C) 2013 taprik

Centrale d alarme DA996

AP1.1 : Montages électroniques élémentaires. Électricité et électronique

Test : principe fondamental de la dynamique et aspect énergétique

Bonjour, Le document qui suit est le support de la formation ''Arduino applications distantes''.

Notice de fonctionnement DVR H Méthode de Visionnage ESEENET

BACCALAURÉAT GÉNÉRAL SÉRIE SCIENTIFIQUE

M HAMED EL GADDAB & MONGI SLIM

Initiation à la programmation en Python

epowerswitch 8XM+ Fiche technique

Informations techniques

Tutorial créer une machine virtuell.doc Page 1/9

Programmation en langage C d un µcontrôleur PIC à l aide du compilateur C-CCS Sommaire

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Scarlett Plug-in Suite

SEO 200. Banc d étude du positionnement angulaire d une éolienne face au vent DESCRIPTIF APPLICATIONS PEDAGOGIQUES

Bac Blanc Terminale ES - Février 2011 Épreuve de Mathématiques (durée 3 heures)

TP 7 : oscillateur de torsion

Chapitre 2 Devine mon nombre!

30.avr.10 Présentation miniprojet. 9.mars.10 Cours 3 4.mai.10 Cours C mars.10 Cours 4 11.mai.10 Cours C++ 2

Manipulations du laboratoire

Traceur GPS Antivol. Le traceur est conforme aux normes européennes 95/56 E27

Recherche dans un tableau

Montage non-linéaire. Techniques et méthodes

N de com. Finition Description Réference Emballage noir fermeture automatique Solo 1. fermeture automatique avec alarme porte ouverte

INDEX Fonctionnement Schéma de câblage... 24

Livret Phoenix-M. Par Georges Khaznadar, Lycée Jean Bart, Dunkerque d'après Phoenix Programmer's Manual

AMICUS 18 (2ème partie) 4) Présentation du logiciel Amicus IDE

Module de mesure de courant pour relais statiques serie HD Module de mesure de courant HD D0340I

TP Détection d intrusion Sommaire

ROTOLINE NOTICE DE POSE

Documentation Technique du programme HYDRONDE_LN

1AN. e n 19" FicheS Techniques. PLV - Dynamique. caractéristiques techniques. dimensions dela structure

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

HAM841K CENTRALE D'ALARME POUR SYSTEMES DE SECURITE COMMERCIAUX ET D'HABITATION

PowerControl VI Getting Started 09/06/2008 1

Guide d utilisation Salles avec un tableau blanc interactif

Temps Réel. Jérôme Pouiller Septembre 2011

MANUEL D UTILISATION Version R1013

Votre partenaire de la fermeture :

Cours Programmation Système

NOTICE GPSTA1 I. DESCRIPTION II. ACCESSOIRES. J. R International - Eclats Antivols. 2014

Observer TP Ondes CELERITE DES ONDES SONORES

Rappels Entrées -Sorties

CREATION D UNE EVALUATION AVEC JADE par Patrick RUER (

Connexion sur REDLION G-308 avec le modem GSM GDW-11 pour envoi de SMS

Manuel d instruction pour la lecture des températures pour radiello

Baccalauréat ES/L Amérique du Sud 21 novembre 2013

Programmation C++ (débutant)/instructions for, while et do...while

MEMOIRES MAGNETIQUES A DISQUES RIGIDES

La programmation des PIC en C. Les fonctions, les interruptions.

TUTORIAL Microsoft Project 2010 Fonctionalités de base

TP : Suivi d'une réaction par spectrophotométrie

Capteur mécanique universel HF 32/2/B

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

SECURIT GSM Version 2

Cours de D.A.O. Mécanique

Version beta. Station Météo 12/11/2012. Réalisation d un Station Météo avec Webserver composée de capteurs Grove et d un module Wifi Flyport.

fullprotect inside EOLE SPEie RS E-SPEie V-0.6A-RS 1.0 revision Protection environnement Datasheet édition française

TD Objets distribués n 3 : Windows XP et Visual Studio.NET. Introduction à.net Remoting

epowerswitch 4M+ Fiche technique

Contrôler plusieurs ordinateurs avec un clavier et une souris

Transcription:

Asservissement moteur CC Table des matières 1. Introduction...2 2. Les interruptions logicielles...2 3. Acquisition des impulsions de la roue codeuse...2 4. Commande et alimentation du moteur...3 5. Échantillonnage...4 6. Asservissement...4 6.1. Asservissement en vitesse...5 6.2. Asservissement en position...7 7. Matériel utilisé...10 Lorsqu'un moteur entraîne un robot pour qu'il se déplace d'une certaine distance, l'organe de commande va envoyer une consigne pendant une certaine durée, sans savoir si le moteur aura réellement effectué ce qu'on lui a demandé. L'asservissement consiste à vérifier ce que le moteur a réellement effectué et à corriger si nécessaire (en augmentant sa commande, pour rattraper le retard par exemple). 6-asservissement_moteur.odt 1

1. Introduction Le moteur DC fonctionne quand on lui envoie un courant. Le rotor tourne plus ou moins vite selon celui-ci, puis s arrête dès lors qu il n est plus alimenté. Cependant, on ne connaît ni la distance angulaire parcourue, ni la vitesse de rotation. Aussi, si l on veut réaliser un asservissement en vitesse ou en position, il faut transformer la consigne pour envoyer un courant pendant le temps nécessaire pour atteindre l objectif. Il faut pouvoir mesurer ce qu il se passe pendant que le moteur est en marche, calculer une position ou une vitesse, en déduire une erreur, puis la corriger pour atteindre la consigne de sortie. Il faut donc se servir de codeurs incrémentaux, acquérir les données, faire les calculs et commander le moteur en même temps. 2. Les interruptions logicielles Pour compter le nombre de tour pendant que le moteur tourne, on utilise une interruption qui va se déclencher à chaque transition de l encodeur et viendra simplement incrémenter un compteur. L encodeur est intégré et constitué de deux capteurs hall (équivalents magnétique des capteurs optique) qui permettent de lire ces interruptions sous forme de front montants et descendants. Deux capteurs, deux fonctions d interruptions. Pour obtenir de l'aide, cliquer sur le bouton 3. Acquisition des impulsions de la roue codeuse Les roues codeuses sont essentielles à l asservissement du moteur. Elles permettent à terme de connaître le sens ainsi que la vitesse de rotation du moteur. Un disque magnétique passe devant deux capteurs qui le détectent tour à tour. A chaque passage de l aimant, une impulsion est envoyée à la carte Arduino. Il y a un front montant et un front descendant pour chaque capteur, soit quatre positions différentes possible (HH,BB,HB,BH). Sur une période, il est donc possible de passer par quatre positions équidistantes de 90 chacune, 360 équivalent à une période. C est pour cela que l on parle de décalage en quadrature du signal. De plus, selon l enchaînement des fronts, il est facile de déterminer le sens de rotation. Par exemple si on avait enregistré HH et qu ensuite HB provient, on sait que le moteur tourne dans le sens horaire. Si au contraire BH provient, c est l inverse. Le codeur magnétique est moins précis qu un codeur optique. En effet, il utilise des aimants à la place des traditionnels traits noirs, et ceux-ci doivent éviter d être trop proches pour ne pas créer d interférences. Cependant, fixé à l arbre moteur, le nombre d impulsions par tour de l arbre de sortie est multiplié par le réducteur et peut donc être largement suffisant. L image ci-dessous montre le fonctionnement d un codeur optique, mais il suffit de remplacer virtuellement les points blancs par des aimants pour obtenir un codeur magnétique. 6-asservissement_moteur.odt 2

Tirer des informations du codeur incrémental revient à créer une fonction compteur. On enregistre une valeur que l on vient incrémenter ou décrémenter selon l ordre des impulsions de la quadrature. Remarque : il est possible de connaître la vitesse de rotation à l aide d un seul capteur. Mais le fait d utiliser deux capteurs permet de plus d en déterminer le sens. 4. Commande et alimentation du moteur Pour commander le moteur dans les deux sens, on utilise un pont en H intégré de type L293D (système composé de quatre transistors qui permet de contrôler électroniquement le sens du courant ou de la tension). L293D Pour obtenir de l'aide, cliquer sur le bouton 6-asservissement_moteur.odt 3

5. Échantillonnage montage L échantillonnage est une technique utilisée pour le traitement du signal et permet de dire à l Arduino de faire des calculs tous les intervalles donnés afin de ne pas saturer la puce de calculs inutiles. Ainsi, au lieu de faire des mesures continues et de ralentir le microprocesseur, celui-ci effectuera ses calculs par exemple toutes les 50ms. Ainsi, toutes les 50ms, l Arduino refera les calculs et nous dira si oui ou non on s est éloigné de la consigne d entrée. Cela permettra alors de corriger la sortie. #include <SimpleTimer.h> SimpleTimer timer; unsigned int time = 0; const int frequence_echantillonnage = 20; void setup() // toutes les 100ms, on appelle la fonction "asservissement" timer.setinterval(1000/frequence_echantillonnage, asservissement); La cartearduino met en mémoire les impulsions de la roue codeuse en continu dans les interruptions, mais ne procédera à l asservissement que toutes les 50ms. 6. Asservissement L'asservissement est réalisé à l'aide un correcteur PID (à effets proportionnel, intégral, et dérivé). Cet asservissement peut être modélisé par la formule ci-dessous, où V est la consigne (en Tr/s) à envoyer au moteur, et Ki, Kd, Kp des coefficients à modifier à la main jusqu à trouver les coefficients les plus satisfaisants : 6-asservissement_moteur.odt 4

V = Kp x Erreur + Kd x Erreur + KI x Erreur avec : Erreur = Consigne Nombre Tour roue par seconde mesuré Erreur = Erreur Erreur précédente Erreur = erreurs Pour obtenir de l'aide, cliquer sur le bouton 6.1. Asservissement en vitesse Voici la fonction «asservissement», appelée par la fonction d échantillonnage : void asservissement() int frequence_codeuse = frequence_echantillonnage * tick_codeuse; //100*tick_codeuse (pour obtenir des secondes) float vit_roue_tour_sec = (float)frequence_codeuse / (float)tick_par_tour_codeuse / (float)rapport_reducteur; // (100*tick_codeuse)/32/19 float erreur = consigne_moteur - vit_roue_tour_sec; // pour le proportionnel somme_erreur += erreur; // pour l'intégrateur float delta_erreur = erreur - erreur_precedente; // pour le dérivateur erreur_precedente = erreur; // P : calcul de la commande vitmoteur = kp*erreur + ki*somme_erreur + kd*delta_erreur; //somme des trois erreurs En donnée brute, on obtient un nombre d'impulsions par période d échantillonnage. Il n y a en fait qu à convertir cette donnée dans l unité de la consigne et d en faire la différence pour trouver l erreur. Ici, la consigne est en tours/s. On n utilise qu un des deux capteurs hall, soit 32 impulsions par tour et la réduction est d 1/19eme. Associée à une roue, on peut obtenir des m/s ou des km/h à partir du diamètre. Le code source : 6-asservissement_moteur.odt 5

// asservissement d'un moteur CC en vitesse avec un correcteur PID. #include <SimpleTimer.h> SimpleTimer timer; // Timer pour échantillonnage unsigned int tick_codeuse = 0; // Compteur de tick de la codeuse int vitmoteur = 0; // Commande du moteur const int frequence_echantillonnage = 100; // Fréquence d'exécution de l'asservissement const int rapport_reducteur = 19; // Rapport nombre de tours de l'arbre moteur et de la roue const int tick_par_tour_codeuse = 32; //64 tick sur deux capteurs hall, ici un seul capteur //definition des entrées const int pininput1 = 6; // Commande de sens moteur, Input 1 const int pininput2 = 7; // Commande de sens moteur, Input 2 const int pinpower = 9; // Commande de vitesse moteur, Output Enabled1 //consigne en tour/s const float consigne_moteur = 2; // Consigne nombre de tours de roue par seconde // init calculs asservissement PID float erreur_precedente = consigne_moteur; // (en tour/s) float somme_erreur = 0; //Definition des constantes du correcteur PID const float kp = 200; // Coefficient proportionnel (choisis par essais successifs) const float ki = 5; // Coefficient intégrateur const float kd = 100; // Coefficient dérivateur /* Routine d'initialisation */ void setup() Serial.begin(115200); pinmode(pinpower, OUTPUT); pinmode( pininput1, OUTPUT ); pinmode( pininput2, OUTPUT ); // Initialisation port COM // Sorties commande moteur analogwrite(pinpower, 0); // Initialisation sortie moteur à 0 delay(300); // Pause de 0,3 sec pour laisser le temps au moteur de s'arréter si celui-ci est en marche // Interruption sur tick de la codeuse (interruption 0 = pin2 arduino) attachinterrupt(0, compteur, CHANGE); // Interruption pour calcul du PID et asservissement appelee toutes les 10ms timer.setinterval(1000 / frequence_echantillonnage, asservissement); /* Fonction principale */ void loop() timer.run(); //on fait tourner l'horloge delay(10); //---- Interruption sur tick de la codeuse void compteur() tick_codeuse++; // On incrémente le nombre de tick de la codeuse. un seul sens //---- Interruption pour calcul du P 6-asservissement_moteur.odt 6

void asservissement() // Calcul de l'erreur int frequence_codeuse = frequence_echantillonnage * tick_codeuse; //100*tick_codeuse float vit_roue_tour_sec = (float)frequence_codeuse / (float)tick_par_tour_codeuse / (float)rapport_reducteur; //(100*tick_codeuse)/32/19 float erreur = consigne_moteur - vit_roue_tour_sec; // pour le proportionnel somme_erreur += erreur; // pour l'intégrateur float delta_erreur = erreur - erreur_precedente; // pour le dérivateur erreur_precedente = erreur; // Réinitialisation du nombre de tick de la codeuse tick_codeuse = 0; // P : calcul de la commande vitmoteur = kp*erreur + ki*somme_erreur + kd*delta_erreur; //somme des trois erreurs // Normalisation et contrôle du moteur if ( vitmoteur > 255 ) vitmoteur = 255; // sachant que l'on est branché sur un pont en H L293D else if ( vitmoteur < 0 ) vitmoteur = 0; TournerDroite (vitmoteur); // DEBUG Serial.print(vit_roue_tour_sec, 8); // affiche à gauche la vitesse et à droite l'erreur Serial.print(" : "); Serial.print(erreur, 4); Serial.print(" : "); Serial.print(vitMoteur); Serial.println(); //---- fonction pour faire tourner le moteur dans un sens (a droite) void TournerDroite( int powerrate ) digitalwrite(pininput1, LOW); digitalwrite(pininput2, HIGH); analogwrite(pinpower, powerrate); 6.2. Asservissement en position L asservissement en position est un peu plus compliqué à mettre en place. Une chose importante est d effectuer tous les calculs en nombres entiers pour ne pas perdre d informations. De plus, plus on se rapproche de l objectif, moins la vitesse du moteur est élevée. On peut bien sûr jouer avec les constantes du PID, pour trouver l optimum entre vitesse, dépassement et temps de réaction. Pour les nombres relatifs présents, ils sont encore une fois le fruit de conversions logiques. Par exemple, une commande de 10 degré en sortie équivaut à : 190 degrés en entrée (R=19) 0,52 tours d arbre moteur (/365 ) 6-asservissement_moteur.odt 7

33,28 ticks (64 ticks par tour) Remarques : on a pris 5,23 cm pour un tour de la roue fixée au moteur et par conséquent il faut 68,8 pour faire avancer la roue d un cm (rapport calculé entre l angle de consigne et la distance parcourue mesurée à la règle). Le code source : // asservissement en position angulaire un moteur à courant continu. #include <SimpleTimer.h> SimpleTimer timer; // Timer pour échantillonnage //definition des entrées const int pininput1 = 6; // Commande de sens moteur, Input 1 const int pininput2 = 7; // Commande de sens moteur, Input 2 const int pinpower = 9; // Commande de vitesse moteur, Output Enabled1 const int encoderpina = 2; // compteur 1 const int encoderpinb = 3; // compteur 2 //init echantillonage unsigned int time = 0; const int frequence_echantillonnage = 20; //init compteur : int encoder0pos = 0; //position de départ=0 int lastreportedpos = 0; boolean A_set = false; boolean B_set = false; //consigne const double target_cm = 48; double target_deg = 68.8 * target_cm; int target_ticks; //plus simple d'asservir en ticks car ce sera toujours un nombre entier // init calculs asservissement PID int erreur = 0; //erreur float erreurprecedente = 0; float somme_erreur = 0; //Definition des constantes du correcteur PID const float kp = 0.90; // Coefficient proportionnel (choisis par essais successifs) const float ki = 0; // Coefficient intégrateur const float kd = 0; // Coefficient dérivateur /* Routine d'initialisation */ void setup() target_ticks = target_deg / 360.0 * 19.0 * 64.0; Serial.begin(115200); pinmode(pinpower, OUTPUT); pinmode(pininput1, OUTPUT); pinmode(pininput2, OUTPUT); // Initialisation port COM // Sorties commande moteur pinmode(encoderpina, INPUT); //sorties encodeur pinmode(encoderpinb, INPUT); digitalwrite(encoderpina, HIGH); // Resistance interne arduino ON digitalwrite(encoderpinb, HIGH); // Resistance interne arduino ON // Interruption de l'encodeur A en sortie 0 (pin 2) 6-asservissement_moteur.odt 8

attachinterrupt(0, doencodera, CHANGE); // Interruption de l'encodeur A en sortie 1 (pin 3) attachinterrupt(1, doencoderb, CHANGE); analogwrite(pinpower, 0); // Initialisation sortie moteur à 0 delay(300); // Pause de 0,3 sec pour laisser le temps au moteur de s'arréter si celui-ci est en marche // Interruption pour calcul du PID et asservissement appelée toutes les 10ms timer.setinterval(1000 / frequence_echantillonnage, asservissement); /* Fonction principale */ void loop() timer.run(); //on fait tourner l'horloge //---- Cette fonction est appelée toutes les 20ms pour calcul du correcteur PID void asservissement() time += 20; // pratique pour graphes excel après affichage sur le moniteur erreur = target_ticks - encoder0pos; somme_erreur += erreur; // Calcul de la vitesse courante du moteur int vitmoteur = kp * erreur + kd * (erreur - erreurprecedente) + ki * (somme_erreur); erreurprecedente = erreur; // Ecrase l'erreur précedente par la nouvelle erreur // Normalisation et contrôle du moteur if ( vitmoteur > 255 ) vitmoteur = 255; // on est branché sur un pont en H L293D else if ( vitmoteur < -255 ) vitmoteur = -255; Tourner (vitmoteur); float angle_deg = encoder0pos / 19.0 / 64.0 * 360.0; //Position angulaire de sortie, pratique pour comparer avec la consigne d'entrée float distance = encoder0pos / 19.0 / 64.0 * 360.0 / 68.83; Serial.print(erreur); // affiche sur le moniteur les données voulues Serial.print(" "); Serial.print(encoder0Pos); Serial.print(" "); Serial.print(angle_deg); Serial.print(" "); Serial.print(distance); Serial.print(" "); Serial.println(vitMoteur); //---- Interruption appelée à tous les changements d'état de A void doencodera() A_set = digitalread(encoderpina) == HIGH; encoder0pos += (A_set!= B_set)? -1 : 1 ; //modifie le compteur selon les deux états des encodeurs //---- Interruption appelée à tous les changements d'état de B void doencoderb() B_set = digitalread(encoderpinb) == HIGH; 6-asservissement_moteur.odt 9

encoder0pos += (A_set == B_set)? -1 : 1 ; //modifie le compteur selon les deux états des encodeurs //---- Fonction appelée pour contrôler le moteur void Tourner( int rapportcyclique ) if ( rapportcyclique > 0 ) digitalwrite(pininput1, LOW); digitalwrite(pininput2, HIGH); else digitalwrite(pininput1, HIGH); digitalwrite(pininput2, LOW); rapportcyclique = -rapportcyclique; analogwrite(pinpower, rapportcyclique); 7. Matériel utilisé Liste du matériel : carte Arduino pont en H L293D moteur à courant continu 12V (de rapport de réduction 1/19) équipe d une roue codeuse pile de 9V pour alimenter le moteur Correspondances entre couleurs et rôles des différents câbles du moteur CC : Schéma du montage final : 6-asservissement_moteur.odt 10

6-asservissement_moteur.odt 11