Weirdest thing happening!

Hello everyone!

I'm apologising by advance for my english and my poor skills in C++.

Here is the plot : I'm trying to create a controller for glass and ceramic ovens. To stock all the cooking and controlling parameters sent by the computer I have a library called "controleurs" that contains all the necessary functions for saving or returning parameters. This parameters are saved into two arrays depending on if they are parameters of my controler or for my heat sensors.... (controltab[] or poidsthermo[]) and since I couldn't find an easy way for multidimensional arrays in just put successively all my parameters and use some index to get to the needed ones.

Now the weirdest thing is happening, the data "poids" is correctly saved into the array since the monitor returns the correct value. But when I use the function "setrelaistype()" (that have absolutely nothing to do with "poids" since one is working on controltab[] and the other on poidsthermo[]) the "poids" data is erased....

            Serial.println(controleurs.getpoids(1,counter2));
            controleurs.setrelaistype(counter2,relaistype);
           Serial.println(controleurs.getpoids(1,counter2));

monitor :

0.40
0.00

setrelaistype and getpoids functions

void Controleurs::setrelaistype(int numcontroleur,int relaistype){
     controltab[(numcontroleur*5)-4]=relaistype;
}

double Controleurs::getpoids(int numth,int numcont){

  int a=(numth-1)*(nbcont+1)-1+numcont;
  return poidsthermo[a];

}

Weird behaviour often needs the whole code to be explained. Could you post it?

I expect your functions go beyond array boundaries and write in the memory where the other arrays lies..
But it can also be an out of RAM error

Yeah sure!

I have tried moving the code lines to see where was the problem and it's giving me the same kind of mistakes in different configuration, like you said it must be a memory out of bounds problem.

so here is the code and the "controleurs" class following

#include <PID_v1.h>



#include <Controleurs.h>

#include <CmdMessenger.h>

#include <Courbedecuisson.h>

#include <Streaming.h>


// on définie les separateurs dans le message et le separateur de commande
char field_separator=' ';
char command_separator=';';


// On attache l'objet cmdMessenger au port Serie;
CmdMessenger cmdMessenger= CmdMessenger(Serial,field_separator, command_separator);


Courbedecuisson courbe=Courbedecuisson(4);
Controleurs controleurs=Controleurs(1,2);
int thermos[5];//tableau contenant le numéro du pin auquel le thermocouple est branché
int relais[5];// tableau contenant le numéro du digital pin auquel le relais est branché
int nbth; //Nb de thermocouples utilisés
int nbcont; //Nb de contrôleur=de relais
int dmesure; //à quel intervalle relever la température
double Tp;
double Treel;
unsigned long temps;
double Input, Output, Setpoint;

PID pid1(&Treel, &Output, &Tp,3,4,1,DIRECT);
PID pid2(&Treel, &Output, &Tp,3,4,1,DIRECT);
PID pid3(&Treel, &Output, &Tp,3,4,1,DIRECT);
PID pid[]= {pid1,pid2,pid3}  ; // tableau contenant le PID correspondant à chaque controleur
int segmentcourant=1; // Segment de courbe sur lequel on se trouve à l'instant t

int WindowSize = 5000; //en ms
unsigned long windowStartTime;



//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ METHODES APPELEE PAR LES COMMANDES_ _ _ _ _ _ _  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __  _ _ _ _ _ _ _
//
//




void DonneesCourbe(){ //cette méthode récupère les paramètres envoyés par l'interface et les assignent à leurs places dans la matrice Courbedecuisson

double a,b,t1,t2;
int nbsegments=cmdMessenger.readInt();
courbe=Courbedecuisson(nbsegments);
int counter=1;

  char buf[10];
       
        
      while (counter<=courbe._nbsegments){// ajoute les segments à la courbe de cuisson
   
      while (cmdMessenger.available()){
       
        cmdMessenger.copyString(buf,10);
        Serial.println(a=atof(buf));       
        cmdMessenger.copyString(buf,10);
         b=atof(buf);
        cmdMessenger.copyString(buf,10);
        t1=atof(buf);
        cmdMessenger.copyString(buf,10);
        t2=atof(buf);

        courbe.addsegment(counter,a,b,t1,t2);
        counter++;
      }
      
    }
    Serial.println(courbe.geta(1));
    Serial.println(courbe.getb(1));
    Serial.println(courbe.gett1(1));
    Serial.println(courbe.gett2(1));

             
  }

      



void DonneesControl(){
    
      nbcont=cmdMessenger.readInt();
      nbth=cmdMessenger.readInt();
      controleurs=Controleurs(nbcont,nbth);
      char buf[10];
      int counter2=1;
      int controltype;
      int relaistype;
      int hyst;
      int P;
      int I;
      double poids;
      
      while (counter2<=nbcont)  {
        
            controltype=cmdMessenger.readInt();
            controleurs.setcontroltype(counter2,controltype); 
            Serial.println(controltype);
            relaistype=cmdMessenger.readInt();
            controleurs.setrelaistype(1,relaistype);
           Serial.println(relaistype);
            hyst=cmdMessenger.readInt();
            controleurs.sethysteresis(counter2,hyst);
            P=cmdMessenger.readInt();
            controleurs.setP(counter2,P);
            I=cmdMessenger.readInt();
            controleurs.setI(counter2,I);

            for (int i=0;i<nbth;i++){
               cmdMessenger.copyString(buf,10);
               Serial.println(poids=atof(buf));
               controleurs.setpoidsth(i+1,counter2,poids); 

               delay(1000);
             }
               
           Serial.print("nombre de contrôleurs : "); Serial.println(nbcont);
           Serial.print("nombre de thermocouples : ");Serial.println(nbth);
           
           Serial.print("- - - - - - - - - -Controleur ");Serial.println(counter2);
           Serial.print("poids du thermocouple 2 pour controleur 1: ");Serial.println(controleurs.getpoids(2,counter2));
           Serial.print("poids du thermocouple 1 pour controleur 1: ");Serial.println(controleurs.getpoids(1,counter2));      
           Serial.print("type de contrôle : ");Serial.println(controleurs.getcontroltype(counter2));
           Serial.print("type de relais : ");Serial.println(controleurs.getrelaistype(counter2));
           Serial.print("coefficient d'hysteresis : ");Serial.println(controleurs.gethysteresis(counter2));
            
           counter2=counter2+1;
      }
}


}

