Problème de mémoire ?

Bonjour,
Lorsque je téléverse le code suivant sur un Nano CH340 atmega328P, cela fonctionne.

/*  sketch_AVR_Linky_STD_1.ino d'après solution de J-M-L pour lire TIC dans le forum https://forum.arduino.cc/t/lecture-tic-standard/1219929
    sketch_AVR_Linky_STD_2.ino fusion avec la partie lecture de https://jojoflyhigh.blogspot.com/2012/08/teleinformation-24-arduino-sw.html
      Résultat : rien ne remonte dans le moniteur après "J'ai reçu :"
    sketch_AVR_Linky_STD_3.ino exploitation du char frame de J-M-L avec des test conditionnel sur extraction de caractères
      TIC pat PiTinfo
      TXD sur pin 2; VCC sur 5V
      Résultat : Conso et Production instantanées stockées dans les variables YOUPI !!
*/


#include <SoftwareSerial.h>

#define UART2_RX  2
#define UART2_TX  3
SoftwareSerial Serial2(UART2_RX, UART2_TX);



#define STARTFRAME 0x02       // Caractère de début de trame
#define ENDFRAME 0x03         // Caractère de fin de trame

const size_t maxFrameSize = 1032;
char frame[maxFrameSize + 1]; // +1 pour le zero d'arrêt
size_t framePos = 0;

int puiConso = 0;
int puiInjec = 0;
int pMax = 0;
int pMin = 0;

bool getFrame() {
  bool frameOK = false;

  if (Serial2.available()) {
    char charIn = Serial2.read() & 0x7F;
    switch (charIn) {
      case STARTFRAME:
        framePos = 0;
        frame[0] = '\0';
        break;

      case ENDFRAME:
        frame[framePos] = '\0';
        frameOK = true;
        break;

      default:
        if (framePos < maxFrameSize)
          frame[framePos++] = charIn;
        break;
    }
  }

  return frameOK;
}

void setup() {
  Serial.begin(115200); Serial.println();
  Serial2.begin(9600); // 
  delay(500);










  Serial.println("PRET");
}

void loop() {
  if (getFrame()) {
    //Serial.print("J'ai reçu: "); 
    // Serial.println(frame);
    // ici traiter la frame
    for (int c = 0; c < maxFrameSize; c++) {
      char lettreS = frame[c];
      //Serial.print(S);
      if (lettreS == 'S') {
        String etiquette = "";
        int d = 0;
        for (d = 0; d < 6; d++) {
          etiquette = etiquette + frame[c + d];
        }
        if (etiquette == "SINSTS") {
          String valeurc = "";
          for (int e = 2; e <7; e++) {
            valeurc = valeurc + frame[c+d+e];
          }
          puiConso = valeurc.toInt();
        }
        if (etiquette == "SINSTI") {
          String valeuri = "";
          for (int f = 2; f <7; f++) {
            valeuri = valeuri + frame[c+d+f];
          }
          puiInjec = valeuri.toInt();
        }
      }
    }
    Serial.print("Conso :"); Serial.println(puiConso);
    Serial.print("Injec :"); Serial.println(puiInjec);
  }
  // ici vous pouvez faire autre chose



}

Le rapport de téléversement est :
Le croquis utilise 5882 octets (19%) de l'espace de stockage de programmes. Le maximum est de 30720 octets.
Les variables globales utilisent 1388 octets (67%) de mémoire dynamique, ce qui laisse 660 octets pour les variables locales. Le maximum est de 2048 octets.

Lorsque j'ajoute du code pour affichage OLED :

/*  sketch_AVR_Linky_STD_1.ino d'après solution de J-M-L pour lire TIC dans le forum https://forum.arduino.cc/t/lecture-tic-standard/1219929
    sketch_AVR_Linky_STD_2.ino fusion avec la partie lecture de https://jojoflyhigh.blogspot.com/2012/08/teleinformation-24-arduino-sw.html
      Résultat : rien ne remonte dans le moniteur après "J'ai reçu :"
    sketch_AVR_Linky_STD_3.ino exploitation du char frame de J-M-L avec des test conditionnel sur extraction de caractères
      TIC par PiTinfo
      TXD sur pin 2; VCC sur 5V
      Résultat : Conso et Production instantanées stockées dans les variables YOUPI !!
      écran Oled  SDA > A4 (vert); SCK > A5 (orange); VCC > 5V ou 3V3
      Résultat : ça boucle sur le setup ???
*/
#include <SoftwareSerial.h>
#include <Adafruit_SSD1306.h>
#define UART2_RX  2
#define UART2_TX  3
SoftwareSerial Serial2(UART2_RX, UART2_TX);

Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);

