Hier der Arduino Sketch mit meiner Datenstruktur und meinen
Leseversuchen (sorry, habe nicht herausfinden können, wie man hier Code
vernünftig formatiert):
"Wichtige Regeln - erst lesen, dann posten!"
Formatierung unter: "C-Code"
Die Strings will ich indiziert in ein Array im RAM kopieren,
Warum?
Eine Ausgabe ist auch ohne Kopie möglich.
Vorschlag:
Wenn die Zeichenketten immer gleich lang sind, dann kannst du auch mit einem 2 Dimensionalen Array arbeiten.
Den doofen Count mitzuführen ist dann nicht notwendig. (vielleicht)
count als char ist doof, weil man mit char nicht rechnen kann/soll
Es ist die Optimierung die dir einen Streich spielt.
Der Compiler weiß nix über PROGMEM und EEMEM.
Kennt er nicht, darum benötigen wir auch besondere Zugriffsfunktionen um in die Speicher zu greifen.
Die Verwendung von Konstanten kann der Optimizer super gut optimieren.
Den Zugriff über Variablen weniger.
Wenn man die Optimierung deaktiviert, dann brichts auch mit Konstanten ins Essen.
Hier schalte ich partiell die Optimierung per volatile ab.
a funktioniert trotz falschem Zugriff, dank Optimierung richtig
b funktioniert, zeigt wie es muss
c hat zwei Gesichter ein richtiges, da mit Zugriffsmethode und ein falsches, da Optimierung für c abgeschaltet
Das ist genau die Falle in die du getappt bist
Dein Menü:
1
#include<Streaming.h> // die Lib findest du selber ;-)
Hier schalte ich partiell die Optimierung per volatile ab.
a funktioniert trotz falschem Zugriff, dank Optimierung richtig
b funktioniert, zeigt wie es muss
c hat zwei Gesichter ein richtiges, da mit Zugriffsmethode und ein
falsches, da Optimierung für c abgeschaltet
Sei mir nicht böse, aber das ist Wort für Wort von vorne bis hinten völliger Unsinn.
Da ist beschrieben und dokumentiert, wie man auf Daten im Flash zugreift. Das hat mit irgendwelchen Gesichtern von C (die es nicht gibt) oder abschalten der Optimierung durch volatile (was völliger Unsinn ist) nichts zu tun.
Du hast das Problem des TO nicht verstanden!
Natürlich liegt es an der Optimierung, dass er "versehentlich" richtige Daten bekommt, wenn ihm Konstanten verwendet.
Vorschlag:
Wenn die Zeichenketten immer gleich lang sind, dann kannst du auch mit
einem 2 Dimensionalen Array arbeiten.
So mache ich das auch. Ansonsten ist das ein riesen Wust an Schreibarbeit und somit gerne eine Fehlerquelle.
Im Flash muß man ja nicht mit jedem Byte geizen, da legt man einfach die maximale Länge für alle Strings im Array fest.
Wie schon gesagt wurde, einen Pointer im Flash muß man dann mit pgm_read_word() zugreifen, die Pointerschreibweise x[i] funktioniert also nicht mehr.
Du hast das Problem des TO nicht verstanden!
Natürlich liegt es an der Optimierung, dass er "versehentlich" richtige
Daten bekommt, wenn ihm Konstanten verwendet.
Wenn ein Programm mit/ohne Optimierung funktioniert, und ohen/mit nicht, liegt es niemals an der Optimierung, sondern immer am Programm (seltene Compilerfehler mal ausgenommen). Und den Begriif volatile mit Optimierung in einem Satz zu nennen ist ebenso immer garantiert unsinnig.
Das Problem, daß folgendes nicht das tut, was der TO erwartet
hat nichts mit Optimierungen zu tun, sondern damit, daß SubArray in Flash liegt, und submenu auch. pgm_read_byte macht das, was es lt. Doku macht, und liest ein byte von der übergeben Adresse aus dem Flash. SubArray[i] wird in dem Fall aber einer Adressen im SRam gelesen, obwohl das eigentlich im Flash stehen. Das liefert in solchen Fällen sogar häufig trotzdem das richtige Ergebnis, weil der gleiche Fehler auch beim Schreiben gemacht wird, und die Daten daher tatsächlich im SRAM stehen, und gar nicht bzw. nicht nur, wie eigentlich gewollt, im Flash.
Falsch ist das trotzdem.
Man kann per PROGMEM ins Flash gelegte Daten, auf die ein ebenfalls im Flash liegender Pointer zeigt, nicht in einem Schritt mit pgm_read über den Flashpointer auslesen. Das braucht immer zwei pgm_read-Aufrufe, einer für den Pointer, den zweiten dann für die Daten.