Voila je suis nouveau dans le monde d'arduino, d'ailleurs je dois recevoir le mien mardi..
Bref je suis en train de m'improviser codeur, sauf que j'aurais souhaité enregistrer deux valeurs différentes dans l'eeprom interne. J'ai trouvé un tuto pour écrire un int, sauf que je n'ai pas du tout comprendre.
Quand je compile j'ai un problème, voici le code utilisé, j'ai gardé l'essentiel concernant cette fonction, en réalité ma sauvegarde est lancé par un interrupteur précédemment à la mise hors tension de l'arduino et non en boucle comme dans le code suivant) et biensur ces valeurs changent lors de l'utilisation de l'arduino...
#include <EEPROM.h>
int boutdeligne = 920; // position du bout de la ligne
int positionpoursauv = 823;
int adressePosition = 0;
int adresseboutdeligne = 100;
void setup() {
int lecturePosition(int adressePosition)
{
unsigned char fort = EEPROM.read(adressePosition); //récupère les 8 bits de gauche (poids fort) -> 1101 0111
unsigned char faible = EEPROM.read(adressePosition+1); //récupère les 8 bits de droite (poids faible) -> 0010 1100
//assemblage des deux variable précédentes
x = fort ; // val vaut alors 0000 0000 1101 0111
x = x << 8 ; // val vaut maintenant 1101 0111 0000 0000 (décalage)
x = x | faible ; // utilisation du masque
// calcul : 1101 0111 0000 0000 | 0010 1100 = 1101 0111 0010 1100
return x ; //on n’oublie pas de retourner la valeur lue !
}
int lectureBoutdeligne(int adresseboutdeligne)
{
unsigned char fort = EEPROM.read(adresseboutdeligne); //récupère les 8 bits de gauche (poids fort) -> 1101 0111
unsigned char faible = EEPROM.read(adresseboutdeligne+1); //récupère les 8 bits de droite (poids faible) -> 0010 1100
//assemblage des deux variable précédentes
boutdeligne = fort ; // val vaut alors 0000 0000 1101 0111
boutdeligne = boutdeligne << 8 ; // val vaut maintenant 1101 0111 0000 0000 (décalage)
boutdeligne = boutdeligne | faible ; // utilisation du masque
// calcul : 1101 0111 0000 0000 | 0010 1100 = 1101 0111 0010 1100
return boutdeligne ; //on n’oublie pas de retourner la valeur lue !
}
}
void loop() {
// put your main code here, to run repeatedly:
sauvegardePosition();
sauvegardeBoutdeligne();
}
void sauvegardePosition(adressePosition, int positionpoursauv)
{
//découpage de la variable val qui contient la valeur à sauvegarder en mémoire
unsigned char faible = positionpoursauv & 0x00FF; //récupère les 8 bits de droite (poids faible) -> 0010 1100
//calcul : 1101 0111 0010 1100 & 0000 0000 1111 1111 = 0010 1100
unsigned char fort = (positionpoursauv >> 8) & 0x00FF; //décale puis récupère les 8 bits de gauche (poids fort) -> 1101 0111
//calcul : 1101 0111 0010 1100 >> 8 = 0000 0000 1101 0111 puis le même & qu’avant
//puis on enregistre les deux variables obtenues en mémoire
EEPROM.write(adressePosition, fort) ; //on écrit les bits de poids fort en premier
EEPROM.write(adressePosition+1, faible) ; //puis on écrit les bits de poids faible à la case suivante
}
void sauvegardeBoutdeligne(adresseboutdeligne, int boutdeligne)
{
//découpage de la variable val qui contient la valeur à sauvegarder en mémoire
unsigned char faible = boutdeligne & 0x00FF; //récupère les 8 bits de droite (poids faible) -> 0010 1100
//calcul : 1101 0111 0010 1100 & 0000 0000 1111 1111 = 0010 1100
unsigned char fort = (boutdeligne >> 8) & 0x00FF; //décale puis récupère les 8 bits de gauche (poids fort) -> 1101 0111
//calcul : 1101 0111 0010 1100 >> 8 = 0000 0000 1101 0111 puis le même & qu’avant
//puis on enregistre les deux variables obtenues en mémoire
EEPROM.write(boutdeligne, fort) ; //on écrit les bits de poids fort en premier
EEPROM.write(boutdeligne+1, faible) ; //puis on écrit les bits de poids faible à la case suivante
}
Et voici les erreurs lors de la compilation
test_eeprom:6: error: variable or field 'sauvegardePosition' declared void
test_eeprom:6: error: 'adressePosition' was not declared in this scope
test_eeprom:6: error: expected primary-expression before 'int'
test_eeprom:7: error: variable or field 'sauvegardeBoutdeligne' declared void
test_eeprom:7: error: 'adresseboutdeligne' was not declared in this scope
test_eeprom:7: error: expected primary-expression before 'int'
test_eeprom.ino: In function 'void setup()':
test_eeprom:11: error: a function-definition is not allowed here before '{' token
test_eeprom:25: error: a function-definition is not allowed here before '{' token
test_eeprom.ino: In function 'void loop()':
test_eeprom:39: error: 'sauvegardePosition' was not declared in this scope
test_eeprom:40: error: 'sauvegardeBoutdeligne' was not declared in this scope
test_eeprom.ino: At global scope:
test_eeprom:43: error: variable or field 'sauvegardePosition' declared void
test_eeprom:43: error: expected primary-expression before 'int'
test_eeprom:58: error: variable or field 'sauvegardeBoutdeligne' declared void
test_eeprom:58: error: expected primary-expression before 'int'
variable or field 'sauvegardePosition' declared void
Rien ne va, mais je ne trouve pas ce qu'il manque, ou cloche en tout cas, si quelqu'un peut me mettre sur la piste !
Je t'avouerais que je n'ai pas tout saisit ni réussit à résoudre mes problèmes, ne me décourageant pas j'ai trouvé un autre tutoriel qui m'a semblé plus clair, et que j'ai compris ! (alors que celui que j'ai partagé, j’avoue que j'étais souvent largué)
Dans tous les cas, je suis arrivé à l'intégrer et sauvegarder les deux données que je souhaitais, le compilateur ne me retourne en tout cas aucune erreur.
Plus qu'à essayer avec l'arduino pour valider le tout !
Je te remercie
PS: je ne sais pas s'il est intéressant que je partage le bout de code qui fonctionnerait à priori ? dites moi
Voici le code que j'ai adapté, ici j'ai enlevé tout le reste du code qui n'a rien à voir ainsi que l'enregistrement d'une 2eme variable sur le même principe
#include <EEPROM.h>
int x = 0; // position en cours, ou reprise de la dernière position enregistré au lancement de l'arduino
int positionpoursauv = 0; //stockage de la position pour sauvegarde
void EEPROMWritelong(long adress, int value){
byte two = (value & 0xFF);
byte one = ((value >> 8) & 0xFF);
EEPROM.write(adress, two);
EEPROM.write(adress + 1, one);
}
int EEPROMReadlong(long address){
//Read the 4 bytes from the eeprom memory.
long two = EEPROM.read(address );
long one = EEPROM.read(address + 1);
//Return the recomposed long by using bitshift.
long positionpoursauv = ((two << 0) & 0xFFFFFF) + ((one << 8) & 0xFFFFFFFF);
}
void setup() {
// lecture au démarrage de l'arduino du x de la dernière sauvegarde
x = EEPROMReadlong(0);
}
void loop() {
// suite à une action (inter)
//reprise du nouveau x pour nouvelle sauvegarde
positionpoursauv = x;
long address;
// ecriture de la nouvelle position
EEPROMWritelong(address, positionpoursauv);
}
Du coup je suis passé sur l'enregistrement d'un long... même si un int aurait suffit (x ne pouvant pas excéder 1500), si ça pose pas de problème je garde (et si ça marche)
#include <EEPROM.h>
int x = 0; // position en cours, ou reprise de la dernière position enregistré au lancement de l'arduino
int positionpoursauv = 0; //stockage de la position pour sauvegarde
int x2 = 0; // position en cours, ou reprise de la dernière position enregistré au lancement de l'arduino
int positionpoursauv2 = 0; //stockage de la position pour sauvegarde
void EEPROMWriteInt(int adress, int value){
byte two = (value & 0xFF);
byte one = ((value >> 8) & 0xFF);
EEPROM.write(adress, two);
EEPROM.write(adress + 1, one);
}
int EEPROMReadInt(int address){
//Read the 4 bytes from the eeprom memory.
int two = EEPROM.read(address );
int one = EEPROM.read(address + 1);
//Return the recomposed int by using bitshift.
int x = ((two << 0) & 0xFFFFFF) + ((one << 8) & 0xFFFFFFFF);
}
int EEPROMReadInt2(int address){
//Read the 4 bytes from the eeprom memory.
int two = EEPROM.read(address );
int one = EEPROM.read(address + 1);
//Return the recomposed int by using bitshift.
int x2 = ((two << 0) & 0xFFFFFF) + ((one << 8) & 0xFFFFFFFF);
}
void setup() {
// lecture au démarrage de l'arduino du x de la dernière sauvegarde
EEPROMReadInt(0);
EEPROMReadInt2(2);
}
void loop() {
// suite à une action (inter)
//reprise du nouveau x pour nouvelle sauvegarde
positionpoursauv = x;
int address;
// ecriture de la nouvelle position
EEPROMWriteInt(address, positionpoursauv);
address+=2;
positionpoursauv2 = x2;
// ecriture de la nouvelle position
EEPROMWriteInt(address, positionpoursauv2);
}
D'ailleurs j'ai repéré une possible erreur, dans la fonction de lecture, le résultat de la lecture s'enregistrer dans la variable pour la sauvegarde et non respectivement dans x (et x2 pour l'exemple de la 2eme variable).
L'appel des fonctions de lecture dans le setup est-il correct ?
Merci de prendre le temps de m'expliquer les choses, en espérant ne pas avoir compris de travers
Effectivement, il y a un hic ! je suis focalisé sur le reste et je n'avais pas vu.
Je propose cela, je n'ai pas résolu les soucis je pense, je suis reparti de ce que j'avais trouvé sur le tuto pour y mettre mes 2 valeurs à stocker.
Je sais pas si ce que j'ai fait : EEPROMWritePosition(adress, value, value2) est possible pour passer mes deux valeurs dans la même fonction d'écriture
Je ne désespère pas d'arriver à sortir quelque chose qui marche
#include <EEPROM.h>
int x = 0; // position en cours, ou reprise de la dernière position enregistré au lancement de l'arduino
int positionpoursauv = 0; //stockage de la position pour sauvegarde
int x2 = 0; // position en cours, ou reprise de la dernière position enregistré au lancement de l'arduino
int positionpoursauv2 = 0; //stockage de la position pour sauvegarde
void EEPROMWritePosition(int adress, int value, int value2){
byte four = (value2 & 0xFF);
byte three = ((value2 >> 8) & 0xFF);
byte two = ((value >> 16) & 0xFF);
byte one = ((value >> 24) & 0xFF);
EEPROM.write(address, four);
EEPROM.write(address + 1, three);
EEPROM.write(address + 2, two);
EEPROM.write(address + 3, one);
}
int EEPROMReadPosition(int address){
int four = EEPROM.read(address);
int three = EEPROM.read(address + 1);
int two = EEPROM.read(address + 2);
int one = EEPROM.read(address + 3);
int x = ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF)
int x2 = ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF)
}
void setup() {
// lecture au démarrage de l'arduino du x de la dernière sauvegarde
EEPROMReadPosition(0);
}
void loop() {
// suite à une action (inter)
//reprise du nouveau x et x2 pour nouvelles sauvegardes
positionpoursauv = x;
positionpoursauv2 = x2;
int address;
// ecriture des deux positions
EEPROMWritePosition(address, positionpoursauv, positionpoursauv2);
}
J'ai bien conscience que mes connaissances sont très très limités, c'est à dire finalement proche de zéro dès que ça dépasse les fonctions les plus classiques (j'avais un peu potassé le C, quand j'étais ado, cela fait quelques années ...)
Quand je vois les possibilités "pratique" de l'arduino et de sa programmation, cela va me donner envie de m'y replonger, sans nul doute ! Et reprendre depuis les bases
Mais la je suis confronté à ce programme, ce dernier point (la sauvegarde) étant le point final des fonctions nécessaire à ma machine, machine qui est pour un usage professionnel.
Ce n'est pas une raison je sais, mais la je ne peux vraiment pas me permettre de me replonger dans mes livres pour revoir les bases et arriver à écrire ce genre de fonctions les yeux fermés, enfin si, je vais le faire un peu le soir en rentrant, mais dans ce cas je n'ose imaginer le délais nécessaire pour mettre en route ma machine avec cette dernière fonction qui me fait coincer.
Bref je comprend que tu te demandes où je vais, vu comme je galère grave ! Je te remercie en tout cas pour toutes les réponses précédentes, mais il va falloir que j'arrive à sortir cette satané sauvegarde
Pour finir, je crois que je vais repartir sur des fonctions séparés pour chaque valeur, le code (s'il marche un jour, lol) sera plus lourd mais comme tu dis, inutile de compliquer ce qu'il l'est déjà (pour moi)
juste pour faire part d'une solution que j'ai trouvé et qui fonctionne (plus facile à vérifier maintenant que j'ai l'arduino)
le code pour enregistrer
void sauverInt(int adresse, int val)
{
//découpage de la variable val qui contient la valeur à sauvegarder en mémoire
unsigned char faible = val & 0x00FF; //récupère les 8 bits de droite (poids faible)
unsigned char fort = (val >> 8) & 0x00FF; //décale puis récupère les 8 bits de gauche (poids fort)
//puis on enregistre les deux variables obtenues en mémoire
EEPROM.write(adresse, fort) ; //on écrit les bits de poids fort en premier
EEPROM.write(adresse+1, faible) ; //puis on écrit les bits de poids faible à la case suivante
}
et pour lire
int lireInt1(int adresse)
{
int val1 = 0 ; // int, vide qui va contenir le résultat de la lecture
unsigned char fort = EEPROM.read(adresse); //récupère les 8 bits de gauche (poids fort)
unsigned char faible = EEPROM.read(adresse+1); //récupère les 8 bits de droite (poids faible)
//assemblage des deux variable précédentes
val1 = fort ;
val1 = val1 << 8 ;
val1 = val1 | faible ;
boutdeligne = val1;
}
J'ai un gros problème de compréhension avec la lecture/écriture dans l'EEPROM.
Si je mets de coté la nouvelle bibliothèque, qui en fait n'est là qu'à cause de l'EEprom plus ou moins virtuelle de Zéro/M0, il y a tout ce qu'il faut dans l'avr-libc.
Mais qu'ont donc ces fonctions Atmel pour qu'arduino n'en utilise qu'une seule et encore il l'encapsule dans une classe pour éviter l'usage d'un pointeur.
Il y a tout :
octet = uint8_t
word -> deux octet =uint16_t = integer celon gcc
dword -> quatre octets = uint32_t = long integer
float
et
block
Qu'est-ce qu'ont ces fonctions pour que personne ne les utilise?
Pourquoi ne pas utiliser la librairie EEPROMex qui gère nativement beaucoup plus de types de variables ?
Sinon, tu peux t'inspirer des méthodes utilisées dans la librairie...