// regul_tor_2_seuils // Regulation de niveau tout-ou-rien a deux seuils pour la carte V2 a relais. // Le programme utilise les coefficients d'etalonnage du capteur MPX5010DP : // niveau_en_mm = a * analogRead(A0) + b // // Principe de regulation : // - si niveau <= SEUIL_BAS_MM : pompe ON // - si niveau >= SEUIL_HAUT_MM : pompe OFF // - entre les deux seuils : on conserve l'etat precedent de la pompe // // Protocole serie compatible avec graphique_regulation_tor.py : // DEBUT // t_s;consigne_mm;niveau_mm;commande_pct // ... // -1 puis FIN // // Pour conserver le meme programme Python, la valeur envoyee comme "consigne_mm" // est le seuil actif de commutation : // - pompe arretee : seuil bas, car c'est le prochain seuil qui peut declencher la pompe // - pompe active : seuil haut, car c'est le prochain seuil qui peut arreter la pompe // Branchement du capteur de pression MPX5010DP : // borne 1 (avec encoche) -> A0 // borne 2 -> GND // borne 3 -> 5V // Branchement du bouton : // SIG -> D2 // VCC -> 5V // GND -> GND // Sur la carte V2 testee : bouton relache = LOW, bouton appuye = HIGH. // Branchement de la commande de pompe par relais : // S / signal relais -> D9 // Sur la carte V2 testee : D9 LOW = pompe arretee, D9 HIGH = pompe active. // Branchement de la LED RGB ou des deux LED : // rouge -> D7 // verte -> D4 const int PIN_CAPTEUR = A0; const int PIN_BOUTON = 2; const int PIN_RELAIS = 9; const int PIN_LED_ROUGE = 7; const int PIN_LED_VERTE = 4; const int RELAIS_ON = HIGH; const int RELAIS_OFF = LOW; // A MODIFIER PAR LES ELEVES APRES L'ETALONNAGE. // Exemple : niveau_mm = a * analogRead(A0) + b const float a = 1.000000; const float b = 0.000000; // A MODIFIER SELON L'EXPERIENCE. const float SEUIL_BAS_MM = 80.0; const float SEUIL_HAUT_MM = 130.0; const unsigned long PERIODE_MESURE_MS = 500; const unsigned long APPUI_LONG_MS = 1500; const int NB_MESURES_A0 = 20; const int DELAI_MESURES_A0_MS = 5; const int AUCUN_APPUI = 0; const int APPUI_COURT = 1; const int APPUI_LONG = 2; bool pompeActive = false; bool regulationActive = false; unsigned long tempsDepartMs = 0; unsigned long derniereMesureMs = 0; void setup() { Serial.begin(115200); pinMode(PIN_CAPTEUR, INPUT); pinMode(PIN_BOUTON, INPUT); pinMode(PIN_LED_ROUGE, OUTPUT); pinMode(PIN_LED_VERTE, OUTPUT); digitalWrite(PIN_RELAIS, RELAIS_OFF); pinMode(PIN_RELAIS, OUTPUT); eteindrePompe(); afficherAttenteDepart(); if (SEUIL_HAUT_MM <= SEUIL_BAS_MM) { Serial.println("ERREUR : SEUIL_HAUT_MM doit etre superieur a SEUIL_BAS_MM."); while (true) { eteindrePompe(); delay(1000); } } attendreAppuiCourtBouton(); regulationActive = true; Serial.println("DEBUT"); tempsDepartMs = millis(); derniereMesureMs = tempsDepartMs - PERIODE_MESURE_MS; } void loop() { if (!regulationActive) { eteindrePompe(); return; } int actionBouton = lireActionBouton(); if (actionBouton == APPUI_LONG) { eteindrePompe(); regulationActive = false; Serial.println("-1"); Serial.println("FIN"); return; } unsigned long maintenant = millis(); if (maintenant - derniereMesureMs >= PERIODE_MESURE_MS) { derniereMesureMs = maintenant; float lectureA0 = lireCapteurMoyenne(); float niveauMm = a * lectureA0 + b; appliquerRegulationTOR2Seuils(niveauMm); afficherLED(niveauMm); envoyerDonneesSerie(niveauMm); } } void afficherAttenteDepart() { Serial.println(); Serial.println("=== REGULATION TOR A DEUX SEUILS ==="); Serial.println("Verifier que les coefficients a et b ont ete recopies dans le programme."); Serial.println("Verifier les valeurs SEUIL_BAS_MM et SEUIL_HAUT_MM."); Serial.println("Lancer graphique_regulation_tor.py sur le PC, puis appuyer sur le bouton pour demarrer."); Serial.println("Pendant la regulation : appui long = arreter l'experience."); Serial.println(); } void attendreAppuiCourtBouton() { while (digitalRead(PIN_BOUTON) == LOW) { delay(10); } delay(250); while (digitalRead(PIN_BOUTON) == HIGH) { delay(10); } delay(250); } int lireActionBouton() { if (digitalRead(PIN_BOUTON) == LOW) { return AUCUN_APPUI; } unsigned long debutAppui = millis(); while (digitalRead(PIN_BOUTON) == HIGH) { if (millis() - debutAppui >= APPUI_LONG_MS) { while (digitalRead(PIN_BOUTON) == HIGH) { delay(10); } delay(250); return APPUI_LONG; } delay(10); } delay(250); return APPUI_COURT; } float lireCapteurMoyenne() { long somme = 0; for (int i = 0; i < NB_MESURES_A0; i = i + 1) { somme = somme + analogRead(PIN_CAPTEUR); delay(DELAI_MESURES_A0_MS); } return ((float)somme) / NB_MESURES_A0; } void appliquerRegulationTOR2Seuils(float niveauMm) { if (niveauMm <= SEUIL_BAS_MM) { allumerPompe(); } if (niveauMm >= SEUIL_HAUT_MM) { eteindrePompe(); } } void allumerPompe() { pompeActive = true; digitalWrite(PIN_RELAIS, RELAIS_ON); } void eteindrePompe() { pompeActive = false; digitalWrite(PIN_RELAIS, RELAIS_OFF); } void afficherLED(float niveauMm) { if (pompeActive) { digitalWrite(PIN_LED_ROUGE, HIGH); digitalWrite(PIN_LED_VERTE, LOW); } else { digitalWrite(PIN_LED_ROUGE, LOW); digitalWrite(PIN_LED_VERTE, HIGH); } } float seuilActifPourGraphique() { if (pompeActive) { return SEUIL_HAUT_MM; } return SEUIL_BAS_MM; } void envoyerDonneesSerie(float niveauMm) { float t = (millis() - tempsDepartMs) / 1000.0; float seuilActifMm = seuilActifPourGraphique(); int commandePct = pompeActive ? 100 : 0; Serial.print(t, 2); Serial.print(";"); Serial.print(seuilActifMm, 2); Serial.print(";"); Serial.print(niveauMm, 2); Serial.print(";"); Serial.println(commandePct); }