Go Down

Topic: Pointer oder Variablennamen nummerieren? (Read 3416 times) previous topic - next topic

hoddl

Ich bin dabei als Einsteiger eine Uhr auf einem 320 x 240 Display zu Programieren.
Die Zahlen lade ich mir als Bitmap von extern. Das Bitmap ist als Array abgespeichert.
Ich will nun das Bitmap mit der richtigen Nummer in Abhängigkeit einer Zählvariablen laden.
Ein Array bekomme ich nicht hin, weil das Bitmap ja schon ein Array ist.
Und alle Anleitungen die ich zum Thema Pointer gefunden habe passen irgendwie nicht.
Ich stelle mir vor, dass ich eine char array definiere mit den Namen der externen Dateien und die Inhalte der Datei als Variablenname gedeutet werden.

extern unsigned int hour0[0xC80];   //Verweis auf die Externe Datei hour0.c
.
.
extern unsigned int hour0[0xC80];   //Verweis auf die Externe Datei hour9.c

char bild[10] = {hour0, hour1, ...., hour9};   //  ich hab auch schon &hour0, &hour1,... versucht
.
.
myGLCD.drawBitmap(40, 40, 40, 80, bild[0]); // das Bitmap zeichnen

Bei den versuchen kommt immer die Fehlermeldung, dass das Umwandeln des int in char nicht klappt.

Kann mir jemand helfen?

uwefed

Es gibt mehrdimensionale Arrays.
zB: zahlen[zahl][bildmap]
Grüße Uwe

hoddl

Hallo Uwe,
danke für den Hinweis aber die Externe Datei hat ja nun den Namen hour1 und nicht hour[1].

mkl0815

Kurze Frage, wird denn die Datei mit den einzelnen Ziffern zur Laufzeit des Programms geladen, oder soll das während des Compilierens passieren? Ich verstehe nämlich irgendwie Deinen Ansatz noch nicht so richtig.
Mario.

uwefed

Ich schaue da auch nicht mehr durch.
Grüße Uwe

jurs


Bei den versuchen kommt immer die Fehlermeldung, dass das Umwandeln des int in char nicht klappt.

Kann mir jemand helfen?


Da es von Anfang an klar ist, dass der Tag 24 Stunden, die Stunde 60 Minuten und die Minute 60 Sekunden hat, ist es eine völlige Verschwendung von Speicherplatz, Dateinamen mit entsprechendem Bezug fest im Programm abzuspeichern, egal in welcher Datenstruktur.

Die Dateinamen kannst Du Dir stattdessen bei Bedarf mit einer selbstgeschriebenen Funktion im Programm in einem char-Array erzeugen lassen. Beispiel anbei, der Dateiname kann mit Präfix, Zählnummer und gewünschter Dateiendung vorgegeben werden und wird vom Beispielprogramm nur über Serial ausgegeben. Natürlich kann der so erzeugte Dateiname auch verwendet werden, um eine Datei mit diesem Namen dann beispielsweise von SD-Karte zu laden.

Code: [Select]

// How to create filenames on the fly
// by "jurs" for German Arduino Forum

void createFilename(char* buf, int bufsize, char* prefix, int i, char* postfix)
{
  snprintf(buf, bufsize, "%s%d%s", prefix, i, postfix);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  char filename[13];
  for (int i=0;i<24;i++)
  {
    createFilename(filename,sizeof(filename),"hour",i,".c");
    Serial.println(filename);
  } 
  for (int i=0;i<60;i++)
  {
    createFilename(filename,sizeof(filename),"minute",i,".bmp");
    Serial.println(filename);
  } 
  for (int i=0;i<60;i++)
  {
    createFilename(filename,sizeof(filename),"sec",i,".abc");
    Serial.println(filename);
  } 
}

void loop() {
  // put your main code here, to run repeatedly:
 
}


hoddl

Also den erste Test für das Layout habe ich nach folgendem  Muster gemacht:

extern unsigned int hour0[0xC80];   //Verweis auf die Externe Datei hour0.c
.
.
extern unsigned int hour0[0xC80];   //Verweis auf die Externe Datei hour9.c
und im loop
myGLCD.drawBitmap(40, 40, 40, 80, hour0); // das Bitmap zeichnen
delay(1000);
myGLCD.drawBitmap(40, 40, 40, 80, hour1); // das nächste Bitmap zeichnen

