<RESOLU> Faire 1 print d'1 pointeur char global (*p) fait exploser la RAM?

Bonjour,

J'ai un peu mieux cerné mon problème... (Alors là, j'ai pas bon car C mon 2eme msg!)

Si j'imprime la valeur retourné d'un pointeur local initié sur un char local => OK
Si j'imprime la valeur retourné d'un pointeur global initié sur ce char local =>+2000Ko en RAM???!!!

    char *pB = NULL; //=> (puis adressé sur le premier bit d'un float....)
void (){
    char A;
    char *pB_L = &A;
    pB = &A;
    
    Serial.print("\n*pB_L");Serial.print(*pB_L);//De 51%RAM Uno => 133%RAM Uno! (NE COMPILE PAS)
    Serial.print("\n*pB");Serial.print(*pB);    //                 51% OK
}
(<RESOLU>En fait avec le stress j'ai inversé les 2 *p dans l'exemple)

Quelqu'un comprend? ( Et voilà com j'ai déjà exposé le pb, je suis à la maison!**)

Je reviens ici pour vous donner la conclusion du****:

  • je cherchait à faire un programme qui d'un pointeur pourrait accéder à toutes les adresses mémoires, et répondre à toutes sollicitations.
  • J'ai donc construit toutes les fondations. Le compilateur a vu, mais n'a pas pris en compte toutes ces lignes inutiles: pour cause on remplissait des cases sans jamais les consulter!
  • Au moment, ou j'ai fait un print de ce pointeur qui pouvait accéder à tout alors pour 3bits (p=&) j'ai en pris 1679 pour 2048 dispos dans la figure!

Click,click.., click.. RAM! Mon prog, c'est juste mis a vivre...

Merci@J-M-L

