Hallo zusammen.
Ich habe mein eigentliches Problem bereits gelöst. Ich möchte aus einem
Array im PROGMEM einen String auf einem LCD ausgeben, unter Zuhilfenahme
der HD44780 Library hier aus dem Board.
So funktioniert es:
Da ich aber zu Anfang nicht wusste, dass die Library auch direkt mit dem
PROGMEM arbeiten kann (lieber zwei Stunden rumprobieren als eine Minute
lesen) habe ich im ersten Ansatz versucht, dies über den (manuellen)
Umweg über das RAM zu machen. Es hat nicht funktioniert, und ich würde
gerne noch verstehen warum nicht?
Also so sah es aus:
// Kopiere den Inhalt der i-ten Zeichenkette vom Flash ins RAM
8
strcpy_P(buf,mainmenu[i]);
9
}
10
11
read_string(buffer,1);
12
lcd_string(buffer);
Nix. Das Display blieb leer. Warum? So müsste es doch eigentlich auch
gehen. Ich verstehe das auch syntaktisch nicht ganz. Es heißt "Kopiere
die Zeichenkette ins RAM", also den "literalen" String aus PROGMEM
mainmenu[] nach RAM buf - zumindest verstehe ich die Beschreibung so.
Warum muss "buf" (und auch mein buffer) dann als Pointer initialisiert
werden? Und wenn der - anders als beschrieben - dann nicht die
Zeichenkette selber sondern nur den Pointer zu der Zeichenkette enthält,
ist auch einlechtend warum nix auf dem Display kommt.
Wie gesagt, ich möchte nur noch verstehen warum es so nicht funktioniert
hatte. Habt Nachsicht mit mir, bin noch AVR-GCC Anfänger :-)
Beste Grüße
Holger
Holger K. schrieb:> const *buffer=NULL;
Diese Konstante hat keinen Typ (wird zum default-Typ gestempelt),
und eine Konstante kann bekanntlich nicht verändert werden.
Versuchs mal mit
@ Holger Keil (zaldo)
>So funktioniert es:>const char mainmenu[] [8] PROGMEM = {"Menue 1","Menue 2","Menue 3"};>lcd_string_P(mainmenu[1]);
Damit ist dein Problem gelöst.
>Umweg über das RAM zu machen. Es hat nicht funktioniert, und ich würde>gerne noch verstehen warum nicht?>const char mainmenu[] [8] PROGMEM = {"Menue 1","Menue 2","Menue 3"};>char *buffer=NULL;
Das ist nur ein Pointer, kein Array. Du brauchst aber ein Array, wo du
deine Daten reinkopierst.
>// so aus dem Tut übernommen...
Tut? tut tut? Baysprache? Hipstersyndrom?
Meine Herrn, man kann es mit den Abks. echt übertreiben!
>void read_string (char* buf, size_t i)>{> // Kopiere den Inhalt der i-ten Zeichenkette vom Flash ins RAM> strcpy_P (buf, mainmenu[i]);>}>read_string(buffer, 1);
Damit landen die Daten im RAM ab Adresse NULL. Das willst du sicher
nicht.
>lcd_string(buffer);
Eher so.
Falk B. schrieb:
Danke, wenigstens mal ein konstruktiver Beitrag!
> Damit ist dein Problem gelöst.
Ich weiß, aber aus Fehlern lernt man nur, wenn man auch versteht wo und
warum sie waren.
>>char *buffer=NULL;>> Das ist nur ein Pointer, kein Array. Du brauchst aber ein Array, wo du> deine Daten reinkopierst.
Ich dachte, weil die Rückgabe von strcpy_P doch ein Pointer ist.
"The strcpy_P() function returns a pointer to the destination string
dest."
Ist die Rückgabe demnach also ein Array von Pointern?
>>// so aus dem Tut übernommen...>> Tut? tut tut? Baysprache? Hipstersyndrom?>> Meine Herrn, man kann es mit den Abks. echt übertreiben!
Die Abk. von Abk. ist Abk.
TUTorial war gemeint
Und ich glaube da war das größte Mißverständnis bei mir. Ich bin davon
ausgegangen, dass er den String aus mit [i] referenzierten Element des
Arrays (im Flash) direkt als Rückgabe übergibt.
Er kopiert also nur das komplette Array vom Flash ins RAM, und liefert
ein Array mit den Startadressen der jeweiligen Elemente im RAM zurück?
> const char mainmenu[] [8] PROGMEM = {"Menue 1","Menue 2","Menue 3"};> char buffer[8];>> strcpy_P (buf, mainmenu[i]);> lcd_string(buffer);
Wo bekommt buffer in dem Beispiel denn seinen Inhalt her?
Arduinoquäler schrieb:> ... keiner hätte es sonst gewusst.
Zumindest hat es keiner sonst geschrieben. Gelegenheit (mehr als nur
Gegenfragen oder Links zu posten) wäre ja gewesen.
@ Holger Keil (zaldo)
>>>char *buffer=NULL;>>>> Das ist nur ein Pointer, kein Array. Du brauchst aber ein Array, wo du>> deine Daten reinkopierst.>Ich dachte, weil die Rückgabe von strcpy_P doch ein Pointer ist.
Der interessiert nicht.
>"The strcpy_P() function returns a pointer to the destination string>dest."
Den kein Mensch braucht, dieser Rückgabewert ist rein akademisch, denn
eben dieser Pointer wird ja als Argument übergeben.
>Ist die Rückgabe demnach also ein Array von Pointern?
Nein.
>TUTorial war gemeint
Das weiß ich, trotzdem geht es mir auf den Keks!
>Und ich glaube da war das größte Mißverständnis bei mir. Ich bin davon>ausgegangen, dass er den String aus mit [i] referenzierten Element des>Arrays (im Flash) direkt als Rückgabe übergibt.
Nein.
>Er kopiert also nur das komplette Array vom Flash ins RAM,
Nein, er kopiert nur einen String des Array, in deinem Beispiel
mainmenu[i].
Vorsicht! mainmenu[i] ist ein Pointer auf den Arrayeintrag so wie
mainmenu (ohne Index) ein Pointer auf das Gesamtarray ist. Nur wenn alle
Indizes angegeben werden, wie z.B. mainmenu[1][i] ist das der INHALT des
Arrays an dieser Stelle. Nicht wundern, das ist nun mal C.
> und liefert>ein Array mit den Startadressen der jeweiligen Elemente im RAM zurück?
Nein, die Funktion liefert einen einfachen Pointer als Rückgabewert,
siehe oben.
>> const char mainmenu[] [8] PROGMEM = {"Menue 1","Menue 2","Menue 3"};>> char buffer[8];>>> strcpy_P (buf, mainmenu[i]);>> lcd_string(buffer);>Wo bekommt buffer in dem Beispiel denn seinen Inhalt her?
Na wie wohl? Das macht die Funktion!!! Die könnte in etwa so aussehen.
Falk B. schrieb:>Nicht wundern, das ist nun mal C
Ja hab schon bemerkt, wenn man sich vorher nur ein wenig mit VB und PHP
befasst hat, kommt man schon das eine oder andere mal ins grübeln :-)
> Na wie wohl? Das macht die Funktion!!! Die könnte in etwa so aussehen.
Ok, dann aber
Holger K. schrieb:> Ok, dann aber strcpy_P (buffer, mainmenu[i]);> und nicht> strcpy_P (buf, mainmenu[i]);
Er zeigt dir wo deine Fehler sind und wie das Ganze aufzubauen ist
und du findest es nötig, ihn auf einen Schreibfehler aufmerksam zu
machen ?
Nu lass mal die Kirche im Dorf Marc. Das war nicht als Belehrung zu
verstehen, ich wollte nur sicher gehen dass ich es richtig verstanden
habe. Und wenn es nur ein Schreibfehler ist finde ich es auch
grundsätzlich nicht verwerflich ihn zu korrigieren. Irgendjemand stößt
vielleicht ein anderer Anfänger mit demselben Problem über die Suche auf
den Thread und findet was was er aus gutem Grund nicht nachvollziehen
kann.
hmmmmmmm ..... ich hätte da gerne noch mal ein Problem ...
Kann mir bitte jemand sagen warum das nicht funktioniert:
1
strcpy_P(buffer,(PGM_P)"TestString");
Die Zeile übersetzt sich fehlerfrei .... aber ....
Man kann den konstanten String casten wie man will, der
GCC reserviert dafür immer RAM.
Anders herum gefragt: wie bekommt man (Konstanten-)Strings
ins Flash ohne Variablen zu deklarieren?
Rainer B. schrieb:> wie wär's mit PSTR ?
Ja danke, das funktioniert.
Wie soll da einer draufkommen .... Ich hab es mir vorher im
Header-File angeschaut und bin nicht drübergestolpert.
Falk B. schrieb:> RTFM. Die Doku der libc ist dein Freund und Helfer.
Ja, ich weiss. Ich hätte eigentlich nicht fragen sollen
dürfen müssen können. Meine Frage war etwa so blöd wie:
"Wie setze ich beim ATMega8, Port B ein Bit auf 1"
'Tschuldigung dass ich meine Frage nicht selbst als
"blöde Frage" deklariert habe.
Stringanwender schrieb:> Ich hab es mir vorher im Header-File angeschaut