PROGMEM_FAR auslesen, wie?

Hallo Zusammen, stehe gerade mit meinem aktuellen Projekt etwas vor einem Problem.

Zum Projekt selbst.
Es handelt sich um eine Ansteuerung von Neopixel LED Strips für zukünftige Live Shows mit meiner Band.
Die LED Streifen werden von Nanos mit Daten versorgt, die Programmnummern von einem HC12 Funkmodul bekommen, und dann diese programmierten Szenen abrufen.

Die Anweisungen werden von einem Klicktrackplayer gesendet, welcher gleichzeitig auch das Tempo für unseren Drummer ausgibt. Dieser arbeitet mit einem Mega, da ich hier realtiv viel Speicher für die Lichtdaten benötige.

Und genau da ist mein Problem. Bisher habe ich alle Lichtdaten in einem PROGMEM Array gespeichert. Doch anscheinend bin ich mittlerweile über dem Limit, was damit möglich ist. Sobald ich mehr daten hinzufüge, funktioniert nichts mehr.

So Speichere ich mir meine Lichtdaten: Pro Array kann es bis 1000 Einträgen kommen.

const long strip12[] PROGMEM = {201001,232032,215015,214001, ... 201001};

Und so lese ich die Daten aus, und sende sie an das HC12 Funkmodul:

if (pgm_read_word(&strip12[anz]) != 200000){HC12.println(pgm_read_dword(&strip12[anz]));}

anz ist dabei nur meine Laufvariable die immer erhöht wird, wenn das nächste Lichtevent gesendet werden soll.

Den Ganze Quellcode möchte ich nicht reinstellen, da dies sonst sehr unübersichtlich wird, und alles andere eigentlich perfekt läuft. Noch zur Info: Laut IDE bin ich bei 38% Programmspeicherplatz, und 14% dynamischen. Also an der Gesammtgröße liegt es nicht. Sobald ich ein paar Events aus einem Array lösche läuft wieder alles.

Meine Suche nach dem Problem ergab, dass ich ab dem Song, der über der Speichergrenze liegt, die Arrays in PROGMEM_FAR anlegen muss. Dies funktioniert soweit auch ganz gut, allerdings stelle ich mich zu blöd an, diese Daten wieder auszulesen. Gibt es eine ähnlich einfache möglichkeit, die Daten wieder auszulesen, so wie ich es beim normalen Progmem schon mache?

Falls ich hier schon irgendwelche massiven Denkfehler habe, bitte etwas Nachsicht. Ich hatte vorher nur kleinere Arduino Projekte und soll gerade in der Technikerschule nebenbei noch Python lernen. Deswegen kann es sein, dass ich hier und da etwas vertausche. Ich hoffe mal jemand kann mir helfen.
Grüße, Jonas!

const long strip12[] PROGMEM = {201001,232032,215015,214001, ... 201001};

Das legt dir eine Variable im Progmem an.
Soweit so gut!

strip12 liefert dir eine 16 Bit Adresse, welche im near Bereich liegt, was du ja nicht unbedingt willst.
Denn in Wirklichkeit weißt du ja nicht ob sie near oder far ist.
Darum benötigst du jetzt einen Zeiger in den far Bereich!
Eine 32 Bit Adresse.

uint32_t far_adresse = pgm_get_far_address(strip12);

Und diese far_adresse kannst du dann mit den pgm_read_word_far() usw. Funktionen auslesen


Ich hoffe, das habe ich jetzt richtig aus meinem Gedächtnis geholt....

Hallo,

Serenifly und Jurs hatten dazu mal was ausführlicher geschrieben ...
https://forum.arduino.cc/index.php?topic=264039.0

combie:
Das legt dir eine Variable im Progmem an.
Soweit so gut!

strip12 liefert dir eine 16 Bit Adresse, welche im near Bereich liegt, was du ja nicht unbedingt willst.
Denn in Wirklichkeit weißt du ja nicht ob sie near oder far ist.
Darum benötigst du jetzt einen Zeiger in den far Bereich!
Eine 32 Bit Adresse.

uint32_t far_adresse = pgm_get_far_address(strip12);

Und diese far_adresse kannst du dann mit den pgm_read_word_far() usw. Funktionen auslesen


Ich hoffe, das habe ich jetzt richtig aus meinem Gedächtnis geholt....

Aaaahhh. Ich glaube ich hatte das bisher immer was vertauscht. Danke, werde ich morgen ausprobieren!

Doc_Arduino:
Hallo,

Serenifly und Jurs hatten dazu mal was ausführlicher geschrieben ...
Zugriff auf PROGMEM-Array - Deutsch - Arduino Forum

Nach so einer Anleitung zu dem Thema habe ich echt lange in google gesucht und nix gefunden. Danke, werde ich mir morgen durchlesen.

Habe gerade etwas rumprobiert, jetzt läufts! Tausend Dank!

Aber warum muss ich für diese Adresse immer um 4 erhöhen, wenn ich meine Elemente aus dem Array lesen möchte? An den 3 Adresse zwischendrin ist nur müll.

So läufts wunderbar, bin nur etwas verwundert über die 4

uint32_t strip12_adresse = pgm_get_far_address(strip12);
if (pgm_read_dword_far(strip12_adresse+anz) != 200000){HC12.println(pgm_read_dword_far(strip12_adresse+anz));}
anz=anz+4

Die Adressen sind byteweise organisiert, Du legst aber long-Werte ab. Die brauchen jeweils 4 Byte.

Aber warum muss ich für diese Adresse immer um 4 erhöhen, wenn ich meine Elemente aus dem Array lesen möchte?

Auch wenn du das Array nicht im Progmem liegen hättest würde der Zeiger mit strip12+1 um 4 weiter gesetzt werden.
Siehe: C++ Zeiger Arithmetik

Da dein Compiler aber keine 32Bit Adressen kennt, funktioniert die Zeiger Arithmetik damit auch nicht.
Darum muss du das händisch tun.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.