( Pensez donc à relire votre post, il peut y avoir d'autres conclusions ;))
(Peut être ce tag mot clé vous permettrait d'accéder directement aux solutions? 8) )

@vous de le noter... ::slight_smile: ...en titre depuis votre 1er msg en haut case Subject :wink:

Bon, je pense avoir trouvé en partant avec un pointeur global vierge initié à NULL

char *pB2 = NULL;//Nouveau pointeur global vierge

Ben la plus de pb! pointeur global *pB2 vierge initié sur char local=> OK

La différence bugg = pointeur global *pB nonvierge
car entre temps il aura vu cette ligne:

case 'A': pB = (char *)&Lati  [iLigne]; Nb_Bit = 4; break;

Donc pointeur global *pB nonvierge initié sur char local => PasOK!

Lati est un tableau de float, a ne pas reproduire donc!

Après si quelqu'un a une astuce pour pouvoir n'utiliser qu'une adresse pointeur quelque soit le type de variable je suis preneur. ( Des conversions permettaient de transferer l'adresse sur un pointeur addoc sans que l'IDE tique)
Je voulais faire une sorte de for Each, pareil si quelqu'un à la solution...
En attendant je vais faire 3 pointeurs... pF, pI, et pB

Après c'est peut être pas normal non plus que le pointeur garde en mémoire que l'on a fait n'importe quoi avec, non?
Normalement, c'est qu'une adresse?

Buggé ou Toqqé?

A vous de voir , merci pour vos retours.

Bon, si je crée 3 pointeurs globaux:

char  *pB = NULL;
int   *pI = NULL;
float *pF = NULL;

Que j'initialise ici:

void Datas::NvFocus(bool Ini){

  if (Ini){iIndex =0;}
  iLigne = 0;
  //Met a jour le CodeCol de la variable parmis le mot du groupe (Obj)
  
  //DEBUG.print(F("Msg: (Colexport) >BUFFER"));
  //Met a jour le CodeCol de la variable parmis le mot du groupe (Obj)
  strncpy_P(Mot,(char *)pgm_read_word(&(C_GLOB[iObjet])),sizeof(Mot));
  //DEBUG.print(Mot);
  this->CodeCol = *(Mot + iIndex);// pgm_read_byte_near(int Adress;
  
  //Met a jour l'adresse du pointeur avec l'adresse d'une ligne dans une colonne propriété
  switch (this->CodeCol){/*
    //case 'D': pB = (char *)&Date  [iLigne]; Nb_Bit = 4; break;
    case 'A': pF = &Lati  [iLigne]; Nb_Bit = 4; break;
    case 'O': pF = &Longi [iLigne]; Nb_Bit = 4; break;
    case 'L': pI = &Alti  [iLigne]; Nb_Bit = 2; break; 
    case 'a': pF = &lati  [iLigne]; Nb_Bit = 4; break;
    case 'o': pF = &longi [iLigne]; Nb_Bit = 4; break;
    case 'l': pI = &alti  [iLigne]; Nb_Bit = 2; break;
    case 'T': pI = &Tmps  [iLigne]; Nb_Bit = 2; break;
    case 'P': pB = &Prof  [iLigne]; Nb_Bit = 1; break;
    case 'W': pI = &Poids [iLigne]; Nb_Bit = 2; break;
    case 'c': pI = &chrgp [iLigne]; Nb_Bit = 2; break;
    case 'C': pI = &ChrgP [iLigne]; Nb_Bit = 2; break;
    case 'R': pB = &R     [iLigne]; Nb_Bit = 1; break;
    case 'G': pB = &G     [iLigne]; Nb_Bit = 1;  break;
    case 'B': pB = &B     [iLigne]; Nb_Bit = 1;  break;*/
  }
  iIndex ++;//Pour le suivant
}

Et bien le besoin en RAM passe de 1051 à 1775! pour trois adresses!
Non 1 adresse du moment que je l'utilise dans cette suite de lignes, (en lieu et place de F2)

float F2=9.9999;
          int Pe = (int)*pF;    <== 1775
          int Pe = (int) F2;    <== 1051
          int Pd = (int)(F2*100)%100;//*pF++*100)%100;
          Buff +=sprintf_P(Buff, PSTR("%d"), Pe);// "Valeurs"
          Buff +=sprintf_P(Buff, PSTR( ".%02d,"), Pd);//*pF++;

Vraiment pas normal Non?
En vrai, je pense que ca mange pas de mémoire mais que le compilateur décompte un peu! trop

Et enfin dernier tests qui permettent de dire que c'est pas normal du tout:

NORMALEMENT Si PartieEntiere = (int) de Float2

          float F2 = 9.9999;
          int Pe = (int)F2;
          Buff +=sprintf_P(Buff, PSTR("%d"), Pe); => 1051

LE BUGG Si PartieEntiere = (int) Float Lati[0] pointé depuis ailleur

          float F2 = 9.9999;
          int Pe = (int)*pF;//pour rappel {...case 'A': pF = &Lati  [iLigne]; Nb_Bit = 4; break;...}
          Buff +=sprintf_P(Buff, PSTR("%d"), Pe); => 1775!!!

Un TEST: avec un pointeur global initié localement sur Float local

          float F2 = 9.9999;
          pF2 = &F2;
          int Pe = (int)*pF2;
          Buff +=sprintf_P(Buff, PSTR("%d"), Pe); => 1051

Un autre test le pointeur global initié en local sur Lati[0]

         float F2 = 9.9999;
          pF2 = &Lati[0];
          int Pe = (int)*pF2;
          Buff +=sprintf_P(Buff, PSTR("%d"), Pe); => 1053

Et le plus fort le pointeur qui merde réinitialisé avec la même ligne de commande en local...

          pF = &Lati[iLigne];
          int Pe = (int)*pF;
          Buff +=sprintf_P(Buff, PSTR("%d"), Pe);

1053 bits!!! Mais, bon ca m'arrange pas...

Ah il me semblait bien que le pointeur était "corrompu" après usage...
J'ai réduis les espaces entre &Lati [iLigne] pour former &Lati[iLigne] , et le pire ensuite je les remet tout pareil c'est a dire &Lati [iLigne]

Et la le test d'initialisation locale ne fonctionne plus!!

Voici le code complet de ce petit prog en trois onglets :

Le Var.cpp

#include "Arduino.h"
#include "Var.h"
//http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.Tableaux
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
//Variables mem     Nature        Char pour Code de détection dans Com   ESP8266      Mega2560
//------------------------------------------------------------------------------------------------
//float Date [60];//Datetime       D -,
float Lati [60];//lAtitude       A  |
float Longi[60];//lOngitude      O  |> Valeurs du GPS compactometre     ComRXTX       ComRXTX
int   Alti [60];//aLtitude       L -'                                  MeEGA2560
//------------------------------------------------------------------------------------------------
float lati [60];//lAtitude       a -,
float longi[60];//lOngitude      o  |> Valeurs du GPS fixe              ComWIFI
int   alti [60];//aLtitude       l -'                                    DGPS
//------------------------------------------------------------------------------------------------
int  Tmps [60];//Temps           T -,
byte Prof [60];   //Profondeur   P  |
int  Poids[60];//poids           W  |> Valeurs du compactometre         ComRXTX       Capteurs
int  chrgp[60];//intge en %      c  |                                  MeEGA2560
int  ChrgP[60];//Charge en PSI   C -'
//------------------------------------------------------------------------------------------------
byte R    [60];//couleurRgb    R -> Valeurs de la camera              ComWIFI        
byte G    [60];//couleurRgb    R -> Valeurs de la camera              ComWIFI        
byte B    [60];//couleurRgb    R -> Valeurs de la camera              ComWIFI        

//Pointeur de char assoccié                                              ESP32Cam
//------------------------------------------------------------------------------------------------
char  *pB = NULL;
int   *pI = NULL;
float *pF = NULL;
float *pF2 = NULL;
byte Nb_Bit = 0;
byte Nb_Dgt = 0;
//------------------------------------------------------------------------------------------------
//Codes variables
const char C_GPS1[]  PROGMEM = "AOL";
const char C_GPS2[]  PROGMEM = "ao";
const char C_COMP[]  PROGMEM = "TPWCc";
const char C_CAM[]   PROGMEM = "RGB";
char Mot[6];///Attention à calibrer!!
const char *const C_GLOB[] PROGMEM = {C_GPS1,C_GPS2,C_COMP,C_CAM};
enum {OGPS1,OGPS2,OCOMPAC,OCAM};

//char CodeCol;//2= 1 seul byte stoké
byte iObjet = 0;
byte iIndex = 0;
byte iLigne = 0;



void Datas::Ini (bool Imprim){
   
    Lati[0] = 1.001;
    for (byte i = 1;i<60;i++){
      Lati[i] = Lati[i-1]+1;
      if(Imprim){DEBUG.println(Lati[i]);};}
      
}



void Datas::ExportColJson(char *Buff){
    //Inspiration
    //https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp
    //this->NvFocus(false);
    //EffaceMsg();  
    this->Point = '1';
    *Buff++ = '{';
    Buff +=sprintf_P(Buff, PSTR("\"cmd\": \"AJ_Col\", \"sht\": \"P%c\","), this->Point); // Comande&Nom
    Buff +=sprintf_P(Buff, PSTR("\"col\": \"%c\","),this->CodeCol);
    Buff +=sprintf_P(Buff, PSTR("\"val\": \""));
    switch (Nb_Bit){
      case 4:
        for (byte i = 0; i < 30 ; i+=2) {
       
          /// En cours de construction tout n'est pas nickel mais on en a plarlé
          float F2 = 9.9999;
          pF = &Lati[0];
          int Pe = (int)*pF;
          Buff +=sprintf_P(Buff, PSTR("%d"), Pe);// "Valeurs"
          
          int Pd = (int)(*pF*100)%100;//*pF++*100)%100;
          Buff +=sprintf_P(Buff, PSTR( ".%02d,"), Pd);//*pF++;
          };//break;   
    } 
    
    *Buff++ = '}';*Buff++ = '0';
}

void Datas::En_Col(){

  //*Buff = '}'
}
void Datas::SetFocus (byte Objet, byte Index){
   
   iObjet = Objet;
   iIndex = Index;
   //iLigne = Ligne;
   NvFocus(false);
}

void Datas::NvFocus(bool Ini){

  if (Ini){iIndex =0;}
  iLigne = 0;
  //Met a jour le CodeCol de la variable parmis le mot du groupe (Obj)
  
  //DEBUG.print(F("Msg: (Colexport) >BUFFER"));
  //Met a jour le CodeCol de la variable parmis le mot du groupe (Obj)
  strncpy_P(Mot,(char *)pgm_read_word(&(C_GLOB[iObjet])),sizeof(Mot));
  //DEBUG.print(Mot);
  this->CodeCol = *(Mot + iIndex);// pgm_read_byte_near(int Adress;
  
  //Met a jour l'adresse du pointeur avec l'adresse d'une ligne dans une colonne propriété
  switch (this->CodeCol){
    //case 'D': pB = (char *)&Date  [iLigne]; Nb_Bit = 4; break;
    case 'A': pF = &Lati  [iLigne]; Nb_Bit = 4; break;
    case 'O': pF = &Longi [iLigne]; Nb_Bit = 4; break;
    case 'L': pI = &Alti  [iLigne]; Nb_Bit = 2; break; 
    case 'a': pF = &lati  [iLigne]; Nb_Bit = 4; break;
    case 'o': pF = &longi [iLigne]; Nb_Bit = 4; break;
    case 'l': pI = &alti  [iLigne]; Nb_Bit = 2; break;
    case 'T': pI = &Tmps  [iLigne]; Nb_Bit = 2; break;
    case 'P': pB = &Prof  [iLigne]; Nb_Bit = 1; break;
    case 'W': pI = &Poids [iLigne]; Nb_Bit = 2; break;
    case 'c': pI = &chrgp [iLigne]; Nb_Bit = 2; break;
    case 'C': pI = &ChrgP [iLigne]; Nb_Bit = 2; break;
    case 'R': pB = &R     [iLigne]; Nb_Bit = 1; break;
    case 'G': pB = &G     [iLigne]; Nb_Bit = 1;  break;
    case 'B': pB = &B     [iLigne]; Nb_Bit = 1;  break;
  }
  iIndex ++;//Pour le suivant
}

Le Var.h

#ifndef ParamMoteur_h
#define ParamMoteur_h

#include "Arduino.h"
#define DEBUG Serial

class Datas{
  
  public:
    void Ini(bool Imprim);                        //Pour Simuler des données
    void ImportLigne (char *Buff, byte Ligne);    //Détecte le code et met les données dans la bonne variable
    void SetFocus (byte Objet,byte Index);        //Met le focus sur un Objet interne et un éventuel sous élément
    void ExportColJson (char *Buff);              //Exporte sous forme de colonnes un élément avec son code et les datas séparées par un virgule
    byte Point = 0;  
    byte Ligne = 0;                          
  private:
    void En_Col();
    void NvFocus(bool Ini);                       //Focuse sur l'élément suivant
    char CodeCol = 0;
    //char *Buff = NULL;
};

#endif

Et le .ino

#include <avr/pgmspace.h>
#include "Arduino.h"
#include "Var.h"
Datas D;
bool Debug =true;

byte Ligne = 0;
byte LigneMax = 10;
enum {OGPS1,OGPS2,OCOMPAC,OCAM};

const byte nInputStringSerie PROGMEM     = 50;     //Taille du buffer
char InputStringSerie[nInputStringSerie];         // a string to hold incoming data
const int sz_Nom PROGMEM     = 8;     //Taille du buffer
char Nom[sz_Nom];         // a string to hold incoming Name
const int sz_Msg PROGMEM                 = 600;
char Msg[sz_Msg];



void setup(){
  Serial.begin(9600);

 
  D.Ini(true);
  Msg[0]='F';
  D.SetFocus(OGPS1,0);
  D.ExportColJson(Msg);//ou &Msg[n]
  //ExportData();
  
  Serial.print(Msg);
  
}
void loop(){
  
  //LigneMax++;
}
 void ExportData(){//byte Obj){Fait bug?
/*
  byte index =0;
  byte Obj = OGPS1;
  
  do{
     MAJ_Focus(Obj,0,index);
     LigneMax++;
     //if (Debug) {Serial.print(F("CodeCol: (Export) >"));Serial.print(CodeCol);Serial.println(F("<"));}
     //EcrireColDataSheets();
     EcrireJsonCol();
     delay(100);
  }while(1); 
 */
}





void EffaceBuffer() {
  memset (InputStringSerie, '\0', sizeof (InputStringSerie));//Efface le buffer
}
void EffaceMsg() {
  memset(Msg, '\0', sizeof(Msg));
}

Si un expert peut m'expliquer tout ceci, merci d'avance.

Bonjour,
J'ai un problème avec un pointeur global qui lorsqu'il est initié dans une procédure annexe provoque un
passage de l'occupation de la RAM du Uno de 51% à 133% (Avec une initialisation Locale on reste à 51%)

J'ai posté plusieurs fois en me répondant pour compléter le diagnostic , du coup personne ne me répond!
Merci de jeter un œil!
Le code est compact 300 Lignes max.
Sur ce post

J’essayerai de jeter un oeil (le lien ne fonctionne pas)

Vous pouvez faire un récapitulatif du besoin ?
Qu’avez vous en entrée, d’où ca vient et que voulez vous en sortie ?

Bonjour J-M-L,

Le programme au global mime une classe pour stocker des datas (plusieurs variables issues de plusieurs boards)
Une autre procédure met en forme pour une variable un Message format JSON avec la serie de data en séparateur ','.

Pour faciliter la com entre modules ou le codage (multi projet), un char code la variable de travail ('A' ou 'O' ou 'L'....) dans le message ou les appels qui miment un for each.
Pour ceci:
1 Une procédure SetFocus met a jour les pointeurs et Nb_Bits adaptés champs de données (float[], int[] ou byte[]) ciblés.
2 Dans un procédure de travail annexe (ici ExportColJSON) on utilisera le pointeur adapté (pF, pI ou pB) en fonction de Nb_bits (4,2,1) et on écrit un des floats ou des ints ou des bytes... avec son Code colonne en amont.
2 bis pour l'import l'esclave dit un code, le maitre SetFocus et Serial.Read(Nb_Bit) qu'il(s) met dans la bonne case via un *pB++

Le plantage vient du recours a un pointeur initialisé dans un procédure différente (SetFocus) de celle de travail (ExportColJSON).

Une copie pF2 du pointeur global initiée en local avec un copié collé du code de la ligne incriminée ne provoque pas de problème...

Voilà le topo. De mon coté je suis partis des lignes de bugs et je complexifie jusqu'au pb.

Voici le code réduit a ca plus simple expression buggante:

En changeant l'adresse du pointeur de float pF par pF = &F (membre d' un tableau de 180 float ) on prend 240 bites dans la RAM??

Pour tester:
1 Copiez Collez
2 Vérifiez le code
3 Notez le besoin RAM
4 Décommentez la ligne 81
5 Vérifiez le code
6 Notez le nouveau besoin RAM

.ino

#include "Datas.h"
Datas D;
char Msg[600];

void setup(){
  // put your setup code here, to run once:
  Serial.begin(9600);
  
  D.Ini();
  D.SetFocus();
  D.ExportColJson_pF_FLocal(Msg);
  
  
}

void loop(){}

Datas.cpp

#include "Arduino.h"
#include "Datas.h"


//???????????????????????
const byte Nb_Pt = 180;//<===================BUGG: Ici on gonfle/crée le besoin mémoire. Suite Ligne 81
//???????????????????????



//Variables mem     Nature        Char pour Code de détection dans Com   ESP8266      Mega25Nb_Pt
//------------------------------------------------------------------------------------------------
//float Date [Nb_Pt];//Datetime       D -,
float Lati [Nb_Pt];//lAtitude       A  |
float Longi[Nb_Pt];//lOngitude      O  |> Valeurs du GPS compactometre     ComRXTX       ComRXTX
int   Alti [Nb_Pt];//aLtitude       L -'                                  MeEGA25Nb_Pt
//------------------------------------------------------------------------------------------------
float lati [Nb_Pt];//lAtitude       a -,
float longi[Nb_Pt];//lOngitude      o  |> Valeurs du GPS fixe              ComWIFI
int   alti [Nb_Pt];//aLtitude       l -'                                    DGPS
//------------------------------------------------------------------------------------------------
int  Tmps [Nb_Pt];//Temps           T -,
byte Prof [Nb_Pt];   //Profondeur   P  |
int  Poids[Nb_Pt];//poids           W  |> Valeurs du compactometre         ComRXTX       Capteurs
int  chrgp[Nb_Pt];//intge en %      c  |                                  MeEGA25Nb_Pt
int  ChrgP[Nb_Pt];//Charge en PSI   C -'
//------------------------------------------------------------------------------------------------
byte R    [Nb_Pt];//couleurRgb    R -> Valeurs de la camera              ComWIFI        
byte G    [Nb_Pt];//couleurRgb    R -> Valeurs de la camera              ComWIFI        
byte B    [Nb_Pt];//couleurRgb    R -> Valeurs de la camera              ComWIFI        

//Pointeur de char assoccié                                              ESP32Cam
//------------------------------------------------------------------------------------------------
char  *pB = NULL;
int   *pI = NULL;
float *pF = NULL;
float *pF2 = NULL;
byte Nb_Bit = 0;
byte Nb_Dgt = 0;


float F[60];
byte Ligne;


void Datas::Ini(){

  for (byte i =0;i<Nb_Pt;i++){
    F[i]=9.9999;
    Alti[i]=9.9999;
    
  }
  this->CodeCol ='A';
}

void Datas::SetFocus(){
  
  //Met a jour l'adresse du pointeur avec l'adresse d'une ligne dans une colonne propriété
  switch (this->CodeCol){
    //case 'D': pB = &Date  [Ligne]; Nb_Bit = 4; break;
    case 'A': pF = &Lati  [Ligne]; Nb_Bit = 4; break;
    
  }
}


bool Datas::ExportColJson_pF_FLocal(char *Buff){
    //Inspiration
    //https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp

  if (this->CodeCol){
    this->EffaceBuff(Buff);  
    this->Point = '1';
    *Buff++ = '{';
    Buff +=sprintf_P(Buff, PSTR("\"cmd\": \"AJ_Col\", \"sht\": \"P%c\","), this->Point); // Comande&Nom
    Buff +=sprintf_P(Buff, PSTR("\"lbl\": \"%c\","),this->CodeCol);
    Buff +=sprintf_P(Buff, PSTR("\"val\": \""));
    switch (Nb_Bit){
      case 4:
      
        //??????????????
        //pF = NULL;
        pF = &F[0];//<====================BUGG: Ici pF est dejà initialisé sur un Float (Lati[], mais on le reinitialise en décommentant 
        //???????????????                       et la on crée un besoin suplémentaire de +240 pour 180 floats
        //                                         
        
        for (byte i = 0; i < Nb_Pt ; i+=2) {
          Buff +=sprintf_P(Buff, PSTR("%d"), (int)*pF);
          Buff +=sprintf_P(Buff, PSTR( ".%06d,"), (int)(*pF++*100)%100);}
       pF++;break;   
    } 
    
    *Buff++ = '}';*Buff++ = '0';
    //Index++;//Pour le suivant
    //this->NvFocus(false);//Préparer le focus suivant
    return true;
  }else{//Pas codecol
    return false;
  }
  
}

void Datas::EffaceBuff(char *Buff) {
  memset (Buff, '\0', sizeof (Buff));//Efface le buffer
}

Datas.h

class Datas{
  
  public:
    
    void SetFocus();        
    bool ExportColJson_pF_FLocal(char *Buff);   
    void Ini();
    byte Ligne = 0;   
    byte Point = 0;                   
  private:
    char CodeCol =0;
    void EffaceBuff(char *Buff);
};

Voici le code réduit a ca plus simple expression buggante:

En changeant l'adresse du pointeur de float pF par pF = &F (membre d' un tableau de 180 float ) on prend 240 bits dans la RAM??

