Fehlermeldung Arduino C++

OP #4078210
Lesenswert?

Hallo Forum,

ich hacke gerade ein bisschen an der TFT Lib vom Arduino, weil das Laden 
eines 24 Bit BMP mit 160x128 ca. 3s dauert.

Anyway, folgender Fehler ist mir vollkommen unklar. Von C++ hab ich 
keine Ahnung, ich mach nur C&P ;-)

In file included from C:\Programme\Arduino\libraries\TFT\src/TFT.h:6:0,
                 from TFTBitmapLogo.ino:25:
C:\Programme\Arduino\libraries\TFT\src/utility/Adafruit_GFX.h: In member 
function 'void Adafruit_GFX::image(PImage&, uint16_t, uint16_t)':
C:\Programme\Arduino\libraries\TFT\src/utility/Adafruit_GFX.h:297:37: 
error: 'setAddrWindow' was not declared in this scope
     setAddrWindow(x, y, x+w-1, y+h-1);
                                     ^
Fehler beim Kompilieren.

Siehe Anhang.

Meine andere, selbstgestrickte Funktion

void Adafruit_ST7735::drawFastHblock(uint8_t *data, uint16_t cnt) {

funktioniert anscheinend. Zumindest erkennt sie der Compiler.
Angehängte Dateien:
OP #4078245
Lesenswert?

@ Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite

>Naja, wo kommt denn "setAddrWindow" her? Das ist eine Memberfunktion der
>Klasse Adafruit_ST7735, die von Adafruit_GFX abgeleitet ist.

So in etwa.

>Woher aber soll die Basisklasse von dieser Funktion wissen?

Na ich dacht mit dem Eintrag

drawFastHblock(uint8_t *data, uint16_t cnt),

in Adafruit_ST7735.h

Siehe unten.
1
class Adafruit_ST7735 : public Adafruit_GFX {
2

3
 public:
4

5
  Adafruit_ST7735(uint8_t CS, uint8_t RS, uint8_t SID, uint8_t SCLK,
6
    uint8_t RST);
7
  Adafruit_ST7735(uint8_t CS, uint8_t RS, uint8_t RST);
8

9
  void     initB(void),                             // for ST7735B displays
10
           initG(void),                             // for ILI9163C displays
11
           initR(uint8_t options = INITR_GREENTAB), // for ST7735R
12
           setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1),
13
           pushColor(uint16_t color),
14
           fillScreen(uint16_t color),
15
           drawPixel(int16_t x, int16_t y, uint16_t color),
16
           drawFastHblock(uint8_t *data, uint16_t cnt),

OK, falsch gedacht. Wo muss die Deklaration noch rein (jaja, aber 
wirklich, ich habe KEINE Ahnung von C++, hab nur mal vor Jahren ein C++ 
Buch durchgeblättert, ich weiß, C++ Buch kaufen und durcharbeiten).
OP #4078261
Lesenswert?

OK, mit C&P hat es dann doch geklappt. ;-)
1
class Adafruit_GFX : public Print {
2
 public:
3

4
  Adafruit_GFX(int16_t w, int16_t h); // Constructor
5

6
  // This MUST be defined by the subclass
7
  virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
8
  virtual void setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) = 0;
9
  virtual void drawFastHblock(uint8_t *data, uint16_t cnt) =0;
OP #4078527
Lesenswert?

So liebe Leute, hier mal mein Ergebnis. Wie gesagt, ich spiel im Moment 
mit dem Arduino TFT rum, die Lib kann BMP Bilder direkt von SD-Karte auf 
den TFT kopieren, allerdings ist das etwas langsam. Darum hab ich die 
Funktionen etwas aufgebohrt, jetzt werden auch direkt 16 Bit BMPs 
gelesen, was schon 7mal so schnell ist, ausserdem kann man Bilder in den 
Flash legen und von dort direkt anzeigen, was nochmal ca. doppelt so 
schnell ist!
1
Datei (B x H x Bits) Ladezeit / ms
2
48x48x24                 351   
3
1260x128x24             2930
4
48x48x16                  47 
5
160x128x16               414 
6
48x48x16 (Flash)          19
7
80x128x16 (Flash)         84

Das kann sich schon mal sehen lassen.
Es gibt dabei folgende Begrenzungen.

1.) Ein einzelnes Bild im Flash darf max. 32767 Bytes groß sein, denn 
hier greift leider die maximale Größe eines einzelnen char[] Arrays. 
D.h. man kann nicht ganz die vollen 160x128 in ein Bild packen. Wenn man 
das will, muss man es zweiteilen.
2.) Die Gesamtanzahl an Bilddaten darf 64kB nicht übersteigen, auch 
nicht auf dem MEGA256, weil auch hier wieder die Grenze der Pointer im 
avr gcc mit 64 kB greift. Ausserdem scheint das Programm gar nicht erst 
loszulaufen, wenn deutlich mehr als 64kB Flashgröße erzeugt werden (Bug 
im avr gcc, wenn der Einsprung vom Resetvektor >64kB?, Problem im 
Bootloader?)

