Probleme de timer mais pas sur tous les sketchs?

Salut a tous,

Je suis en train de faire un programme et j’ai un soucis de timer. J’utilise la librairie “simpleMinuteur” de “bricoleau” (Merci à lui d’ailleurs)

Dans mon programme, lorsque le ventilo tourne, je fais une petite anim sur le 1602 LCD (une succession de |,/,-,\ pour faire comme une hélice qui tourne)

sauf que mon code ne fonctionne pas dans mon programme … Le premier timer fonctionne mais pas le deuxième.

  // Partie ventilation
  if (tempoVentilo.estTermine())  {
    if (!digitalRead(ventilation)) {
      digitalWrite(ventilation, HIGH);
    }
    else {
      digitalWrite(ventilation, LOW);
    }
    tempoVentilo.redemarrer();
  }

  if (digitalRead(ventilation)) {
    if (tempoAnim.estTermine())  {
      animVentilo();
      tempoAnim.redemarrer();
    }

Donc la “tempoVentilo” fonctionne, mais pas la “tempoAnim”?
si, pour tester je mets un “delay” dans la boucle ça fonctionne, le soucis vient vraiment du timer.

j’ai essayer de vider au max mon programme pour tester, et la il fonctionne!

voici la version simplifié (juste sans la sonde et les sorties relais)

#include <LiquidCrystal.h>
#include <Wire.h>
#include <SPI.h>
#include <simpleMinuteur.h>

simpleMinuteur tempoCompresseurOff(300000);  //timer temps mini compresseur
simpleMinuteur tempoVentilo(5000);  //timer ventilation ext
simpleMinuteur tempoAnim(300);  //timer animation ventilo

const int ventilation =  13;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

enum {Verticale, ObliqueD, Horizontal, ObliqueG}
etatCaractAnim = Verticale;

void setup()
{
  pinMode(ventilation, OUTPUT);
  digitalWrite(ventilation, LOW);
  lcd.begin(16, 2);
  lcd.clear();
  tempoVentilo.demarrer();
  tempoAnim.demarrer();
}

void loop()
{

  // Partie ventilation
  if (tempoVentilo.estTermine())  {
    if (!digitalRead(ventilation)) {
      digitalWrite(ventilation, HIGH);
    }
    else {
      digitalWrite(ventilation, LOW);
    }
    tempoVentilo.redemarrer();
  }

  if (digitalRead(ventilation)) {
    if (tempoAnim.estTermine())  {
      animVentilo();
      tempoAnim.redemarrer();
    }
  }
}

void animVentilo() {
  switch (etatCaractAnim) {
    case Verticale:
      lcd.setCursor(9, 1);
      lcd.print("|");
      etatCaractAnim = ObliqueD;
      break;
    case ObliqueD:
      lcd.setCursor(9, 1);
      lcd.print("/");
      etatCaractAnim = Horizontal;
      break;
    case Horizontal:
      lcd.setCursor(9, 1);
      lcd.print("-");
      etatCaractAnim = ObliqueG;
      break;
    case ObliqueG:
      lcd.setCursor(9, 1);
      lcd.print("M");
      etatCaractAnim = Verticale;
      break;
  }
}

auriez-vous une piste pour chercher ? a t on une limitation du nombre de timers possible ? ou le fait que quasiment toutes les IO de ma Nano soient utilisées ?

Merci de votre aide

Nico

pas d'idee? :frowning: :frowning:

Salut,

avec le programme complet , apres verification du programme et pas televersement , dans le bas de l' IDE , il affiche quoi ?

puis ca :

if (digitalRead(ventilation)) {
    if (tempoAnim.estTermine())  {
      animVentilo();
      tempoAnim.redemarrer();
    }

pourquoi ne pas faire une boucle while a la place , ca serait plus aproprié non ?

voila la sortie du programme complet

Le croquis utilise 12618 octets (39%) de l'espace de stockage de programmes. Le maximum est de 32256 octets.
Les variables globales utilisent 664 octets (32%) de mémoire dynamique, ce qui laisse 1384 octets pour les variables locales. Le maximum est de 2048 octets.

donc pas de pb…

peux tu me donner un exemple de la boucle while?

voila programme quasi complet (j’ai pas encore gerer le temps mini du compresseur)

#include <LiquidCrystal.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <simpleMinuteur.h>


//Valeurs par defaut
byte temp_sechage = 13;
byte hum_sechage = 70;
byte temp_etuve = 24;
byte hum_etuve = 85;
float tdelta = 2;  // demi delta de temperature
float hdelta = 2;  // demi delta d'humidité
simpleMinuteur tempoCompresseurOff(300000);  //timer temps mini compresseur 5 min (5x60x1000 millisecondes)
simpleMinuteur tempoVentilo(5000);  //timer ventilation ext
simpleMinuteur tempoAnim(500);  //timer animation ventilo

byte temp_consigne = temp_sechage;
byte hum_consigne = hum_sechage;
String Mode_courant = "Sechage";
String MessageErreur;
bool RelaisCompresseur = false;
bool RelaisHumidificateur = false;
bool RelaisDeshumidificateur = false;
bool RelaisChauffe = false;

const int inter =  2; // (Ex 14)
const int ventilation =  13;
const int humidificateur =  14; //(ex 2)
const int Refroidisseur =  15;
const int deshumidificateur =  16;
const int chauffe =  17;
const int buzzer = 10;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
float hmesure;
float tmesure;


char CaraSpeLcd;            // nom de caractère spécial "\"
byte binCaraSpeLcd[] = {
  B00000,
  B10000,
  B01000,
  B00100,
  B00010,
  B00001,
  B00000,
  B00000
};
enum {Verticale, ObliqueD, Horizontal, ObliqueG}
etatCaractAnim = Verticale;


int EtatInter = 0;    //variable etat entrée inter
unsigned status;
Adafruit_BME280 bme; // I2C

void setup()
{
  pinMode(humidificateur, OUTPUT);
  pinMode(Refroidisseur, OUTPUT);
  pinMode(deshumidificateur, OUTPUT);
  pinMode(chauffe, OUTPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(ventilation, OUTPUT);
  pinMode(inter, INPUT_PULLUP);
  digitalWrite(humidificateur, HIGH);
  digitalWrite(Refroidisseur, HIGH);
  digitalWrite(deshumidificateur, HIGH);
  digitalWrite(chauffe, HIGH);
  digitalWrite(ventilation, LOW);

  lcd.createChar(CaraSpeLcd, binCaraSpeLcd);
  lcd.home();

  demarrage();
  while (!Serial);   // Attente du serial
  lcd.clear();

  tempoVentilo.demarrer();
  tempoAnim.demarrer();

  //  unsigned status;
  status = bme.begin(0x76);
  if (!status) {
    erreur();
  }
}

void loop()
{
  hmesure = bme.readHumidity();
  tmesure = bme.readTemperature();
  EtatInter = digitalRead(inter);


  if (EtatInter == HIGH && Mode_courant == "Etuve") {
    Mode_courant = "Sechage";
    temp_consigne = temp_sechage;
    hum_consigne = hum_sechage;
  }
  else if (EtatInter == LOW && Mode_courant == "Sechage") {
    Mode_courant = "Etuve";
    temp_consigne = temp_etuve;
    hum_consigne = hum_etuve;
  }
  afficheur();

  if (hmesure > (hum_consigne + hdelta) && Mode_courant == "Sechage" && !RelaisDeshumidificateur) {
    RelaisDeshumidificateurOn();
  }
  else if (hmesure <= (hum_consigne - hdelta) && Mode_courant == "Sechage" && RelaisDeshumidificateur) {
    RelaisDeshumidificateurOff();
  }
  else if (hmesure > (hum_consigne + hdelta) && Mode_courant == "Etuve" && RelaisHumidificateur) {
    RelaisHumidificateurOff();
  }
  else if (hmesure <= (hum_consigne - hdelta) && Mode_courant == "Etuve" && !RelaisHumidificateur) {
    RelaisHumidificateurOn();
  }

  if (tmesure > (temp_consigne + tdelta) && !RelaisCompresseur) {
    RelaisCompresseurOn();
  }
  else if (tmesure < (temp_consigne - tdelta) && RelaisCompresseur) {
    RelaisCompresseurOff();
  }


  // Partie ventilation
  if (tempoVentilo.estTermine())  {
    if (!digitalRead(ventilation)) {
      digitalWrite(ventilation, HIGH);
    }
    else {
      digitalWrite(ventilation, LOW);
    }
    tempoVentilo.redemarrer();
  }

  if (digitalRead(ventilation)) {
    if (tempoAnim.estTermine())  {
      animVentilo();
      tempoAnim.redemarrer();  // fonctionne en externe mais pas la, a voir
    }
  }
}

void animVentilo() {
  switch (etatCaractAnim) {
    case Verticale:
      lcd.setCursor(9, 1);
      lcd.print("|");
      etatCaractAnim = ObliqueD;
      break;
    case ObliqueD:
      lcd.setCursor(9, 1);
      lcd.print("/");
      etatCaractAnim = Horizontal;
      break;
    case Horizontal:
      lcd.setCursor(9, 1);
      lcd.print("-");
      etatCaractAnim = ObliqueG;
      break;
    case ObliqueG:
      lcd.setCursor(9, 1);
      lcd.write(CaraSpeLcd);
      etatCaractAnim = Verticale;
      break;
  }
}

void afficheur() {

  lcd.setCursor(0, 0);
  lcd.print(Mode_courant);
  lcd.print("  ");
  lcd.setCursor(9, 0);
  lcd.print(temp_consigne);
  lcd.print((char)223);
  lcd.print("/");
  lcd.print(hum_consigne);
  lcd.print("%");

  lcd.setCursor(0, 1);
  lcd.print("T:");
  lcd.print(tmesure, 1);
  lcd.print((char)223);
  lcd.print("C   ");
  lcd.print("H:");
  lcd.print(hmesure, 0);
  lcd.print("%");

}
void demarrage() {
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("XXXXXXX");
  lcd.setCursor(0, 1);
  lcd.print("Demarrage");
}
void erreur() {
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Systeme en panne");
  lcd.setCursor(0, 1);
  lcd.print(MessageErreur);
  tone(buzzer, 800);
  while (1);
}
void RelaisCompresseurOn() {
  digitalWrite(Refroidisseur, LOW);
  RelaisCompresseur == true;
}
void RelaisCompresseurOff() {
  digitalWrite(Refroidisseur, HIGH);
  RelaisCompresseur == false;
}
void RelaisHumidificateurOn() {
  digitalWrite(humidificateur, LOW);
  RelaisHumidificateur = true;
}
void RelaisHumidificateurOff() {
  digitalWrite(humidificateur, HIGH);
  RelaisHumidificateur = false;
}
void RelaisDeshumidificateurOn() {
  digitalWrite(deshumidificateur, LOW);
  RelaisDeshumidificateur = true;
}
void RelaisDeshumidificateurOff() {
  digitalWrite(deshumidificateur, HIGH);
  RelaisDeshumidificateur = false;
}
void RelaisChauffeOn() {
  digitalWrite(chauffe, LOW);
  RelaisChauffe = true;
}
void RelaisChauffeOff() {
  digitalWrite(chauffe, HIGH);
  RelaisChauffe = false;
}

n1c0l45:
peux tu me donner un exemple de la boucle while?

si tu veux que l ' animation se produise en permanence pendant que le ventilo tourne , avec une boucle while ce code devrait faire l' affaire :

if (digitalRead(ventilation)) {
   while (1)  {
      animVentilo();
    }
}

while 1 fait une boucle qui ne s' arrete jamais .
ici elle s ' execute tout le temps a condition que ventilation soit vrai.

Bonsoir

En regardant rapidement rien ne saute aux yeux pour expliquer l'ano.
Je regarderai plus en détail demain.

Dans le doute, quand un truc cloche dans un programme, mettre des Serial.print pour comprendre ce qui se passe dans la bestiole.

En passant :

 if (tempoAnim.estTermine())  {
    animVentilo();
    tempoAnim.redemarrer();
  }

peut être simplifié en

 if (tempoAnim)  {
    animVentilo();
  }

a+

ah oui je vois un truc :

  // Partie ventilation
  if (tempoVentilo.estTermine())  {
    if (!digitalRead(ventilation)) {
      digitalWrite(ventilation, HIGH);
    }
    else {
      digitalWrite(ventilation, LOW);
    }
    tempoVentilo.redemarrer();
  }

  if (digitalRead(ventilation)) {
    if (tempoAnim.estTermine())  {
      animVentilo();
      tempoAnim.redemarrer();
    }

Il faut bien appréhender la différence entre les méthodes .demarrer() et .redemarrer()

.demarrer() lance le minuteur à partir de l’instant présent
.redemarrer() lance le minuteur à partir de l’instant où il s’était arrêté, potentiellement dans le passé.

tempoAnim ne fonctionne que par intermittence, donc il faut :

  • soit utiliser .demarrer()
  // Partie ventilation
  if (tempoVentilo.estTermine())  {
    if (!digitalRead(ventilation)) {
      digitalWrite(ventilation, HIGH);
    }
    else {
      digitalWrite(ventilation, LOW);
    }
    tempoVentilo.redemarrer();
  }

  if (digitalRead(ventilation)) {
    if (tempoAnim.estTermine())  {
      animVentilo();
      tempoAnim.demarrer(); //et non redemarrer()
    }
  }
  • soit le faire tourner en permanence
  // Partie ventilation
  if (tempoVentilo.estTermine())  {
    if (!digitalRead(ventilation)) {
      digitalWrite(ventilation, HIGH);
    }
    else {
      digitalWrite(ventilation, LOW);
    }
    tempoVentilo.redemarrer();
  }

  if (tempoAnim.estTermine()) { //inversion des if pour faire tourner le minuteur en permanence
    if (digitalRead(ventilation))  {
      animVentilo();
    }
    tempoAnim.redemarrer();
  }

Et en version simplifiée

  if (tempoVentilo)  {
    if (!digitalRead(ventilation)) {
      digitalWrite(ventilation, HIGH);
    }
    else {
      digitalWrite(ventilation, LOW);
    }
  }

  if (tempoAnim && digitalRead(ventilation)) {
    animVentilo();
  }

Si le pb persiste, il n’est probablement pas dans les minuteurs :slight_smile:

Merci pour votre aide!!

je viens de tester, mais cela ne fonctionne pas. Je pense que le soucis vient de l'animation en elle meme (un switch case)

void animVentilo() {
  switch (etatCaractAnim) {
    case Verticale:
      lcd.setCursor(9, 1);
      lcd.print("|");
      etatCaractAnim = ObliqueD;
      break;
    case ObliqueD:
      lcd.setCursor(9, 1);
      lcd.print("/");
      etatCaractAnim = Horizontal;
      break;
    case Horizontal:
      lcd.setCursor(9, 1);
      lcd.print("-");
      etatCaractAnim = ObliqueG;
      break;
    case ObliqueG:
      lcd.setCursor(9, 1);
      lcd.write(CaraSpeLcd);
      etatCaractAnim = Verticale;
      break;
  }
}

je pense que le switch est trop rapide et que donc du coup on voit pas le caractère...
comment ralentir cela sans utiliser de delay? faut encore rajouter un timer?
Merci

Ajoute un Serial.println(etatCaractAnim); dans ta fonction animVentilo()