Pour tester:
1 Copiez Collez
2 Vérifiez le code
3 Notez le besoin RAM
4 Décommentez la ligne 81
5 Vérifiez le code
6 Notez le nouveau besoin RAM

.ino

#include "Datas.h"
Datas D;
char Msg[600];

void setup(){
  // put your setup code here, to run once:
  Serial.begin(9600);
  
  D.Ini();
  D.SetFocus();
  D.ExportColJson_pF_FLocal(Msg);
  
  
}

void loop(){}

Datas.cpp

#include "Arduino.h"
#include "Datas.h"


//???????????????????????
const byte Nb_Pt = 180;//<===================BUGG: Ici on gonfle/crée le besoin mémoire. Suite Ligne 81
//???????????????????????



//Variables mem     Nature        Char pour Code de détection dans Com   ESP8266      Mega25Nb_Pt
//------------------------------------------------------------------------------------------------
//float Date [Nb_Pt];//Datetime       D -,
float Lati [Nb_Pt];//lAtitude       A  |
float Longi[Nb_Pt];//lOngitude      O  |> Valeurs du GPS compactometre     ComRXTX       ComRXTX
int   Alti [Nb_Pt];//aLtitude       L -'                                  MeEGA25Nb_Pt
//------------------------------------------------------------------------------------------------
float lati [Nb_Pt];//lAtitude       a -,
float longi[Nb_Pt];//lOngitude      o  |> Valeurs du GPS fixe              ComWIFI
int   alti [Nb_Pt];//aLtitude       l -'                                    DGPS
//------------------------------------------------------------------------------------------------
int  Tmps [Nb_Pt];//Temps           T -,
byte Prof [Nb_Pt];   //Profondeur   P  |
int  Poids[Nb_Pt];//poids           W  |> Valeurs du compactometre         ComRXTX       Capteurs
int  chrgp[Nb_Pt];//intge en %      c  |                                  MeEGA25Nb_Pt
int  ChrgP[Nb_Pt];//Charge en PSI   C -'
//------------------------------------------------------------------------------------------------
byte R    [Nb_Pt];//couleurRgb    R -> Valeurs de la camera              ComWIFI        
byte G    [Nb_Pt];//couleurRgb    R -> Valeurs de la camera              ComWIFI        
byte B    [Nb_Pt];//couleurRgb    R -> Valeurs de la camera              ComWIFI        

