Encore et toujours des variables

Bonjour,

J'ai encore un problème de variable :

#include <DS3231.h>
DS3231  rtc (SDA,SCL);
char heure;

void setup()
{
  Serial.begin(9600);
  rtc.begin();
}

void loop()
{
  heure = rtc.getTimeStr();
  Serial.println(heure);
}

L'heure (sous la forme "15:29:57") ne s'affiche pas, avez-vous une solution ?

La fonction est définie comme ceci :

char *DS3231::getTimeStr(uint8_t format)

Je pense qu'elle te renvoie non pas l'heure mais un pointeur vers l'heure. Tu dois définir un tableau de char
char heure[];dans lequel tu mettras l'heure.
Le format est expliqué ici

Attention lesept.
La méthode retourne un pointeur. Donc :

char *heure;
heure  = rtc.getTimeStr();

@+

Oui, de l'eau aura coulé sous les ponts lorsque j'aurai compris comment utiliser les pointeurs. Je suis plus fort sur ce genre de pointeur :

Merci beaucoup, ca a marché pour le code précédent mais, dans celui-ci plus rien ne s'affiche :

#include <DS3231.h>
DS3231  rtc (SDA,SCL);

char *heure;


void setup()
{
  Serial.begin(9600);
  rtc.begin();
  heure = rtc.getTimeStr();
}

void loop()
{
  if (rtc.getTimeStr() != heure)
  {
  Serial.println("heure : ");   
  Serial.println(heure);
  heure = rtc.getTimeStr();
  }
}

Si rien ne s'affiche c'est que la comparaison ne donne rien. Tu devrais afficher des choses pour voir ce que tu compares :

void loop()
{
  Serial.print(heure);Serial.print("\t");Serial.println(rtc.getTimeStr());  // <---
  if (rtc.getTimeStr() != heure)
  {
  Serial.println("heure : ");   
  Serial.println(heure);
  heure = rtc.getTimeStr();
  }
}

Comparer deux pointeurs revient à vérifier s'ils pointent vers la même adresse, alors que tu veux comparer le contenu de la mémoire à ces adresses : c'est différent.

If we want to see if two pointers point to the same memory location we can do that. Also if we want to compare the contents of the memory pointed to by two pointers we can do that too, just remeber to dereference them first.

If we have
int *a = something;
int *b = something;
which are two pointers of the same type we can:

Compare memory address:
a==b
and compare contents:
*a==*b

Mais je ne sais pas comment adapter ça à ton cas particulier... Peut-être

void loop()
{
  char *heure2 = rtc.getTimeStr();
  if (*heure2 != *heure)
  {
  Serial.println("heure : ");   
  Serial.println(heure);
  heure = rtc.getTimeStr();
  }
}

Pour comparer le contenu de 2 chaines de caractères, il faut utiliser strcmp.

#include <DS3231.h>
DS3231  rtc (SDA,SCL);

char *heure;

void setup()
{
  Serial.begin(9600);
  rtc.begin();
  heure = rtc.getTimeStr();
}

void loop()
{
  char *heure2 = rtc.getTimeStr();
  if (strcmp(heure2,heure)==0)
  {
  Serial.println("heure : ");
  heure = rtc.getTimeStr();
  }
  //else {Serial.println("...");}
}

Dans ce code, juste "heure : " s'affiche.
Donc, est ce que le problème vient des char ?

Ceci devrait marcher mais, il n'y a pas de diiférence entre heure et rtc.getTime

#include <DS3231.h>
DS3231  rtc (SDA,SCL);

char *heure;

void setup()
{
  Serial.begin(9600);
  rtc.begin();
  heure = rtc.getTimeStr();
}

void loop()
{
  
  if (strcmp(rtc.getTimeStr(),heure)!=0){
  Serial.println(heure);
  heure = rtc.getTimeStr();
  }
  
}

Oui, de l'eau aura coulé sous les ponts lorsque j'aurai compris comment utiliser les pointeurs.

Explication. Voici le code de la méthode getTimeStr :

char *DS3231::getTimeStr(uint8_t format)
{
 static char output[] = "xxxxxxxx";
 Time t;
 t=getTime();
 if (t.hour<10)
 output[0]=48;
 else
 output[0]=char((t.hour / 10)+48);
 output[1]=char((t.hour % 10)+48);
 output[2]=58;
 if (t.min<10)
 output[3]=48;
 else
 output[3]=char((t.min / 10)+48);
 output[4]=char((t.min % 10)+48);
 output[5]=58;
 if (format==FORMAT_SHORT)
 output[5]=0;
 else
 {
 if (t.sec<10)
 output[6]=48;
 else
 output[6]=char((t.sec / 10)+48);
 output[7]=char((t.sec % 10)+48);
 output[8]=0;
 }
 return (char*)&output;
}

Entre nous le rédacteur de de code aurait pu écrire :

 return output;

Cela revient exactement au même.

output est une chaîne de caractères statique.
La méthode getTimeStr() retourne l'adresse de output, que tu vas ranger dans un char *

