Problème d'affichage de l'horloge dans l'écran lcd sparkfun sur Arduino

Bonjour, j'ai fais un programme pour une ARDUINO MEGA, qui regroupe 3 choses:

  • L'horloge
  • Les résultats des valeurs de la température et de l'humidité
  • Les résultats des valeurs de la luminosité

Mon problème est que l'heure de l'horloge s’arrête lorsque l'écran se clean pour afficher les 3 valeurs.
C'est-à-dire que le temps ne continu pas lorsque l'écran se clean pour afficher les valeurs

Pouvez vous m'aidez?

Programme:

#include <ColorLCDShield.h>//librairie du lcd
#include "DHT.h"//librairie du capteur
int DHTPIN = A0;//DHT11 connecté à la broche A0
float h;
float t;
#define DHTTYPE DHT11//définie le type de capteur de température et d'humidité 
DHT dht(DHTPIN, DHTTYPE);
#define HOURS 10
#define MINUTES 21
#define SECONDS 00
#define AMPM 0  // enter 0 for AM, 1 for PM
int hours, minutes, seconds, ampm;
#define CLOCK_RADIUS 45  // radius of clock face
#define CLOCK_CENTER 50  // If you adjust the radius, you'll probably want to adjust this
#define H_LENGTH  25  // length of hour hand
#define M_LENGTH  35  // length of minute hand
#define S_LENGTH  43  // length of second hand
LCDShield lcd;
int LDR = A1;//la LDR est connecté à la broche A1     
int luminosite;
char affichageluminosite [16];
char affichagetemperature[16];
char affichagehumidite[16];
char mystring[] = "Luminosite:";
char Text1[] = "temperature:";
char Text2[] = "humidite:";
char Unit[] = "Lux";
char Unit1[] = "*C";
char Unit2[] = "%";

void setup()//initialisation du programme 
{
  Serial.begin(9600);
  lcd.init(PHILIPS);  
  lcd.contrast(-70);//définie le contraste de l'écran lcd
  pinMode(LDR, INPUT);//définie la broche de la LDR en entrée
  afficheText();
  dht.begin();
  hours = HOURS;
  minutes = MINUTES;
  seconds = SECONDS;
  ampm = AMPM;
  drawClock();  // Draw the clock face, this includes 12, 3, 6, 9
  displayAnalogTime(hours, minutes, seconds);  // Draw the clock hands
  displayDigitalTime(hours, minutes, seconds, ampm);  // 
}
 
void loop()//boucle principale du programme  
{
  seconds++;//les secondes augmentent de 1
  if (seconds >= 60)//si les secondes sont supérieurs ou égales à 60 alors...
    {
    seconds = 0;  //les secondes retournent à 0
    minutes++;    // les minutes augmentent de 1
    if (minutes >= 60)//si les minutes sont supérieurs ou égales à 60
    {
      minutes = 0;  // les minutes retournent à 0
      hours++;      // les heures augmentent de 1
      if (hours == 12)//si c'est 12h
        ampm ^= 1;//au lieu d'afficher am, ça affiche pm
      if (hours >= 13)//si les heures sont supérieurs ou égales à 13
        hours = 1; //les heures retournent à 1
    }
  }
  delay(2500);
  lcd.clear(WHITE);
  drawClock();
  displayAnalogTime(hours, minutes, seconds);
  displayDigitalTime(hours, minutes, seconds, ampm);
  h = dht.readHumidity();//lire les données(humidité) du capteur reçue 
  t = dht.readTemperature();//lire les données(température) du capteur reçue
  luminosite = analogRead(LDR);//lire les données de la LDR reçue
  Serial.print("Analog reading = ");
  Serial.print(luminosite);//afficher les informations de la LDR
  Serial.println("temp: ");//afficher le texte 
  Serial.println(t);//afficher les informations du capteur de température
  Serial.println("hum: ");//afficher le texte 
  Serial.println(h);//afficher les informations du capteur d'humidité
  delay(2500);
  lcd.clear(WHITE);
  afficheText();
  
  
  
}
void displayDigitalTime(int h, int m, int s, int ap)//affichage de l'heure
{
  
  char timeChar[12];
  
  if (!ap)
  {
    sprintf(timeChar, "%.2d:%.2d:%.2d AM", h, m, s);
  }
  else
  {
    sprintf(timeChar, "%.2d:%.2d:%.2d PM", h, m, s);
  }
  /* Print the time on the clock */
  lcd.setStr(timeChar, CLOCK_CENTER + CLOCK_RADIUS + 4, 22, 
              BLUE, WHITE);
}

