Affichage date et heure

Bonjour,

Newbie sur Arduino, voici mon 1er programme pour afficher la date et l'heure en vue d'installer cela sur le tableau de bord de mon véhicule.

Tout est indiqué dans l'entête du fichier source attaché. 8)

Sinon, ce petit programme est un bon exemple de calculs des années bissextiles, du passage en horaire d'été et d'hiver, du jour dans la semaine, ... :wink:

Exemple de l'affichage :

Saisissez le jour: 5
Saisissez le mois: 10
Saisissez l'annee: 2018
Saisissez l'heure: 8
Saisissez les minutes: 53
Voulez-vous afficher les secondes ?(O/N) o
dateinitok
Vendredi 05 octobre 2018
08:53:00
08:53:01
08:53:02
08:53:03
08:53:04
08:53:05
08:53:06
08:53:07
08:53:08
08:53:09
08:53:10
08:53:11
08:53:12
08:53:13
08:53:14
08:53:15
08:53:16
08:53:17
08:53:18
08:53:19
08:53:20

Affichage_Date_Heure.ino (12.1 KB)

avec toutes ces String dedans, j'ai bien peur que ça plante après assez peu de temps...

non, pourquoi des strings feraient planter ?????
surtout que la nouvelle version implante celles-ci dans la mémoire flash afin de libérer de la place pour les variables.

on parle de String, pas de string... String alloue de la mémoire dynamiquement, et dans si peu de RAM, ça part vite en sucette

J'avais bien compris :stuck_out_tongue_closed_eyes: , mais si tu regardes le source un peu plus en détail, tu t’apercevra que j'utilise F() dans les déclarations de mes String

exemple: Serial.print(F("un message quelconque"));
ou texte=F("un texte quelconque");

et que j'indique comme "astuce" dans l'entête du source. :wink:
Ceci veut dire qu'elles sont écrites dans la memory flash, voila le résultat de la compile:

Le croquis utilise 8414 octets (26%) de l'espace de stockage de programmes. Le maximum est de 32256 octets.
Les variables globales utilisent 488 octets (23%) de mémoire dynamique, ce qui laisse 1560 octets pour les variables locales. Le maximum est de 2048 octets. :grin:

je crois qu'on ne se comprend pas :smiley:

J'ai bien vu que tu utilises progmem pour un certain nombre de chaines (des **s**tring ,donc), et c'est très bien. Mais comme tu le dis si bien, ce sont des chaines statiques, uniquement des messages envoyés par Serial, pour ce que j'en ai vu.

Ce qui posera problème en revanche, c'est l'utilisation des **S**tring qui est faite tout au long du programme, et ça ça n'a rien à voir avec des chaines statiques stockés en flash !

message=Serial.readString();


int saisir(String libelle,int mini,int maxi)

<--la pire utilisation étant sans doute ici, en argument de fonction : à chaque appel les Strings sont crées en mémoire dynamique, puis agrandies quand tu t'en sers, pus détruites lorsque la fonction se termine, puis recrées à l'appel suivant, et ainsi de suite. Sur un processeur avec 2ko de ram... tu arrives très (très) vite au bout. Et après tout part en vrille, car ça aloue alors par dessus des variables existantes.

Milles excuses :-[

Effectivement, je n’avais pas tout compris mais comme je dis sur mon 1er post, je suis un newbie :slightly_frowning_face: et donc il faut me mettre "les points sur les I".

Tu me dis :
"int saisir(String libelle,int mini,int maxi) <--la pire utilisation étant sans doute ici"
mais ceci ne sera exécuté que 5 fois au moment du setup.

J'ai corrigé mes erreurs dans le fichier source sur le 1er post, dis-moi si cela est "dans les règles de l'art". :roll_eyes:

oui, "que" 5 fois... donc probablement 5 zones avec des "trous" dans la RAM à la fin

D'autant plus que par exemple :

   String erreur = F("Valeur incorrecte, saisir entre ");
    erreur.concat(mini);
    erreur.concat(" et ");
    erreur.concat(maxi);
    Serial.println(erreur);

là le F() ne sert à rien, une String c'est de toutes manières de la mémoire dynamique, et ensuite tu va à chaque concat faire allouer un peu plus de ram pour allonger la String, alors qu'il n'y en a aucun besoin, tu pourrais faire directement :

Serial.print(F("Valeur incorrecte, saisir entre "));
Serial.print(mini);
Serial.print(F(" et "));
Serial.println(maxi);

Et la même chose est applicable à plein d'endroits dans ton code... et pour se passer de String, il existe déjà des fonctions standard du C pour manipuler des chaines.

Si tu veux aussi rester "dans les règles del'art" il faut éviter d'utiliser goto.

Pour ce qui est de l'utilisation de la ram, rajoute cette fonction dans ton code :

//from http://jeelabs.org/2011/05/22/atmega-memory-use/
int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

Et de temps en temps fais un Serial.println(freeRam());, par exemple à la fin de saisir(), puis dans la loop(), etc.
ensuite fais les modifs pour se passer de String au maximum et vois comment ça évolue, ça risque d'être instructif.

oui, "que" 5 fois... donc probablement 5 zones avec des "trous" dans la RAM à la fin

Pas cinq trous. Un seul, ayant une taille équivalente à la somme des allocations.

ensuite fais les modifs pour se passer de String au maximum et vois comment ça évolue, ça risque d'être instructif.

C'est une bonne habitude à prendre en effet.

@+

Merci bricofoy,

J'ai suivi tes conseils et utilisé ton test, il s'avère que la valeur revient et reste à son point de départ.

Je voulai joindre l'image du test mais je ne sais pas comment l'insérer !!!

FB78:
Merci bricofoy,

J'ai suivi tes conseils et utilisé ton test, il s'avère que la valeur revient et reste à son point de départ.

Je voulai joindre l'image du test mais je ne sais pas comment l'insérer !!!

tu peux copier/coller le contenu de la fenetre du moniteur comme texte

si tu reviens à la valeur initiale après les utilisations de String, tu as de la chance, c'est qu''il n'y a pas eu de création de variable après celle de String, du coup ça n'a pas laissé de trou.Mais j'ai envie de dire que c'est l'exception qui confirme la règle...

Voila le test de la SRAM :

Compilation terminée.
Le croquis utilise 8672 octets (26%) de l'espace de stockage de programmes. Le maximum est de 32256 octets.
Les variables globales utilisent 428 octets (20%) de mémoire dynamique, ce qui laisse 1620 octets pour les variables locales. Le maximum est de 2048 octets.

Pendant l'exécution du programme :
Saisissez le jour: 4
SRAM restant libre = 1525
Saisissez le mois: 10
SRAM restant libre = 1524
Saisissez l'annee: 2018
SRAM restant libre = 1522
Saisissez l'heure: 4
SRAM restant libre = 1525
Saisissez les minutes: 58
SRAM restant libre = 1487
Voulez-vous afficher les secondes ?(O/N) o
dateinitok
Jeudi 04 octobre 2018
04:58:00
SRAM restant libre = 1525
Jeudi 04 octobre 2018
04:58:01
SRAM restant libre = 1525
Jeudi 04 octobre 2018
04:58:02
SRAM restant libre = 1525
Jeudi 04 octobre 2018
04:58:03
SRAM restant libre = 1525
Jeudi 04 octobre 2018
04:58:04
SRAM restant libre = 1525
Jeudi 04 octobre 2018
04:58:05
SRAM restant libre = 1525
Jeudi 04 octobre 2018
04:58:06