Réglage temps tmElements_t

Wemos d1 mini

Bonjour,
Je voudrais régler le temps "now" pour n'exploiter que les heures et minutes, sans NTP ni RTC.
Je sais convertir une date/heure en timestamp (par exemple 12h30 vaut 45000), mais après cela, c'est le trou noir : comment régler cette heure et puis l'exploiter.
J'ai regardé le fichier/librairie TimeLib.h (c'est souvent instructif), mais cela ne veut pas compiler.
Un petit coup de pouce ?
Merci !

01_time:20:6: error: 'struct tmElements_t' has no member named 'setTime'
   20 |   tm.setTime(tmConvert_t(1970, 1, 1, 12, 30, 0));
      |      ^~~~~~~
exit status 1
'struct tmElements_t' has no member named 'setTime'

Voici le code :

/*
   HH:MM
   01
*/

const char Version[] = "Version 01_Time \n 06/12/21 ";

#include <TimeLib.h>

tmElements_t tm ;

void setup() {
  Serial.begin(115200) ;
  delay(50) ; //
  Serial.println("\n\n\n") ;
  Serial.println(Version) ;
  Serial.println("\n\n\n") ;
  Serial.print (tmConvert_t(1970, 1, 1, 12, 30, 0)) ; // comme attendu, 45000 secondes
  tm.setTime(tmConvert_t(1970, 1, 1, 12, 30, 0));
}

void loop() {}

time_t tmConvert_t(int YYYY, byte MM, byte DD, byte hh, byte mm, byte ss) {
  tmElements_t tmSet ;
  tmSet.Year = YYYY - 1970 ;
  tmSet.Month = MM ;
  tmSet.Day = DD ;
  tmSet.Hour = hh ;
  tmSet.Minute = mm ;
  tmSet.Second = ss ;
  return makeTime(tmSet) ;         //convert to time_t
}
void    setTime(time_t t);
void    setTime(int hr,int min,int sec,int day, int month, int yr);

setTime() est une fonction, ce n'est pas une méthode, et elle prend en argument soit un temps en secondes, soit une suite hr, min, sec, day, month, yr.

// soit 
setTime(45000);
// soit 
setTime(12, 30, 0, 1, 1, 1970);

Bonjour,

Il faudrait faire
breakTime(tmConvert_t(1970, 1, 1, 12, 30, 0),tm);
Mais je ne vois pas trop l'intérêt de calculer un time_t à partir des jours, mois, années... pour le reconvertir en jours, mois, années...

Bonjour et merci de votre intérêt,

C'est pour un usage pédagogique (pas de mon choix), où seuls HH:MM sont utilisés

Bonsoir,

Merci de la réponse, je vais regarder cela plus en détail.
Merci encore !

Bon,
Ce setTime est censé régler l'horloge interne ?
Comment s'exprime t'elle en pratique ?
Je rappelle qu'il ne me faut que les heures et minutes,
Merci d'avance

Et tant que j'y suis, je ne comprends pas ces déclarations comme

void setTime(time_t t);

merci

Dans le premier post, tu associes setTime() à une instance de tmElements_t tm.
Or, c'est une fonction C, elle s'appelle tout simplement, sans qu'elle soit associée à un objet.
setTime(tmConvert_t(1970, 1, 1, 12, 30, 0));

Bien,
j'ai trouvé un code sur GitHub qui fonctionne fort bien.

Mais mon objectif est de pouvoir régler manuellement les heures et les minutes.
Donc, quand je retire tout ce qui concerne le NTP, l'horloge démarre à zéro, le 1/1/1970

  • Retrouver le timestamp epoch actuel
  • Ajouter ou soustraire 60 pour les minutes ou 3600 pour les heures.
  • Régler l'horloge

Merci de vos lumières :wink:

À noter que j'ai changé le nom de la String en "temps" au lieu de "time" qui prête à confusion

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
//#include <time.h>
#include <TimeLib.h>

// d'après https://github.com/G6EJD/ESP8266-MAX7219-LED-4x8x8-Matrix-Clock/blob/master/ESP8266_MAX7219_Time.ino

const char Version[] = "Version 03 LED";
int pinCS = D4; // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI )
int numberOfHorizontalDisplays = 4;
int numberOfVerticalDisplays   = 1;
char time_value[20];