//Pointeur de char assoccié                                              ESP32Cam
//------------------------------------------------------------------------------------------------
char  *pB = NULL;
int   *pI = NULL;
float *pF = NULL;
float *pF2 = NULL;
byte Nb_Bit = 0;
byte Nb_Dgt = 0;


float F[Nb_Pt];
byte Ligne;


void Datas::Ini(){

  for (byte i =0;i<Nb_Pt;i++){
    F[i]=9.9999;
    Alti[i]=9.9999;
    
  }
  this->CodeCol ='A';
}

void Datas::SetFocus(){
  
  //Met a jour l'adresse du pointeur avec l'adresse d'une ligne dans une colonne propriété
  switch (this->CodeCol){
   
    case 'A': pF = &Lati  [Ligne]; Nb_Bit = 4; break;
    
  }
}


bool Datas::ExportColJson_pF_FLocal(char *Buff){
    //Inspiration
    //https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp

  if (this->CodeCol){
    
    this->Point = '1';
    *Buff++ = '{';
    Buff +=sprintf_P(Buff, PSTR("\"cmd\": \"AJ_Col\", \"sht\": \"P%c\","), this->Point); // Comande&Nom
    Buff +=sprintf_P(Buff, PSTR("\"lbl\": \"%c\","),this->CodeCol);
    Buff +=sprintf_P(Buff, PSTR("\"val\": \""));
    switch (Nb_Bit){
      case 4:
      
        //??????????????
        //pF = NULL;
        pF = &F[0];//<====================BUGG: Ici pF est dejà initialisé sur un Float (Lati[], mais on le reinitialise en décommentant 
        //???????????????                       et la on crée un besoin suplémentaire de +240 pour 180 floats
        //                                         
        
        for (byte i = 0; i < Nb_Pt ; i+=2) {
          Buff +=sprintf_P(Buff, PSTR("%d"), (int)*pF);
          Buff +=sprintf_P(Buff, PSTR( ".%06d,"), (int)(*pF++*100)%100);}
       pF++;break;   
    } 
    
    *Buff++ = '}';*Buff++ = '0';
    //Index++;//Pour le suivant
    //this->NvFocus(false);//Préparer le focus suivant
    return true;
  }else{//Pas codecol
    return false;
  }
  
}

