bad results when using complex structure

Hello, again a new blocking problem when using complex structures :

first of all, I use MEGA2560 in IDE1.0.5 because some librairies in my project don’t work properly in IDE 1.6.2 so I can’t use the new eeprom functions used with structure !!
I have written my own functions to be able to use eeprom with my structures…

I try to initiate a structure named profil_1 with a given value for lundi.plage1 :
HeurDeb=0, HeurFin=1439, Cons=19,00
others plage are razed to 0 … init is OK but I have a (big!) pb :

here below is my (simplified) working code : all is nice except I can’t succeed to use 2 functions :

function ecrire_plage : the variable k is supposed to contain the value HeurDeb so after init, k should be 0 … but it desesperatly remains to 255 why ???

the code used for ecrire_plage () is the same as for init_plage () and is is working for init_plage…

note : a very curious thing is if you suppress the word struct in the declaration of init_plage (), it does’nt compile but if you suppress in raz_plage () it compiles !! why ???

exemple not compiling :

void init_plage (Plage *beach)  // init plage à 19°
{   beach->HeurDeb=0; beach->HeurFin=1439; beach->Consigne=19; }
void raz_plage (struct Plage *beach)  // plage non utilisée (cons=0)
{   beach->HeurDeb=0; beach->HeurFin=1439; beach->Consigne=0; }

exemple compiling :

void init_plage (struct Plage *beach)  // init plage à 19°
{   beach->HeurDeb=0; beach->HeurFin=1439; beach->Consigne=19; }
void raz_plage (Plage *beach)  // plage non utilisée (cons=0)
{   beach->HeurDeb=0; beach->HeurFin=1439; beach->Consigne=0; }

the working code :

#include <EEPROM.h>

typedef struct Plage {//Structure pour plage horaires ( 8 bytes) - Heur en nb de min (timestamp)
int    HeurDeb; int    HeurFin; float    Consigne; };

typedef struct Jour {//Structure pour Jour (8 plages = 64 bytes)
Plage    plage1;  Plage    plage2;  Plage    plage3;  Plage    plage4;
Plage    plage5;  Plage    plage6;  Plage    plage7;  Plage    plage8;};

typedef struct Profil {//Structure pour Profil (7 jours = 448 bytes)
Jour    lundi; Jour    mardi; Jour    mercredi;  Jour jeudi;  Jour   vendredi;  Jour    samedi;  Jour    dimanche; };

//*****************************************************************************************
//*                             Declaration variables                                     * 
//*****************************************************************************************
// general

// index de travail k,l,choix
byte k=0;
byte l;
byte choix = 0;                 // variable de travail (ex page WEB)

// def profils pour programmation
struct Profil profil_1;
struct Profil profil_2;

// def mode regulation
byte  choix_profil = 0;  // 0 par defaut, 1 ou 2 sinon

// -------------------------- ROUTINES ---------------------------------------------------


void init_plage (struct Plage *beach)  // init plage à 19°
{   beach->HeurDeb=0; beach->HeurFin=1439; beach->Consigne=19; }
void raz_plage (struct Plage *beach)  // plage non utilisée (cons=0)
{   beach->HeurDeb=0; beach->HeurFin=1439; beach->Consigne=0; }

void raz_profil (byte prof) {
  if (prof == 1)
  {
           init_plage(&profil_1.lundi.plage1);
        raz_plage(&profil_1.lundi.plage2); raz_plage(&profil_1.lundi.plage3); raz_plage(&profil_1.lundi.plage4);
        raz_plage(&profil_1.lundi.plage5); raz_plage(&profil_1.lundi.plage6); raz_plage(&profil_1.lundi.plage7);
        raz_plage(&profil_1.lundi.plage8);

// etc for other plages 
     
  }
  else // profil=2
  {
     
  }  
}

/* les fonctions EEPROM.get et EEPROM.put sont dispo avec l'IDE 1.6.2
 mais il y a des pbs de fonctionnement a verifier donc continuer avec l'IDE 1.0.5 en attendant */
 

// lecture d'un float en eeprom
float readFloat(unsigned int addr) {
union  { byte b[4]; float f; } data;  
 for(int i = 0; i < 4; i++) data.b[i] = EEPROM.read(addr+i);
 return data.f; }
 
 // ecriture d'un float en eeprom
float writeFloat(int addr, float x) {
union  { byte b[4]; float f; } data;
 data.f = x;
 for(int i = 0; i < 4; i++) EEPROM.write(addr+i, data.b[i]);  } 
 