Controleurs.cpp :


#include "WProgram.h"
#include "Controleurs.h"

Controleurs::Controleurs(int nbcont1,int nbth1){
   nbcont=nbcont1;
   nbth=nbth1;
  controltab[nbcont*5];
poidsthermo[nbth*(nbcont+1)];
}


void Controleurs::addcontroleur(int numcontroleur,int typedecontrole,int typederelais,int coeffhysteresis,int P,int I)
{
  int save[(nbcont+1)*5];
    for ( int i = 0; i <nbcont*5; i++ ){
      
      save[i]=controltab[i];
    }
    

  save[numcontroleur*5-5] =typedecontrole;
  save[numcontroleur*5-4]=typederelais;
  save[numcontroleur*5-3]=coeffhysteresis;
  save[numcontroleur*5-2]=P;
  save[numcontroleur*5-1]=I;

nbcont=nbcont+1;
delete [] controltab;
controltab[nbcont*5];
 for (int i=0;i<nbcont*5;i++){
 controltab[i]=save[i];}
}

double Controleurs::getcoefth(int numth){return poidsthermo[numth*(nbcont+1)-1];}

int Controleurs::getcontroltype(int numcontroleur){return controltab[numcontroleur*5-5];}

int Controleurs::getrelaistype(int numcontroleur){return controltab[numcontroleur*5-4];}

int Controleurs::gethysteresis(int numcontroleur){return controltab[numcontroleur*5-3];}

double Controleurs::getpoids(int numth,int numcont){

  int a=(numth-1)*(nbcont+1)-1+numcont;
  return poidsthermo[a];

}

int Controleurs::getvalP(int numcontroleur){return controltab[(numcontroleur*5)-2];}

int Controleurs::getvalI(int numcontroleur){return controltab[(numcontroleur*5)-1];}



void Controleurs::setpoidsth(int numth,int numcontroleur,double poidsth){
   
  poidsthermo[(numth-1)*(nbcont+1)-1+numcontroleur]=poidsth;

}
void Controleurs::setcoefth(int numth,double coefth){
  poidsthermo[(numth)*(nbcont+1)-1]=coefth;
}

void Controleurs::setcontroltype(int numcontroleur,int controltype){controltab[(numcontroleur*5)-5]=controltype;}

void Controleurs::sethysteresis(int numcontroleur,int hysteresis){controltab[(numcontroleur*5)-3]=hysteresis;}
void Controleurs::setP(int numcontroleur,int P){controltab[numcontroleur*5-2]=P;}
void Controleurs::setI(int numcontroleur,int I){controltab[numcontroleur*5-1]=I;}
void Controleurs::setrelaistype(int numcontroleur,int relaistype){controltab[(numcontroleur*5)-4]=relaistype;}
void Controleurs::addthermo(int numth,double coefth)
{
  double saver[(nbth+1)*(nbcont+1)];
    for ( int i = 0; i <(nbth)*(nbcont+1); i++ ){
      
      saver[i]=poidsthermo[i];
    }
    nbth=nbth+1;
delete [] poidsthermo;
poidsthermo[nbth*(nbcont+1)];
this->setcoefth(numth,coefth);
}

Controleurs.h :


#ifndef Controleurs_h
#define Controleurs_h

#include "WProgram.h"

class Controleurs

{
  
  public:
  
  Controleurs(int nbcontroleurs,int numcontroleur);
  int getcontroltype(int numcont); // retourne le type de controle 0 si PID, 1 si hysteresis
  int getrelaistype(int numcont); // retourne la fonction du relais 0 si chauffe, 1 si refroidissement
  int gethysteresis(int numcont); //retourne la valeur d'hysteresis
  double getpoids(int numcont,int numth);
  double getcoefth(int numth);
  int getvalP(int numcont);
  int getvalI(int numcont);
  void addthermo(int numth,int coefth);//ajoute un thermocouple � la matrice poidsthermo
  void setpoidsth(int numth,int numcont, double coefth);//fixe le poids d'un thermocouple par rapport � un contr�leur
  void setcoefth(int numth,double coefth);
  void setcontroltype(int numcont,int controltype);
  void setrelaistype(int numcont,int relaistype);
  void sethysteresis(int numcont,int hysteresis);
  void setP(int numcont,int P);
  void setI(int numcont,int I);
  void addcontroleur(int numcontroleur,int typedecontrole,int typederelais,int coeffhysteresis,int P,int I);
  void addthermo(int numth, double coefth);
  
  int nbth;
  int nbcont;
  int controltab[];
  double poidsthermo[];
};

#endif
Controleurs::Controleurs(int nbcont1,int nbth1){
   nbcont=nbcont1;
   nbth=nbth1;
  controltab[nbcont*5];
poidsthermo[nbth*(nbcont+1)];
}

Afaik this constructor does not allocate memory for controlTab or poidsThermo. Was that the purpose?
If so it explains why all accesses to the array's (which don't exist) corrupt other RAM locations.

similar in other places