Darauf möchte ich gern ein oder zwei Grafiken anzeigen (Skalen für Messwerte). Damit das ganze halbwegs schön aussieht, würde ich die Skalen in GIMP designen und dann in ein Array umwandeln wollen, so wie das beiligende Testbild. Das Anzeigen des Testbilds funktioniert einwandfrei (siehe Anhang).
Mein Problem:
Ich finde keinen Converter, der dass passende Format ausgibt.
Kenn ihr einen? Mir ist klar das das Bild welches ich wandeln will, die passende Dimension haben muss (320x240px). Die Online Converter wie:
https://notisrac.github.io/FileToCArray/
bieten zwar eine Reihe von Einstellmöglichkeiten, aber leider nicht die Option ein Array zu erstellen.
Das wäre ja super, ich habe GIMP 2.10.32. Da finde ich keine Option den Export oder das Speichern in c auszuwählen, nur .xcf. Gibt es das in den neuen Versionen nicht mehr?
Nimm xxd (xxd -i) oder nimm einen Compiler, der schon das C23
feature #embed unterstützt (clang mit P1967).
Ich habe grade man danach gegoogelt, aber ich verstehe es leider trotzdem noch nicht. Ist "xxd" ein Programm? Und nennt man C23 das Format dieser Bilddatei? Ähnlich wie png, jpg und co bei Bildern?
So lang das Bild bei, ich hab es jetzt erstmal genommen.
Wenn ich das .h in .c ändere und ein neues .h file erstelle, meckert der Compiler. Ich hänge die beiden Dateien mal mit an. Was mache ich falsch? Also laut Compiler gibt es eine Mehrfach Definition, aber wie macht man es richtig?
ili9341/testimg.h:5: multiple definition of `test_img_240x240'; ./Core/Src/main.o:...../ili9341/testimg.h:5: first defined here
Nimm xxd (xxd -i) oder nimm einen Compiler, der schon das C23
feature #embed unterstützt (clang mit P1967).
Ich habe grade man danach gegoogelt, aber ich verstehe es leider
trotzdem noch nicht. Ist "xxd" ein Programm? Und nennt man C23 das
Format dieser Bilddatei?
Nein, mit C23 ist hier der neue C-Standard C23 gemeint.
wenn der Zeiger über die Skalenelemnte schreibt, dann bekommt man beim Pixelbasierten Löschen und Zeichnen flackernde Anzeigen. Das machen Objetbasierte Grafiklibs besser, siehe z.B. lvgl. Es hängt dann vom verwendeten STM32 ab, das braucht schon etwas mehr RAM und Flash.
Damit das ganze halbwegs schön aussieht, würde ich die
Skalen in GIMP designen und dann in ein Array umwandeln wollen,...
Also das Thema "Grafiken auf dem µC" ist schon fast uralt und dazu hat es hier in diesem Forum auch schon ellenlange Beiträge gegeben. Auch von mir.
Naja, zeichnen kannst du sowas mit einem recht beliebigen Programm, solange du ein übliches Dateiformat damit erzeugen kannst. Die Frage ist eher, wie du so eine Grafik im µC halten willst. Als einfache Bitmap, also im Prinzip BMP, wird sowas recht unfänglich. Also wäre es durchaus angesagt, so eine Grafik komprimiert vorzuhalten, vorausgesetzt, die Entkomprimierung ist einfach zu erledigen. Also nix mit JPG oder PNG, die sind für den µC nicht die erste Wahl.
Siehe mal da:
Beitrag "Bildformat für Farb-LCD"
Nein, mit C23 ist hier der neue C-Standard C23 gemeint.
OK, aber kann ich das überhaupt einstellen? Ich nutze die Cube IDE von STM. Ist da nicht immer "der aktuellste Stand" drin? So oft wie die IDE ein Update machen will gehe ich davon mal aus :D.
Ich verwende einen F303CC, meint ihr der schafft die lvgl?
https://lvgl.io/demos Das Thermostat UI wäre sowas in der Richtung was ich anstrebe, dass sieht schon nett aus. Der Vorteil von lvgl wäre natürlich auch der Font und Image Converter, passend zur lib.
Ich hatte mich eigentlich schon mit Touch GFX versucht, aber das war mir zu aufgebläht. Jede Variable die ich anzeigen lassen wollte, musste ich durch mehrere Files durchreichen und der Speicherverbrauch war auch recht hoch.
Ich verwende einen F303CC, meint ihr der schafft die lvgl?
Sollte schon passen.
lvgl braucht nicht den ganzen Bildschirminhalt im RAM vorhalten, sondern kommt mit einem Buffer über ein paar Zeilen aus.
Optional aber empfehlenswert: einen zweiten Buffer und DMA für den Display-Treiber. Dann kann der zweite Buffer vor-gerendert werden, während der erste noch über SPI rausgeht.
Ich finde keinen Converter, der dass passende Format ausgibt.
Du brauchst gar keinen Konverter - jedenfalls, wenn Du den GNU Linker ld verwendest. Der kann beliebige Dateien in Objektdateien umwandeln, die man direkt im Linkprozess einsetzen kann (der "Umweg" über C-Code ist also nicht notwendig).
Wenn Du dein Bild in "img" hast:
1
ld -r -b binary -o binary.o img
ld erzeugt dann die Symbole (aus dem Namen der Datei)
1
binary_img_start
2
binary_img_end
3
binary_img_size
Im Programm referenzierst Du auf das Bild einfach so:
1
...
2
externchar*binary_img_start[];
und linkst dein binary.o einfach - wie jede andere Objektdatei - dazu.
Du brauchst gar keinen Konverter - jedenfalls, wenn Du den GNU Linker ld
verwendest.
Interessant! Das muss ich mal probieren. Danke für die Erklärung. Falls die lvgl Sache zu stark in die Performance eingeht, dann wird das wohl der Weg sein den ich weiter gehen werde.
Allerdings hat mich der Gedanke mit der lvgl nicht mehr losgelassen, seit ihr mir davon erzählt habt.
Dieses habe ich in CUBE IDE reingeladen und wollte es einfach mal kompilieren...6 Errors.
Soweit ich rausgefunden habe, hängt das damit zusammen, dass die header Dateien an mehreren Stellen im Code eingebunden werden und das geht so nicht. Es sei denn man macht sowas hier: -fno-common (wobei ich noch nicht weiß was das genau ist und wo ich das in CUBE IDE finde)
Damit blendet man aber wohl noch weitere Meldungen aus, daher möchte ich das vermeiden es sei denn das ist der "normale" Weg bei solchen größeren Projekten. Wie würde man das Problem richtig lösen?
ich habe schon angefangen das mit Mbed und dem F303 zu bauen, das Robotdyn Board ist da aber kein Standard Target und ich musste das erst einbauen. Und dann kamen die Nickeligkeiten der neuen toolchain Installation dazu.
Bei lvgl ist sicher die erste Konfiguration das Aufwändigste. Für die Includes gibt es zwei Varianten, über ein define gesteuert: simple wenn alle includes in Suchpfaden vorliegen, oder es wird ein Pfad verwendet und die includes enthalten die kompletten Pfade.
Das -fno-common ist eine Änderung seit gcc10, da wurde der default umgekehrt weil die Defintion der Variablen im Header unschön ist. In der CubeIDE müsste man das in den Compiler Settings angeben.
Beim F303 ist der RAM mit 40 (48?) kB etwas knapp, ich würde da einen 401/411 bevorzugen, die sind ja auch als Blackpill Boards zu bekommen.
das benutzt auch noch die ältere Version 7, ich würde unbedingt die V8 nehmen. Es sind viele Dinge inkompatibel und der Squarline Editor generiert auch Code für die V8, damit kann man das Thermostat Projekt direkt benutzen.
So ein Programm, um eim Bild in ein passentes programminternes Format zu konvertieren, kann man sich ganz schnell und einfach in python, C, php, etc. schreiben. Das geht schneller, als zu fragen.
Und eine Datei einbinden ist mittlerweile (seit c23) extrem einfach geworden:
Oder ist das Sternchen da
optional, wenn man die eckigen Klammern immer vergisst ?
Ich denke das Sternchen ist schlicht falsch, und sollte weg. Und nein, nur das Sternchen darf es auch nicht sein. Nur die [] und gut.
Die Adresse eines Arrays ist die Selbe wie das seines ernsten Elements, es hat selbst keinen Speicherplatz, um einen Zeiger zu speichern. Ein Pointer, hingegen, speichert einen Zeiger. Die Adresse eines Pointers ist, wo dieser gespeichert ist, und nicht der Inhalt. Beim Linken wird die Adresse von Symbolen aufgelöst, deshalb geht das hier schief, wenn es nicht zusammenpasst. Dann würden die ersten paar Elemente als ein Zeiger interpretiert.
So ein Programm, um eim Bild in ein passentes programminternes Format zu
konvertieren, kann man sich ganz schnell und einfach in python, C, php,
etc. schreiben. Das geht schneller, als zu fragen.
Und eine Datei einbinden ist mittlerweile (seit c23) extrem einfach
geworden:
Das Mehrfacheinbinden sollte normalerweise über Header Guards mit
entsprechend bedingter Kompilierung verhindert werden.
Diese Header Guards sind doch überall drin, soweit ich das verstehe und sehe:
1
#ifndef __ILI9341_H__
2
#define __ILI9341_H__
3
....Inhalt.....
4
#endif // __ILI9341_H__
Der Kompiler beschwert sich ja zum einen über "multiple defines" und im gleichen Atemzug über "first defined here" (siehe Fehlermeldung, die ich oben gepostet hab.
das benutzt auch noch die ältere Version 7, ich würde unbedingt die V8
nehmen.
Hmm, ich würde ja erstmal gern die V7 hier zum laufen bringen, einen F411 hab ich als BlackPill da zum testen. Es hängt aber immer noch an den Fehlermeldungen. Der F303 sitzt auf einer Platine, da würde ich gern das Display nachrüsten. Der Umstieg auf V8 ist doch hoffetlich bloß das austusche des LVGL Ordners, oder :)? Aber Sinn würde es schon machen, da hast du natürlich recht.
Die Bytes von so einem Bild sind doch auch höchstwahrscheinlich
vorzeichenlos, oder ?
Du wirst es kaum glauben: Die Hardware interessiert sich kein bissel für das Vorzeichen. Der ist es scheißegal, mit einen Array welchen Datentypes das in C deklariert/definiert ist. Hauptsache, die Bitmuster stimmen.
signed char -1 und unsigned char 255 und uint8_t 0xff z.B. haben alle exakt das gleiche Bitmuster (jedenfalls auf allen neuzeitlichen Systemen).
Nur das C-Gelumpe braucht "Datentypen". Echte Männer und echte Hardware brauchen die nicht.
Der Kompiler beschwert sich ja zum einen über "multiple defines" und im
gleichen Atemzug über "first defined here" (siehe Fehlermeldung, die ich
oben gepostet hab.
Die Struktur Disp ist mehrfach vorhanden, im Modul für den ILI und ST. Wenn nur das ILI verwendet wird, dann das ST löschen oder umbenennen damit es nicht mitkompiliert wird.
Vielleicht sollten mal beide Display gleichzeitig angesteuert werden, das kann lvgl ja auch. Dann muss man das mit dem Disp aber besser lösen.
Aber doch hoffentlich nicht extra wegen meinem Problemen hier, sondern
weil du es selbst gerade brauchst?
den F303 hatte ich gerade beim Aufräumen in der Hand und wollte den auch mal nutzbar machen. lvgl habe ich schon für mehrere Controller eingebaut, auch direkt über git in das Projekt eingebaut.
Wenn nur das ILI verwendet wird, dann das ST löschen oder umbenennen
damit es nicht mitkompiliert wird.
Das bringt leider nichts, es verschwindet nur ein Fehler. Ich steh auf dem Schlauch, wie kann man das Problem beheben?
Der Kollege wird doch kein Projekt hochgeladen haben welches NICHT geht?
Das kann doch nicht im Sinne des (der) Erfinders sein?
Tja, das kommt davon, wenn man ein Ziel anvisiert und es ohne eigenes Verstehen des Ganzen erreichen will. Allerdings räume ich ein, daß gerade bei dem großen Müllhaufen namens GIT gar vieles dabei ist, was so, wie es dort steht, nur unter ganz bestimmten Bedingungen überhaupt funktionabel ist - was dank des besonders geringen Dokumentationseifers der Autoren auch nirgendwo zu lesen steht. Man geht da eben davon aus, daß jeder Leser bereits alles darüber von selbst weiß.
Ich kann dir hier nur die folgenden recht allgemeinen Ratschläge geben:
mach dir klar, wieviel Flash dein µC hat und wieviel davon du für Grafiken verwenden willst. Grafiken brauchen relativ viel Platz und du mußt ja auch noch Platz haben für die eigentliche Firmware, die davon Gebrauch machen soll und obendrauf auch noch irgend eine Nutzfunktion haben soll.
mach dir klar, wieviele Grafiken in welcher Größe und welcher Farbauflösung und welcher Codierungsart du in dem angedachten Platz unterbringen kannst. Wenn das mit gewöhnlicher Bitmap-Codierung (also quasi überhaupt keiner) geht, dann bist du fein raus, denn dann brauchst du nur die Bytes der Grafik(en) unterzubringen und fertig. Wie du diese dann in dein Display schaufelst, solltest du selber wissen. Wenn du aber mit dem Platz nicht auskommst (was ich stark vermute), dann mußt du eine komprimierterer Codierung benutzen. Allerdings brauchst du dann noch eine Dekomprimierung in deiner Firmware und die kann je nach Codierung der Grafik recht aufwendig sein. Ich schrieb ja schon, daß JPG und PNG für die Verwendung auf einem µC nicht so günstig sind.
wenn du für deine Grafiken Komprimierung brauchst, dann fängt genau HIER das Lernen und Nachdenken für dich an. Ratschläge und Tips dazu findest du hier im Forum genug, sofern du mal danach suchst.
lvgl läuft auf dem F303, aber man kommt schon schnell in Speichernot. Neben dem Framebuffer braucht man noch Speicher für die Objekte, und das läppert sich auch auf mehrere kB. Dazu macht lvgl noch einiges dynamisch und braucht dafür auch Speicher, ich hatte einige Hardfaults zur Laufzeit und musste einge der Demoscreens rauswerfen. Ein µC mit mehr Resourcen ist da schon besser.
Das war jetzt eine Demo die beim SquareLine Studio dabei ist. Das Thermostat Projekt fehlt da leider, bzw. in einer einfachen Form vorhanden. Ich habe mal angefragt wo die Quellen sind, das interessiert mich auch.
Die Ausgabe läuft flüssig, es werden aber auch nur kleine Speicherbereiche bewegt. Wenn es ruckelt dann weil ich frei Hand gefilmt habe... Mein Treiber ist minimal ohne DMA mit einem Framebuffer. Mit DMA geht es nochmal deutlich fixer, macht aber vor allem Sinn wenn man genug Speicher für zwei FB hat, dann kann beim Schaufeln ins Display schon der nächste Bereich von der CPU berechnet werden.
Sieht gut aus :).
Das ist ja schon mal gut zu wissen, nur bei mir eben noch nicht so wie sie soll :D.
Ich habe jetzt die V8 runtergeladen, der lvgl Ordner in mein Projekt eingefügt, die Pfade verlinkt etc. Mein bisheriges Projekt braucht ca. 25% des RAMs...wenn ich jetzt die lvgl einbinde und die "lv_init" aufrufe, bekommt ich die Meldung das ich 17KB über dem RAM Limit bin. In der Config hab ich schon alles mögliche versucht abzuschalten, aber gefühlt bringt es keine Verbesserung.
Wie viel Speicher RAM und Flash verbraucht deine DEMO bei dir?
wenn ich jetzt die lvgl einbinde und die "lv_init"
aufrufe, bekommt ich die Meldung das ich 17KB über dem RAM Limit bin.
Das hängt von den Einstellungen in lv_conf.h ab. Man muss eine aus dem template erstellen und sich mal durch die Einstellungen hangeln, default wird nicht passen.
Ich habe vom F303 bisher nur die 40 kB genutzt, die 8 kB CCM gerade erst eingebaut und teste da noch weiter. Man kann ein Logging einschalten um den dynamischen Speicherbedarf zu kontrollieren. Für diese Demo musste ich schon Screens rauswerfen, das braucht schon einiges.
Touch habe ich auch noch nicht drin, dafür ist der Aufbau mit Dupont Kabeln auch zu wackelig.
Mein Projekt ist auf github, aber noch sehr WIP. Für den F303CC war die RAM größe noch falsch und das muss im mbed-os repo noch gefixt werden.