[gelöst] ESP8266 - PROGMEM-String-Array will nicht ...

Hallo.
Ich habe wieder ein Problem. Ich möchte ein String-Array für ein Display-Projekt mit PROGMEM für den ESP hinkriegen, da der Text wahrscheinlich mindestens 10 kB einnimmt. Doch das will irgendwie nicht so, wie ich es will. Das Programm kompiliert zwar, aber ich bekomme vom ESP Fehlermeldungen. Programm:

/*
 PROGMEM string demo
 How to store a table of strings in program memory (flash),
 and retrieve them.

 Information summarized from:
 http://www.nongnu.org/avr-libc/user-manual/pgmspace.html

 Setting up a table (array) of strings in program memory is slightly complicated, but
 here is a good template to follow.

 Setting up the strings is a two-step process. First define the strings.
*/

#include <avr/pgmspace.h>
const char string_0[] PROGMEM = "String 0";   // "String 0" etc are strings to store - change to suit.
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";


// Then set up a table to refer to your strings.

const char* const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5};

char buffer[30];    // make sure this is large enough for the largest string it must hold

void setup()
{
  Serial.begin(115200);
  Serial.println("OK");
}


void loop()
{
  /* Using the string table in program memory requires the use of special functions to retrieve the data.
     The strcpy_P function copies a string from program space to a string in RAM ("buffer").
     Make sure your receiving string in RAM  is large enough to hold whatever
     you are retrieving from program space. */


  for (int i = 0; i < 6; i++)
  {
    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy.
    Serial.println(buffer);
    delay(500);
  }
}

Es ist ein Referenz-Beispiel. Fehler vom ESP:

Exception (28):
epc1=0x402068ce epc2=0x00000000 epc3=0x00000000 excvaddr=0x000083c8 depc=0x00000000

>>>stack>>>

ctx: cont
sp: 3ffffdc0 end: 3fffffc0 offset: 01a0
3fffff60:  800083c8 00000001 3ffee254 40201319  
3fffff70:  3ffe8560 00000001 3ffee254 fffffffc  
3fffff80:  4023839c 00000020 40238384 402010a7  
3fffff90:  feefeffe 00000000 3ffee254 3ffee2ac  
3fffffa0:  3fffdad0 00000000 3ffee27c 40201800  
3fffffb0:  feefeffe feefeffe 3ffe84f4 40100461  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v8b899c12
~ld
OK

Exception (28):
epc1=0x402068ce epc2=0x00000000 epc3=0x00000000 excvaddr=0x000083c8 depc=0x00000000

>>>stack>>>

ctx: [...]

Exception 28 steht für "A load referenced a page mapped with an attribute that does not permit loads", was ich erstens mit Hilfe von Google Translate nicht ganz verstehen kann und worüber ich zweitens keine Lösung online finden konnte. Was mache ich falsch? Braucht ihr mehr Infos?

Bevor ihr denkt, dass ich mich überhaupt nicht mit µCs auskenne: Mir ist klar, dass sich AVR-Arduinos und ESPs wesentlich unterscheiden. Aber alles, was ich für den ESP gefunden habe, war genau das oder ähnliches (mit anderen Variablennamen und so).

Wie wäre es, wenn Du uns auch noch sagst für welchen ESP? Die unterscheiden sich doch erheblich.

Den ESP-Exceptiondecoder hast Du schon im Einsatz?

Gruß Tommy

Hallo,

ich verwende einen NodeMCU. Diesen Dingsbums-Decoder kenne ich nicht.

Dein Google ist defekt? Exceptiondecoder.

Die andere Antwort ist genau so sinnlos. NodeMCU gibt es sowohl mit ESP8266, als auch mit ESP32.
Sorry, der ESP8266 steht ja in der Überschrift, das hatte ich übersehen.
Hier ist die Doku zu PROGMEM auf ESP8266.

Gruß Tommy

Hallo,

die Doku hatte ich mir auch schon näher angesehen - ohne Erfolg. Ich habe kein Beispiel gefunden, das dem der Arduino-Referenz ähnelt.

So funktioniert es:

#include <pgmspace.h>

const char string_0[] PROGMEM = "String 0";   // "String 0" etc are strings to store - change to suit.
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";


// Then set up a table to refer to your strings.

const char* const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5};

char buffer[30];    // make sure this is large enough for the largest string it must hold

void setup()
{
  Serial.begin(115200);
  Serial.println("OK");
}


void loop()
{
  /* Using the string table in program memory requires the use of special functions to retrieve the data.
     The strcpy_P function copies a string from program space to a string in RAM ("buffer").
     Make sure your receiving string in RAM  is large enough to hold whatever
     you are retrieving from program space. */


  for (int i = 0; i < 6; i++)
  {
    strcpy_P(buffer, (char*)pgm_read_ptr(&(string_table[i]))); // Necessary casts and dereferencing, just copy.
    Serial.println(buffer);
    delay(500);
  }
}

Du musst pgm_read_word durch pgm_read_ptr ersetzen.
ich habe auch nur <pgmspace.h> includiert, nichts mit avr.

IDE 1.8.10 ESP8266 Version 2.5.2 oder auch 1.8.8 mit 2.4.2

Gruß Tommy

Super! Funktioniert, vielen Dank!

Tommy56:
ich habe auch nur <pgmspace.h> includiert, nichts mit avr.

Die Unterscheiden sich nicht. Ist nur für bessere Kompatibilität. Und für faule Menschen :wink: . Inhalt von avr/pgmspace.h:

#include "../pgmspace.h"