Académique Documents
Professionnel Documents
Culture Documents
Kicad : Raccorder deux pistes en plaçant des vias Amplificateur opérationnel VS comparateur Les mots clefs
Le transistor Q2 vient driver le MOSFET de puissance. Lorsque la sortie 9 de l'arduino est à l'état haut, Q1 est
bloqué et le moteur ne tourne pas. A l'inverse, lorsque la sortie 9 de l'arduino est à l'état bas, alors Q1 devient
passant et le moteur tourne à plein régime. Le moteur se contrôle donc en "tout ou rien", ce qui tombe bien, car
la sortie "analogique" de l'Arduino est en réalité une sortie PWM de rapport cyclique ajustable.
Au niveau du câblage, j'utilise une Arduino Mega. La sortie 9 commande mon moteur. La codeuse (je n'utilise
qu'une seule des deux sorties de la codeuse) est branché sur la pin 2 de l'arduino mega (pin qui correspond à
l'interruption 0).
Si vous voulez utiliser une autre Arduino, pensez à brancher la codeuse, non plus sur la pin 2, mais sur la pin qui
correspond à une pin d'interruption !
Ainsi, il suffit de mettre une interruption qui se déclenche à chaque transition de la codeuse et qui exécute une
fonction qui viendra simplement incrémenter un compteur.
D'abord, la consigne, qui correspondra, dans notre exemple, au nombre de tours de roue par seconde. Je vais
fixer cette consigne à 5, ce qui veut dire que je souhaite que le moteur effectue 5 tours de roue par seconde.
Ensuite, il nous faut le nombre de tour de roue qu'a effectué le moteur durant les dernière 20ms. Rien de bien
compliqué. On a notre variable tick_codeuse qui compte le nombre de changement d'état de la codeuse durant
les 20 dernières millisecondes. On sait qu'il y a 32 changements d'état de la codeuse par tour de l'arbre moteur.
On sait qu'il faut 29 tours d'arbre moteur pour faire un tour de roue.
On en déduit donc que la roue à fait tick_codeuse/32/29 tours de roues durant les 20 dernières milliseconde, et
donc 50*tick_codeuse/32/29 tours de roue par seconde !
Avec cette information, on peut donc calculer l'erreur qui est la différence entre la consigne (le nombre de tour
de roue par seconde voulu) et la réponse à cette consigne (le nombre de tours de roue par seconde réalisé).
Il ne nous reste plus qu'a trouver notre coefficient de proportionnalité de notre régulation, ce qui nous donne la
fonction d'asservissement suivante :
Notons que lors de l'envoie du signal de commande au transistor, il faut inverser le résultat trouvé avec notre
asservissement proportionnel car dans notre cas, le moteur tourne pour une commande de 0 et s'arrête pour
une commande de 255 ! (d'où la ligne analogWrite(_MOTEUR, 255-cmd); )
Il faut donc maintenant définir le coefficient de proportionnalité. J'ai tracé, ci-dessous, différentes réponses de
mon moteur en fonction du temps pour des coefficients de proportionnalité différents. On remarque bien que
quand kp augmente, la réponse se rapproche de plus en plus à la consigne voulu, mais que quand kp est trop
grand, la réponse oscille fortement autour de la consigne.
Amélioration PI
D'après les résultats précédent, j'ai décidé de prendre un coefficient de proportionnalité kp égal à 300. Ainsi,
l'erreur statique sera d'environ 5%. Pour améliorer le comportement de notre asservissement et pour annuler
notre erreur statique, j'ai décidé de rajouter un terme intégrateur afin d'obtenir un asservissement PI.
Pour cela, je vais garder en mémoire la somme de toutes les erreurs de mon système. Plus cette somme des
erreurs est importante et plus j'essaye de corriger ma commande. Ainsi, il faut que j'ajoute ce nouveau terme
intégrale à la ligne calculant la commande.
1 somme_erreur += erreur;
2 // PI : calcul de la commande
3 cmd = kp*erreur + ki*somme_erreur;
Dans cette seconde phase, nous avons donc à régler ce coefficient intégrateur ki.
Plus on augmente le coefficient d'intégration ki, est plus le système répond vite, mais en contre partie, le
système devient de plus en plus instable. Le but est donc de trouver un compromis entre temps de réponse et
stabilité. On voit que pour des ki trop grand, le système part en oscillation.
D'après ces graphiques, un coefficient proportionnel de 300 et un coefficient intégrateur de 5 ou 6 nous permet
d'atteindre une réponse quasiment optimale, avec un dépassement très faible et un temps de réponse d'envirion
120 milliseconde. Le système se stabilise donc après 6 exécutions de la fonction asservissement.
Après plusieurs essais, je suis arrivé à un triplet assez performant. Voici l'allure de la réponse :
1 /**
2 * Asservissement d'un moteur à l'aide d'un régulateur PID
3 * Avril 2012 - Ferdinand Piette
4 */
5
6 #include <SimpleTimer.h> // http://arduino.cc/playground/Code/Simpl
7 #define _DEBUG false
8
9 SimpleTimer timer; // Timer pour échantillonnage
10 const int _MOTEUR = 9; // Digital pin pour commande moteur
11 unsigned int tick_codeuse = 0; // Compteur de tick de la codeuse
12 int cmd = 0; // Commande du moteur
13
14 const int frequence_echantillonnage = 50; // Fréquence du pid
15 const int rapport_reducteur = 29; // Rapport entre le nombre de tour
16 const int tick_par_tour_codeuse = 32; // Nombre de tick codeuse par tour
17
18 float consigne_moteur_nombre_tours_par_seconde = 5.; // Nombre de tours de
19
20 float erreur_precedente = consigne_moteur_nombre_tours_par_seconde;
21 float somme_erreur = 0; // Somme des erreurs pour l'intégrateur
22 float kp = 300; // Coefficient proportionnel
23 float ki = 5.5; // Coefficient intégrateur
24 float kd = 100; // Coefficient dérivateur
25
26 /* Routine d'initialisation */
27 void setup() {
28 Serial.begin(115200); // Initialisation port COM
29 pinMode(_MOTEUR, OUTPUT); // Sortie moteur
30 analogWrite(_MOTEUR, 255); // Sortie moteur à 0
31
32 delay(5000); // Pause de 5 sec pour laisser le temps au
33
34 attachInterrupt(0, compteur, CHANGE); // Interruption sur tick de la c
35 timer.setInterval(1000/frequence_echantillonnage, asservissement); // In
36 }
37
38 /* Fonction principale */
39 void loop(){
40 timer.run();
41 delay(10);
42 }
43
44 /* Interruption sur tick de la codeuse */
45 void compteur(){
46 tick_codeuse++; // On incrémente le nombre de tick de la codeuse
47 }
48
49 /* Interruption pour calcul du PID */
50 void asservissement()
51 {
52 // Réinitialisation du nombre de tick de la codeuse
53 int tick = tick_codeuse;
54 tick_codeuse=0;
55
56 // Calcul des erreurs
57 int frequence_codeuse = frequence_echantillonnage*tick;
58 float nb_tour_par_sec = (float)frequence_codeuse/(float)tick_par_tour_cod
59 float erreur = consigne_moteur_nombre_tours_par_seconde - nb_tour_par_sec
60 somme_erreur += erreur;
61 float delta_erreur = erreur-erreur_precedente;
62 erreur_precedente = erreur;
63
64 // PID : calcul de la commande
65 cmd = kp*erreur + ki*somme_erreur + kd*delta_erreur;
66
67 // Normalisation et contrôle du moteur
68 if(cmd < 0) cmd=0;
69 else if(cmd > 255) cmd = 255;
70 analogWrite(_MOTEUR, 255-cmd);
71
72 // DEBUG
73 if(_DEBUG) Serial.println(nb_tour_par_sec,8);
74 }
Publié par Ferdinand Piette à 21:49 Taggué avec : Arduino, Asservissement, Automatique, Capteur, Electronique, Montage, Robotique
1. Ulysse2 dit :
9 août 2012 à 11:01
Répondre
2. TeRRy dit :
22 octobre 2012 à 21:26
Bonjour,
J'ai une question. La variable somme_erreur ne risque pas un dépassement? Ne devrait elle pas etre remis a zero, tous
les n boucles? sinon le tuto est une bonne application du tuto, le PID sans calculs.
TeRRy
Répondre
Bonjour,
Normalement, si le PID est bien fait, il n'y aura pas de dépassement vu que la somme des erreurs oscillera
autour de 0 🙂
EDIT : Sinon, on pourrait imaginer "brider" cette valeur dans un intervalle et que si la somme des erreurs
dépasse une des borne de l’intervalle, on la ramène toujours à la borne.
Répondre
3. bastof dit :
1 novembre 2012 à 09:22
bonjour,
Bastof
Répondre
Bonjour,
C'est pour éviter de consommer du CPU inutilement.
Répondre
4. Jean dit :
5 février 2013 à 16:49
Pour moi Ki dépend des conditions initiales. Sauriez vous m'expliquer pourquoi si ce n'est pas le cas ?
Par exemple :
Le moteur tourne à 20 tours de roue par minute. Je lui demande d'aller à 100 tours. la somme des écarts au moment de
la stabilisation vaudra l'aire sous (et sur) la consigne mettons x.
Le moteur tourne à 40 tous de roue par minute. Je lui demande d'aller à 100 tours. la somme des écarts au moment de
la stabilisation vaudra à nouveau l'aire sous (et sur) la consigne mettons y.
Partant d'un écart plus grand, x sera supérieur à y. Un unique Ki introduira un surplus différent dans ma commande pour
x et y. L'état stable ne sera donc pas à la même "hauteur" en fonction de mes conditions initiales.
Je pense avoir raté quelquechose. Quand vous dites que la somme va osciller autour de 0, je ne suis pas d'accord, elle va
osciller autour d'une valeur constante. La somme serait nulle soit en la faisant sur une fenetre soit en ayant un régulateur
qui passe autant de "temps * amplitude" sous la consigne que sur la consigne. Et si c'est le cas, ce terme intégrateur ne
compense pas l'erreur statique puisqu'il est nul.
Je ne sais pas suis je suis clair dans l'explication de mon problème. J'espère que vous saurez m'aider à comprendre.
Merci d'avance
Jean
Répondre
Pour moi Ki dépend des conditions initiales. Sauriez vous m'expliquer pourquoi si ce
n'est pas le cas ?
Non non, Ki est bien indépendant des conditions initiales. Ki ne dépend que des caractéristiques du moteur.
Non, c'est bien y qui est supérieur à x puisque y est la somme de x plus un terme d'erreur (qui ici est de même
signe).
L'erreur grandit donc.
Le terme d'intégration sert à dire "Si je reste longtemps avec une erreur importante, alors je modifie
violemment la commande pour essayer de me stabilisé".
Dit autrement : "Avoir une petite erreur pendant un laps de temps important équivaut à avoir une grande
erreur pour un laps de temps cours".
Je pense avoir raté quelquechose. Quand vous dites que la somme va osciller autour
de 0, je ne suis pas d'accord, elle va osciller autour d'une valeur constante.
Hum... en effet, il semble que je me sois quelque peu fourvoyé dans mes explications. La somme va osciller
autour d'une valeur constante qui vaudra l'erreur statique du système P. C'est l'erreur qui oscille autour de
zéro.
Répondre
Jean dit :
6 février 2013 à 16:23
Non, c'est bien y qui est supérieur à x puisque y est la somme de x plus un
terme d'erreur (qui ici est de même signe).
L'erreur grandit donc.
Je vois plus le terme d'intégration par son effet : compenser l'erreur statique. C'est peut être là
que je me fourvoie.
Mon objectif est d'atteindre la consigne sans écart statique quelque soit la consigne et quelque
soit T0 sans changer Kp, Ki(, et Kd). Ce n'est pas possible avec un Ki constant, c'est ce que je
retiens de mes expérimentations.
Par exemple :
T0 = 24°C, C = 50°, Ki = 0.0001 -> Somme = 3500 environ
T0' = 28°C, C = 50°, Ki = 0.0001 -> Somme' = 3700 environ
Du coup ma température de stabilisation est différente entre T0 et T0'
Ce qui est logique, mais ne m'arrange pas. ^^
C'est surtout pour le cas où je dois descendre en température que ça ne m'arrange pas vu que la
somme oscille autour d'une constante négative ce qui augmente encore plus mon écart statique.
^^
Répondre
En effet, mais les constantes Kp, Ki et Kd sont définies afin d'obtenir une réponse ayant
toujours la même forme, quelque soit la consigne de départ et l'état initial du système.
Ce qu'on cherche, c'est bien d'avoir une forme toujours identique pour la réponse.
Si vous changez dynamiquement le terme intégrateur, la forme de la réponse changera
aussi et dans certains cas, vous aurez un système oscillant et dans d'autre, un
système apériodique... ce qui peut être dangereux dans certaines situations (exemple,
asservir un bras pour écrire sur une feuille de papier. Dans ce cas, la réponse doit
toujours être apériodique, sinon, s'il y a un léger dépassement, la pointe s'écrase sur la
table (ou transperce la feuille))
Répondre
5. Goligo dit :
26 février 2013 à 02:12
MERCI !
Je crois que j'ai enfin compris comment mettre simplement en place un asservissement PID avec un Arduino, un moteur
et une roue codeuse.
En revanche, comment avez-vous obtenu vos courbes pour déterminer les constantes kp, ki et kd ? (Processing ?)
Répondre
En revanche, comment avez-vous obtenu vos courbes pour déterminer les constantes
kp, ki et kd ? (Processing ?)
Non, j'ai activé le mode débug, ce qui m'a permis d'envoyer sur le port série le nombre de tours par seconde
du moteur à chaque fois que je recalcule la commande.
#define _DEBUG true
[...]
void asservissement()
{
[...]
if(_DEBUG) Serial.println(nb_tour_par_sec,8);
}
Attention néanmoins à bien régler le baudrate pour que la vitesse de transmission soit suffisamment rapide
afin de ne pas perturber la boucle d'asservissement !
Répondre
Goligo dit :
27 février 2013 à 01:31
Répondre
6. loow dit :
29 avril 2013 à 14:28
Merci.
Répondre
Cf commentaire du dessus 😉
Répondre
7. loow dit :
30 avril 2013 à 10:34
Mais qu'avez-vous copier-coller dans votre graphique et comment avez vous fait?
Répondre
J'ai copié les valeurs que j'obtiens sur le port série en mode debug dans un tableur Excel.
if(_DEBUG) Serial.println(nb_tour_par_sec,8);
Ces valeurs représentent le nombre de tours de roues par seconde estimé toutes les 50ms.
Je trace ensuite le graph.
Répondre
emily dit :
8 mai 2017 à 19:45
j'ai pas trouvé les valeurs vous pouvez m'indiquer comment ça marche
Répondre
8. Clément dit :
4 juin 2013 à 02:39
Salut,
Tout d'abord merci beaucoup pour ces 2 tutos sur l'asservissement en vitesse c'est vraiment utile.
J'ai essayé aujourd'hui de le mettre en oeuvre sur mon robot mais j'ai un problème (Mon moteur avec encodeur intégré).
En fait quand je lit la réponse de mon encodeur avec analogueWrite, il me donne soit 0 soit 5, or 5 avec analogueWrite ça
veut bien dire 5/1024*5 Volt non ?
Ensuite j'ai quand même réussi a lire les tick de mon codeur avec analogueWrite :
if(analogRead(54) == 5 && verif == 0)
{
tickCodeuseG++;
//Serial.println(tickCodeuseG);
verif = 1;
}
_ Est t'il normale que la réponse de mon encodeur soit si faible en tension ?
_ Faut-il absolument utiliser la fonction attachInterrupt ? (Elle a un meilleur temps de réaction peut-être et elle capte
tous les tick elle)
_ Faut-il absolument utiliser la fonction attachInterrupt sur les pin Interrupt de la arduino ?
Bonsoir,
_ Est t'il normale que la réponse de mon encodeur soit si faible en tension ?
Non, ce n'est pas normal. Déjà, sur une Arduino Méga, les entrées analogiques sont les pin 0 à 15. La pin 54
n'existe pas.
Sinon, pourquoi utiliser une entrée alors qu'un tick codeuse est un signal numérique ? Autant utiliser une
entrée numérique.
Oui, l'interruption se déclenchera à chaque fois que tu auras un tick (montant, descendant ou les deux). Ainsi,
tu n'en louperas pas.
Uniquement sur les pins 2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20 (interrupt 3), et 21
(interrupt 2) pour l'arduino méga : http://arduino.cc/en/Main/arduinoBoardMega
Répondre
Clément dit :
5 juin 2013 à 05:51
Répondre
Clément dit :
7 juin 2013 à 00:33
Salut,
Merci pour ton aide maintenant ça marche très bien !
J'ai mis les réponses des encodeurs sur les bon pin (20 et 21) avec la bonne fonction
attachInterrupt et ça marche très bien.
Merci encore !
Répondre
9. T-Chou dit :
27 août 2013 à 14:14
Bonjour,
j'ai grasse a votre tutorial réussi a implémenter un PID pour des tètes de lecture HDD avec capteur optique.
Entre mon code de gestion d'erreurs et cette technique, c'est le jour et la nuit (un angle bien propre !)
J'avais quasiment implémenter un PID sans m'en rendre compte, une sorte de PD agissant comme suit :
Répondre
Bonjour.
En sachant qu'erreur tend vers -inf lorsque la mesure est trop haute
Justement non. L'erreur ne tend jamais vers -inf. C'est la somme des erreurs qui peut potentiellement tendre à
l'infinie si l'asservissement se fait mal.
Ici, une commande à 0 signifie que le moteur n'est pas alimenté. Une commande positive signifie que le
moteur est alimenté pour tourner dans un sens. Une commande négative signifierai que le moteur puisse
tourner dans le sens inverse, ce qui est impossible dans mon exemple.
Ici, si l’erreur est négative, on n'alimente plus le moteur. Ce n'est pas un stop moteur : ne pas alimenter le
moteur ne signifie pas que celui-ci ne tourne pas !
Répondre
D'abord je tiens à vous dire que je suis nouveau dans arduino. Je voudrais compiler votre code PID complet avec arduino
uno r3. Le compilateur me dit erreur :(SimpleTimer Timer 😉
does not the name type.
Et donc je sais pas quoi faire ? S'il vous plait, pouvez vous m'aider comment il faut faire pour résoudre cette problème,
je vous mercis infiniment.
Répondre
Bonjour,
Il suffit d'installer la bibliothèque SimpleTimer. Le lien est dans le code :
http://arduino.cc/playground/Code/SimpleTimer
Répondre
Répondre
Répondre
Répondre
Bonjour Ferdinand.
Je développe actuellement un fauteuil roulant électrique pour personne handicapée.
Mon cahier des charges: autonomie supérieure à 6 heures, capacité de franchissement de marches de 16 cm, et donc
des trottoirs, et fonction tout terrain, l'ensemble devant rester dans les dimensions d'un fauteuil roulant, et à un prix
abordable.
J'ai un moteur 24v, DC par roue, soit 4 moteurs. Tous les contrôleurs pilotés par joystick que j'ai trouvés à ce jour ne
peuvent contrôler que 2 moteurs. Je pensais coupler les moteurs droits ensembles et gauches ensembles, mais je
risque d'avoir une vitesse différente entre les deux moteurs, et donc un comportement chaotique du fauteuil. J'ai donc
pensé à asservir le moteur arrière droit au moteur avant droit afin qu'il tourne à la même vitesse de manière
automatique, et idem à gauche, et ainsi je pourrais utiliser le joystick. Pourriez-vous m'aider à réaliser cette partie
électronique que je ne maitrise absolument pas. A quel coût?
Voila. Si cela retient votre attention, merci de m'envoyer un email pour poursuivre.
Merci, Cordialement
Rémy
Répondre
jean dit :
8 août 2014 à 19:38
bonjour Rémy
avez vous trouvé quelqu'un pour vous aider?
Jean
Répondre
Répondre
Répondre
Bonjour,
Je veux réaliser une pompe à eau en fonction d'une consigne de débit. Pour cela je dispose d'un pompe dc12v et d'un
débitmètre qui me sort un signal sinusoïdal à fréquence variable. n'ayant pas de roue codeuse puis je me servir des
informations fournis par le débitmètre pour réaliser un asservissement PID?
Répondre
Bonjour,
Il faut donc réaliser le PID sur cette information de débit : il faut calculer l'erreur et la somme des erreurs par
rapport à un débit de consigne. Le résultat du PID servira à commander le moteur.
Répondre
Du coup, j'ai essayé de le modifier pour faire tourner 2 moteurs avec la même consigne et là... problème. Le deuxième
moteur tourne à pleine vitesse. Apparemment, les interruptions sur la broche 3 (int1) ne fonctionne pas.
Répondre
Répondre
Bonjour , j'aurais 2 questions . C'est lorsque j'essaie de compiler le code , j'ai une erreur dans arduino : "class simple
timer has no menber named 'set interval'", j''ai donc un problème de compilation sachant que j'ai bien inclu la
bibliotheque simpletimer .
Utilisie-tu simplement ta carte arduino et ton moteur codeur ou tu utilise à la place une carte romeo ?. Car j'ai fait des
recherche , le codeur incrémentale delivre bcp trop d'impulsions pour la carte arduino donc elle est incapable de gerer
toutes et ces impusions , il faut donc utiliser une carte romeo qui inclus une sorte de diviseur de frequence qui a pour
but de diminuer la frequence des impulsions et donc d'avoir une frequence plus basse pour que arduino puisse la gérer
correctement , merci d'avance
Répondre
Bonjour,
Pour la première question, je ne sais pas. La bibliothèque contient toujours un membre setInterval
(http://playground.arduino.cc/Code/SimpleTimer#F_setInterval). Il doit y avoir un problème dans le code :
avez-vous bien fait l'include ? avez vous bien instancié un objet timer ?
Pour la seconde question, oui, j'ai testé mon code sur une arduino uno et mega et ça marche parfaitement.
La uno est tout à fait capable de gérer les quelques 5500 impulsions par secondes que peut délivrer la
codeuse lorsque le moteur est à plein régime.
Pas besoin de "diminuer la fréquence des impulsions". Ce n'est d'ailleurs possible qu'en utilisant une codeuse
moins précise ou en mettant la codeuse après le réducteur et non sur l'arbre moteur. Mais dans les deux cas,
on perd en précision.
Répondre
bat dit :
17 mai 2015 à 10:24
Merci de m'avoir répondu aussi rapidement , j'ai donc laisser tomber le diviseur de frequence ,
mais aurait-tu une idée de la capacité de la carte arduino à recevoir des données , peut-elle gérer
plus de 6000 impulsions par sec(en moyenne)? J'ai tester ton code , j'ai bien inclus le fichier
SimpleTimer.h et SimpleTimer.cpp , le code marche mais mon problème concernant le 'set
interval' et 'run'(dans le loop)persiste , le code se compile très bien sans ces deux lignes , arduino
ne semble pas les connaitre . Aurait -tu une idée ? cordialement
Répondre
Bonjour M ferdinand , je tiens tous d'abord à vous remercier pour le travail que vous avez réalisé . Mais si je vous envoie
ce message , c'est parce que j'ai un véritable problème qui me bloque complètement .
Je précise tous d'abord que mon moteur à un régime nominal de 6v , une reduction de 1/53 et 48 impulsions pour
chaque tour de moteur effectuer .
Lorsque je lance le programme , et que j'essaie d'afficher les impulsions stoker dans la variable compteur , il m'affiche
300 impulsions alors que moteur en sortie de reducteur n'a fait que 1 tour (il devrait m'afficher environ 2544 impulsion
car 53 * 48 =2544)
2)Comment pouvons nous déterminer les coeficients kp , ki , kd ?
merci
Répondre
MajorLee dit :
18 septembre 2015 à 16:31
Je me permet ce petit commentaire car je suis confronté en ce moment au même genre de problèmes.
Tout d'abord un grand merci à M.Piette pour ses tutoriaux.
@dakito : Attention quand un fabricant/fournisseur donne un codeur à 48 impulsions par tour cela sous
entend 2 fronts (montant et descendant) sur chacune des voies A et B (cas d'un encodeur à 2 voies en
quandrature). Si on n’échantillonne seulement un des 2 signaux et seulement un seul front, on se retrouve
avec 4 fois moins d'impulsions. Cela peut être une piste dans votre cas.
Répondre
Si je ne me trompe pas, c'est l’asservissement I qui permet d'avoir un système précis, et non l'asservissement P, pour un
système d'ordre 0.
Répondre
est ce ke j peux avoir votre compte personnel parce que je veux que tu m'aide dans mon projet
Répondre
bonjour. je suis un novice et je m'intéresse à tout ce qui touche le handicap. je me bat pour comprendre le langage et la
programmation. pour le côté matériel hardware et mécanique ce là devrait aller pour moi. à la lecture des commentaires
aux quels j'arrive à comprendre. une idée me viens:pourquoi ne pas utiliser un moteur pas à pas . avec réducteur devant
un différentiel des deux arbre de roues. y aurait-il un problème de puissance pour ne pas utiliser un pas a pas.
merci par avance de votre reponse
cordialement
Roger
Répondre
Bonjour,
Oui, c'est possible, mais dans ce cas là, la régulation PID et la roue codeuse ne sert plus à rien.
Le propos de l'article était justement d'illustrer l'utilisation d'un PID.
L'utilisation d'un moteur à courant continue ou pas à pas dépend de l'application.
Répondre
Bonjour,
Je ne comprend pas à quoi servent les résistances R1 et R2 exactement. Comment elles ont été choisies ? Il s'agit de
limiter la tension ? le courant ?
Je ne comprend pas non plus pourquoi on a besoin d'un transistor Bipolaire ? pourquoi ne pas directement utiliser le
transistor MOFSET ? Pourquoi passer par l’intermédiaire d'un transistor bipolaire avant ?
La diode est une diode de roue libre ? pour eviter les surtensions sur le moteur ?
Cordialement
Michel
Répondre
Bonjour,
J'avais réalisé à l'époque l'interface de commande rapidement avec les composants à ma disposition.
Il y a donc surement moyen de faire mieux (notamment, cette interface ne peut pas faire tourner le moteur
dans les deux sens). Néanmoins, compte tenu de mes besoins, celle-ci est plus que suffisante.
R1 est juste une résistante de pull-up pour commander le MOFSET à 12V lorsque le bipolaire est bloqué.
Lorsque le bipolaire est passant, la gate du MOFSET est forcé à 0V et R1 sert à éviter un court-circuit (il y a
seulement 12mA qui passent dans R1 et dans le bipolaire du coup).
La valeur de R1 a été choisi au pifomètre, mais on pourrait l'augmenter encore afin de limiter le courant
traversant le bipolaire (aucun courant ne passe dans la gate du MOFSET qui est un transistor commandé en
tension et non en courant comme le bipolaire).
R2, quant à elle, sert à limiter le courant entrant à la base du bipolaire (vu que c'est un transistor commandé
en courant cette fois).
Lorsque la pin9 de l'Arduino est en état haut (5V), le bipolaire conduit. Sa base est donc environ à 0.7V, ce qui
fait que le courant de commande du bipolaire est de (5-0.7)/1000 soit 4.3mA environ.
On ne peut pas commander directement le MOFSET via l'Arduino car celle-ci délivre du 5V alors que le
MOFSET doit être commandé en 12V.
Le bipolaire permet donc de passer d'une commande 0-5V à une commande 12V-0V (ici, la commande est
inversée, mais on pourrait imaginer une interface qui n’inverse pas la commande).
Donc l'Arduino, R1, R2 et le bipolaire forment la partie commande alors que le MOFSET et D1 forment la
partie puissance.
La diode D1 est en effet une diode de roue libre afin d'évacuer le courant du moteur lorsque le MOFSET se
coupe. Le moteur étant composé d'une bobine et donc une inductance, on ne peut pas avoir de discontinuité
dans le courant sous peine de sur-tension au moment où l'on active ou coupe le MOFSET.
En théorie le MOFSET inclut déjà une diode de roue libre, mais en pratique elle est souvent sous
dimensionnée.
Répondre
Michel dit :
16 novembre 2015 à 22:41
Répondre
Bonjour
Je souhaite mettre en place une surveillance de mon regulateur Pid vitesse afin d'eviter tout emballement en cas de
panne-panne encodeur par exemple.en surveillant que ma composante integrale (sur consigne elevee)ne depasse pas
un seuil pendant plus de 2sec jarrive a empecher cette survitesse. Oui mais voila ,des que je rentre une consigne tres
petite et que je simule de nouveau cette panne d'encodeur le systeme de secu ne se declenche que 3 min apres le debut-
le robot ayant deja pris beaucoup de vitesse....je cherche une idee donc pour que la surveillance soit efficace aussi bien
en consigne haute quant consigne basse...si vous avez une idee?!CDT
Répondre
Bonjour
Les explications sont très claires . Je suis un projet de construction de gyropode (type segway) à base d accelometre et
gyroscope sous arduino et j ai pu lire certains projets sur le net mais en anglais
Il y a la notion de pid par rapport à la mesure de l angle d inclinaison et la vitesse moteur associée
Pouvez m aider sur ces notions ?
Merci et encore bravo !
Répondre
Bonjour,
merci pour votre article tres interressant et tres clair. Pour illustrer celui ci vous avez des graphes, pouvez vous
mexpliquer comment vous les avez obtenus car pour le projet que je développe j'ai besoins de tracer les sorties
obtenues.
Cordialement.
Répondre
Bonjour,
J'ai récupéré les valeurs affiché dans la console Arduino et je les ais importés dans Excel.
Répondre
Bonjour,
Je suis désolé de vous poser la question ici car elle n'a pas forcément un très grand rapport avec le sujet du dessus.
J'aurais préféré vous contacter autrement ... Veuillez m'en excuser.
Je cherche à contrôler avec un Arduino si c'est possible plusieurs multiplexeurs. Je vous explique le contexte:
Je veux réaliser une mesure 4 fils de faible résistance à l'aide d'un ohmmètre que je pense acheter. Le problème est que
j'ai une bonne centaine de résistance à mesurer et j'aimerai bien automatiser la chose... ( La valeur des résistances
varient au cours du temps ).
J'aimerais donc pouvoir aiguiller mes pistes de façon à ce que mon ohmmètre mesure la résistance 1 puis la résistance
2 ainsi de suite ...
j'aimerais savoir si vous avez déjà réalisé un montage arduino avec un multiplexeur. Si cela vous semble possible car il
me faut plusieurs multiplexeur et que en tout j'aurais je pense avoir au moins 200 pistes à gérer. Ce qui me ferait utiliser
au moins 8 sorties numériques de l'arduino pour coder la positions des multiplexeurs ? je pense que 8 sorties
numériques c'est vraiment un minimum ... Sachant qu'il y 13 sorties numériques sur l'arduino dont 6 qui sont des PWM .
Bon après rien ne m'empèche d'utiliser des PWM en guise de sortie numérique non ?
Voila merci beaucoup ! Si vous avez des idées à me suggérer, n'hésitez pas 🙂
Encore une fois désolé de m'adresser sur un sujet qui parle d'asservissement.
Répondre
comment faire commande 5 moteurs a courant continu dans des deffernts sens a l'aide d'un clavier pour donner l'angle
et un ecrant LCD 😕
Répondre
Salut
Déja , beau boulot pour tes différentes explications sur la régul PID .
Je suis entrain d'essayer de régler la mienne pour le chauffage d'une pièce (salle de bain de 5m2).
En commençant mes tests de Kp , j'arrive à trouver une valeur qui me satisfait , sans trop de d'oscillations mais en étant
un peu éloigné de ma consigne (env. 0,5 °C) , du coup j'ai voulu faire intervenir le Kd mais le soucis est que la pièce a une
certaine inertie et donc elle met un peu de temps à atteindre une tempêrature proche de ma consigne et que pendant ce
temps ma somme d'erreurs augmente tout le temps ... Et donc une fois la consigne dépassée, avec l'inertie , elle met du
temps à revenir proche de zéro . Je me suis dit que j'allais augmenter le Kd , sauf que ça fait s'emballer le système et si à
l'inverse je le diminue .. bah il me sert plus à rien ^^ !
Aurais tu une piste pour éviter ce phénomène ? Je pensais imposer des limites au produit Kd*somme_erreurs ou alors
commencer à compter la somme d'erreurs "le plus tard possible" et non dès le début ...
Merci
Répondre
Bonjour,
Répondre
Bonjour,
Je viens solliciter votre aide car cela fait 3 mois que mes neurones surchauffe sur mon projet et là je sature....
Pour faire vite, j'ai un plateau tournant actionner par un petit moteur mais la partie réducteur ce fait avec une vis sans fin.
Ce plateau est fixé à la vertical avec un bras en porte à faux ce qui entraîne un freinage en monté et donc une
accélération en descente...
Le problème que je rencontre, contrairement à votre projet c'est que quand le moteur n'est pas alimenté, il s'arrête quasi
instantanément.
Ceci entraîne donc une rotation saccadée qui ne permet pas de régler le PID correctement.
J'ai chercher à commander le plateau en degré par minute car cela correspond plus à la vitesse rechercher qui est au
maximum de 3 où 4 tours par minute.
Auriez vous une piste pour créé un asservissement angulaire qui ne coupe pas complètement le moteur en cas de
dépassement de la consigne ??
Je suis novice mais je ne cherche pas de solution "toute faite" mais juste un p'tit coup pouce pour ne pas finir de
m'arracher les cheveux 🙂
Merci d'avance pour votre aide
Cordialement,
Pierro
const int _MOTEUR = 10; // Digital pin en PWM pour commande moteur
/* Routine d'initialisation */
void setup() {
Serial.begin(250000); // Initialisation port COM
pinMode(_MOTEUR, OUTPUT); // Sortie moteur
analogWrite(_MOTEUR, 255); // Sortie moteur a 0
delay(1000); // Pause de 1 sec pour laisser le temps au moteur de s'arreter si celui-ci est en marche
attachInterrupt(0, compteur, RISING); // Interruption sur tick de la codeuse (interruption 0 = pin2 arduino mega)
timer.setInterval(1000/frequence_echantillonnage, asservissement); // Interruption pour calcul du PID et asservissement
}
/* Fonction principale */
void loop() {
timer.run();
delay(10);
}
[/PHP]
Répondre
Bonjour,
Répondre
salut,
j'ai un mini projet sur asservissement en vitesse linéaire , si et possible donnez-moi quelques exemples de vitesse
linéaire! je trouve des machines en vitesse angulaire mais je ne trouve pas en vitesse linéaire!!
Répondre
Bonjour,
Merci et bravo pour ces deux articles clairs et qui expliquent simplement les PID et leurs mise en oeuvre pratique.
M'amusant beaucoup avec des drones je m'explique mieux leurs comportement et cela facilite grandement les réglages.
Répondre
Merci pour votre cours, mais quelles sont les puissances des résistances et quel type de diode ?
Répondre
Salut,
Ma roue codeuse fait 2400 tick par tour et j'essai d'avoir une vitesse constante de 137 ticks toutes les 100 ms.
c'est ce que j'obtiens quand ma fréquences de boucle est à 13µs environ. delayMicroseconds(cmd);
Ce que je ne comprends pas c'est que les valeurs de CMD issue du cacul de PID sont bien au dessus du chiffre 13 ce qui
fait que mon moteur se retrouve aux vitesses de seuil fixés. Soit vitesse maxi, soit à l'arret.
Pour info voici ma fonction, je n'ai pas à traduire les tick en frequence de rotation car ma consigne est le nombre de tick
lui même sur 100ms
void asservissement()
{
// Calcul de l'erreur
int erreur = consnbticks - tick;
somme_erreur += erreur;
float delta_erreur = erreur - erreur_precedente;
erreur_precedente = erreur;
Serial << tick << ";" << erreur << ";" << somme_erreur << ";" << delta_erreur << ";" << cmd << endl;
}
Bonjour, est ce que vous pouvez me donner une methode pour convertir la commande calculée par le PID en des signaux
PWM? quelle relation entre cette commande et les rapports cycliques des Timers?
Répondre
Bonjour,
en fait c'est la question que je me pose aussi... une mise à l'échelle entre le résultat du pid et la commande moteur est
obligatoire en fait non ?
Par exemple cela fonctionnerait t'il si on souhaitait avoir comme consigne le nombre de tick codeur par 100ms ?
l'échelle n'est pas la même et il n'y a pas de rapport précis entre le dutycycle du pwm et la vitesse de rotation.
Répondre
Bonjour et simplement merci pour ces démonstrations et ces aides que vous nous apportez.
Je reconnais que j'avais oublié ces notions et donc abandonné un projet mais ces petits rappels me donnent l'envie de
m'y remettre : donc MERCI Ferdinand.
Répondre
Bonjour,
Est que vous pouvez m'aider a faire un organigramme pour ce programme. Merci
Répondre
Bonsoir
Je trouve votre tuto très intéressant merci beaucoup , en fait je voulais demander autre chose , les graphes vous les
obtenez comment ? est ce un logiciel ou bien vous les tracez vous même ?
Merci
Répondre
44. DD_ard_56 dit :
22 février 2017 à 23:23
Répondre
Répondre
Bonsoir
J ai un projet de construction d un gyropode type "segway" , et je pense que la mise en place d'un pid indispensable au
sujet du calcul angulaire de la plate forme et faire réagir les moteurs en conséquence
Par contre je ne sais pas comment déterminer les consignes !
Pourriez.vous m'aider sur le sujet ?
Merci d avance
Giloris
Répondre
Bonjour, je travaille actuellement sur une maquette d'ascenseur et je suis bloquer au niveau de sin asservissement en
vitesse svp faite un schéma complet qui marche avec le programme final de ferdinand. Merci
Répondre
bonjour
je ne comprends pas comme fonctionne cet asservissement de vitesse, si il s'agit bien d'un asservissement de vitesse?
Pour faire simple on va se placer dans le cas ou on ne fait que du proportionnel (donc pas de Ki et pas de Kd)
j'ai donc cmd qui vaut : Kp * erreur
la commande qui est envoyée avec analogwrite est : analogwrite(broche, 255-cmd)
Lorsque la vitesse réelle est égale à la consigne j'ai cmd=0 car erreur =0 donc une valeur de 255 est envoyée ce qui
correspond à la vitesse max indépendamment de ma valeur de consigne. Il n'y a donc pas d'asservissement par rapport
à la consigne de vitesse? ou alors il y a quelque chose de gros qui m'échappe...
Répondre
mrc pour les eplication j ai an dynamotachemitrique a la place de l encodeur j'arrive pas a faire son asservissement
Répondre
Bonsoir, moi j'essaie d'utiliser ce code mais j'ai besoin du schéma si possible
Répondre
Bonsoir,
Merci pour ce processus détaillé de mise en œuvre d'une régul PID sur ARDUINO, avec un moteur cc pour actionneur.
Retraité de la pétrochimie en centrale thermique, j'étais toujours en admiration devant les personnes en charge de régler
les boucles de régulation avec la phase identification, et réglages. C'était quelques fois du PI seul.
Je vais peut-être mettre en œuvre ce code pour une appli de rotation de tube en phase de soudure pour un ami
ferronnier. L'entrainement du tube en rotation devant se faire à vitesse constante et stable, l'actionneur serait un moteur
d'essuie-glace via un réducteur 50:1.
Merci à vous pour ce brillant développement sur un cas concret, aboutissant à du code directement applicable, sous
réserve de trouver les coefficients appropriés.
Bonne continuation!!
Répondre
Salut,
je ne comprends pas comment tu calcules la vitesse de rotation en tours/s a partir du nombre d impulsions.
( ligne 57 et 58 du code )
A partir de ma roue codeuse je peux directement obtenir la vitesse de rotation en tours par seconde , et je pourrais
directement passer a la ligne du code 59 . est ce possible?
Répondre
bonjour,
c'est étrange mais je ne vois à aucun moment l'utilisation de la codeuse O_o.
Comment faites vous pour mesurez quoi que ce soit sans même l'instancier?
Répondre
Laisser un commentaire
Your Comment
bilink href=""b-quotecode ;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :lol:
:idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:?
Apercu
Vous pouvez utiliser ces tags et attributs HTML&nsbp;: <a href="" title=""> <abbr title=""> <acronym
title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s>
<strike> <strong>
Name (required)
E-mail (required)
URI
Soumettre le commentaire
Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.