// LED Matrix Pin -> ESP8266 Pin
// Vcc            -> 3v  (3V on NodeMCU 3V3 on WEMOS)
// Gnd            -> Gnd (G on NodeMCU)
// DIN            -> D7  (Same Pin for WEMOS)
// CS             -> D4  (Same Pin for WEMOS)
// CLK            -> D5  (Same Pin for WEMOS)

Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

int spacer = 1;
int width  = 5 + spacer; // The font width is 5 pixels

void setup() {
  Serial.begin(115200) ;
  matrix.setIntensity(10); // Use a value between 0 and 15 for brightness
  matrix.setRotation(0, 1);    // The first display is position upside down
  matrix.setRotation(1, 1);    // The first display is position upside down
  matrix.setRotation(2, 1);    // The first display is position upside down
  matrix.setRotation(3, 1);    // The first display is position upside down
  Serial.println("\n\n\n") ;
  Serial.println(Version) ;
  Serial.println("\n\n\n") ;
}

void loop() {
  matrix.fillScreen(LOW);
  time_t now = time(nullptr);
  String temps = String(ctime(&now));
  temps.trim();
  Serial.println(temps);
  temps.substring(11, 19).toCharArray(time_value, 10);
  matrix.drawChar(2, 0, time_value[0], HIGH, LOW, 1); // H
  matrix.drawChar(8, 0, time_value[1], HIGH, LOW, 1); // HH
  if (time_value[7] % 2 == 0) { // 1 seconde sur 2
    matrix.drawChar(14, 0, time_value[2], HIGH, LOW, 1); // HH:
  } else {
    matrix.drawChar(14, 0, ' ', HIGH, LOW, 1); // HH  pas les ":"
  }
  matrix.drawChar(20, 0, time_value[3], HIGH, LOW, 1); // HH:M
  matrix.drawChar(26, 0, time_value[4], HIGH, LOW, 1); // HH:MM
  matrix.write(); // Send bitmap to display
  delay(1000);
}

Ce qui est tout à fait normal. Pour que l'heure soit sauvegardée il faut un circuit RTC.
Si l'on veut ensuite la régler, il faut un organe de commande (boutons, clavier, encodeur rotatif, etc.).

Oui, bien entendu, je comprends bien. Sans NTP, l'horloge démarre à zéro et continue à avancer.
Je reformule ma double question : comment récupérer (Get) le timestamp, comment y envoyer (SET) un timestamp. Je ne parle pas des moyens mis en œuvre pour y parvenir (ce sera une interface WEB).
Là, je suis en train de me demander si je ne vais pas la programmer de A à Z !
En tout cas, merci de tes efforts :wink:

Tout est dans la TimeLib :

time_t now();              // return the current time as seconds since Jan 1 1970 
void    setTime(time_t t);
void    setTime(int hr,int min,int sec,int day, int month, int yr);

Qui dit interface WEB dit TCP/IP (Ethernet ou WIFI). Donc à partir de là le NTP est accessible.

Merci à tous pour vos efforts

Cela ne fonctionne pas, en tout cas sur un Wemos D1R2, et je crois l'avoir déjà dit.

Hé bien oui, je sais bien cela, mais cela n'est pas mon objectif, un peu marre de me répéter.

Bref, je passe par une programmation tout autre. Elle me permettra d'atteindre mon objectif : régler les heures et minutes comme je le veux.

Encore merci à tous !


#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>

int pinCS = D4; // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI )
int numberOfHorizontalDisplays = 4;
int numberOfVerticalDisplays   = 1;

// LED Matrix Pin -> ESP8266 Pin
// Vcc            -> 3v  (3V on NodeMCU 3V3 on WEMOS)
// Gnd            -> Gnd (G on NodeMCU)
// DIN            -> D7  (Same Pin for WEMOS)
// CS             -> D4  (Same Pin for WEMOS)
// CLK            -> D5  (Same Pin for WEMOS)

Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

int spacer = 1;
int width  = 5 + spacer; // The font width is 5 pixels

unsigned long long time_sm; // 64 bits non signé
byte hh = 23; // heures
byte mm = 58; // minutes
byte ss = 30; // secondes
char hms[10];

