Projet afficheur.

Bonjour à tous, je me lance actuellement dans la création d'un nouveau projet, un afficheur de donnée arduino, celui afficherait plusieurs données: heure date température et un chrono. Je dispose de tout le matériel et j'ai déjà bien entamé la programmation de l'afficheur. Dans le programme il y a la fonction setup et loop, puis une pour chaque fonctionnalité de l'afficheur: c'est à dire la fonction heure, la fonction chrono et la fonction température. Celle-ci ne doivent comporter aucun delay() pour que l'arduino puisse détecter ou non l'appui sur le bouton destiné au changement de mode.
J'ai déjà terminé la fonction heure qui ne m'a pas posé de problèmes majeurs, la voici :

  void processMenuHeure(){
    DateTime now = RTC.now();
  
  // l'heure sur la premiêre ligne du LCD
  lcd.setCursor(0, 0);
  lcd.print(now.hour());
  lcd.print(":");
  if (now.minute() < 10) {
    lcd.print("0");
  }
  lcd.print(now.minute());
  lcd.print(":");
  if (now.second() < 10) {
    lcd.print("0");
  }
  lcd.print(now.second());
  
  
  // la date sur la deuxième ligne du LCD
  lcd.setCursor(0, 1); 
  lcd.print(now.day()); 
  lcd.print(" "); 
 
  switch (now.month()) {
  case 1:
    lcd.print("janvier");
    break;
  case 2:
    lcd.print("fevrier");
    break;
  case 3:
    lcd.print("mars");
    break;
  case 4:
    lcd.print("avril");
    break;
  case 5:
    lcd.print("mai");
    break;
  case 6:
    lcd.print("juin");
    break;
  case 7:
    lcd.print("juillet");
    break;
  case 8:
    lcd.print("aout");
    break;
  case 9:
    lcd.print("septembre");
    break;
  case 10:
    lcd.print("octobre");
    break;
  case 11:
    lcd.print("novembre");
    break;
  case 12:
    lcd.print("decembre");
    break;
  }
  lcd.print(" "); 
  lcd.print(now.year()); 
  if((millis() - temps) > 1000){
      lcd.clear();
      temps = millis();
  }

  }

cependant les deux autres fonctions me posent quelques problèmes: premièrement je n'arrive pas à coder une fonction chrono fonctionnant sans delay():

void processMenuChrono() {
        int heures,minutes,secondes,disec;
        char message[16] = "";


    lcd.begin(16, 2); 
    lcd.print("Chronometre");
    if((millis() - temps) > 2000 ){
        
    
    lcd.clear();
   
    heures = 0;
    minutes = 0;
    secondes = 0;
    disec = 0;

    if(disec == 10){
      disec = 0;
      secondes++;
        
    }
    if(secondes == 60) 
    {
        secondes = 0; 
        minutes++;
    }
    if(minutes == 60) 
    {
        minutes = 0;
        heures++;
    }
    if(heures == 24) 
    {
        heures = 0;
    }

    
    sprintf(message,"%d,%d,%d,%d",heures,minutes,secondes,disec);


    lcd.home();          

    lcd.write(message);  
    if((millis() - temps) > 100){
                 
    disec++;
    temps = millis();


      }
    }
  }

: celle-ci ne fait pas se lancer le chrono...

