ssi_elec_regulation_asservissement
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| ssi_elec_regulation_asservissement [2025/11/29 14:01] – mistert2 | ssi_elec_regulation_asservissement [2025/12/09 13:54] (Version actuelle) – mistert2 | ||
|---|---|---|---|
| Ligne 3: | Ligne 3: | ||
| ==== COURS ==== | ==== COURS ==== | ||
| - | {{https:// | + | {{https:// |
| - | - asservissement/ | + | |
| - | ==== TP – Régulation de vitesse d’un moteur à courant continu avec PID ==== | + | ==== MODELES MATLAB |
| - | === Objectifs du TP === | + | {{https:// |
| - | -- Mesurer la vitesse d’un moteur CC avec un codeur incrémental. | + | {{https:// |
| - | -- Comprendre la différence entre boucle ouverte et boucle fermée. | + | |
| - | -- Mettre en œuvre progressivement un correcteur P, puis PI, puis PID. | + | |
| - | -- Observer l’erreur statique, le dépassement et la sensibilité au bruit. | + | |
| - | === Travail demandé === | ||
| - | -- Décrire la réponse du moteur en boucle ouverte. | + | ---- |
| - | -- Tracer ou décrire la courbe vitesse / consigne pour P. | + | |
| - | -- Expliquer pourquoi un écart statique persiste. | + | |
| - | -- Montrer comment I supprime cet écart. | + | |
| - | -- Comparer les dépassements pour P, PI et PID. | + | |
| - | -- Conclure sur l’intérêt des trois termes du PID. | + | |
| - | + | ||
| - | === 1) Commande du moteur en boucle ouverte === | + | |
| - | + | ||
| - | Manipulations : | + | |
| - | -- Envoyer une commande PWM fixe (ex : 50 %, puis 80 %). | + | |
| - | -- Observer la vitesse indiquée par le programme. | + | |
| - | -- Bloquer légèrement l’axe du moteur avec le doigt (sans forcer). | + | |
| - | + | ||
| - | Observations attendues : | + | |
| - | -- La vitesse chute immédiatement lorsque l’axe est freiné. | + | |
| - | -- Le moteur ne corrige pas cette chute : c’est normal en boucle ouverte. | + | |
| - | -- La vitesse dépend de la charge, des frottements et de la tension. | + | |
| - | + | ||
| - | Conclusion : | + | |
| - | La boucle ouverte ne permet pas de maintenir une vitesse constante. | + | |
| - | + | ||
| - | === 2) Mise en place d’un correcteur P (Proportionnel) === | + | |
| - | + | ||
| - | Manipulations : | + | |
| - | -- Activer le correcteur proportionnel : | + | |
| - | <mt>u = K_p \cdot e</ | + | |
| - | -- Fixer une consigne (ex : 200 ticks/s). | + | |
| - | -- Freiner légèrement le moteur avec le doigt. | + | |
| - | -- Augmenter progressivement Kp : 0.2 → 0.5 → 1.0 → 2.0. | + | |
| - | + | ||
| - | Observations attendues : | + | |
| - | -- Le moteur augmente la PWM pour compenser la perturbation. | + | |
| - | -- La vitesse remonte partiellement. | + | |
| - | -- Il reste un écart statique : | + | |
| - | < | + | |
| - | -- Si Kp devient trop grand : oscillations, | + | |
| - | + | ||
| - | Conclusion : | + | |
| - | Le correcteur P réduit l’erreur, mais ne la supprime pas. | + | |
| - | + | ||
| - | === 3) Mise en place du correcteur I (Intégral) === | + | |
| - | + | ||
| - | Manipulations : | + | |
| - | -- Ajouter le terme intégral : | + | |
| - | <mt>u = K_p e ;+; K_I \int e(t), | + | |
| - | -- Débuter avec Ki = 0.05, puis 0.1 max. | + | |
| - | -- Freiner l’axe puis relâcher. | + | |
| - | + | ||
| - | Observations attendues : | + | |
| - | -- L’erreur statique disparaît. | + | |
| - | -- La vitesse atteint précisément la consigne. | + | |
| - | -- Si Ki trop fort : dépassement, | + | |
| - | + | ||
| - | Conclusion : | + | |
| - | Le correcteur I supprime l’erreur statique, mais ne doit jamais être trop fort. | + | |
| - | + | ||
| - | === 4) Mise en place du correcteur D (Dérivé) === | + | |
| - | + | ||
| - | Manipulations : | + | |
| - | -- Ajouter le terme dérivé : | + | |
| - | <mt>u = K_p e ;+; K_I \int e,dt ;+; K_D \frac{de}{dt}</ | + | |
| - | -- Tester avec Kd = 0.01, puis 0.05. | + | |
| - | -- Freiner l’axe pour observer la réaction. | + | |
| - | + | ||
| - | Observations attendues : | + | |
| - | -- Le système est mieux amorti. | + | |
| - | -- Le dépassement diminue. | + | |
| - | -- La stabilité augmente. | + | |
| - | + | ||
| - | Attention : | + | |
| - | -- Si Kd trop élevé → bruit, vibrations, instabilité. | + | |
| - | + | ||
| - | Conclusion : | + | |
| - | Le terme D stabilise le système, mais n’améliore pas la précision. | + | |
| - | + | ||
| - | === Synthèse des rôles P / I / D ==== | + | |
| - | + | ||
| - | ^ Correcteur ^ Rôle principal ^ Risques si trop fort ^ | + | |
| - | | P | réduit l’erreur | oscillations | | + | |
| - | | I | supprime l’erreur statique | dépassement, | + | |
| - | | D | amortit, stabilise | amplification du bruit | | + | |
| - | + | ||
| - | ==== Code Arduino du TP ==== | + | |
| - | + | ||
| - | < | + | |
| - | + | ||
| - | // --- Pont en H --- | + | |
| - | const int M_AV = 3; // PWM forward | + | |
| - | const int M_AR = 6; // PWM reverse | + | |
| - | + | ||
| - | // --- Codeur incrémental --- | + | |
| - | const int canalA = 2; // interruption 0 | + | |
| - | const int canalB = 11; | + | |
| - | + | ||
| - | volatile long ticks = 0; // compteur modifié par ISR | + | |
| - | + | ||
| - | // === PID === | + | |
| - | float consigne = 0; // vitesse ciblée (ex : en ticks/s) | + | |
| - | float kp = 0.8; // gains PID : à régler en TP | + | |
| - | float ki = 0.1; | + | |
| - | float kd = 0.05; | + | |
| - | + | ||
| - | float erreur, erreurPrec = 0; | + | |
| - | float integral = 0; | + | |
| - | + | ||
| - | // === Mesure période === | + | |
| - | unsigned long lastMeasure = 0; | + | |
| - | const unsigned long period = 100; // calcul vitesse toutes les 100 ms | + | |
| - | + | ||
| - | // === Prototypes === | + | |
| - | void ISR_codeur(); | + | |
| - | void commandeMoteur(float pwm); | + | |
| - | float lireConsigne(); | + | |
| - | + | ||
| - | void setup() { | + | |
| - | Serial.begin(9600); | + | |
| - | + | ||
| - | pinMode(M_AV, | + | |
| - | pinMode(M_AR, | + | |
| - | + | ||
| - | pinMode(canalB, | + | |
| - | + | ||
| - | attachInterrupt(digitalPinToInterrupt(canalA), | + | |
| - | + | ||
| - | Serial.println(" | + | |
| - | Serial.println(" | + | |
| - | } | + | |
| - | + | ||
| - | // ====================== BOUCLE PRINCIPALE =========================== | + | |
| - | void loop() { | + | |
| - | // --- Lecture consigne si disponible --- | + | |
| - | if (Serial.available() > 0) { | + | |
| - | consigne = lireConsigne(); | + | |
| - | Serial.print(" | + | |
| - | Serial.println(consigne); | + | |
| - | } | + | |
| - | + | ||
| - | // --- Boucle PID toutes les 100 ms --- | + | |
| - | unsigned long now = millis(); | + | |
| - | if (now - lastMeasure >= period) { | + | |
| - | lastMeasure = now; | + | |
| - | + | ||
| - | long ticksMesures = ticks; // copie atomique | + | |
| - | ticks = 0; // RAZ pour prochaine fenêtre | + | |
| - | + | ||
| - | float vitesse = ticksMesures * (1000.0 / period); | + | |
| - | + | ||
| - | // ================= PID ================= | + | |
| - | erreur = consigne - vitesse; | + | |
| - | integral += erreur * (period / 1000.0); | + | |
| - | float deriv = (erreur - erreurPrec) / (period / 1000.0); | + | |
| - | erreurPrec = erreur; | + | |
| - | + | ||
| - | float commande = kp * erreur + ki * integral + kd * deriv; | + | |
| - | + | ||
| - | // Limiter entre -255 et 255 | + | |
| - | if (commande > 255) commande = 255; | + | |
| - | if (commande < -255) commande = -255; | + | |
| - | + | ||
| - | commandeMoteur(commande); | + | |
| - | + | ||
| - | // --- Affichage TP --- | + | |
| - | Serial.print(" | + | |
| - | Serial.print(consigne); | + | |
| - | Serial.print(" | + | |
| - | Serial.print(vitesse); | + | |
| - | Serial.print(" | + | |
| - | Serial.println(commande); | + | |
| - | + | ||
| - | + | ||
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | // ========== INTERRUPTIONS CODEUR ========== | + | |
| - | void ISR_codeur() { | + | |
| - | if (digitalRead(canalB)) | + | |
| - | ticks++; | + | |
| - | else | + | |
| - | ticks--; | + | |
| - | } | + | |
| - | + | ||
| - | // ========== COMMANDE MOTEUR ========== | + | |
| - | void commandeMoteur(float pwm) { | + | |
| - | if (pwm >= 0) { | + | |
| - | digitalWrite(M_AR, | + | |
| - | analogWrite(M_AV, | + | |
| - | } else { | + | |
| - | digitalWrite(M_AV, | + | |
| - | analogWrite(M_AR, | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | // ========== LECTURE CONSIGNE ========== | + | |
| - | float lireConsigne() { | + | |
| - | String txt = Serial.readStringUntil(' | + | |
| - | txt.trim(); | + | |
| - | return txt.toFloat(); | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | Si tu veux, je t’ajoute : | + | |
| - | + | ||
| - | 📌 une version imprimable PDF | + | |
| - | 📌 un schéma fonctionnel de la boucle PID | + | |
| - | 📌 une activité complémentaire “réglage Ziegler–Nichols” | + | |
| - | 📌 un graphe ASCII montrant | + | |
| - | + | ||
| - | Vous avez dit : | + | |
| - | les lstes en -- marchent pas garder * | + | |
| - | ChatGPT a dit : | + | |
| - | Réflexion durant 4 secondes | + | |
| - | + | ||
| - | Voici la version corrigée avec les listes en * (et toujours gras + balises < | + | |
| - | + | ||
| - | ===== REGULATION ET ASSERVISSEMENT ===== | + | |
| - | + | ||
| - | ==== COURS ==== | + | |
| - | + | ||
| - | {{https:// | + | |
| - | - asservissement/ | + | |
| ==== TP – Régulation de vitesse d’un moteur à courant continu avec PID ==== | ==== TP – Régulation de vitesse d’un moteur à courant continu avec PID ==== | ||
| Ligne 243: | Ligne 18: | ||
| === Objectifs du TP === | === Objectifs du TP === | ||
| - | Mesurer la vitesse d’un moteur CC avec un codeur incrémental. | + | * Mesurer la vitesse d’un moteur CC avec un codeur incrémental |
| + | * Comprendre la différence entre boucle ouverte et boucle fermée | ||
| + | * Mettre en œuvre progressivement un correcteur P, puis PI, puis PID | ||
| + | * Observer l’erreur statique, le dépassement et la sensibilité au bruit | ||
| - | Comprendre la différence entre boucle ouverte et boucle fermée. | + | ---- |
| - | + | ||
| - | Mettre en œuvre progressivement un correcteur P, puis PI, puis PID. | + | |
| - | + | ||
| - | Observer l’erreur statique, le dépassement et la sensibilité au bruit. | + | |
| === Travail demandé === | === Travail demandé === | ||
| - | Décrire la réponse du moteur en boucle ouverte. | + | * Décrire la réponse du moteur en boucle ouverte |
| - | + | | |
| - | Tracer ou décrire la courbe vitesse / consigne pour P. | + | |
| - | + | | |
| - | Expliquer pourquoi un écart statique persiste. | + | |
| - | + | * Conclure sur l’intérêt des trois termes du PID | |
| - | Montrer comment I supprime cet écart. | + | |
| - | + | ||
| - | Comparer les dépassements pour P, PI et PID. | + | |
| - | Conclure sur l’intérêt des trois termes du PID. | + | ---- |
| === 1) Commande du moteur en boucle ouverte === | === 1) Commande du moteur en boucle ouverte === | ||
| Ligne 269: | Ligne 40: | ||
| Manipulations : | Manipulations : | ||
| - | Envoyer | + | * Choisir le mode boucle ouverte |
| - | + | * Choisir | |
| - | Observer la vitesse indiquée par le programme. | + | |
| - | + | | |
| - | Bloquer légèrement l’axe du moteur avec le doigt (sans forcer). | + | |
| Observations attendues : | Observations attendues : | ||
| - | La vitesse chute immédiatement lorsque l’axe est freiné. | + | * La vitesse chute immédiatement lorsque l’axe est freiné |
| + | * Le moteur ne corrige pas cette chute : c’est normal en boucle ouverte | ||
| + | * La vitesse dépend de la charge, des frottements et de la tension | ||
| - | Le moteur ne corrige pas cette chute : c’est normal en boucle ouverte. | + | Conclusion |
| + | La boucle ouverte | ||
| - | La vitesse dépend de la charge, des frottements et de la tension. | + | ---- |
| - | + | ||
| - | Conclusion : | + | |
| - | La boucle ouverte ne permet pas de maintenir une vitesse constante. | + | |
| === 2) Mise en place d’un correcteur P (Proportionnel) === | === 2) Mise en place d’un correcteur P (Proportionnel) === | ||
| Ligne 290: | Ligne 60: | ||
| Manipulations : | Manipulations : | ||
| - | Activer le correcteur proportionnel : <mt>u = K_p \cdot e</ | + | * Activer le correcteur proportionnel : <mt>u = K_p \cdot e</ |
| - | + | | |
| - | Fixer une consigne (ex : 200 ticks/s). | + | * Le programme convertit automatiquement en ticks/s |
| - | + | | |
| - | Freiner légèrement le moteur avec le doigt. | + | |
| - | + | ||
| - | Augmenter progressivement K_p : 0.2 → 0.5 → 1.0 → 2.0. | + | |
| Observations attendues : | Observations attendues : | ||
| - | Le moteur augmente la PWM pour compenser la perturbation. | + | * Le moteur augmente la PWM pour compenser la perturbation |
| + | * La vitesse remonte partiellement | ||
| + | * Il reste un écart statique : < | ||
| + | * Si K_p devient trop grand : oscillations, | ||
| - | La vitesse remonte partiellement. | + | Conclusion : Le correcteur P réduit l’erreur, mais ne la supprime pas |
| - | Il reste un écart statique : < | + | ---- |
| - | + | ||
| - | Si K_p devient trop grand : oscillations, | + | |
| - | + | ||
| - | Conclusion : | + | |
| - | Le correcteur P réduit l’erreur, mais ne la supprime pas. | + | |
| === 3) Mise en place du correcteur I (Intégral) === | === 3) Mise en place du correcteur I (Intégral) === | ||
| Ligne 315: | Ligne 81: | ||
| Manipulations : | Manipulations : | ||
| - | Ajouter le terme intégral : <mt>u = K_p e + K_I \int e(t), | + | * Ajouter le terme intégral : <mt>u = K_p e + K_I \int e(t)\, |
| - | + | | |
| - | Débuter avec K_I = 0.05, puis 0.1 max. | + | |
| - | + | ||
| - | Freiner l’axe puis relâcher. | + | |
| Observations attendues : | Observations attendues : | ||
| - | L’erreur statique disparaît. | + | * L’erreur statique disparaît |
| + | * La vitesse atteint précisément la consigne | ||
| + | * Si < | ||
| - | La vitesse atteint précisément la consigne. | + | Conclusion : Le correcteur I supprime l’erreur statique, mais ne doit jamais être trop fort |
| - | Si K_I est trop fort : dépassement, | + | ---- |
| - | + | ||
| - | Conclusion : | + | |
| - | Le correcteur I supprime l’erreur statique, mais ne doit jamais être trop fort. | + | |
| === 4) Mise en place du correcteur D (Dérivé) === | === 4) Mise en place du correcteur D (Dérivé) === | ||
| Ligne 336: | Ligne 99: | ||
| Manipulations : | Manipulations : | ||
| - | Ajouter le terme dérivé : <mt>u = K_p e + K_I \int e,dt + K_D \frac{de}{dt}</ | + | * Ajouter le terme dérivé : <mt>u = K_p e + K_I \int e\,dt + K_D \frac{de}{dt}</ |
| - | + | | |
| - | Tester avec K_D = 0.01, puis 0.05. | + | |
| - | + | ||
| - | Freiner l’axe pour observer la réaction. | + | |
| Observations attendues : | Observations attendues : | ||
| - | Le système est mieux amorti. | + | * Le système est mieux amorti |
| + | * Le dépassement diminue | ||
| + | * La stabilité augmente | ||
| - | Le dépassement diminue. | + | Attention : Si < |
| - | La stabilité augmente. | + | Conclusion : Le terme D stabilise le système, mais n’améliore pas la précision |
| - | Attention : | + | ---- |
| - | + | ||
| - | Si K_D est trop élevé → bruit, vibrations, instabilité. | + | |
| - | + | ||
| - | Conclusion : | + | |
| - | Le terme D stabilise le système, mais n’améliore pas la précision. | + | |
| === Synthèse des rôles P / I / D === | === Synthèse des rôles P / I / D === | ||
| Ligne 364: | Ligne 122: | ||
| | D | amortit, stabilise | amplification du bruit | | | D | amortit, stabilise | amplification du bruit | | ||
| - | ==== Code Arduino du TP ==== | + | ---- |
| + | ==== Code Arduino du TP (consigne en tr/min, PID en ticks/s) ==== | ||
| - | < | + | < |
| - | // === TP : PID pour régulation de VITESSE d’un moteur CC === | + | /* |
| - | // Mesure vitesse | + | ====================================== |
| - | // Consigne reçue par le Moniteur Série (en tr/ | + | |
| + | | ||
| + | |||
| + | MODE BO : | ||
| + | - PWM = conversion(consigne_tr/ | ||
| + | | ||
| + | - aucune régulation | ||
| + | |||
| + | MODE PID : | ||
| + | - consigne | ||
| + | - codeur mesure vitesse | ||
| + | - PID corrige PWM | ||
| + | */ | ||
| + | |||
| + | const int TICKS_PAR_TOUR = 90; // à ajuster selon le codeur | ||
| // --- Pont en H --- | // --- Pont en H --- | ||
| Ligne 376: | Ligne 149: | ||
| const int M_AR = 6; // PWM reverse | const int M_AR = 6; // PWM reverse | ||
| - | // --- Codeur | + | // --- Codeur --- |
| - | const int canalA = 2; // interruption 0 | + | const int canalA = 2; |
| const int canalB = 11; | const int canalB = 11; | ||
| - | volatile long ticks = 0; // compteur modifié par ISR | + | volatile long ticks = 0; |
| - | // === PID === | + | // --- PID --- |
| - | float consigne = 0; // vitesse ciblée (ex : en ticks/s) | + | float kp = 0.8; |
| - | float kp = 0.8; // gains PID : à régler en TP | + | |
| float ki = 0.1; | float ki = 0.1; | ||
| float kd = 0.05; | float kd = 0.05; | ||
| Ligne 391: | Ligne 163: | ||
| float integral = 0; | float integral = 0; | ||
| - | // === Mesure | + | float consigne_rpm = 0; |
| + | float consigne_ticks_s | ||
| + | |||
| + | // --- Modes --- | ||
| + | enum Mode { BO, PID_MODE }; | ||
| + | Mode mode = BO; | ||
| + | |||
| + | // --- Mesure | ||
| unsigned long lastMeasure = 0; | unsigned long lastMeasure = 0; | ||
| - | const unsigned long period = 100; // calcul vitesse toutes les 100 ms | + | const unsigned long period = 100; // 100 ms |
| - | // === Prototypes | + | |
| - | void ISR_codeur(); | + | // ============ INTERRUPTIONS CODEUR ============ |
| - | void commandeMoteur(float | + | void ISR_codeur() |
| - | float lireConsigne(); | + | if (digitalRead(canalB)) |
| + | ticks++; | ||
| + | | ||
| + | ticks--; | ||
| + | } | ||
| + | |||
| + | |||
| + | // ============ CONVERSION tr/min -> PWM (BO) ============ | ||
| + | int rpmToPWM(float | ||
| + | // Ajuste selon ton moteur | ||
| + | // Ex : 0–150 tr/min -> 0–255 PWM | ||
| + | if (rpm < 0) rpm = 0; | ||
| + | | ||
| + | |||
| + | return map(rpm, 0, 150, 0, 255); | ||
| + | } | ||
| + | // ============ CONVERSION tr/min -> ticks/s (PID) ============ | ||
| + | float rpmToTicksSec(float rpm) { | ||
| + | return (rpm * TICKS_PAR_TOUR) / 60.0; | ||
| + | } | ||
| + | |||
| + | |||
| + | // ============ COMMANDE MOTEUR ============ | ||
| + | void setPWM(int pwm) { | ||
| + | if (pwm >= 0) { | ||
| + | digitalWrite(M_AR, | ||
| + | analogWrite(M_AV, | ||
| + | } else { | ||
| + | digitalWrite(M_AV, | ||
| + | analogWrite(M_AR, | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | // ============================================= | ||
| + | // SETUP | ||
| + | // ============================================= | ||
| void setup() { | void setup() { | ||
| Serial.begin(9600); | Serial.begin(9600); | ||
| Ligne 406: | Ligne 221: | ||
| pinMode(M_AV, | pinMode(M_AV, | ||
| pinMode(M_AR, | pinMode(M_AR, | ||
| - | |||
| pinMode(canalB, | pinMode(canalB, | ||
| attachInterrupt(digitalPinToInterrupt(canalA), | attachInterrupt(digitalPinToInterrupt(canalA), | ||
| - | Serial.println(" | + | Serial.println(" |
| - | Serial.println(" | + | Serial.println(" |
| + | Serial.println(" | ||
| } | } | ||
| - | // ====================== | + | // ============================================= |
| + | // LOOP | ||
| + | // ============================================= | ||
| void loop() { | void loop() { | ||
| - | | + | |
| + | | ||
| if (Serial.available() > 0) { | if (Serial.available() > 0) { | ||
| - | consigne = lireConsigne(); | + | |
| - | Serial.print(" | + | txt.trim(); |
| - | Serial.println(consigne); | + | |
| + | if (txt.equalsIgnoreCase(" | ||
| + | mode = BO; | ||
| + | Serial.println(" | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | if (txt.equalsIgnoreCase(" | ||
| + | mode = PID_MODE; | ||
| + | Serial.println(" | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | // Sinon c'est une consigne | ||
| + | consigne_rpm | ||
| + | consigne_ticks_s = rpmToTicksSec(consigne_rpm); | ||
| + | |||
| + | Serial.print(" | ||
| + | Serial.print(consigne_rpm); | ||
| + | Serial.print(" | ||
| + | Serial.print(consigne_ticks_s); | ||
| + | Serial.println(" ticks/ | ||
| } | } | ||
| - | | + | |
| + | | ||
| unsigned long now = millis(); | unsigned long now = millis(); | ||
| - | if (now - lastMeasure | + | if (now - lastMeasure |
| - | lastMeasure = now; | + | lastMeasure = now; |
| + | |||
| + | long ticks_mes = ticks; | ||
| + | ticks = 0; | ||
| - | long ticksMesures | + | float vitesse_ticks_s |
| - | | + | float vitesse_rpm |
| - | float vitesse = ticksMesures * (1000.0 / period); | ||
| - | | + | |
| - | erreur = consigne | + | // MODE BO |
| + | // ============================================ | ||
| + | if (mode == BO) { | ||
| + | |||
| + | int pwm = rpmToPWM(consigne_rpm); | ||
| + | setPWM(pwm); | ||
| + | |||
| + | Serial.print(" | ||
| + | Serial.print(consigne_rpm); | ||
| + | Serial.print(" | ||
| + | Serial.print(vitesse_ticks_s); | ||
| + | Serial.print(" | ||
| + | Serial.print(vitesse_rpm); | ||
| + | Serial.print(" | ||
| + | Serial.println(pwm); | ||
| + | |||
| + | return; | ||
| + | } | ||
| + | |||
| + | |||
| + | // ============================================ | ||
| + | // | ||
| + | // ============================================ | ||
| + | if (mode == PID_MODE) { | ||
| + | |||
| + | erreur = consigne_ticks_s | ||
| integral += erreur * (period / 1000.0); | integral += erreur * (period / 1000.0); | ||
| float deriv = (erreur - erreurPrec) / (period / 1000.0); | float deriv = (erreur - erreurPrec) / (period / 1000.0); | ||
| Ligne 443: | Ligne 310: | ||
| float commande = kp * erreur + ki * integral + kd * deriv; | float commande = kp * erreur + ki * integral + kd * deriv; | ||
| - | // Limiter entre -255 et 255 | + | // saturation |
| if (commande > 255) commande = 255; | if (commande > 255) commande = 255; | ||
| if (commande < -255) commande = -255; | if (commande < -255) commande = -255; | ||
| - | | + | |
| - | | + | |
| - | Serial.print(" | + | Serial.print(consigne_rpm); |
| - | Serial.print(consigne); | + | Serial.print(" |
| - | Serial.print(" | + | Serial.print(vitesse_ticks_s); |
| - | Serial.print(vitesse); | + | Serial.print(" |
| - | Serial.print(" | + | Serial.print(vitesse_rpm); |
| + | Serial.print(" | ||
| Serial.println(commande); | Serial.println(commande); | ||
| - | } | ||
| - | } | ||
| - | + | return; | |
| - | // ========== INTERRUPTIONS CODEUR ========== | + | |
| - | void ISR_codeur() { | + | |
| - | if (digitalRead(canalB)) | + | |
| - | ticks++; | + | |
| - | else | + | |
| - | ticks--; | + | |
| - | } | + | |
| - | + | ||
| - | + | ||
| - | // ========== COMMANDE MOTEUR ========== | + | |
| - | void commandeMoteur(float pwm) { | + | |
| - | if (pwm >= 0) { | + | |
| - | digitalWrite(M_AR, | + | |
| - | analogWrite(M_AV, | + | |
| - | } else { | + | |
| - | digitalWrite(M_AV, | + | |
| - | analogWrite(M_AR, | + | |
| } | } | ||
| - | } | ||
| - | |||
| - | |||
| - | // ========== LECTURE CONSIGNE ========== | ||
| - | float lireConsigne() { | ||
| - | String txt = Serial.readStringUntil(' | ||
| - | txt.trim(); | ||
| - | return txt.toFloat(); | ||
| } | } | ||
| </ | </ | ||
ssi_elec_regulation_asservissement.1764424874.txt.gz · Dernière modification : de mistert2