das hat auch soweit geklappt.

myGLCD ist aus der Bibliothek zum Display. Ich rufe also nacheinander die einzelnen Bitmaps auf und überschreibe damit die entsprechende Stelle im Display.
Und ich möchte halt nicht für jede Ziffer 10 bzw. 5 oder 2 Abfragen nach dem Motto
If Stunde =1 drawBitmat hour1
sondern
Stunde=i drawBitmap hour

Das Display hat auch eine SD card, ich kann also auch die Bitmaps darauf speichern.
Also zu Deiner Frage Mario: Die Datei wird zur Laufzeit geladen.

hoddl

Hallo Jurs,
es geht darum, die Ziffern der Uhr zu gestalten. Ich Male sie also, und wandele sie in Bitmaps um.
Also habe ich 10 Ziffern für die Stunden und 10 Ziffern für die Minuten also 20 Bilder.
Wie man das macht aus der Uhrzeit die einzelnen Ziffern und danach dem richtigen Bitmaps zuzuorden bekomme ich hin.
Aber dann das Bitmap auch zu laden nicht.

jurs


Hallo Jurs,
es geht darum, die Ziffern der Uhr zu gestalten. Ich Male sie also, und wandele sie in Bitmaps um.
Also habe ich 10 Ziffern für die Stunden und 10 Ziffern für die Minuten also 20 Bilder.


OK, ich hatte anfangs verstanden, Du hast 24 Bilder für 24 Stunden, und 60 Bilder für 60 Minuten, aber im Prinzip ist es dasselbe: Der Dateiname kann aus Dateipräfix, Zählnummer und Dateiendung vom Programm gebildet werden. Im Programm gibt es nur eine einzige Variable für den Dateinamen. Also NICHT verschiedene Variablen für verschiedene Dateinamen, sondern EINEN (sich nach Bedarf ändernden) Dateinamen.


Wie man das macht aus der Uhrzeit die einzelnen Ziffern und danach dem richtigen Bitmaps zuzuorden bekomme ich hin.
Aber dann das Bitmap auch zu laden nicht.


Und wenn Du das mit den Dateinamen so weit abstrahiert hast, ist es mit den Bitmaps genau dasselbe: Du brauchst nicht x verschiedene Bitmaps mit x verschiedenen Namen im Programm, sondern Du brauchst nur EIN Bitmap. Und in das eine Bitmap lädst Du dann ganz verschiedene Inhalte hinein, mal das Bitmap aus der einen Datei, dann das Bitmap aus der nächsten Datei, dann wieder das nächste. Und zwar immer wieder in das EINE existierende Bitmap, von dem aus Du es dann auf den Bildschirm überträgst.


hoddl

Hallo Jurs,
ich habe nun mal versucht Deinen Hinweis um zusetzten.
Ich habe das Gefühl das mir da einige Grundlagen fehlen um das zu verstehen.
Mein Problem ist der Befehl

myGLCD.drawBitmap(40, 40, 40, 80, hour2);

Mit diesem zeichne ich ein Bitmap das als int hour2[0xC80]; definiert ist.

Wenn ich nun nach Deinem Vorschlag ein Filename generiere und dieses in den Befehl zum Schreiben des Bitmaps einfüge kommt die Fehlermeldung, dass es sich um ein char array und nicht um ein int Array handelt.
Es wird also als char array gedeutet und nicht als Variablenname.


uwefed

Die Idee von Jurs ist eine große Bildmap mit allen Zahlen und immer nur den Teil herauslesen den man braucht.

Grüß Uwe

jurs


myGLCD.drawBitmap(40, 40, 40, 80, hour2);

Mit diesem zeichne ich ein Bitmap das als int hour2[0xC80]; definiert ist.


Ok, Du definierst in Deinem Programm ein Bitmap folgender Größe:
sizeof(int) * 0xC80 = 2 * 3200 = 6400 Bytes

Ein Arduino UNO hat nur 2048 Bytes RAM gesamt, den kannst Du dafür gar nicht verwenden, läuft nicht.