Auf dem DUE mit dem ARM sollten diese Begrenzungen nicht greifen. Kann 
ich mangels Hardware aber nicht testen.

Beim Laden von Bildern vom Flash gibt es keine Größenbegrenzung.

Wenn man ein Bild in den Flash legen will, muss man

-das Bild mit einem Grafikprogramm wie GIMP o.ä. als 16 Bit BMP 
speichern, wobei es als Top-Down gespeichert werden muss!
- mit dem Tool bin2c in C-Quelltext umwandeln und per include einfügen.

auf der Kommandozeile z.B. so

bin2c bild.bmp >bild.c

- die Kopfzeile muss man manuell anpassen, siehe Beispiel.
- in sketch mittels der neuen Methode TFTscreen.loadImageFlash() 
"laden", dabei wird der Header dekodiert.
- Die Anzeige auf dem TFT erfolgt mit der bekannten Methode 
TFTscreen.image(), welche erweitert wurde.

Das Archiv TFT.zip muss in C:\Programme\Arduino\libraries, es enthält 
die erweiterten Methoden für den TFT
Das Archiv TFTBitmapLogo.zip enthält das sketch und die includes für die 
Bilder sowie das tool. Im sketch muss man die Pfade der Bilder anpassen, 
irgendwie mag Arduino keine relativen Pfade im Projektverzeichnis, oder?

Ach ja, das Pinout für den TFT/SD-Shield hab ich passend für meinen 
Lochrasterausbau gewählt, kann man aber leicht mit den #defines am 
Anfang ändern, ist glaube ich selbsterklärend.

Viel Spaß damit
Falk
Angehängte Dateien:
OP #4078789
Lesenswert?

@ Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite

>> Ein einzelnes Bild im Flash darf max. 32767 Bytes groß sein, denn hier
>> greift leider die maximale Größe eines einzelnen char[] Arrays.

>Wieso sollte es da eine Begrenzung geben?

Weil dass der gcc auspuckt.
1
In file included from TFTBitmapLogo.ino:28:0:
2
D:\Projekte\Arduino\TFT\TFTBitmapLogo\a\che.c:1:12: error: size of variable 'che' is too large
3
 const char che[] PROGMEM = {

Das Array ist ~40kB.

http://www.avrfreaks.net/forum/sizet

> Könnte es sein, daß Du einen
>ungünstigen Datentyp als Index zum Arrayzugriff verwendest?

Nö, er meckert über die Definition. Da gibt es noch dar keinen Index.
OP #4078970
Lesenswert?

Ein paar Links zum Thema.

http://www.avrfreaks.net/forum/maximum-size-progmem-array

http://www.avrfreaks.net/forum/sizet

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Flash_mit_PROGMEM_und_pgm_read

Bisschen runter, Variablenzugiff > 64kB. (ich kann keinen direkten Link 
erzeugen, doofe Formatierung).

Was am Ende zu der Aussage führt, dass der ArduinoMEGA256 mit seinem 
großen Speicher nutzlos ist, denn der avr gcc kann damit nicht direkt 
umgehen. Ein typischer Aduinouser kann und will nicht mit den Makros und 
den Linkeroptionen rumeiern, ich auch nur bedingt. Also Leute, kauft 
euch besser einen Arduino DUE oder andere ARMs, die können ihren 
Speicher ohne Handstände voll ausnutzen.
Der einzige Vorteil des MEGA256 sind mehr Pins und IO Module (UARTs, 
SPI, Timer, PWM, etc).
#4094434
Lesenswert?

frischling schrieb:
> Ich dachte es gäbe eine "logische" Erklärung.
> Irgend einen Hintergrund technischer Natur.

Wie Vieles: weil's schon immer so war und jetzt kann's keiner mehr 
ändern.

Die Definition erlaubt aber auch negative Indizes (und Compiler können 
damit umgehen, obwohl's keiner benutzt). Mit
1
    char *p, *arr;
2
    int i;
3

4
    p = malloc(64 * 1024L);
5
    arr = p + 32 * 1024L;
6

7
    for (i = -32 * 1024; i < 32 * 1024 - 1; i++)
8
        arr[i] = 'A';
(mag sein, daß da noch ein "um eins daneben" Fehler drinsteckt, hab' ich 
jetzt aus der Hüfte geschossen) kannst Du deswegen auch mit 16-Bit 
signed ints 64k Arrays beackern.
#4096594
Lesenswert?

frischling schrieb:
> Naive gefragt, warum signed ?
>
> Zur Adressierung braucht es doch keine negativen Zahlen ?

Pointer-Arithmetik erlaubt die Bildung der Differenz der Adressen zweier 
Elemente eines Arrays. Da diese Differenz auch negativ sein kann, wird 
ein vorzeichenbehafteter Wert benötigt.

Beispiel:

Ich will in einem String die Zahl an Zeichen vom ersten e bis zum ersten 
a ermitteln:
1
const char* text = "Hallo Welt";
2

3
const char* e = strchr(text, 'e');
4
const char* a = strchr(text, 'a');
5
int diff = a - e;
Da das a vor dem e liegt, ist das Ergebnis hier negativ.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren