Bonjour,
Je suis en train d’apprendre à utiliser l’EEPROM d’un Arduino Nano pour un petit projet dont le but est de stocker une donnée quotidiennement sur 2 années glissantes mais je rencontre de petites difficultés : Les résultats obtenus ne sont pas ceux attendu.
Je souhaite stocker une structure constituée de 2 tableaux de taille 365 contenant des entiers et une variable entière :
struct MaStructure
{
int TabYear[365];
int TabPreviousYear[365];
int NumJour;
};
Dans le setup je rempli mes tableaux et ma variable :
for (int i=0;i<365;i++)
{
ms.TabYear[i]=i;
ms.TabPreviousYear[i]=i;
}
ms.NumJour=5;
Et je stocke la structure dans l’EEPROM :
EEPROM.put(0,ms);
Dans la loop je récupère le contenu de ma structure
Mon 2eme tableau me renvoie les bonnes valeur : par ex ms.TabPreviousYear[5]=5 ; ms.TabPreviousYear[100]=100 ….. La aussi pas de soucis
Mais je rencontre des problèmes sur le premier tableau : il y a comme un décallage
o ms_lue.TabYear[0]=217
o ms_lue.TabYear[1]=218
o …..
o ms_lue.TabYear[149]=0
o ms_lue.TabYear[150]=1
o .....
J'ai essayé d'initialiser l'EEPROM avant de stocker ma structure mais ça ne change rien
Qu'est ce que j'ai raté ?
Merci pour votre aide.
Voici le programme au complet :
#include<EEPROM.h>
struct MaStructure
{
int TabYear[365];
int TabPreviousYear[365];
int NumJour;
};
void setup() {
Serial.begin(9600);
// Initialisation de l'EEPROM
for (unsigned int i = 0 ; i < EEPROM.length() ; i++) {
EEPROM.write(i, 0);
}
MaStructure ms;
for (int i=0;i<365;i++)
{
ms.TabYear[i]=i;
ms.TabPreviousYear[i]=i;
ms.NumJour=5;
}
EEPROM.put(0,ms);
delay(3000);
}
void loop()
{
MaStructure ms_lue;
EEPROM.get(0,ms_lue);
Serial.print("jour : ");
Serial.println(ms_lue.NumJour);
Serial.println("************************");
delay(2000);
for (int i=0;i<50;i++)
{
Serial.print("Tab1 : valeur ");
Serial.print(i);
Serial.print("-> ");
Serial.println(ms_lue.TabYear[i]);
delay(1000);
}
for (int i=0;i<50;i++)
{
Serial.print("Tab2 : valeur ");
Serial.print(i);
Serial.print("-> ");
Serial.println(ms_lue.TabPreviousYear[i]);
delay(1000);
}
Serial.println("************************");
delay(2000);
}
un entier soit 2 octets
Soit un ensemble de 1462 octets.
L'EEPROM intégrée dans un ATmega328 a une capacité de 1024 octets.
Donc il y a une erreur de casting.
Il faudrait réduire la quantité de données à stocker ou travailler avec une EEPROM externe.
Si tu changeais ta structure en un tableau de structures ?
struct MaStructure
{
int Year;
int PreviousYear;
int NumJour;
};
MaStructure MaStructure[365];
Tu stockes ensuite comme ceci :
MaStructure[i].Year
Ensuite
EEPROM.put(0,MaStructure);
et pour lire l'indice k, tu vas à l'adresse qui va bien : k*sizeof MaStructure
EDIT : la remarque de fdufnews est pertinente ! Il faut peut-être stocker des bytes au lieu de int, ou passer sur un ESP8266/ESP32 pour plus de mémoire
Je suis en train d'apprendre à utiliser l'EEPROM d'un Arduino Nano pour un petit projet dont le but est de stocker une donnée quotidiennement sur 2 années glissantes mais je rencontre de petites difficultés : Les résultats obtenus ne sont pas ceux attendu.
une carte SD serait peut-être plus appropriée s'il y a trop de données
Je ne sais pas pourquoi, je m'étais mis en tête que j'avais 2048 octets dispo
Forcément, ça dépend, ça dépasse
Je préférerais éviter d'utiliser un lecteur de carte SD.
j'essaye de faire un projet minimaliste.
Cette partie est vraiment la cerise sur le gâteau.
Effectivement les ESP ouvrent plus de possibilités.
Je les ai découvert récemment et suis déjà converti mais il faut bien que j'utilise la dizaine de nano que j'ai en stock
Une bonne alternative serait bien une EEPROM externe
Dans un premier temps je ne vais stocker qu'un seul tableau en mémoire. Le second ne me servira que dans 1 an après tout !
D'ici là j'aurai eut le temps de m'équiper et de faire évoluer le projet
Suivant le type de données à stocker tu peux compresser les informations pour qu'elles occupent moins de place en mémoire.
Par exemple, si les valeurs d'un jour à l'autre sont assez proches, tu pourrais ne stocker que la différence avec le jour précédent si tu es certain que celle-ci peut tenir sur un octet. Ainsi, pour simplifier le dépouillement des données, tu pourrais tout les 10 ou 20 jours sauver une valeur complète et les autres jours seulement la différence.
Il y a aussi une lacune dans ton système. Il y a des années avec 366 jours.
fdufnews:
Suivant le type de données à stocker tu peux compresser les informations pour qu'elles occupent moins de place en mémoire.
Par exemple, si les valeurs d'un jour à l'autre sont assez proches, tu pourrais ne stocker que la différence avec le jour précédent si tu es certain que celle-ci peut tenir sur un octet. Ainsi, pour simplifier le dépouillement des données, tu pourrais tout les 10 ou 20 jours sauver une valeur complète et les autres jours seulement la différence.
Interessant.
En fait mon projet consiste à relevé la capacité journalière d'une citerne à eau de pluie (capacité max 10600 L).
Mais ce volume est calculé à partir d'une distance (utilisation de capteurs ultrason).
Au lieu de stocker le résultat je pourrai peut être stocker la mesure initiale et refaire le calcul lors de l'exploitation et si ça ne suffit pas, effectivement n'enregistrer que la différence qui sera effectivement faible d'un jour à l'autre
fdufnews:
Il y a aussi une lacune dans ton système. Il y a des années avec 366 jours.
Oui je sais mais je vais faire avec. De plus j'ai 4 ans pour voir venir
J-M-L:
clarifiez ce que vous capturez. est-ce que ça a besoin d'être sur un int?
Comme dis au-dessus j’étais parti pour stocker des entiers de 0 à 10600
Je vais essayer avec des décimales de 0.0 à 180.0
Mais si on peut faire mieux en convertissant, je suis preneur.
Comment peut-on convertir ces données en bytes par exemple ?
Et cela fera t il gagner de la place ?
qu'est-ce que retourne le capteur ? une distance en cm ? si elle fait moins de 255 vous stocker cela sur un seul octet. comme vous le dites vous pouvez toujours refaire les calculs pour afficher l'info
Je suppose qu’en fonction de cela vous estimez un volume et donc cette distance influence un truc au cube (puissance 3). Quelle est la précision sur la mesure de la cuve (qui ne doit pas être un cube parfait) ? Est-ce critique pour l’historique ?
J-M-L:
Je suppose qu’en fonction de cela vous estimez un volume et donc cette distance influence un truc au cube (puissance 3).
S'il mesure un niveau dans une cuve (supposée indéformable), le volume est plutôt linéaire (ou presque) en fonction du niveau.
Mais la question sur la précision réalistement recherchée reste pertinente.
fdufnews:
Avec un capteur ultrason, je pense que le dixième est dans le bruit de mesure. Est-ce vraiment pertinent?
Quand je parle du dixième, je parle d'un chiffre après la virgule et non d'une tolérance de
0.1. J'estime à 0.5 cm mon besoin de précision.
Quant au bruit, j'ai 2 capteurs. Chacun fait 100 relevés que je moyennise.
Enfin, je calibre chaque capteur par un coef correcteur que j'évalue tous les 5 cm (la cuve était vide la semaine dernière, j'en profite pour mesurer physiquement chaque jour et appliquer la correction)
J-M-L:
Je suppose qu’en fonction de cela vous estimez un volume et donc cette distance influence un truc au cube (puissance 3). Quelle est la précision sur la mesure de la cuve (qui ne doit pas être un cube parfait) ? Est-ce critique pour l’historique ?
Il faut que je regarde l'incidence , mais utiliser la racine cubique peut être aussi une approche. Merci pour le tuyau