Datas.h

class Datas{
  
  public:
    
    void SetFocus();        
    bool ExportColJson_pF_FLocal(char *Buff);   
    void Ini();
    byte Ligne = 0;   
    byte Point = 0;                   
  private:
    char CodeCol =0;
    
};

L’optimisation vous joue sans doute des tours, tous les tableaux non utilisés ne sont pas alloués.
S’il y a qu’un accès à un indice particulier seule une variable pourrait être allouée
Etc...

Gardons la conversation dans un seul post.

J-M-L:
L’optimisation vous joue sans doute des tours, tous les tableaux non utilisés ne sont pas alloués.
S’il y a qu’un accès à un indice particulier seule une variable pourrait être allouée
Etc...

Gardons la conversation dans un seul post.

Je ne comprends pas le sens de ces mots:
-> tous les tableaux sont utilisés: c'estt les variables aquises en attente de transfert vers un serveur (Fichier Google sheet)
-> l'accès doit être a tout les items des colonnes de ce tableau d'aquisition (ecriture en ligne, export en colonne)
-> l'intérêt de ce mode de codage est de pouvoir facilement transposer à un autre projet;
1 on réécrit les mots de x char compilant les x propriétés en PROGMEM d'un objet
2 et la liste des Mots objets
3 puis on met a jour le tableau d'affectation setFocus et basta...
... Avec une lettre on appellerait ou stockerait ce que l'on voudrait...

