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

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.

Disons que +200 octet pour stocker une adresse je trouve cela élevé. Si le compilateur recrée un tableau, je ne vois pas a quoi cela sert de donner un pointeur... et vous que pensez vous de ceci? quelle conséquences cela aura t'il dans une boucle?

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

Un appareil qui n'a pas d'équivalant sur le marché un Pro-Fileuse de sol (ou de Brol). Elle permettrait d’accélérer les capacités de diagnostic de sols, et donc accélérer la recherche agronomique afin de pouvoir relever le défis de la résolution climatique (Rassurez vous pour la résolution climatique les preuves de concept sont largement dépassées: voir Kiss the Ground)

Mon application nécessite une collaboration entre plusieurs microcontrôleurs.

  • une Mega récupère des données de balance et télémètres, complétées par les données du GPS1 connecté en Serial3.
    Ses données sont évacuées et transmisses à la volée sur le serial à un module WIFI. (Je pensait les envoyer sur mon smartphone puis Googlesheets)
  • Mais Google étant trop lent et l'ESP8266 disposant de place, j'ai décidé d'y stocker la data. La réception est en ligne au rythme de l’acquisition par paquet environ 1/par secondes .
    Ensuite cet ESP8266 peut recevoir des données d'un deuxième GPS en WIFI (pour ce µc prog simple), la aussi transfert en ligne sur un second champ en anticipé ou léger différé (recyclage de la procédure).
    Puis après 60 points (1200 à 3600 bits), cet ESP8266 dispose de temps pour commencer un transfert vers Sheet en attendant de recevoir un dernier champ de données d'ou le transfert en colonne qui permet également de faire de plus gros paquets pour gaver Google.
  • Dernier intervenant pour générer le champ de données, un ESP32 avec caméra LCD. Au départ, je pensait utiliser mon smartphone dans ce rôle, mais étant limité en Android même si je parle Ai2 depuis 3 semaines, j'ai opté pour ce module me paraissant plus accessible... L'objet de cet élément est de remonter les couleurs composantes R &G&B. Le positionnement se fera soit par lecture optique, soit en lien avec le télémètre. L'ESP8266 étant en position centrale, il est devenu pour moi le cerveaux de la manœuvre...
    La contrainte que je me fixe est de pouvoir attaquer un nouveau cycle au plus vite et de ne pas avoir de transfert de données à faire ni sur le terrain, ni après.

Pour sûr cela me donne du boulot, peut être aurez vous une solution plus simple à me proposer...Dites moi

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 ):

