Problème de précision de temps

Bonjour,
je voulais programmer mon Arduino pour suivre le schéma suivant :
Il faut que l'arduino envoie un signal pour allumer un gyrophare si la température reçue
(par un capteur de température) est au dessus de 28°C pendant 3h. Il faut cependant ajouter un programme qui met en pause (pendant 5H) le programme précédent quand elle reçoit un signal de 5V."

J'ai donc écrit le programme suivant (quelques valeurs ont été changées pour le tester) :

// Constantes
const int brocheGyrophare = 7;
const int brocheCapteur = 2;
const int seuilTemp = 24;
const int tempsAlarme = 10800; // 3 heures en millisecondes
const int tempsPause = 18000000; // 5 heures en millisecondes
const float T0 = 25 + 273.15;
const float RT0 = 10000;
const float R0 = 10000;
const float B = 3977;
// Variables
float temperature;
bool alarme = false;
unsigned long tempspasse = 0;
unsigned long temps = 0;
unsigned long intervalle = 0;
#define B 3977 // ntc b constant
#define RESISTOR 10000 // résistance de la résistance, 10 kOhm
#define THERMISTOR 10000 // résistance nominale de la thermistor, 10 kOhm
#define NOMINAL 25 // température nominale
 
#define sensor A0
 

void setup() {
  // Initialisation des broches
  pinMode(brocheCapteur, INPUT);
  pinMode(brocheGyrophare, OUTPUT);
  pinMode(sensor, INPUT);
  Serial.begin(9600);

}

void loop() {
  
  if(alarme){Serial.println("alarme=vraie");}
  else{Serial.println("alarme=fausse");}
  
  // Lecture de la température
  int t = analogRead(sensor);
    float tr = 1023.0 / t - 1;
    tr = RESISTOR * tr;
    Serial.print("R=");
    Serial.print(tr);
    Serial.print(", t=");
 
    float temperature;
    temperature = tr / THERMISTOR;
    temperature = log(temperature);
    temperature /= B;
    temperature += 1.0 / (NOMINAL + 273.15);
    temperature = 1.0 / temperature;
    temperature -= 273.15; 
    Serial.println(temperature);

  // Vérification de la température
  if (temperature > seuilTemp) {
    tempspasse=millis()-temps;
    intervalle = intervalle+tempspasse;
    Serial.println(intervalle);
    if (!alarme && (intervalle >= tempsAlarme)) {
      // Alarme déclenchée
      alarme = true;
      intervalle=0;
      digitalWrite(brocheGyrophare, HIGH);

    }
  } else {
    intervalle = 0;
    if (alarme) {
      // Alarme terminée
      alarme = false;
      digitalWrite(brocheGyrophare, LOW);
    }
  }
  // Vérification du signal de pause
  
  if (digitalRead(brocheCapteur) == HIGH) {
    // Signal de pause reçu
    alarme = false;
    digitalWrite(brocheGyrophare, LOW);
    delay(tempsPause);
  }

temps=millis();


}

Mon problème est que le calcul de temps est très imprécis (environ 3 secondes pour 10 secondes). Auriez vous une idée d'où cela peut venir ?

Merci, Léopold

I moved your topic to an appropriate forum category @leopold-53.

In the future, please take some time to pick the forum category that best suits the subject of your topic. There is an "About the _____ category" topic at the top of each category that explains its purpose.

This is an important part of responsible forum usage, as explained in the "How to get the best out of this forum" guide. The guide contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

1 Like

Salut. Un int, c'est au max 32767, un unsigned int 65536.
Mais delay() accepte un unsigned long (4294967295).
Et 3H = 10800000 ms

const unsigned long tempsAlarme = 10800000UL; // 3 heures en millisecondes
const unsigned long tempsPause = 18000000UL; // 5 heures en millisecondes
1 Like

Au passage dans la ligne Serial.begin(9600) passe au minimum de 9600 a 115200.
Un jour ou l’autre tu ralentira ton programme avec cette valeur de 9600 qui date de la préhistoire.

1 Like

Merci de votre réponse.
Mon erreur était dûe au placement de mon temps=millis();
qui devait être placé juste après mon calcul d'intervalle et non à la fin du programme.
Ta solution va m'aider cependant pour des test plus longs car j'aurait sûrement eu des problème pour des calculs d'alarme de 3h (ici je testait avec une alarme de 30secondes)

Merci de votre réponse. J'ai cependant essayé de changé à 115200 et le Serial Monitor me rend des valeurs bizarres :
image
Cela est peut être dû au fait qu'il n'a pas le temps d'imprimer ?

bonjour

faut changer dans le programme ET dans le moniteur
les deux ont été changé ?

1 Like

Merci, ça fonctionne, mon problème était là !

Votre code écrit avec un long delay()

va être bloqué dès que vous envoyez le signal et vous n'aurez aucun moyen de débloquer sauf à rebooter l'arduino.

S'il y a un besoin de ce côté, vous pourriez traiter cela différemment par la programmation par machine à états (cf mon tuto éventuellement)

1 Like

Merci pour votre aide. Le tuto de la programmation par machine à états est très intéressant mais pas très utile dans mon cas qui est plutôt simple.

Oui si c’est OK d’attendre de manière bloquante sans rien faire alors un delay() peut être la solution adéquate.

L'interet d'une machine à état ou d'un algorithme non bloquant, n'est pas lié à la complexité du projet.
l'avantage qui dit porjet simple, dit machine à état simple :slight_smile:

Aprés comme l'indique @J-M-L ton projet se satisfait très bien de partie bloquante et qu'il n'y a aucun chance que tu le fasse evoluer, effectivement une machine à état est inutile.
Dans le cas contraire, il sera bien plus simple et surtout rapide de passer par une machine à état ou un algorithme non bloquant.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.