/*
  drawClock() simply draws the outer circle of the clock, and '12',
  '3', '6', and '9'. Room for growth here, if you want to customize
  your clock. Maybe add dashe marks, or even all 12 digits.
*/
void drawClock()//affichage caractere de l'horloge
{
  /* Draw the circle */
  lcd.setCircle(CLOCK_CENTER, 66, CLOCK_RADIUS, BLACK);
  
  /* Print 12, 3, 6, 9, a lot of arbitrary values are used here
     for the coordinates. Just used trial and error to get them 
     into a nice position. */
  lcd.setStr("12", CLOCK_CENTER - CLOCK_RADIUS, 66-9, BLACK, WHITE);
  lcd.setStr("3", CLOCK_CENTER - 9, 66 + CLOCK_RADIUS - 12, BLACK, WHITE);
  lcd.setStr("6", CLOCK_CENTER + CLOCK_RADIUS - 18, 66-4, BLACK, WHITE);
  lcd.setStr("9", CLOCK_CENTER - 9, 66 - CLOCK_RADIUS + 4, BLACK, WHITE);
  //afficher des caractères sur le lcd(variable, position y , position x,couleur caractere,couleur ensemble caractere)
}


void displayAnalogTime(int h, int m, int s)//affichage de l'horloge
{
  double midHours;  // this will be used to slightly adjust the hour hand
  static int hx, hy, mx, my, sx, sy;
  
  /* Adjust time to shift display 90 degrees ccw
     this will turn the clock the same direction as text */
  h -= 3;
  m -= 15;
  s -= 15;
  if (h <= 0)
    h += 12;
  if (m < 0)
    m += 60;
  if (s < 0)
    s += 60;
    
  /* Delete old lines: */
  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, WHITE);  // delete second hand
  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, WHITE);  // delete minute hand
  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, WHITE);  // delete hour hand
  
  /* Calculate and draw new lines: */
  s = map(s, 0, 60, 0, 360);  // map the 0-60, to "360 degrees"
  sx = S_LENGTH * sin(3.14 * ((double) s)/180);  // woo trig!
  sy = S_LENGTH * cos(3.14 * ((double) s)/180);  // woo trig!
  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, BLACK);  // print second hand
  
  m = map(m, 0, 60, 0, 360);  // map the 0-60, to "360 degrees"
  mx = M_LENGTH * sin(3.14 * ((double) m)/180);  // woo trig!
  my = M_LENGTH * cos(3.14 * ((double) m)/180);  // woo trig!
  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, BLACK);// print minute hand
  
  midHours = minutes/12;  // midHours is used to set the hours hand to middling levels between whole hours
  h *= 5;  // Get hours and midhours to the same scale
  h += midHours;  // add hours and midhours
  h = map(h, 0, 60, 0, 360);// map the 0-60, to "360 degrees"
  hx = H_LENGTH * sin(3.14 * ((double) h)/180);// woo trig!
  hy = H_LENGTH * cos(3.14 * ((double) h)/180);// woo trig!
  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, BLUE);// print hour hand
  
}