Quoi qu'il en soit, sommes nous bien d'accord sur ces points:
-> un pointeur contient bien l'adresse de la case mémoire d'un Objet désigné par &Objet?
-> cette adresse pour l'arduino est codé sous forme d'un int?
-> cette adresse a toujours la même taille quelle que soit la "longueur de la rue" et la "taille de maison"?
-> il n'est pas normal qu'en stockant une nouvelle adresse, vu qu'en principe on écrase l'ancienne, le besoin RAM augmente?
Merci pour votre aide.

Le code tel qu’il est posté fait juste n’importe quoi... je ne sais pas quoi dire...

La fichier de la classe contient au moins 14 tableaux (qui seront des variables globales non liées à la classe) de Nb_Pt element Et le tableau F de 60 floats

Le code instancie une variable de la classe Datas et fait 3 appels

 D.Ini();
  D.SetFocus();
  D.ExportColJson_pF_FLocal(Msg);

La méthode Ini() ne touche en écriture que F et Alti et déborde très largement la mémoire associée à F (vous écrivez 180 elements dans un tableau de 60). Dès cet appel le programme est dans les choux

La méthode SetFocus initialise juste des valeurs en dur et deux pointeurs variable globales, l’un pB de type char* avec l’adresse du premier élément d’un tableau Date qui n’est pas déclaré (il est commenté et c’est des float) (Ligne n’est même pas initialisée, il y a une version variable globale qui vaut 0 et une variable d’instance...) et pF à l’adresse d’un élément d’un tableau qui n’a jamais été utilisé ailleurs ou initialisé.