void ecrire_plage (int adr, struct Plage *beach) {  // 8 bytes
int k = beach->HeurDeb;
Serial.print (" k="); Serial.print(k);
Serial.print (" k1="); Serial.print(beach->HeurDeb);
    EEPROM.write(adr++,lowByte(beach->HeurDeb));
    EEPROM.write(adr++,highByte(beach->HeurDeb));
    EEPROM.write(adr++,lowByte(beach->HeurFin));
    EEPROM.write(adr++,highByte(beach->HeurFin));
     Serial.print (" adr ecr="); Serial.print (adr); Serial.print (" val deb ="); Serial.print (lowByte(beach->HeurDeb)); Serial.println (highByte(beach->HeurDeb));    
    writeFloat (adr, beach->Consigne); 
    // version IDE 1.6     EEPROM.put(adr,beach->Consigne); // ecire de +4 a +7 Consigne
}

void lire_plage (int adr, struct Plage *beach) {  // 8 bytes
  byte loByte=EEPROM.read(adr++);
  byte hiByte=EEPROM.read(adr++);
  beach->HeurDeb = word(hiByte, loByte);
      Serial.print ("adr lue="); Serial.print (adr); Serial.print (" val deb lue ="); Serial.print (loByte); Serial.println (hiByte);
  loByte=EEPROM.read(adr++);
  hiByte=EEPROM.read(adr++);
  beach->HeurFin = word(hiByte, loByte);
     Serial.print ("adr lue="); Serial.print (adr); Serial.print (" val fin lue ="); Serial.print (loByte); Serial.println (hiByte);  
  beach->Consigne = readFloat(adr);
// version IDE 1.6
//    EEPROM.get(adr,beach->HeurDeb);
//    EEPROM.get(adr+2,beach->HeurFin);
//    EEPROM.get(adr+4,beach->Consigne);   
}


void ecrire_profil (byte prof) { // adr profil 1 =500  profil 2 = 1000)
  if (prof == 1)
  {
    int adr=500;
  // IDE 1.6 EEPROM.put(500,profil_1);
    ecrire_plage(adr,&profil_1.lundi.plage1);
//    ecrire_plage(adr+8,&profil_1.lundi.plage2); ecrire_plage(adr+16,&profil_1.lundi.plage3); ecrire_plage(adr+24,&profil_1.lundi.plage4);
//    ecrire_plage(adr+32,&profil_1.lundi.plage5); ecrire_plage(adr+40,&profil_1.lundi.plage6); ecrire_plage(adr+48,&profil_1.lundi.plage7); ecrire_plage(adr+56,&profil_1.lundi.plage8);   
    Serial.println ("profil 1 ecrit");
  }
  else // profil=2
  { 
  // IDE 1.6 EEPROM.put(1000,profil_2);
 
    Serial.print("profil 2 ecrit");
  }  
}

void lire_profil (byte prof) { // adr profil 1 =500  profil 2 = 1000)
  if (prof == 1)
  {
    int adr=500;    
//  EEPROM.get(500,profil_1);
    lire_plage(adr,&profil_1.lundi.plage1);
//    lire_plage(adr+8,&profil_1.lundi.plage2); lire_plage(adr+16,&profil_1.lundi.plage3); lire_plage(adr+24,&profil_1.lundi.plage4);
//    lire_plage(adr+32,&profil_1.lundi.plage5); lire_plage(adr+40,&profil_1.lundi.plage6); lire_plage(adr+48,&profil_1.lundi.plage7); lire_plage(adr+56,&profil_1.lundi.plage8);
    Serial.print("profil 1 ");
Serial.print("deb lu :"); Serial.print (profil_1.lundi.plage1.HeurDeb);
Serial.print(" fin lu :"); Serial.print (profil_1.lundi.plage1.HeurFin);
Serial.print(" cons lu :"); Serial.println (profil_1.lundi.plage1.Consigne);   
  }
  else // profil=2
  {
//    EEPROM.get(1000,profil_2);
    Serial.print("profil 2 lu");
  }  
}



// ************** initialisation **********************************************************************************************************init****
//**************************************************************************************************************************************************
void setup() 
{
// init liaison serie
    Serial.begin(9600);
// affichage version  
Serial.print (F("ARTI SYSTEM "));

  raz_profil(1);

Serial.println ("test init plage1 ");
Serial.print (" deb "); Serial.print (profil_1.lundi.plage1.HeurDeb);
Serial.print (" fin "); Serial.print (profil_1.lundi.plage1.HeurFin);
Serial.print (" lowbytefin "); Serial.print (lowByte(profil_1.lundi.plage1.HeurFin));
Serial.print (" cons ");Serial.println (profil_1.lundi.plage1.Consigne);

// test profil
  lire_profil (1);
  ecrire_profil (1);
  delay(1000);  
  lire_profil (1);
  for (;;);  // infinite   
     
}

// ************** boucle principale ********
void loop()                     
{
}

You have some code that compiles fine, and you show us that code.

