Montage de la maquette du château d’eau

Sketch arduino pour l’étude de l’influence de Kp et de Ki sur la réponse temporelle d’une régulation proportionnelle intégrale

Montage

Sortie série

L’affichage de la sortie série peut se faire de trois manières différentes :

Code à téléverser

/** * regulation_proportionnelle_integrale.ino * Ce sketch allume plus ou moins la pompe afin que le niveau d'eau atteigne une consigne choisie * La commande calculée, contient un terme proportionnel et un terme intégral * Le sketch affiche la date t, la hauteur d'eau et la valeur de la commande PWM * * La pompe est allumée en permanence pour ne pas la désamorcer en dessous d'une commande minimale * Certaines consignes trop faibles ne peuvent donc pas être atteintes * * --> Évolution des grandeurs pertinentes en fonction du temps, influence de Kp et de Ki */ // 1. Déclarations des constantes et variables globales // Capteur de pression const byte PRESSURE_SENSOR_PIN = A0; // Capteur Pin1 A0, Pin2 GND et Pin3 5 V. // La hauteur est obtenue grâce à une relation affine hauteur (mm) = a × tension (V) + b const float PENTE = 225.6; // Coefficient directeur a (mm/V) – Déterminé séparément const float OFFSET = -30.50; // Ordonnée à l’origine b (mm) – Déterminé séparément float hauteur = 0.0; // Variable globale car conception des sketches par blocs // Module de puissance const byte PWM_PIN = 11; // Module de puissance entre GND et PIN11 // Gestion du temps pour affichage unsigned long startTime; // Régulation proportionnelle intégrale const float CONSIGNE_DE_HAUTEUR = 90.0; // Consigne en mm const float COMMANDE_POMPE_MINIMALE = 80.0; // Valeur en dessous de laquelle la pompe ne s'amorce pas const float Kp = 5.0; // Gain proportionnel const float Ki = 1.0; // Gain intégral const float dt = 0.2; // En secondes − accroissement (infinitésimal) de temps float termeIntegral = 0.0; // Variable globale mémorisée entre deux passages dans loop() // 2. Setup − Exécuté une seule fois void setup() { // Fixe la vitesse de communication entre arduino et le PC Serial.begin(9600); // Configuration du module de puissance TCCR2B = (TCCR2B & 0b11111000) | 0x07; // Fréquence PWM = 30 Hz pinMode(PWM_PIN, OUTPUT); // Broche PWM_PIN parametrée en sortie // Origine des dates startTime = millis(); } // 3. Loop − Variables recréées à chaque boucle void loop() { // Détermination de la hauteur int pressureSensorRawValue = averageAnalogRead(PRESSURE_SENSOR_PIN, 30); // Moyenne de 30 valeurs entre 0 et 1023 float pressureSensorVoltage = pressureSensorRawValue * 5.0 / 1023.0; // Valeur de la tension en volts hauteur = PENTE * pressureSensorVoltage + OFFSET; // Calcul de la hauteur d’eau dans le réservoir // Date courante float date = (millis() - startTime) / 1000.0; // Correction PI float erreur = CONSIGNE_DE_HAUTEUR - hauteur; termeIntegral = termeIntegral + Ki * erreur * dt; termeIntegral = constrain(termeIntegral, -255, 255); // Anti emballement - Limite les dépassements float termeProportionnel = Kp * erreur; int commande_pwm = termeProportionnel + termeIntegral + COMMANDE_POMPE_MINIMALE; commande_pwm = constrain(commande_pwm, COMMANDE_POMPE_MINIMALE, 255); // Certaines consignes trop faibles ne pourront pas être atteintes analogWrite(PWM_PIN, commande_pwm); // Afficahge des varaibles Serial.print(date); Serial.print('\t'); Serial.print(hauteur, 0); Serial.print('\t'); Serial.println(commande_pwm, DEC); // On attend pendant dt delay(dt * 1000); } // 4. Fonctions − Variables locales /* Cette fonction effectue une moyenne sur les sampleCount valeurs renvoyées par analogRead(pin) */ int averageAnalogRead(byte pin, byte sampleCount) { long sum = 0; for(byte i = 0; i < sampleCount; i++){ sum = sum + analogRead(pin); } return sum / sampleCount; }