Aide pour avoir une horloge bien lineaire

bonjour,
je viens de creer un programme pour avoir une horloge qui indique date et heure, et en meme temps qui messure avec un dht11 et un cmp 180 la pression l' humidite etc, mon souci est qu avec se programme, toutes les environ 4 secondes l horloge passe de 13 seconde a 15 seconde, je ne sais pas comment je pourrai avoir une horloge qui soit independante avec le delai de mesure des capteurs
j espere que j ai ete asser précis merci pour votre aide

Post mis dans la mauvaise section, on parle anglais dans les forums généraux, je viens de déplacer le post dans la section francophone.

Merci de prendre en compte les recommandations listées dans "Les bonnes pratiques du Forum Francophone".

hello
il nous faut ton code, ton cablage et savoir quel type de platine arduino tu utilises

je suppose que tu utilises millis() pour faire ton compte du temps.

il faut utiliser une horloge extérieure type RS3231.

nota: jette un oeil sur les bonnes pratiques du forum.

desole je debute dans le forum

1 Like
#include <DS1302.h>
#include <LiquidCrystal_I2C.h>

#include "Wire.h"
#include "SFE_BMP180.h"

// Init the DS1302
DS1302 rtc(2, 3, 4);
LiquidCrystal_I2C lcd(0x27, 20, 4);

#include "DHT.h"
#define DHTPIN 7
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

SFE_BMP180 pressure;
#define ALTITUDE 1655.0

void setup()
{
  // Set the clock to run-mode, and disable the write protection
  rtc.halt(false);
  rtc.writeProtect(false);
  
  // Setup Serial connection
  Serial.begin(9600);

  dht.begin(); 
  Serial.begin(9600);
  pressure.begin();

  lcd.init();
  lcd.backlight();

  // The following lines can be commented out to use the values already stored in the DS1302
  rtc.setDOW(VENDREDI);        // Set Day-of-Week to FRIDAY
  rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
  rtc.setDate(25, 5, 2024);   // Set the date to August 6th, 2010
}