Und bei einem MEGA Board mit 8 KB = 8120 Bytes verballerst Du 6400 Bytes für EINE Variable!
Auch bei einem MEGA hast Du nicht den RAM-Speicher, um noch ein zweites solches Array derselben Größe zu definieren, es fehlt schlichtweg an RAM-Speicher dafür.

Oder welches Arduino-Board verwendest Du? Den DUE vielleicht?

Um RAM-Speicher zu sparen, mußt Du immer dasselbe Array für die Bilder verwenden, die an das Display gesendet werden, und nicht für jedes Bild eine neue Riesen-Variable deklarieren.


ich habe nun mal versucht Deinen Hinweis um zusetzten.
Ich habe das Gefühl das mir da einige Grundlagen fehlen um das zu verstehen.
Mein Problem ist der Befehl

myGLCD.drawBitmap(40, 40, 40, 80, hour2);

Mit diesem zeichne ich ein Bitmap das als int hour2[0xC80]; definiert ist.


Wo kommt denn das Bild in hour2 her? Wie wird diese Variable mit Bilddaten gefüllt? Lädst Du die Bilddatei nicht von einer SD-Karte? Hast Du die Daten im Programm codiert vorliegen?


Wenn ich nun nach Deinem Vorschlag ein Filename generiere und dieses in den Befehl zum Schreiben des Bitmaps einfüge kommt die Fehlermeldung, dass es sich um ein char array und nicht um ein int Array handelt.
Es wird also als char array gedeutet und nicht als Variablenname.


Die Funktion myGLCD.drawBitmap arbeitet doch nicht mit Dateinamen, sondern mit Bilddaten, die in einem Array enthalten sein müssen, im RAM-Speicher! Und die Bilddaten müssen natürlich erstmal von der SD-Karte in das Array eingelesen werden.

Mal angenommen, Du möchtest nacheinander die Ziffern 1, 2, 3, 4 auf dem LCD darstellen, dann sieht der Programmablauf grob skizziert so aus:

- Bilde ersten Dateinamen "bild1.bmp"
- Lade Datei "bild1.bmp" von SD-Karte in die Varible "hour2"
- Sende mit der Funktion myGLCD.drawBitmap den Inhalt von hour2 an das Display
- Bilde zweiten Dateinamen "bild2.bmp"
- Lade Datei "bild2.bmp" von SD-Karte in die Varible "hour2"
- Sende mit der Funktion myGLCD.drawBitmap den Inhalt von hour2 an das Display
- Bilde dritten Dateinamen "bild3.bmp"
- Lade Datei "bild3.bmp" von SD-Karte in die Varible "hour2"
- Sende mit der Funktion myGLCD.drawBitmap den Inhalt von hour2 an das Display
- Bilde vierten Dateinamen "bild4.bmp"
- Lade Datei "bild4.bmp" von SD-Karte in die Varible "hour2"
- Sende mit der Funktion myGLCD.drawBitmap den Inhalt von hour2 an das Display

D.h. es wird immer ein neues Bild erst in die (immer gleiche) Variable hour2 geladen, dann das Bild an das Display übertragen.

Wenn Dir jemand den Auftrag gibt "gieß mal 10 Gießkannen Wasser in den Garten", dann holst Du Dir ja auch nicht 10 verschiedene Gießkannen, um dann jede einzelne Kanne im Garten auszugießen, sondern dann gehst Du mit einer einzigen Gießkanne zehnmal zum Wasserhahn, füllst die Kanne, gießt sie aus, füllst sie wieder, gießt sie aus, u.s.w.

Und dasselbe machst Du mit der Bildvariablen hour2 (oder wie Du sie nennen möchtest): Du füllst diese Variable mit immer neuen Bilddaten und gießt die Daten dann über dem Display aus. Aber Du gießt die Daten immer aus derselben Kanne namens "hour2" aus und nicht für 10 Zahlen aus 10 verschiedenen Gießkannen.

hoddl

Vielen Dank noch einmal für die Hilfe.
Ich habe das nun anders gelöst.
Es gibt eine Bibliothek UTFT_ tinyFAT und darin ein Befehl Load Bitmap und der erwartet ein string als Dateinamen. Daher kann ich mit einem char array die einzelnen Zahlen laden.
Gruß

Go Up