Sauvegarde données avec Module DS1307

Bonjour à tous,
J'ai crée un projet Arduino il y a peu de temps pour suivre ma consommation d'eau Mensuelle et Annuelle. Cela fonctionne plutôt pas mal, le seul soucis est que lorsqu'il y a une coupure de courant je perds toutes mes données. J'aimerais donc sauvegarder mes variables qui correspondent à ma consommation et ainsi être tranquille.
Pour info j'ai un module RTC DS1307 dans mon installation et j'ai vu sur certains forum que l'on pouvait sauvegarder des données sur la NVRAM de ce module. Mon problème et que l'on peut sauvegarder que des "octets" dessus et non des "Long" comme j'ai besoin. Comment puis je faire la conversion?
Y a-t-il d'autres moyens plus simple?

Merci d'avance pour vos retours.

Clément

Bonjour,

Un long c'est 4 octets, il suffit que tu sauvegarde les 4 octets qui composent le long.

Bonjour,
Merci pour la réponse rapide c'est gentil.
Par contre je ne sais pas comment convertir mon "long" en 4 octet et surtout comment le réutiliser ensuite pour le sauvegarder sur la NVRAM du module rtc DS1307.
Est ce que quelqu'un a déjà eu le soucis?
J'aimerais un exemple svp. Je débute avec l'arduino (c'est mon 1er projet) et j'ai encore un peu de mal avec toutes les fonctions de conversion et les astuces.

Merci d'avance.
Clément.

Tu n'as pas à convertir, un long c'est déjà 4 octets
Voici un exemple que j'avais écrit pour mémoriser dans l'eeprom d'une DS3231

  // mémorise la date/heure de mise à l'heure
  uint32_t dmh = nowNtp.TotalSeconds();
  RtcEeprom.SetMemory(0, (const uint8_t*)&dmh, sizeof dmh);

Merci pour l'exemple je vais essayer des que possible.
Et encore merci pour la réactivité.

Clément.

Bonsoir,
Kamill t'a répondu pour l'eeprom de la DS3231 mais pour la nvram de la DS1307 c'est un peu différent
voici un extrait de ce que j'utilise pour un int : pdsjp et un long : moyenESjour

....
ramrtc1[22] = lowByte(pdsjp);
ramrtc1[23] = highByte(pdsjp);
PointES = (byte *)&moyenESjour;        
ramrtc1[24] = *(PointES);
ramrtc1[25] = *(PointES+1);
ramrtc1[26] = *(PointES+2);
ramrtc1[27] = *(PointES+3);
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(byte (0x08));
    for (int i=0; i<=27; i++){
        Wire.write(ramrtc1[i]);
    } 
Wire.endTransmission();

Bonsoir rjnc38,
Ca dépend quelle librairie tu utilises.
Personnellement j'utilise la librairie Rtc_by_Makuna et il existe une fonction pour écrire dans la ram de la ds1307 équivalente à la fonction pour écrire dans l'eeprom du ds3231

   uint8_t SetMemory(uint8_t memoryAddress, const uint8_t* pValue, uint8_t countBytes)

Je ne l'ai pas essayée.
Mais bien sur tu peux le faire 'à la main' comme tu le proposes.

effectivement Kamill à l'époque j'avais géré ma RTC complétement "à la mano"
je viens de regarder la lib adafruit propose bien 2 fonctions pour la ram

void readnvram(uint8_t* buf, uint8_t size, uint8_t address);
void writenvram(uint8_t address, uint8_t* buf, uint8_t size);

et en utilisant une structure mon code perdrait quelques dizaines de lignes ....

Bonjour,
Je viens d'essayer les solutions que vous m'avez donné et cela à l'air de très bien fonctionner.

Merci pour votre aide cela m'a bien servi

Clément.

   // Ecrire dans la NVRAM du Module DS1307
  TotalPulseMem = TotalPulse;
  RTC.writenvram(24, (const uint8_t*)&TotalPulseMem, sizeof TotalPulseMem);
  TotalPulseMoisMem = TotalPulseMensuel;
  RTC.writenvram(28, (const uint8_t*)&TotalPulseMoisMem, sizeof TotalPulseMoisMem);
  // Fin Ecriture dans la NVRAM
 // Lire dans la NVRAM du Module DS1307
 uint8_t readData[4] = {0};
  RTC.readnvram(readData, 4, 24);
  Serial.println(readData[0], HEX);
  Serial.println(readData[1], HEX);
  Serial.println(readData[2], HEX);
  Serial.println(readData[3], HEX);
  ArrayToInteger converter1 = {readData[0],readData[1],readData[2],readData[3]}; //Create a converter
  TotalPulse = converter1.integer;

  readData[4] = {0};
  RTC.readnvram(readData, 4, 28);
  ArrayToInteger converter2 = {readData[0],readData[1],readData[2],readData[3]}; //Create a converter
  TotalPulseMensuel = converter2.integer;
  // Fin Lecture dans la NVRAM

Bonjour,

Tu t'es bien embêté, il suffisait de faire

  // écriture
  RTC.writenvram(28, (const uint8_t*)&TotalPulseMensuel, sizeof TotalPulseMensuel);
  // lecture
  RTC.readnvram((const uint8_t*)&TotalPulseMensuel, sizeof TotalPulseMensuel, 28);

Bonjour

Lorsque l'on utilise la nvram du DS1307, c'est pour sauvegarder une valeur de manière permanente, même lorsque l'arduino est éteint.

Mais la nvram du DS1307 reste une ram, c'est-à-dire qu'elle a besoin d'une tension d'alimentation permanente.
Lorsque l'arduino est mis hors tension, c'est la pile qui prend le relais, tant qu'elle a du jus.

Au démarrage de l'arduino, lors de la première lecture de la nvram, il vaut mieux s'assurer que ce qui est lu est bien valide.

Perso j'ai l'habitude de toujours stocker une valeur constante dans les premiers octets, qui me sert de clé de vérification. Si la première lecture retourne bien la constante attendue, c'est que la mémoire est intègre.

" Si la première lecture retourne bien la constante attendue, c'est que la mémoire est intègre."

Je vais faire mon puriste:
Ca peut signifier que la mémoire est corrompue, mais qu'on a eu de la chance avec le première donnée. Les suivantes peuvent être pires... selon les lois de Murphy.

Par contre, si on ne reçoit pas la constante attendue, on est sûr qu'il y a un problème et que la mémoire a flanché.

"corrompue" n'est peut-être pas le bon terme.

Le test permet de savoir si la pile a bien fonctionné pendant la mise hors tension de l'arduino.
Sans pile ou avec une pile hs, le RTC perd l'intégralité du contenu de sa ram (dont la date et l'heure dans les premiers octets).