Enfin ExportColJson appel la méthode EffaceBuff() qui ne met à 0 que 2 octets car Buff est un pointeur donc sizeof (Buff) c’est 2... et parcours en dépassant largement la mémoire allouée à F à nouveau

Bref ce que vous avez posté ne doit même pas compiler à mon avis...et je n’ai toujours pas compris à quoi ça doit servir.

Demandez au modérateur de fusionner vos 2 posts pour n’avoir qu’une seule conversation svp

J-M-L:
Le code tel qu’il est posté fait juste n’importe quoi... je ne sais pas quoi dire...

La fichier de la classe contient au moins 14 tableaux (qui seront des variables globales non liées à la classe) de Nb_Pt element Et le tableau F de 60 floats

Le code instancie une variable de la classe Datas et fait 3 appels

 D.Ini();

D.SetFocus();
 D.ExportColJson_pF_FLocal(Msg);




La méthode Ini() ne touche en écriture que F et Alti et déborde très largement la mémoire associée à F (vous écrivez 180 elements dans un tableau de 60). Dès cet appel le programme est dans les choux

La méthode SetFocus initialise juste des valeurs en dur et deux pointeurs variable globales, l’un pB de type char* avec l’adresse du premier élément d’un tableau Date qui n’est pas déclaré (il est commenté et c’est des float) (Ligne n’est même pas initialisée, il y a une version variable globale qui vaut 0 et une variable d’instance...) et pF à l’adresse d’un élément d’un tableau qui n’a jamais été utilisé ailleurs ou initialisé.