J'aime bien cette idée de code qui est capable de répondre à toutes les questions que l'on lui pose... et qui se recycle en changeant une phrase...
J'ai eu fait pire!! Une espèce d’enchaînement de 4 char permettant d'interroger ou gérer tout et n’importe quel capteur ou portes ou système associé à la régulation climatique de ma serre. Le système se tendait, comme un système mécanique que l'on remonte, mais réagissant ici sous la contrainte de la question, puis une fois tendue la mécanique est laissée libre et crache la réponse...
1 capteur PV SP SB, SH,Min,Max... un lieu (interieur, extérieur, intereirur2, 3... Température, Humidité, Masse d'eau, une ouverture, des capteurs, une combinaison, tout paramètres, changer une consigne, un seuil reseter le minmax, cracher sur le SMS, un serveur... bref le coeur de l'appli
La je tente une version intermédiaire qui me servira de base déclinable?

Disons que +200 octet pour stocker une adresse je trouve cela élevé. Si le compilateur recrée un tableau, je ne vois pas a quoi cela sert de donner un pointeur... et vous que pensez vous de ceci? quelle conséquences cela aura t'il dans une boucle?

regardez la mémoire totale allouée dans le cas où il n’y a pas ces octets « en plus ».

Je suis sûr que Vous verrez que vous n’aurez pas 15 x 180 éléments x 4 octets déjà alloués (et heureusement parce que ça ne tient pas sur un mega). Le compilateur a en fait vu que plein de tableaux ne servaient à rien, n’étaient pas utilisés et donc il les a virés. Quand vous modifiez le code pour introduire des pointeurs, l’optimiseur sera moins sûr de lui et va peut être allouer juste un des tableaux (celui pointé). Ce n’est donc pas de la mémoire réellement en plus par rapport à ce que vous avez demandé initialement mais juste l’un de ces tableaux qui a été alloué comme il se doit.

Pour l’autre partie est-ce que tout est monté au même endroit ? Multiplier les microcontrollers c’est multiplier les sources de problèmes. Est-ce que l’ESP32 ne peut pas tout faire ?

regardez la mémoire totale allouée dans le cas où il n'y a pas ces octets « en plus ».
Je ne comprends pas le sens de vos mots. Ce que j'observe est une augmentation du besoin mémoire de 200 octets pour 1 changement d'adresse du pointeur. Touts les autres paramètres sont constants. Pour le test, je ne change rien toutes les déclarations restent identiques: je ne fait que décommenter une ligne (celle de la réaffectation de l'adresse du pointeur) Vous pouvez faire ce test.

Je suis sûr que Vous verrez que vous n'aurez pas 15 x 180 éléments x 4 octets déjà alloués (et heureusement parce que ça ne tient pas sur un mega). Le 180 est la pour amplifier le problème 60 est réel. En vrai je n'aurai pas de problèmes car l'ESP8266 à 45000 de RAM. Mais bon si je peut multiplier les carnets en mémoires pour cracher 3 colonnes pour une comparaison instantanée, ca m'intéresse.

Le compilateur a en fait vu que plein de tableaux ne servaient à rien, n'étaient pas utilisés et donc il les a virés.
Ok, c'est intéressant à savoir (vous avez la version plus complète en amont )

Quand vous modifiez le code pour introduire des pointeurs, l'optimiseur sera moins sûr de lui et va peut être allouer juste un des tableaux (celui pointé). Ce n'est donc pas de la mémoire réellement en plus par rapport à ce que vous avez demandé initialement mais juste l'un de ces tableaux qui a été alloué comme il se doit.
Je ne pense pas puisque je les remplis et ensuite je les consultes, mais je fais faire le test en consultant la variable avant de changer l'adresse du pointeur. Faut-il tout consulter ou juste un item du tableau? Ok je comprend mieux votre discours. Merci, je me coucherai, moins c++

Pour l'autre partie est-ce que tout est monté au même endroit ?
Je tiens a une caméra sans fils qui va dans la poche... La méga est sur le "guidon" avec un shield LCD KeyPad pour les menus (Merci Skywood!)

Multiplier les microcontrôleurs c'est multiplier les sources de problèmes. Est-ce que l'ESP32 ne peut pas tout faire ?
Ca c'est sûr et à débuguer c'est bien la m++ l'ESP32 ne dispose pas de port 5V, ni de ports du tout. C'est un TTGO avec mini écran de 240240pixels et une CAM qui sort du vrai RGB888. L'avantage de l'écran local, c'est que je vais facilement pouvoir débugger. Après elle est nouvelle dans le projet, elle est arrivée avant hier, parmi d'autres modules ESP32 classiques ou des CAM...
Une bonne combinaison serait un Arduino Wifi intégré et une TTGO en master mais elle aura toujours besoin d'un code de ce type, a moins qu'avec 8Mo on puisse griller un peu de place... En plus elle à 4
16Mo de SD...
Bref, une belle bestiole sans pattes! Heureusement, elle a la gueule!

Je fais un retour sur le test en utilisant le tableau de float pipo F[] avant de réaffecter son adresse au pointeur...

Je ne comprends pas le sens de vos mots. Ce que j'observe est une augmentation du besoin mémoire de 200 octets pour 1 changement d'adresse du pointeur. Touts les autres paramètres sont constants. Pour le test, je ne change rien toutes les déclarations restent identiques: je ne fait que décommenter une ligne (celle de la réaffectation de l'adresse du pointeur) Vous pouvez faire ce test.

je suis sur mon smartphone, je ne peux pas tester mais répondez à ces 3 questions

En regardant votre demande pour ces variables globales:

const byte Nb_Pt = 180; // ou même 60

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;

sachant qu’un byte occupe 1 octet, un int 2 octets, un pointeur 2 octets et un float 4 octets, Combien de mémoire devrait réellement être allouée (celle demandée par VOTRE code) ?

Combien de mémoire est RÉELLEMENT allouée par le compilateur avant la modification (pour tout le programme, ce que vous lisez en compilant) ? Est-ce cohérent avec ce que vous aviez demandé ou est-ce moins ?

Combien de mémoire allouée après la modification ? Est-ce cohérent avec ce que vous aviez demandé ou est-ce moins ?

Reponse(s):

for (byte i = 0; i < Nb_Pt ; i++){Serial.print(F("\nF[i]"));Serial.print(F[i]);}
        //??????????????
        //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
        //

Après, avoir réellement consulté le tableau de float F, et ne pas l'avoir seulement créé et rempli de données, l'affectation du pointeur sur un item de cet élément ne fait pas varier la taille du besoin en mémoire 1516 = 1516
Donc tout est logique.
Comment avez vous découvert ce fait? Tuto, information, cours?

Comment avez vous découvert ce fait? Tuto, information, cours?

je suis "vieux"... donc l’expérience et la compréhension assez fine de ce que fait un compilateur et un optimiseur de code

J-M-L:
je suis sur mon smartphone, je ne peux pas tester mais répondez à ces 3 questions

En regardant votre demande pour ces variables globales:

const byte Nb_Pt = 180; // ou même 60

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;



sachant qu’un byte occupe 1 octet, un int 2 octets, un pointeur 2 octets et un float 4 octets, Combien de mémoire devrait réellement être allouée (celle demandée par VOTRE code) ?

Combien de mémoire est RÉELLEMENT allouée par le compilateur avant la modification (pour tout le programme, ce que vous lisez en compilant) ? Est-ce cohérent avec ce que vous aviez demandé ou est-ce moins ?

Combien de mémoire allouée après la modification ? Est-ce cohérent avec ce que vous aviez demandé ou est-ce moins ?

Ben à la découverte du "BUGG", je suis pas de 51% à 133% donc +1679 octets qui dormaient dans le compilateur...
A ton accès à cette info au moment de la compilation (RAM réellement utilisé? Besoin RAM en dormance?)
1679 vous parait cohérant avec 6043? Votre outil de programmation donne ces infos je suppose...
Mon tableau de calcul de gestion de la mémoire me dis, si je supprime la variable petit L représentant l'altitude du GPS2 1940 donc pas si loin du compte.
Ca fait juste bizarre de voir compile plus (et oh!! 133% moi stop!) et que ctrl Z ramène à 51% pour un p =& !

Après, je l'ai un peu cherché: je voulais un prog qui répond a toutes les questions, pour 3bits j'ai en pris 1679 pour 2048 dispos dans la figure!

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

J-M-L:
je suis "vieux"... donc l’expérience et la compréhension assez fine de ce que fait un compilateur et un optimiseur de code

J'entends bien que vous avez de l'expérience, mais n'avez vous pas une anecdote associée?

Anecdote? ou pas, Merci J-M-L pour cet accompagnement! 8)

jfs:
Messages fusionnés

:wink:

Merci JFS, on a trouvé! Enfin J-M-L.

J-M-L:
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 ?

Pourquoi pas? Avez vous le lien?

Non pas d’anecdotes particulières, juste une bonne formation d’ingénieur et un intérêt pour comprendre comment ça marche :slight_smile:

Pour le Tuto c’est par là: Introduction à la mémoire et aux pointeurs sur Arduino

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

bravo