Cela m'étonnerait qu'il soit possible que seulement la moitié des 64 octets de la ram puissent être perdus. C'est du tout ou rien.

Bon, je vais supposer que, lors de la perte de l'intégralité du contenu de la RAM, la RAM se remplit avec des valeurs aléatoires... (ça dépend de la technologie du moment...)
Il y a alors, si ces valeurs aléatoires n'ont pas de valeur préférentielle, une chance sur 256 que le premier octet ait pour valeur celle qui vous sert à détecter la corruption de ladite RAM. (donc, votre test a 4 chances sur 1000 de ne pas détecter une corruption de la RAM.... on est bien obligé d'admettre qu'il n'est pas infaillible -après, c'est une affaire de goût de décider si on peut vivre avec ou pas)

Bonjour,

bricoleau n'a pas dit qu'il écrivait un octet mais une valeur constante sur les premiers octets.
Si on écrit un double mot judicieusement choisit par exemple 55aaaa55 il n'y a pratiquement aucune chance qu'un problème ne soit pas détecté.

Avec 4 octets, vous avez une chance sur 4 E9 de rater une corruption de mémoire ( si vos fabricants de disques disaient que c'est pratiquement nul -ce qui a l'air vrai- , vous seriez bien malheureux avec vos disques)

J'aime bien DEADBEEF

Mais on peut aussi y coller un CRC16.