void loop()
{
  {
   lcd.setCursor(0, 0);  
  lcd.print(rtc.getDOWStr());
  // Send Day-of-Week
  lcd.setCursor(9,0);
  lcd.print(rtc.getDateStr());
  // Send date
  lcd.setCursor(6,1);
  lcd.print(rtc.getTimeStr());
  // Send Day-of-Week
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");
  
  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Send time
  Serial.println(rtc.getTimeStr());
  
  // Wait one second before repeating :)
   delay(1000);
}

   char status;
   double T,P,p0,a;

   float h = dht.readHumidity ();

  Serial.println();
  Serial.print("humidite: ");
  Serial.print(h,0);
  Serial.println("%");

  

   Serial.println();
   Serial.print("provided altitude: ");
   Serial.print(ALTITUDE,0);
   Serial.println(" meters");
  
   status = pressure.startTemperature();
   if (status != 0){
      delay(status);

      status = pressure.getTemperature(T);
      if (status != 0){
         Serial.print("temperature: ");
         Serial.print(T,2);
         Serial.println(" deg C");

         status = pressure.startPressure(3);
         if (status != 0){
            delay(status);

            status = pressure.getPressure(P,T);
            if (status != 0){
               Serial.print("absolute pressure: ");
               Serial.print(P,2);
               Serial.print(" mb, ");
               Serial.print(P*0.0295333727,2);
               Serial.println(" inHg");

              p0 = pressure.sealevel(P,ALTITUDE);
              Serial.print("relative (sea-level) pressure: ");
              Serial.print(p0,2);
              Serial.print(" mb, ");
              Serial.print(p0*0.0295333727,2);
              Serial.println(" inHg");
           }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");


lcd.setCursor(10, 2);
lcd.print(P,2);
lcd.setCursor(17, 2);
lcd.print("hPa");
lcd.setCursor(10, 2);
lcd.print("P:");

lcd.setCursor(0, 2);
lcd.print("A:");
lcd.setCursor(2, 2);
lcd.print(p0/82);
lcd.setCursor(7, 2);
lcd.print("m");

lcd.setCursor(07, 3);
lcd.print("Temp:");
lcd.setCursor(12, 3);
lcd.print(T,2);
lcd.setCursor(17, 3);
lcd.print(" C");

lcd.setCursor(0, 3 );
lcd.print("Hu:");
lcd.setCursor(3, 3);
lcd.print(h,0);
lcd.setCursor(5, 3);
lcd.print("%");


  
}

voici mon code j espere que j ai bien fait

Hello,
Tu réédités ton post #1 en mode modif
Puis tu sélectionnes ton ce qui concerne ton code et tu supprimes.
Tu retournes dans ton ide Arduino et tu recopies ton code en entier.
Tu reviens dans ton poste#1 et tu cliques sur les balises de code <>
Tu colles ton code à la place des ....... Entre les balises de code<>

voila je viens de refaire merci

avec cette ligne

vous avez déjà perdu la bataille.. comment voulez vous pouvoir avoir le temps d'extraire les données du capteur puis de les afficher ainsi que le temps qui passe si vous ne faites rien pendant toute une seconde... forcément ça ne va pas fonctionner.

il faut remanier votre code:

  • regardez si ce que vous souhaitez faire est compatible avec le temps d'affichage et le temps de lecture des capteurs. regardez si les capteurs ont un mode de lecture asynchrone (on demande une mesure, on revient plus tard voir si la mesure est prête, on ne bloque pas en attendant la mesure)

  • gérez le temps avec millis, pas de délais

  • effectuez les affichages sur le LCD uniquement pour les données qui ont changées. Ne raffichez pas tout

Ton code contient deux délais, dont 1 de 1seconde.
Donc, tu ne peux pas afficher le temps juste toutes les secondes.
Ensuite, pour gagner du temps d'affichage, tu devrais afficher dans le setup tous les textes qui ne varient pas et dans la loop, tu affiches seulement les variables.

Tu peux même dans le setup afficher une fois les variables, puis dans la loop, n'afficher que les variables qui ont changées.

Édit, grillé par jml😁

merci pour l aide je debute dans le arduino le millis je ne maitrise pas du tout aucune idee de comment les mettres dans le programme

si je comprend bien dans le setup je pourrai par exemple y mettre les lignes fixe du genre ecriture comme temperature, humidite par exemple
merci pour l aide

si vous lisez l'anglais, regardez

sinon dans les tutos d'eskimon il y a un chapitre sur la gestion du temps qui passe

je maitrise pas l anglais je pensais trouve une solution ou l horloge fonctionne sur la seconde et la parti capteur fonctionne par exemple sur 4 secondes a moins que avec millis je peux faire fonctionnes les capteurs sur 4 secondes et l horloge sur la seconde

millis, permet d'obtenir le temps qu'il est.
millis tout seul ne fait rien, à la différence de delay.
comme tu as le temps qui passe, tu peux ne faire des choses qu'au moment que tu décides.
par exemple afficher l'heure à chaque seconde et demander toutes les 4s de lire les données de ton capteur, si bien sur tu peux faire une demande d'acquisition en asynchrone, comme l'a induqué @J-M-L

ok d accord vu que je debut sa l air un peu complique au premier abord je vais chercher un peu sur internet et avec le lien donne pour la fonction millis
merci

Non ce n'est pa spécialement compliqué, c'est comme tout, il faut prendre des exemples ou des articles, dessus et manipuler le fonction sur des programmes simples pour appréhender le comportement.

regardez éventuellement la programmation par machine à états (cf mon tuto éventuellement) - je parle du temps aussi comme un événement

l ai trouve des exemple avec une simple led, je vois pas comment l adapter pour mes capteurs

merci je vais regarde ca

Bonjour calimeros

Je t'ai fait un petit programme "démo".

Il y a une partie où l'on affiche ce qui ne doit l'être qu'au départ:
void lcdSetup();
La mise à jour des données se fait dans:
void mesures()

Le tout est rythmé par les millis():
actuellement, toutes les secondes à toi d'ajuster à ta guise.

const unsigned long affichageTempo = 1000;     // Tempo d'affichage
unsigned long affichageMillis = millis();     // Tempo d'affichage, chrono
	if (millis() - affichageMillis >= affichageTempo)     // Si c'est le moment d'afficher
	{

où l'on n'affiche que le nécessaire.

Le programme:

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);

const unsigned long affichageTempo = 1000;     // Tempo d'affichage
unsigned long affichageMillis = millis();     // Tempo d'affichage, chrono

const unsigned long tempsDepart = millis();     // Temps de départ
int tempsEcoule = 0;

void setup()
{
	Serial.begin(9600);
	lcd.init();
	lcd.backlight();

	lcdSetup();
}

void loop()
{
	if (millis() - affichageMillis >= affichageTempo)     // Si c'est le moment d'afficher
	{
		mesures();

		lcd.setCursor(14, 1);
		lcd.print(tempsEcoule);

		lcd.setCursor(10, 2);
		lcd.print(120 - tempsEcoule);
		lcd.print("  ");

		affichageMillis = millis();     // Redémarrage du chrono

	}
	
}

void mesures()
{
	tempsEcoule = (millis() - tempsDepart) / 1000;
}

void lcdSetup()     // Ce qui ne doit être affiché qu'au départ

{
	lcd.setCursor(0, 1);
	lcd.print("Temps ecoule:");
	lcd.setCursor(0, 2);
	lcd.print("Decompte:");
}

Ainsi, plus de delay().

A toi d'adapter la méthode dans ton programme :wink:

Cordialement
jpbbricole