De plus la fonction température fait se rafraîchir l'écran lcd bien trop souvent rendant ainsi sa vue désagréable.

  void processMenuTemperature(){
      int tempSensor = analogRead(tempSensor);
      float voltage = (tempSensor/1024.0)*5.0;
      lcd.setCursor(0,0);
      float temperature = (voltage - .5) * 100;
      lcd.print(temperature);
      lcd.print(" degres C");
      if((millis() - temps) > 1000) {
          temps = millis(); // je ne sais pas comment régler une fréquence de rafraîchissement moins élevée. 
      }

Si quelqu'un à déjà rencontré le même problème ou si quelqu'un sait comment faire, je suis preneur :wink:

if((millis() - temps) > 2000...

il faut au préalable mémoriser temps = millis();

Je ne comprends pas : j'ai rajouté temps = milis(); après ma définition de tableau mais mon lcd reste bloqué sur Chronometre:

#include <LiquidCrystal.h>
#include <Wire.h>
#include <RTClib.h>

#define MENU_HEURE 1
#define MENU_CHRONO 2
#define MENU_TEMPERATURE 3

RTC_DS1307 RTC;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int menuActuel = MENU_HEURE;
int Etat1; // bouton pour changer de menu
int Etat2; // bouton pour lancer le chrono 
int Etat3; // bouton pour arrêter le chrono
int Etat4; // bouton pour reset le chrono
int tempSensor = A0;
int i = 0;
long unsigned temps; 


  void processMenuChrono() {
        int heures,minutes,secondes,disec;
        char message[16] = "";
        temps = millis();

    lcd.begin(16, 2); 
    lcd.print("Chronometre");
    if((millis() - temps) > 2000 ){
        
    
    lcd.clear();
   
    heures = 0;
    minutes = 0;
    secondes = 0;
    disec = 0;

    if(disec == 10){
      disec = 0;
      secondes++;
        
    }
    if(secondes == 60) 
    {
        secondes = 0; 
        minutes++;
    }
    if(minutes == 60) 
    {
        minutes = 0;
        heures++;
    }
    if(heures == 24) 
    {
        heures = 0;
    }

    
    sprintf(message,"%d,%d,%d,%d",heures,minutes,secondes,disec);


    lcd.home();          

    lcd.write(message);  
    if((millis() - temps) > 100){
                 
    disec++;
    temps = millis();


      }
    }
  }

 void setup()
{
	 

  Wire.begin();
  RTC.begin();
  lcd.begin(16, 2);
  for(i=13; i<=17; i++){
  	pinMode(i, INPUT);
  }

 }
 void loop()
 {
 	processMenuChrono();
 }

hello
pour ne pas louper un appui sue le BP, il faut passer par une routine d'interruption. celle ci te fait seulement monter un flag . et dans chacune de tes fonctions, tu teste l'état du flag. s'il est armé, tu agit en sortant de ta fonction pour retourner dans la boucle loop, et aller exécuter la fonction suivante

un bout de code pour t'aider dans l'affichage de la temperature
( change l'affectation des pins LCD)

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int temperature=22;
void setup() {
  
lcd.begin(20, 4);                          // initialise le LCD
   Serial.begin(57600);                      //pour afficher sur moniteur
}

void loop() {
 lcd.clear();
processMenuTemperature();
}

void processMenuTemperature()

{   

  lcd.setCursor(0,0);
      lcd.print("affi tempe ");
      int tempSensor = analogRead(tempSensor);
      float voltage = (tempSensor/1024.0)*5.0;
      //lcd.setCursor(0,1);
      //temperature = (voltage - .5) * 100;
      temperature ++;
      lcd.print(temperature);
      lcd.print(" degres C");
      
      delay(2000);
       lcd.setCursor(0,1);
    lcd.print("debut attente");
      unsigned long temps = millis();  
      while ((millis() - temps) < 1000)
      { 
      lcd.setCursor(0,1);
      lcd.print((millis() - temps));
    }
    
    lcd.setCursor(0,1);
    lcd.print("fin attente");
}

Je suis désolé, mais mon faible niveau fait que je n'ai pas du tout compris ce que tu viens de poster :wink: Je pense que le mieux serait de reprendre à 0. En gros j'aimerais faire un afficheur lcd qui m'affiche la température, la date, l'heure et si possible un chrono. Je galère pour faire le menu et remplacer les delay() initiaux par millis().

le lien : sur les interruptions : http://www.arduino.cc/en/Reference/AttachInterrupt
le code : une explication des routines d'interruptions

BP = 2;                               //Bouton poussoir sur pinoche 2 de la platine soit INT_0
 volatile int appui_BP = LOW;          //flag ou témoin d'appui sur le BP
 
void setup()
{
   pinMode(BP, INPUT_PULLUP);          //l'entrée 2 de la platine est "tirée vers le haut par la résistance interne
   attachInterrupt(0, isr_BP,FALLING); //c'est la routine qui sera exécutée sur un appui sur le BP
}

void loop()
{
   processMenuTemperature();
   processMenuautre fonction();
   processMenuautre fonction();
   //etc...
}
  void processMenuTemperature()
  {
    while (appui_BP = HIGH)                      //on boucle sur cette fonction "temperature" en attendant un appui sur le BP
    {
      int tempSensor = analogRead(tempSensor);
      float voltage = (tempSensor/1024.0)*5.0;
      lcd.setCursor(0,0);
      float temperature = (voltage - .5) * 100;
      lcd.print(temperature);
      lcd.print(" degres C");
      
      if((millis() - temps) > 1000) {
      temps = millis(); // je ne sais pas comment régler une fréquence de rafraîchissement moins élevée. 
      }
      appui_BP = HIGH; // irs ayant passé le flag à low, on sort de la boucle while et repositionne le flag pour un nouvel appui sur le BP
    }


void isr_BP()
{
   appui_BP = LOW;
}

ok je pense avoir compris :wink: cependant lorsque je procède aux ajustements nécessaires au programme il me sort :

sketch_jun19a.ino: In function 'void processMenuTemperature()':
sketch_jun19a:40: error: a function-definition is not allowed here before '{' token
sketch_jun19a:42: error: expected `}' at end of input

le code que j'utilise :

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int BP = 13;     
//Bouton poussoir sur pinoche 2 de la platine soit INT_0
volatile int appui_BP = LOW;          //flag ou témoin d'appui sur le BP
 unsigned long temps;
void setup()
{
   pinMode(BP, INPUT_PULLUP);          //l'entrée 2 de la platine est "tirée vers le haut par la résistance interne
   attachInterrupt(0, isr_BP,FALLING); //c'est la routine qui sera exécutée sur un appui sur le BP
}

void loop()
{
   processMenuTemperature();

   //etc...
}
  void processMenuTemperature()
  {
    while (appui_BP = HIGH)                      //on boucle sur cette fonction "temperature" en attendant un appui sur le BP
    {
      int tempSensor = analogRead(tempSensor);
      float voltage = (tempSensor/1024.0)*5.0;
      lcd.setCursor(0,0);
      float temperature = (voltage - .5) * 100;
      lcd.print(temperature);
      lcd.print(" degres C");
      
      if((millis() - temps) > 1000) {
      temps = millis(); // je ne sais pas comment régler une fréquence de rafraîchissement moins élevée. 
      }
      appui_BP = HIGH; // irs ayant passé le flag à low, on sort de la boucle while et repositionne le flag pour un nouvel appui sur le BP
    }


void isr_BP()

  {
   appui_BP = LOW;
  }

Après avoir trouvé mon erreur j'ai cru un court instant que cela marchait, or dès que je lance le programme, une multitude de valeurs défilent pour enfin se bloquer aux alentours de 150 °C. :slight_smile:

teste ce code
nota BP doit absolument être sur la pinoche 2

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


//int temperature=22;
int BP = 2;     
//Bouton poussoir sur pinoche 2 de la platine soit INT_0
volatile int appui_BP = LOW;          //flag ou témoin d'appui sur le BP
 unsigned long temps;
void setup()
{lcd.begin(20, 4);                          // initialise le LCD
   Serial.begin(57600);                      //pour afficher sur moniteur
   pinMode(BP, INPUT_PULLUP);          //l'entrée 2 de la platine est "tirée vers le haut par la résistance interne
   attachInterrupt(0, isr_BP,FALLING); //c'est la routine qui sera exécutée sur un appui sur le BP
}

void loop()
{
   processMenuTemperature();

   //etc...
}
  void processMenuTemperature()
  {
    while (appui_BP = HIGH)                      //on boucle sur cette fonction "temperature" en attendant un appui sur le BP
    {
      int tempSensor = analogRead(tempSensor);
      float voltage = (tempSensor/1024.0)*5.0;
      lcd.setCursor(0,0);
      float temperature = (voltage - .5) * 100;
      lcd.print(temperature);
      lcd.print(" degres C");
      
      temps = millis();  
      while ((millis() - temps) < 1000)
      {;} 
      }
      appui_BP = HIGH; // irs ayant passé le flag à low, on sort de la boucle while et repositionne le flag pour un nouvel appui sur le BP
    }

void isr_BP()

  {
   appui_BP = LOW;
  }

J'ai un peu de mal à comprendre le branchement de ton lcd: plutôt (9,8,7,6,5,4) ?

non, c'est le cablage chez moi, toi tu dois mette // devant ma ligne et enlever // devant ta ligne

Okay merci :slight_smile: juste par curiosité pourquoi le bp doit absolument être sur le pin 2.

la pin 2 correspond à INT0
l'appui sur le BP déclenche une interruption
cette interruption exécute la routine "isr BP"
les interruptions sont prioritaires sur tout le reste du code.
en les utilisant, tu ne peux pas rater un appui sur le BP

regarde ce code en ouvrant le moniteur à 57600 bauds
en jouant avec le BP tu verras ce qui se passe.
attention tes fonctions ne fonctionnent pas, mais ce n'est pas l'important.
il vaut mieux que tu comprennes le déroulement du code
ensuite, tu pourras lui faire faire ce que tu veux

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


//int temperature=22;
int BP = 2;     
//Bouton poussoir sur pinoche 2 de la platine soit INT_0
boolean  appui_BP = false;          //flag ou témoin d'appui sur le BP
 unsigned long temps;
void setup()
{lcd.begin(20, 4);                          // initialise le LCD
   Serial.begin(57600);                      //pour afficher sur moniteur
   pinMode(BP, INPUT_PULLUP);          //l'entrée 2 de la platine est "tirée vers le haut par la résistance interne
   attachInterrupt(0, isr_BP,FALLING); //c'est la routine qui sera exécutée sur un appui sur le BP
 //Serial.print("  BP dans set up = ");Serial.println(appui_BP);
 }


  void processMenuTemperature()
  {
    Serial.println("   processMenuTemperature");
 // Serial.print("  BP avant while = ");Serial.println(appui_BP);
                                     // utilisation d'une boucle "DO WHILE"
                                     // on boucle sur cette fonction "temperature" en attendant un appui sur le BP
     do                              // FAIRE
    {
      //Serial.print("  BP sous while = ");Serial.println(appui_BP);
      int tempSensor = analogRead(tempSensor);
      float voltage = (tempSensor/1024.0)*5.0;
      lcd.setCursor(0,0);
      float temperature = (voltage - .5) * 100;
      lcd.print(temperature);
      lcd.print(" degres C");
      Serial.print("   temps = ");Serial.println( temps);
      temps = millis();  
      while ((millis() - temps) < 1000)
       { ; } 
   }while (appui_BP == false);       //TANT QUE appui BP est "false" (pas d'appui sur le BP)
                                     //il y a eu un appui sur le bP, on sort de la boucle
      appui_BP = false; // irs ayant passé le flag à true, on sort de la boucle DO WHILE et repositionne le flag pour un nouvel appui sur le BP
 }

void isr_BP()
  {
 static  unsigned long memo_temps = 0;      //20ms pour laisser passer les rebonds du BP
 unsigned long temps_actuel = millis();
 if (temps_actuel - memo_temps > 200) 
 {
   appui_BP = true;                        //on arme le flag d'appui sur le BP
   memo_temps = temps_actuel;
 }
 }
  /*
  void processMenuHeure()
  {Serial.print("   processMenuHeure");
    
    DateTime now = RTC.now();
  
  // l'heure sur la premiêre ligne du LCD
  lcd.setCursor(0, 0);
  lcd.print(now.hour());
  lcd.print(":");
  if (now.minute() < 10) {
    lcd.print("0");
  }
  lcd.print(now.minute());
  lcd.print(":");
  if (now.second() < 10) {
    lcd.print("0");
  }
  lcd.print(now.second());
  
  
  // la date sur la deuxième ligne du LCD
  lcd.setCursor(0, 1); 
  lcd.print(now.day()); 
  lcd.print(" "); 
 
  switch (now.month()) {
  case 1:
    lcd.print("janvier");
    break;
  case 2:
    lcd.print("fevrier");
    break;
  case 3:
    lcd.print("mars");
    break;
  case 4:
    lcd.print("avril");
    break;
  case 5:
    lcd.print("mai");
    break;
  case 6:
    lcd.print("juin");
    break;
  case 7:
    lcd.print("juillet");
    break;
  case 8:
    lcd.print("aout");
    break;
  case 9:
    lcd.print("septembre");
    break;
  case 10:
    lcd.print("octobre");
    break;
  case 11:
    lcd.print("novembre");
    break;
  case 12:
    lcd.print("decembre");
    break;
  }
  lcd.print(" "); 
  lcd.print(now.year()); 
  if((millis() - temps) > 1000){
      lcd.clear();
      temps = millis();
  }

  }
*/
void processMenuChrono() 
{       Serial.print("   processMenuChrono ");
        int heures=0,minutes=0,secondes=0,disec=0;
        char message[16] = "";
temps=millis();
while (appui_BP == false)                       //on boucle sur cette fonction "chrono" en attendant un appui sur le BP
  {
    lcd.begin(16, 2); 
    lcd.print("Chronometre");
    Serial.println("Chronometre ");
    if((millis() - temps) > 500 )
    {  lcd.clear();heures = 0;minutes = 0;secondes = 0;disec = 0;
        if(disec == 10){disec = 0;secondes++;}
        if(secondes == 60) {secondes = 0; minutes++;}
        if(minutes == 60) {minutes = 0;heures++;}
        if(heures == 24) {heures = 0;
    }
    sprintf(message,"%d,%d,%d,%d",heures,minutes,secondes,disec);
    //lcd.home();          
    lcd.write(message);
  lcd.setCursor(0,1);  
  lcd.print(heures);lcd.print(" ");lcd.print(minutes);lcd.print(" ");lcd.print(secondes);lcd.print(" ");lcd.print(disec);lcd.print(" ");
  Serial.print(heures);Serial.print(" ");Serial.print(minutes);Serial.print(" ");Serial.print(secondes);Serial.print(" ");Serial.println(disec);
    if((millis() - temps) > 100)
    {   disec++;temps = millis();
    }
 }
  temps = millis();  
  //while ((millis() - temps) < 1000)
  //{} 
}
      appui_BP = false; // // irs ayant passé le flag à low, on sort de la boucle while et repositionne le flag pour un nouvel appui sur le BP
}


void loop()
{Serial.print(" Loop = ");Serial.println("1");
   processMenuTemperature();
   Serial.print(" Loop = ");Serial.println("2");
   processMenuChrono();
   Serial.print(" Loop = ");Serial.println("3");
   //etc...
}