void setup() {
  Serial.begin(115200);
  matrix.setIntensity(10); // Use a value between 0 and 15 for brightness
  matrix.setRotation(0, 1);    // The first display is position upside down
  matrix.setRotation(1, 1);    // The first display is position upside down
  matrix.setRotation(2, 1);    // The first display is position upside down
  matrix.setRotation(3, 1);    // The first display is position upside down
  
  time_sm = superMillis(); // démarrage de l'horloge
}

void loop() {
  if (superMillis() >= time_sm) { // 1000 mSec sont passées, ajout d'une seconde, controle et affichage de l'heure
    time_sm += 1000; //seconde suivante, surtout si on a pris du retard pour arriver ici.  Ce sera toujours une seconde
    ss++; // une seconde en plus
    ControleHeure('A'); // si nécessaire, ajuste les dépassements de secondes, minutes ou heures
    matrix.fillScreen(LOW);
    sprintf(hms, "%02d:%02d:%02d", hh, mm, ss); // mise en forme de l'heure minute seconde
    Serial.println(hms);
    // Affiche les chiffres de l'heure à des positions précises
    matrix.drawChar(2, 0, hms[0], HIGH, LOW, 1); // H
    matrix.drawChar(8, 0, hms[1], HIGH, LOW, 1); // HH
    if (ss % 2 == 0) { // une seconde sur deux : on fait clignoter les « : » toutes les secondes
      matrix.drawChar(14, 0, ':', HIGH, LOW, 1); // affiche les « : »
    } else {
      matrix.drawChar(14, 0, ' ', HIGH, LOW, 1); // n'affiche pas les « : »
    }
    matrix.drawChar(20, 0, hms[3], HIGH, LOW, 1); // HH:M
    matrix.drawChar(26, 0, hms[4], HIGH, LOW, 1); // HH:MM
    matrix.write(); // Send bitmap to display
  }
  // autres traitements possibles
}

void ControleHeure(char type) {
  if (type == 'A') { // Horloge "Automatique" + 1 seconde
    // si nécessaire, ajuste les dépassements de secondes, minutes ou heures
    if (ss > 59) { // minute suivante
      ss = 0;
      mm++;
    }
    if (mm > 59) { // heure suivante
      mm = 0;
      hh++;
    }
    if (hh > 23) { // tour de l'horloge
      hh = 0;
      mm = 0;
      ss = 0;
    }
  }
  else
  { // réglage manuel, vérification individuelle des minutes et des heures
    if (mm < 0) {
      mm = 59;
    }
    if (hh < 0) {
      hh = 23;
    }
    if (mm > 59) {
      mm = 0;
    }
    if (hh > 23) {
      hh = 0;
    }
  }
}


unsigned long long superMillis() {
  /*
    @return Le nombre de millisecondes depuis le démarrage du programme sous la forme d'un nombre entier sur 64 bits (unsigned long long).
    Le max est donc de
    18.446.744.073.709.551,62 secondes
    307.445.734.561.825,86 minutes
    5.124.095.576.030,43 heures
    213.503.982.334,60 jours
    584.542.046,09 années ... il y aura longtemp que le composant aura été décomposé voire désintégré !
  */
  static unsigned long nbRollover = 0;
  static unsigned long previousMillis = 0;
  unsigned long currentMillis = millis();

  if (currentMillis < previousMillis) {
    nbRollover++;
  }
  previousMillis = currentMillis;

  unsigned long long finalMillis = nbRollover;
  finalMillis <<= 32;
  finalMillis +=  currentMillis;
  return finalMillis;
}

Bonjour,

Je me suis demandé pourquoi ce post n'était pas dans le fil sur le forum : mais tu as dû le retirer car cela ne concerne que l'ESP32 ...
Pas de solution pour l'ESP8266 ?

Merci !

Il n'y a de solution ni pour l'ESP32, ni pour l'ESP8266.
La doc semble fausse, surtout en ce qui concerne settimeofday(), absente de la librairie.

La méthode classique est : utiliser configTzTime(), mais c'est forcément NTP.
Ensuite les fonctions standard sont utilisables : time(), localTime(), etc.