Enfin ExportColJson appel la méthode EffaceBuff() qui ne met à 0 que 2 octets car Buff est un pointeur donc sizeof (Buff) c’est 2... et parcours en dépassant largement la mémoire allouée à F à nouveau

Bref ce que vous avez posté ne doit même pas compiler à mon avis...et je n’ai toujours pas compris à quoi ça doit servir.

Bonjour J-M-L,
Merci vos informations sont riches et exactes!
-> En 1 ce prog compile mais ne sert a rien ci se n'est a reproduire que le phénomène qui me dérange, a savoir conso de mémoire excessive à la compilation, avec un minimum de ligne de code (la version complète est dans l'autre post OK pour fusion)
-> Les variables ne sont pas liées pour l'instant à la classe. (Par "précaution?",/maque de pratique, j'ai juste interfacé les parties visibles dans le .ino) et OK ce serait plus intéressant de pouvoir les multiplier par appel d'autant que le prog ira sur un ESP32 avec 8Mb de RAM.

-> Pour l'effaceBuff: je ne le trouvait pas très efficace... en gros le code équivalait à pointeur = NULL donc sans dégât possible, merci pour ce diagnostic.

  • J'ai corrigé le 60 et changé en Nb_Pt pour être en phase avec le 180 (pour le débordement pas de risques, le "bugg" se lit au compte rendu de compilation avec un résultat besoin mémoire aberrant a mon sens)

J'ai corrigé le code dans le fil de discussion en virant effacebuff, le 60 et le //case 'D': et sur mon projet: il compile.
A priori avec ces corrections pour vous il n'y a plus de défaut de syntaxe?
Merci d'essayer le mode opératoire que j'ai décrit et d'observer le besoin mémoire des versions commentée et décommentée de la ligne 81 et me dire si ce delta est normal ou pas?

Bonjour

Le "défaut de mémoire" ne veut rien dire.

C’est juste l’optimisation de code qui optimise plus ou moins en décidant ou non de rajouter un tableau qu’il n’utilisait pas avant. Ne perdez pas de temps avec ça.

Je n’ai toujours pas compris en quoi vous avez besoin d’une nouvelle classe et ce que vous essayez de faire.

Si vous avez plusieurs tableau de données et que en fonction d’un élément de décision vous voulez exporter ce tableau c’est juste une histoire d’indices (si vous faites un tableau de tableau) ou éventuellement un pointeur qui va parcourir le bon tableau (à condition de définir le pointeur correctement ).

const byte nb=50;
float tab0[nb];
float tab2[nb];
float tab0[nb];
...
void printTabReference(float & t) {
  for (byte i=0; i<nb; i++) Serial.println(t[i]);
}

void printTabPointeur float * t) {
  for (byte i=0; i<nb; i++) Serial.println(*(t+i)); // ou Serial.println(t[i]); marche aussi
}

... dans le code
  printTabReference(tab0);
  printTabPointeur(tab1);

j’ai un tuto sur la mémoire et les pointeurs, éventuellement ça pourra vous aider ?

Messages fusionnés

:wink:

Merci @jfs