A chaque appel, pour une instance donnée, getTimeStr() retourne la même adresse.

En aucun cas tu ne pourras affecter la valeur de retour de getTimeStr() à un tableau de char. Le compilateur va hurler.

#include <DS3231.h>

DS3231  rtc (SDA,SCL);

char heure[10];

void setup()
{
  Serial.begin(9600);
  rtc.begin();
  heure = rtc.getTimeStr();
}

void loop()
{
 
  if (strcmp(rtc.getTimeStr(),heure)!=0){
  Serial.println(heure);
  heure = rtc.getTimeStr();
  }
}
sketch_aug31a:11: error: incompatible types in assignment of 'char*' to 'char [10]'
   heure = rtc.getTimeStr();

Par contre tu peux écrire :

#include <DS3231.h>

DS3231  rtc (SDA,SCL);

char heure[10];

void setup()
{
  Serial.begin(9600);
  rtc.begin();
  strcpy(heure, rtc.getTimeStr());
}

void loop()
{
 
  if (strcmp(rtc.getTimeStr(),heure)!=0){
  Serial.println(heure);
  strcpy(heure, rtc.getTimeStr());
  }
}

@+

Ca marche dans ce cas, mais, j'ai voulu étendre pour comprendre le code ça bloque à ce niveau ;

#include <DS3231.h>

DS3231  rtc (SDA,SCL);

char heure[10];

void setup()
{
  Serial.begin(9600);
  rtc.begin();
  strcpy(heure, rtc.getTimeStr(FORMAT_SHORT));
}

void loop()
{
 
  if (strcmp(rtc.getTimeStr(),heure)!=0){
  Serial.println(heure);
  strcpy(heure, rtc.getTimeStr(FORMAT_SHORT));
  }
}

Résultat, l'heure s'affiche au bon format mais le if marche plus.

Le format short renvoie l'heure sous la forme hh:mm si j'ai bonne mémoire. Il faut 6 caractères pas 10.

Dans ta comparaison, tu appelles rtc.getTimeStr() sans paramètre, ne faudrait-il pas mettre rtc.getTimeStr(FORMAT_SHORT) ?

rtc.getTimeStr(FORMAT_SHORT) retourne l'heure au format HH:MM
rtc.getTimeStr() retourne l'heure au format HH:MM:SS

Je fais un essai et je reviens.

@+

Tu lis l'heure ainsi :

  strcpy(heure, rtc.getTimeStr(FORMAT_SHORT));

Ensuite tu compares heure avec la valeur retournée de rtc.getTimeStr()

  if (strcmp(rtc.getTimeStr(),heure)!=0) {

Dans la variable heure tu récupère une heure au format HH:MM et rtc.getTimeStr() retourne une heure au format HH:MM:SS.
Donc la comparaison est toujours fausse.

Il faut d'abord que tu décides dans quel format tu désires récupérer l'heure.
Ensuite tu utilises le même format partout.

@+

Tu te demandes peut-être pourquoi le code précédent utilisant un pointeur ne fonctionne pas ?
Un simple exemple :

#include <DS3231.h>

DS3231  rtc (SDA,SCL);
char *heure;

void setup()
{
  Serial.begin(115200);
  rtc.begin();
}

void loop()
{
  heure = rtc.getTimeStr();
  Serial.print("heure: ");
  Serial.println(heure);
  Serial.println("attente 5s");
  delay(5000);
  Serial.print("rtc.getTimeStr(): ");
  Serial.println(rtc.getTimeStr());
  Serial.print("heure: ");
  Serial.println(heure);
  delay(10000);
}

Exécution :

heure: 00:28:25
attente 5s
rtc.getTimeStr(): 00:28:30
heure: 00:28:30

La variable heure a changé !
Oui, car c'est un pointeur et ce pointeur contient l'adresse de la chaîne interne utilisée par la méthode getTimeStr() pour formater l'heure.
Donc heure et rtc.getTimeStr() sont toujours équivalents.
Donc la comparaison des deux est toujours vraie.

Il faut donc bien travailler avec strcpy() et des chaînes de caractères si l'on veut faire des comparaisons.

Le format short renvoie l'heure sous la forme hh:mm si j'ai bonne mémoire. Il faut 6 caractères pas 10.

Pas grave, qui peut le plus peut le moins. rtc.getTimeStr(FORMAT_SHORT) placera de toutes façons un '\0' à la fin de la chaîne, donc après les minutes.
En laissant une taille de 9, tu es sûr que ça passe même avec un format HH:MM:SS.

@+

J'ai pas réussi à trouver de solutions. ^^

As-tu lu le post #14 ?

Oui j'ai essayé de comprendre comment marcher ce changement mais, c'est bizarre, quoi que je fasse l'heure s'affiche en permanence avec le format_short.

Sinon, ce n'est pas grave, je vais garder l'heure avec les secondes bien que cela puisse paraître bizarre ^^

Poste ton code.