You have some code that does not compile, but you don't show us that or the error messages.

We can't help without knowing what the problem is.

exact Paul ! so the bad code is the same as the correct one, except when I suppress the struct in the following line :

void init_plage (struct Plage *beach) // init plage à 19°

the error message is : debug: 4 : error : variable or field 'init_plage' declared void

but it is no so boring ... just I want to undestand why as when I suppress same word in the function raz_profil (while I keep init_plage unchanged) , there is no error... it is not logical...

but the real big problem is the one described in my post :

-> why my variable *beach seems bad initialized in the function ecrire_plage as it is well initiated in the function init_plage... the two functions are exactly coded the same way...

I would really appreciate if someone could check the code above and found some way to fix this bug...I have really checked in all directions and I begin to loose my last hair...

It's simply the IDE helping to simplfy the programming experience for the new and uninitiated by preprocessing your code before passing it to the real preprocessor and compiler.

Move the structure definitions to header files, include them in main .ino sketch file and you'll be happier.

thanks Paul ! compiling is nice now with header.h containing the typedef struct statements ...

more of that, I can suppress the word "struct" from any declaration of instance in the main sketch by using directly the name of the struct ...

now the main problem remains : the code is always not working fine : try my previous (very simple) code and you will find that result is always "-1" for k variable ... it should be obviously "0"

I can't understand where is the trick, and why this parameter is bad transmitted to the function ecrire_plage and well transmitted to others....

sorry, Thanks Lloyddean I mean…

to help, here is a new simplified code which have the same problem… here is the pb again :

after init , &profil_1.lundi.plage1 contains 0

why after calling the function ecrire_plage with parameters (500, &profil_1.lundi.plage1) the local parameter Plage *beach contains always a bad value = 255 or (-1) ???

#include <EEPROM.h>

//Structure pour plage horaires ( 8 bytes) - Heur en nb de min (timestamp)
typedef struct Plage {int    HeurDeb; };

//Structure pour Jour (8 plages = 64 bytes)
typedef struct Jour {Plage    plage1;  };

//Structure pour Profil (7 jours = 448 bytes)
typedef struct Profil {Jour    lundi;  };

// def profils pour programmation
Profil profil_1;

// -------------------------- ROUTINES ---------------------------------------------------
void init_plage ( struct Plage *beach)  // init plage à 19°
{   beach->HeurDeb=0;  }

void raz_plage ( struct Plage *beach)  // plage non utilisée (cons=0)
{   beach->HeurDeb=0;  }

void raz_profil () {
  init_plage(&profil_1.lundi.plage1);   }

void ecrire_plage (int adr, Plage *beach) {  // 8 bytes
int k = beach->HeurDeb;
Serial.print (" k="); Serial.print(k);
Serial.print (" k1="); Serial.println(beach->HeurDeb);
    EEPROM.write(adr++,lowByte(beach->HeurDeb));
    EEPROM.write(adr++,highByte(beach->HeurDeb));
     Serial.print ("ecriture adr="); Serial.print (adr); Serial.print (" val ="); Serial.print (lowByte(beach->HeurDeb)); Serial.println (highByte(beach->HeurDeb));    
}

void lire_plage (int adr, Plage *beach) {  // 8 bytes
  byte loByte=EEPROM.read(adr++);
  byte hiByte=EEPROM.read(adr++);
  beach->HeurDeb = word(hiByte, loByte);
      Serial.print ("lecture adr ="); Serial.print (adr); Serial.print (" val ="); Serial.print (loByte); Serial.println (hiByte);     
}

void ecrire_profil () { // adr profil 1 =500  profil 2 = 1000)
    ecrire_plage(500,&profil_1.lundi.plage1);
    Serial.println("profil 1 ecrit"); 
}

void lire_profil () { // adr profil 1 =500  profil 2 = 1000)  
    lire_plage(500,&profil_1.lundi.plage1);
    Serial.print("profil 1 lu :");
Serial.println (profil_1.lundi.plage1.HeurDeb);    
}

// ***** init
void setup() 
{
// init liaison serie
    Serial.begin(9600);
  raz_profil();

Serial.println ("test init plage1 ");
Serial.print (" HeurDeb= "); Serial.println (profil_1.lundi.plage1.HeurDeb);


// test profil
  lire_profil ();
  ecrire_profil ();
  delay(1000);  
  lire_profil ();
  for (;;);  // infinite   
     
}

// ************** boucle principale ********
void loop()                     
{
}

wowh !!!!!!!!! I apologize.... all is absolutly normal and LOGICAL !!!

as I read eeprom BEFORE to write the eeprom, result is 255 so no more problem ...

I think I need some quiet hours without any programming activies... anyway, thanks for all as I understand a little more the fabulous word of structures...