En premier lieu, ton programme cherche à effectuer des actions à des heures très précises, alors qu'il contient un gros delay(5000).
Par exemple : à 17:59:57 il n'est pas 18:00:00 et à la loop() suivante il est 18:00:02 et il n'est toujours pas 18:00:00, donc l'action voulue à 18:00:00 n'a pas été déclenchée
Je te laisse mariner un autre algo et le proposer
Une indication : il vaut mieux se poser la question "Est-ce que l'heure de ma prochaine action est encore dans le futur?" plutôt que "Là maintenant tout de suite est-ce qu'il est pile poil l'heure de ma prochaine action?"
D'autre part, effectuer une synchro réseau NTP toutes les 5 secondes est parfaitement inutile.
La fonction millis() a une dérive d'au maximum quelques secondes par jour (variable selon le matos).
Tu pourrais déclencher une synchro NTP seulement une fois par jour.
Eventuellement, si tu as besoin d'une précision maximum, tu peux augmenter la cadence jusqu'à une fois par heure mais aller au-delà est inutile.
Attention aussi au fait que certains serveurs NTP publics limitent le nombre de connexions par client.
Je me doutais que Delay(5000) pouvait perturber le sketch mais je l'avais mis pour débuguer en affichant : Serial.print("lastNtpTimestamp: ");Serial.println(lastNtpTimestamp);
à chaque itération.
Je vais réfléchir aux pistes que tu proposes, sans doute en utilisant Millis() après une mise à jour journalière du temps unix.
Je vais réfléchir aussi à coder ton indication : [quote="bricoleau, post:4, topic:1252531"]
il vaut mieux se poser la question "Est-ce que l'heure de ma prochaine action est encore dans le futur?" plutôt que "Là maintenant tout de suite est-ce qu'il est pile poil l'heure de ma prochaine action?"
[/quote]
Tu peux aussi faire des variantes de la question, comme est ce que l'heure de ma prochaine est dans le passé ou n'est plus dans le future, en fonction de ce qui te parle le plus.
void loop() {
timeClient.update();
unsigned long currentTime = timeClient.getEpochTime();
// Effectuer un envoi des données à 0h 6h 12h et 18h
// Le temps est découpé en tranches de 6 heures
// Détection du changement de tranche
if ((currentTime / 21600) != (lastSentTimestamp / 21600)) {
sendData();
lastSentTimestamp = currentTime;
}
}
Ce que tu proposes doit fonctionner mais on fait sans arrêt appel à timeClient.update et on envoie les données toutes les 6 heures mais pas à heure fixe ( 0h, 6h, 12h,18h).
J'essaie de suivre les indications de Terwal et de ne synchroniser l'heure qu'une fois par jour, par exemple à 0h, puis utiliser millis().
Pour l'instant je réfléchi et teste plusieurs solutions mais c'est pas probant!
Merci
J'ai jeté un oeil au fichier header de la bibliothèque NTPClient.h et il y est conseillé de faire un update() à chaque loop.
Visiblement cette fonction actualise les variables en mémoire, et déclenche de temps en temps une synchro NTP avec un serveur.
D'ailleurs à ce sujet la synchro NTP est déclenchée une fois par minute (valeur par défaut) ce qui me semble beaucoup trop souvent. Une fonction de la bibliothèque permet d'augmenter l'intervalle.
Le code que je propose envoie bien les data aux heures fixes 0h 6h 12h 18h
Faut juste vérifier si EpochTime est en UTC ou heure locale avec gestion des heures d'été
J'ai un peu tardé à répondre pour cause de test ( sur 24h c'est long!).
Ta solution fonctionne bien et envoie les données aux heures voulues (0h, 6h,12h,18h) .
EpochTime est en heure locale et tient compte des heures d'été.
Juste une question : Comment le programme fait il pour mettre à jour aux heures voulues indépendamment de l'heure ou on charge le programme sur l'ESP8266?
Merci.
C'est tout simple, il suffit de changer d'unité de mesure du temps.
Au lieu de compter les secondes, il suffit de compter les quarts de jour.
Puisque epoch correspond au nombre de secondes écoulées depuis un instant origine, alors epoch/21600 correspond au nombre de quarts de jour écoulés depuis ce même instant origine.
Le bout de code ne fait que surveiller le temps qui s'écoule en détectant le changement de quart.
Voilou
Pour un peu plus détailler la réponse de @bricoleau, le IF vérifié sur la valeur courante du nombre de seconde depuis 1970 et différente de celle renregistrée.
Si c'est le cas, les données sont envoyé(sendata) et la nouvelle valeur est sauvegardé pour que le if s'execute à nouveau lorsque la condition est respecté.
une autre façon de faire est au lieu de sauvegarder la valeur courante, c'est d'avoir une variable avec la valeur en seconde de la prochaine execution.
Du coup le if comparera la valeur epoch courante avec celle voulu, si la valeur courante est supérieur alors on fait de même, envois des données et sauvegarde de la prochaine valeur.