#define STARTFRAME 0x02       // Caractère de début de trame
#define ENDFRAME 0x03         // Caractère de fin de trame

const size_t maxFrameSize = 1032;
char frame[maxFrameSize + 1]; // +1 pour le zero d'arrêt
size_t framePos = 0;

int puiConso = 0;
int puiInjec = 0;
int pMax = 0;
int pMin = 0;

bool getFrame() {
  bool frameOK = false;

  if (Serial2.available()) {
    char charIn = Serial2.read() & 0x7F;
    switch (charIn) {
      case STARTFRAME:
        framePos = 0;
        frame[0] = '\0';
        break;

      case ENDFRAME:
        frame[framePos] = '\0';
        frameOK = true;
        break;

      default:
        if (framePos < maxFrameSize)
          frame[framePos++] = charIn;
        break;
    }
  }

  return frameOK;
}

void setup() {
  Serial.begin(115200); Serial.println();
  Serial2.begin(9600); // 
  delay(500);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x32

  // // Clear the buffer.
  display.clearDisplay();

  // // text display tests
  display.setTextSize(2,2);
  display.setTextColor(WHITE);

  Serial.println("PRET");
}

void loop() {
  if (getFrame()) {
    //Serial.print("J'ai reçu: "); 
    // Serial.println(frame);
    // ici traiter la frame
    for (int c = 0; c < maxFrameSize; c++) {
      char lettreS = frame[c];
      //Serial.print(S);
      if (lettreS == 'S') {
        String etiquette = "";
        int d = 0;
        for (d = 0; d < 6; d++) {
          etiquette = etiquette + frame[c + d];
        }
        if (etiquette == "SINSTS") {
          String valeurc = "";
          for (int e = 2; e <7; e++) {
            valeurc = valeurc + frame[c+d+e];
          }
          puiConso = valeurc.toInt();
        }
        if (etiquette == "SINSTI") {
          String valeuri = "";
          for (int f = 2; f <7; f++) {
            valeuri = valeuri + frame[c+d+f];
          }
          puiInjec = valeuri.toInt();
        }
      }
    }
    Serial.print("Conso :"); Serial.println(puiConso);
    Serial.print("Injec :"); Serial.println(puiInjec);
  }
  // ici vous pouvez faire autre chose
  display.clearDisplay();
  display.setCursor(0, 0);
  display.print("Inj: ");
  display.println(puiInjec);
  display.print("Conso: ");
  display.print(puiConso);
  display.display();

}

Le rapport de téléversement est :
Le croquis utilise 17436 octets (56%) de l'espace de stockage de programmes. Le maximum est de 30720 octets.
Les variables globales utilisent 1727 octets (84%) de mémoire dynamique, ce qui laisse 321 octets pour les variables locales. Le maximum est de 2048 octets.
Et le moniteur série affiche PRET en boucle.
Est ce un problème de mémoire dynamique trop petite ?
Merci pour vos réponses.
Laurent

La librairie Adafruit alloue un buffer dynamiquement :

  if ((!buffer) && !(buffer = (uint8_t *)malloc(WIDTH * ((HEIGHT + 7) / 8))))

Dans le cas du 128x32 : 128 * ((32 + 7) / 8) = 624 bytes
Les 321 bytes ne suffisent pas.

Il faudrait essayer la librairie de Greiman.
Mais il est impossible d'afficher des graphiques avec cette librairie.
Autre point : le positionnement en Y se fait en nombre de lignes, pas en pixels.

Merci.

Ton problème vient en grande partie de ceci.

Avec un processeur pourvu de 2K de RAM ça fait beaucoup ...

Le débit en entrée n'est pas très élevé. Tu devrais pouvoir traiter les données à la volée avec une petite machine à états ce qui permettrait d'éviter ce gros buffer.

J'ai donc essayé la librairie de Greiman qui améliore les choses mais pas suffisament :
Le croquis utilise 8198 octets (26%) de l'espace de stockage de programmes. Le maximum est de 30720 octets.
Les variables globales utilisent 1423 octets (69%) de mémoire dynamique, ce qui laisse 625 octets pour les variables locales. Le maximum est de 2048 octets.

Le program fonctionne un peu mais de manière aléatoire.

J'ai donc décidé de passer sur un nano every (6kbyte de ram) :
Le croquis utilise 20886 octets (42%) de l'espace de stockage de programmes. Le maximum est de 49152 octets.
Les variables globales utilisent 1902 octets (30%) de mémoire dynamique, ce qui laisse 4242 octets pour les variables locales. Le maximum est de 6144 octets.

Mais la libriarie de Greiman n'est pa compatible avec cette carte et malgré la profusion de RAM ça ne fonctionne pas mieux avec adafruit.

Retour à la case départ...

Qu'est ce qui cloche ?