void afficheText()
{
  
  sprintf (affichageluminosite, "%d", ((int)luminosite));
  sprintf (affichagetemperature, "%d", ((int)t));
  sprintf (affichagehumidite, "%d", ((int)h));    
  
  lcd.setStr(mystring, 0, 10, BLACK, WHITE);
  lcd.setStr(affichageluminosite, 20, 50, BLACK,WHITE);
  lcd.setStr(Unit, 20, 75, BLACK, WHITE);
  lcd.setStr(Text1, 40, 10, BLACK, WHITE);
  lcd.setStr(affichagetemperature, 60, 50, BLACK, WHITE);
  lcd.setStr(Unit1, 60, 70, BLACK, WHITE);
  lcd.setStr(Text2, 80, 10, BLACK, WHITE);
  lcd.setStr(affichagehumidite, 100, 50, BLACK, WHITE);
  lcd.setStr(Unit2, 100, 70, BLACK, WHITE);
  //afficher des caractères sur le lcd(variable, position y , position x,couleur caractere,couleur ensemble caractere) 
}

Bonjour,

Enlève les delay() et utilise une méthode non bloquante, comme dans l'exemple Blink Without Delay.

Huuum est-ce que tu en auras une méthode plus précise, car avec BlinkWhitoutDelay c'est avec une Led, et ça me trouble

Bonjour,

Il faut que tu incrémente tes secondes en testant la fonction millis()

 static unsigned long lastTime=millis();
 if (millis()-lastTime>=1000)
 {
   seconds++;//les secondes augmentent de 1
   lastTime+=1000;
 }

Et bien sur comme l'a dit guix tu supprimes les delay()

Rebonjour, j'ai essayer avec les millis est le résultat est le même, c'est un peu mieux mais le temps est toujours en retard comparé a une vrai horloge

Tu es sur que tu as bien supprimer les deux delays()?

Oui c'est sur

Alors c'est que la fonction loop() dure plus d'une seconde.
Il y a plusieurs méthode pour pallier ça:

  • fractionner la loop() et en faire une partie la seconde courante et une partie la seconde suivante
  • ou incrémenter second de plus de 1s si nécessaire

La deuxième méthode me parait la plus simple

Ça donnerai:

void loop()//boucle principale du programme  
{
 static unsigned long lastTime=millis();
 while (millis()-lastTime>=1000)
 {
   seconds++;//les secondes augmentent de 1
   lastTime+=1000;
 }
 if (seconds >= 60)//si les secondes sont supérieurs ou égales à 60 alors...
   {
   seconds-=60;  // ote 1 mn des secondes
   minutes++;    // les minutes augmentent de 1
...

Même avec cette partie, le programme ne veux pas faire passer les secondes, lorsque l'on y clean

Tony748:
Même avec cette partie, le programme ne veux pas faire passer les secondes, lorsque l'on y clean

Qu'est ce que tu entends par là?

Dans displayDigitalTime() le buffer est trop petit pour le format que tu donnes, qui d'ailleurs ne semble pas correct

void displayDigitalTime(int h, int m, int s, int ap)//affichage de l'heure
{
 
 char timeChar[16];
 
 if (!ap)
 {
   sprintf(timeChar, "%2d:%2d:%2d AM", h, m, s);
 }
 else
 {
   sprintf(timeChar, "%2d:%2d:%2d PM", h, m, s);
 }
 /* Print the time on the clock */
 lcd.setStr(timeChar, CLOCK_CENTER + CLOCK_RADIUS + 4, 22, 
             BLUE, WHITE);
}

Ba le problème reste le même qu'au départ, les secondes de l'horloge ne continu pas d'avancer, lorsque l'écran se clean et affiche les valeurs

Est ce que ton programme continue à tourner? Est ce que tu as des affichages sur le moniteur série?

J'ai essayer votre programme, et ça ne marche pas du tout. La petite partie de votre programme nous ajoute un problème, qui est la suppression d'un 0 à l'horloge, et le problème du départ reste le même.

Pour ton problème de zéro, il suffit de modifier un peu le format

void displayDigitalTime(int h, int m, int s, int ap)//affichage de l'heure
{
char timeChar[16];

if (!ap)
{
  sprintf(timeChar, "%02d:%02d:%02d AM", h, m, s);
}
else
{
  sprintf(timeChar, "%02d:%02d:%02d PM", h, m, s);
}
/* Print the time on the clock */
lcd.setStr(timeChar, CLOCK_CENTER + CLOCK_RADIUS + 4, 22, 
            BLUE, WHITE);
}

Tu n'as pas répondu à ma question:

Est ce que ton programme continue à tourner? Est ce que tu as des affichages sur le moniteur série?

du coup nous avons réussi a résoudre le problème

#include <ColorLCDShield.h>//
#include "DHT.h"
int DHTPIN = A0;//DHT11 connecté à la broche A0
float h;
float t;

#define DHTTYPE DHT11//définie le type de capteur de température et d'humidité 
DHT dht(DHTPIN, DHTTYPE);
#define BACKGROUND WHITE
#define C_COLOR RED
#define H_COLOR BLUE
#define M_COLOR GREEN
#define S_COLOR YELLOW
#define W_COLOR WHITE
#define B_COLOR BLACK
#define HOURS 8
#define MINUTES 37
#define SECONDS 00
#define AMPM 0  // enter 0 for AM, 1 for PM
int hours, minutes, seconds, ampm;
#define CLOCK_RADIUS 45  // radius of clock face
#define CLOCK_CENTER 50  // If you adjust the radius, you'll probably want to adjust this
#define H_LENGTH  25  // length of hour hand
#define M_LENGTH  35  // length of minute hand
#define S_LENGTH  43  // length of second hand
LCDShield lcd;
int LDR = A1;     
int luminosite;
char affichageluminosite [16];
char affichagetemperature[16];
char affichagehumidite[16];
char mystring[] = "Luminosite:";
char Text1[] = "temperature:";
char Text2[] = "humidite:";
char Unit[] = "Lux";
char Unit1[] = "*C";
char Unit2[] = "%";

void setup() 
{
  Serial.begin(9600);
  lcd.init(PHILIPS);  
  lcd.contrast(-70);//définie le contraste de l'écran lcd
  pinMode(LDR, INPUT);//définie la broche de la LDR en entrée
  afficheText();
  dht.begin();
  hours = HOURS;
  minutes = MINUTES;
  seconds = SECONDS;
  ampm = AMPM;
  drawClock();  // Draw the clock face, this includes 12, 3, 6, 9
  displayAnalogTime(hours, minutes, seconds);  // Draw the clock hands
  displayDigitalTime(hours, minutes, seconds, ampm);  // 
}
 
void loop() 
{
  static unsigned long ta = millis();
  while(millis()-ta>=1000)
  {
   seconds++;
   ta+=1000;
  }
  
  if (seconds >= 60)
  {
    seconds = 0;  // If seconds is 60, set it back to 0
    minutes++;    // and increase minutes by 1
    if (minutes >= 60)
    {
      minutes = 0;  // If minutes is 60, set it back to 0
      hours++;      // and increase hours by 1
      if (hours == 12)
        ampm ^= 1;  // If it's 12 o'clock, flip ampm
      if (hours >= 13)
        hours = 1;  // If hours is 13, set it to 1. 12-hr clock.
    }
  }
  
  h = dht.readHumidity();//lire les données(humidité) du capteur reçue 
  t = dht.readTemperature();//lire les données(température) du capteur reçue
  luminosite = analogRead(LDR);//lire les données de la LDR reçue
  Serial.print("Analog reading = ");
  Serial.print(luminosite);//afficher les informations de la LDR
  Serial.println("temp: ");//afficher le texte 
  Serial.println(t);//afficher les informations du capteur de température
  Serial.println("hum: ");//afficher le texte 
  Serial.println(h);//afficher les informations du capteur d'humidité
    delay(2500);
    lcd.clear(WHITE);
    drawClock();
    displayAnalogTime(hours, minutes, seconds);
    displayDigitalTime(hours, minutes, seconds, ampm);
    delay(2500);
    lcd.clear(WHITE);
    afficheText();
  
  
  
}
void displayDigitalTime(int h, int m, int s, int ap)
{
  
  char timeChar[16];
  
  if (!ap)
  {
    sprintf(timeChar, "%.2d:%.2d:%.2d AM", h, m, s);
  }
  else
  {
    sprintf(timeChar, "%.2d:%.2d:%.2d PM", h, m, s);
  }
  /* Print the time on the clock */
  lcd.setStr(timeChar, CLOCK_CENTER + CLOCK_RADIUS + 4, 22, 
              BLUE, WHITE);
}

/*
  drawClock() simply draws the outer circle of the clock, and '12',
  '3', '6', and '9'. Room for growth here, if you want to customize
  your clock. Maybe add dashe marks, or even all 12 digits.
*/
void drawClock()
{
  /* Draw the circle */
  lcd.setCircle(CLOCK_CENTER, 66, CLOCK_RADIUS, BLACK);
  
  /* Print 12, 3, 6, 9, a lot of arbitrary values are used here
     for the coordinates. Just used trial and error to get them 
     into a nice position. */
  lcd.setStr("12", CLOCK_CENTER - CLOCK_RADIUS, 66-9, BLACK, WHITE);
  lcd.setStr("3", CLOCK_CENTER - 9, 66 + CLOCK_RADIUS - 12, BLACK, WHITE);
  lcd.setStr("6", CLOCK_CENTER + CLOCK_RADIUS - 18, 66-4, BLACK, WHITE);
  lcd.setStr("9", CLOCK_CENTER - 9, 66 - CLOCK_RADIUS + 4, BLACK, WHITE);
}


void displayAnalogTime(int h, int m, int s)
{
  double midHours;  // this will be used to slightly adjust the hour hand
  static int hx, hy, mx, my, sx, sy;
  
  /* Adjust time to shift display 90 degrees ccw
     this will turn the clock the same direction as text */
  h -= 3;
  m -= 15;
  s -= 15;
  if (h <= 0)
    h += 12;
  if (m < 0)
    m += 60;
  if (s < 0)
    s += 60;
    
  /* Delete old lines: */
  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, WHITE);  // delete second hand
  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, WHITE);  // delete minute hand
  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, WHITE);  // delete hour hand
  
  /* Calculate and draw new lines: */
  s = map(s, 0, 60, 0, 360);  // map the 0-60, to "360 degrees"
  sx = S_LENGTH * sin(3.14 * ((double) s)/180);  // woo trig!
  sy = S_LENGTH * cos(3.14 * ((double) s)/180);  // woo trig!
  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, BLACK);  // print second hand
  
  m = map(m, 0, 60, 0, 360);  // map the 0-60, to "360 degrees"
  mx = M_LENGTH * sin(3.14 * ((double) m)/180);  // woo trig!
  my = M_LENGTH * cos(3.14 * ((double) m)/180);  // woo trig!
  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, BLACK);// print minute hand
  
  midHours = minutes/12;  // midHours is used to set the hours hand to middling levels between whole hours
  h *= 5;  // Get hours and midhours to the same scale
  h += midHours;  // add hours and midhours
  h = map(h, 0, 60, 0, 360);// map the 0-60, to "360 degrees"
  hx = H_LENGTH * sin(3.14 * ((double) h)/180);// woo trig!
  hy = H_LENGTH * cos(3.14 * ((double) h)/180);// woo trig!
  lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, BLUE);// print hour hand
  
}

void afficheText()
{
  
  sprintf (affichageluminosite, "%d", ((int)luminosite));
  sprintf (affichagetemperature, "%d", ((int)t));
  sprintf (affichagehumidite, "%d", ((int)h));    
  
  lcd.setStr(mystring, 0, 10, BLACK, WHITE);
  lcd.setStr(affichageluminosite, 20, 50, BLACK,WHITE);
  lcd.setStr(Unit, 20, 75, BLACK, WHITE);
  lcd.setStr(Text1, 40, 10, BLACK, WHITE);
  lcd.setStr(affichagetemperature, 60, 50, BLACK, WHITE);
  lcd.setStr(Unit1, 60, 70, BLACK, WHITE);
  lcd.setStr(Text2, 80, 10, BLACK, WHITE);
  lcd.setStr(affichagehumidite, 100, 50, BLACK, WHITE);
  lcd.setStr(Unit2, 100, 70, BLACK, WHITE);
  
}