Bei einem Projekt bei dem in einem Controller nicht mehr wirklich viel
Flashspeicher vorhanden war, wollte ich dennoch auf einem verwendeten
TFT-SPI Display noch etwas Grafik darstellen, was aufgrund der
Speichergröße von Bitmaps nicht mehr möglich war.
Entsinnend an uralte Zeiten (sogar noch prä-MS-DOS) gab es etwas das
sich Turtlegrafik nannte. Daran erinnernd habe ich einen (sehr) kleinen
aber auch einfachen Interpreter für Mikrocontroller geschrieben, der
Zeichenkommandos in einem String beinhaltet und entsprechend diese
Zeichenkommandos auf dem Display zeichnet. Den grundsätzlichen
Interpreter habe ich schon vor einer weile geschrieben, aber jetzt habe
ich den doch wieder gebraucht (um ein stylisiertes Thermometer
darzustellen) und fand es heute wie damals mühselig, di Grafikkommandos
von Hand einzugeben. Also habe ich den Interpreter überarbeitet und
-viel aufwändiger- ein HTML-Tool geschrieben, mit dem man Turtlegrafiken
für meinen proprietären Interpreter generieren kann.
Bevor ich hier jetzt weiterschreibe, die Links, auf der das zu finden
ist:
Beschreibung von Turtlegrafik grundsätzlich:
https://www.jjflash.de/turtlegraphics.html
Link zum Creator und Generator: https://www.jjflash.de/turtledraw.html
Grundsätzlich wäre es jedoch ganz nett, ihr geht auf die Seite
https://www.jjflash.de , dort gibt es die gesamte Webseite und man kann
dort im Frame auch die Turtlebeschreibung und den Generator anklicken
und das ganze im Contentfenster eines Framesets anschauen.
Die Beschreibung von Turtlegrafik findet ihr auch hier im Textanhang als
reines Textdokument.
Den Interpreter habe ich hier ganz bewußt nicht als .h / .c Kombination
eingestellt, weil es nicht klar ist, auf welcher Zielplattform er laufen
soll.
Grundsätzlich kann der Interpreter mittels copy & paste in jeden
Quelltext eingefügt werden. Damit der Interpreter arbeiten kann,
benötigt es im Programm eine Funktion Putpixel. Der Prototyp von
putpixel muß folgenden Prototyp haben:
1
void putpixel(int x, int y, uint16_t color);
x,y bezeichnet die Bildschirmkoordinate an der ein Pixel ausgegeben
wird. 0,0 bezeichnet die linke obere Ecke
color bezeichnet einen 16-Bit Farbwert im Format RGB565, mit dem ein
Pixel gezeichnet wird
Verwendungsbeispiel des Interpreters:
Zeichne ab absoluter Koordinate 50,30 ein Rechteck mit der RGB-Farbe
rot= 255, grün= 128, blau= 20 und einer Breite von 60 Pixel mit einer
Höhe von 40 Pixel. Auch wenn ein Rechteck mit Anweisung r 60,40
gezeichnet werden könnte werden hier die Kommandos für r, l, u, d
verwendet um die Anwendung des Interpreters zu zeigen
Code für Controller mit linearem Adressraum (nicht AVR):
Obiger Code ist zwar auch auf einem AVR-Mikrocontroller ausführbar wenn
die Source für NICHT-AVR verwendet wird, hat aber den Nachteil, dass
trotz der Angabe von static const eine Kopie des Strings im RAM abgelegt
wird. Aus diesem Grund soll die Source für AVR-Controller verwendet
werden (die einem in progmem abgelegten String erwartet):
:-) weil das händische Erstellen einer Turtlegrafik aufwändig ist, hilft
einem oben genannter Creator & Generator weiter.
Hier "just for fun" ein C-Arraystring, das von hier kopiert und beim
Creator importiert werden kann:
Wie mir mitgeteilt wurde, haben sich 2 Fehler im Interpretercode
eingeschlichen, bzw. fehlt etwas.
Auf meinem System sind bei Benutzung von SPI-TFT Displays die Funktionen
- rgbfromvalue
- rgbfromega
immer vorhanden, aber in den ersten angehängten Dateien sind die nicht
dabei. Hier also die beiden Dateien für linearen Adressraum und für
AVR-Progmem hier im Anhang.
Sorry für den Bug!
Horst schrieb:> Warum ich mich jetzt angemeldet hab und schreib ist: kann ich das auch> mit einem Arduino anzeigen? Ich bekomme das nicht hin!
das funktioniert auch mit Arduino, siehe Sketch im Anhang. Ich hab der
Einfachheit halber die Adafruit-Library installiert und verwendet. In
Arduino bei
- Werkzeuge - Bibliotheken verwalten
nach ST7735 suchen (je nachdem welches Display du hast) und installieren
wenn nicht schon geschehen.
Die Verdrahtung kontrollieren, meine ist so verdrahtet:
(ist irgendwie ein lustiges Bildchen).
Wenn du hier postest, solltest du gezeigten Code, auch wenn es ein Array
ist, mit Formatierungsregeln des Forums: code ... /code (in eckigen
Klammern eingeschlossen) markieren damit das auch korrekt angezeigt
wird.
Ralph S. schrieb:> Entsinnend an uralte Zeiten (sogar noch prä-MS-DOS) gab es etwas das> sich Turtlegrafik nannte. Daran erinnernd habe ich einen (sehr) kleinen> aber auch einfachen Interpreter für Mikrocontroller geschrieben,
Da kommen natuerlich Erinnerungen wieder hoch, aus der Disco-Zeit. 1982
hatte das Byte-Magazine eine Ausgabe ueber Turtle-Graphic gemacht:
https://archive.org/details/byte-magazine-1982-08/mode/2up
Turtlegraphics war ganz eng verknuepft mit Logo, der Programmiersprache.
Die hat dann Smalltalk beeinflusst, und das war der Beginn der
KI-Programmierung.
Thomas W. schrieb:>> Turtlegraphics war ganz eng verknuepft mit Logo, der Programmiersprache.> Die hat dann Smalltalk beeinflusst, und das war der Beginn der> KI-Programmierung.
Logo gibt es seit 1967, Lisp seit 1958. Siehe z.B. hier:
https://de.wikipedia.org/wiki/Lisp
So, für die, die unbedingt Arduino machen wollen, habe ich das jetzt
einmal umgebaut zu einer Library, damit das in Arduino auch schön
aufgeräumt aussieht (Library im Anhang, zu installieren über den
Bibliotheksverwalter. War relativ leicht, weil ich mich in letzter Zeit
häufiger mit Libraryerstellung für Arduino (allerdings für einen anderen
Controller) beschäftigt habe.
Ein Programm sieht jetzt so aus:
Habs zwar noch nicht ausprobiert, aber werde das in Kürze gebrauchen.
Deshalb von mir schon mal im Voraus vielen Dank für deine Arbeit.
Super Sache, sowas kann man immer wieder mal gebrauchen.
Ich habe jetzt deine Arduino Library ausprobiert und es läuft nicht. Wie
kann das sein? Hat das irgendwer außer Ralph schon getest?
Kann es sein dass mein Display defekt ist? Allerdings leuchtet es hell
ohne erkennbaren Inhalt. Es ist ein 128x160 Display. Die Verdrahtung mit
DIO, CLK etc. habe ich sehr oft kontrolliert und die stimmt.
Das Beispiel aus der Arduino Library compiliert und überträgt auch in
meinen Arduino. Auf keinem meiner beiden Boards funktioniert es. Die
Boards selbst sind intakt, ich kann an jedem Anschluß der beteiligt ist
eine LED blinken lassen.
Auf dem Display steht: 1.8 SPI 128x160 und 1.8 TFT MODULE. Auf der
Unterseite stehen sehr kleine Tabellen und ILI9163.
Ich muß dazu sagen, dass ich das Display noch nie zum Funktionieren
gebracht habe (warum es immer wieder in der Schublade lag). Vielleicht
sollte ich es wegwerfen.
Horst schrieb:> Auf dem Display steht: 1.8 SPI 128x160 und 1.8 TFT MODULE. Auf der> Unterseite stehen sehr kleine Tabellen und ILI9163.
Ach herjeh, das ist ja ein "uralt" Display (was nicht heißen muß, dass
das schlecht ist).
Meine Demo zum Turtlegrafikinterpreter verwendet ein ST7735 Display mit
"Treiber" von Adafruit, wie man hier sehen kann:
Ein ST7735 Display ist dem ILI9163 sehr ähnlich, auch in den
Steuerkommandos, aber eben nur sehr ähnlich. Die Initsequenzen sind
jedoch komplett unterschiedlich, was der Grund sein dürfte, warum das
bei dir nicht funktioniert.
Horst schrieb:> Das Beispiel aus der Arduino Library compiliert und überträgt auch in> meinen Arduino.
Die Arduino-Libraries hast du scheinbar schon korrekt installiert, sonst
würde dein Code nicht compilieren. Meines Wissens nach hat Adafruit nie
ein ILI9163 Display vertrieben, was wohl der Grund dafür sein dürfte,
dass es auch keinen Arduino-Treiber dafür gibt.
Jetzt habe ich in meinem Sammelsurium noch ein ILI9163 Display gefunden
und auf die Schnelle (wirklich auf die Schnelle) die originale Adafruit
Library für ST7735 mit den Initsequenzen des ILI9163 versehen und eine
"neue" Library daraus erstellt. Damit funktionieren augenscheinlich die
Funktionen des originalen Treibers auch auf einem ILI9163 Display. Die
Library findest du hier im Anhang und mußt du wie bei Arduino üblich
über die Bibliothekenverwaltung installieren. Danach sollte auch dein
Display, so es keinen Defekt hat, funktionieren.
Dein Sketch für den Turtlegrafikinterpreter sieht dann so aus (nur die
Instanziierung des Displaytreibers geändert):
Kann es sein, dass du noch nie etwas mit TFT-Displays gemacht hast, bzw.
noch nie eines zum Funktionieren gebracht hast? :-) immer schön daran
denken, dass das, was aus China kommt und gleich aussieht nicht immer
auch gleich ist!
Hallo Ralph und "holla die Waldfee", das hat jetzt wirklich mit deiner
ILI9163 Library funktioniert und ich kann meinen Grafikstring auf den
Display sehen.
Natürlich habe ich schon etwas mit Displays gemacht Textdisplay und auch
s/w Oled Display mit I2c, aber ein Farbdisplay hatte ich bisher noch nie
zum Funktionieren gebracht.
Ich freu mich und vielen Dank für Deine Arbeit,
Horst
Horst schrieb:> Hallo Ralph und "holla die Waldfee", das hat jetzt wirklich mit deiner> ILI9163 Library funktioniert und ich kann meinen Grafikstring auf den> Display sehen.
Freut mich sehr, dass das bei dir jetzt funktioniert hat.
Mit der Adafruit_ILI9163 wirst du dann jetzt wohl auch einiges anderes
mit dem Display anstellen können.
Viele Grüße,
Ralph
Interessantes Projekt, vielen Dank.
Auf meinem Tisch lag gerade ein ESP32 mit einem OLED-Display 480x240,
das für ein anderes Projekt über die TFT_eSPI Library angesteuert wurde.
Die erforderlichen Änderungen im Programm beschränkten sich auf die
ersten Zeilen für die Definition des Displays und die Befehle in
setup(). Alles andere funktionierte sofort.
Im Anhang die main.cpp Datei für Arduino mit PlatformIO und VSCode.
Bin da durch Zufall noch auf ein Problem gestossen: durch Fehlbedienung
im Editor hatte ich einen Kreis mit Radius 0 erzeugt, der dann durch
einen Kreis mit Radius 13 überschrieben wurde (siehe Screenshot).
Eigentlich kein Problem, allerdings führte der Befehl K0 dazu, dass
anschliessend im Programm nichts mehr gezeichnet wurde.
Habe das erst mal abgefangen, vielleicht gibt es aber auch eine bessere
Lösung:
case 'k' :
{
str = cmd_getonearg(str, &arg1);
if (arg1 > 0)
drw_circle(drw_aktx, drw_akty, arg1, drw_color);
break;
}
case 'K' :
{
str = cmd_getonearg(str, &arg1);
if (arg1 > 0)
drw_fillcircle(drw_aktx, drw_akty, arg1, drw_color);
break;
}
Das hier verwendete Display war übrigens OLED mit ILI9341, 320 x 240
Pixel.
Pindefinition in der der Datei User_setup.h:
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
//#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST 4
Lutz S. schrieb:> Bin da durch Zufall noch auf ein Problem gestossen: durch Fehlbedienung> im Editor hatte ich einen Kreis mit Radius 0 erzeugt, der dann durch> einen Kreis mit Radius 13 überschrieben wurde (siehe Screenshot).
Oha... eigentlich dürfte im Generator ein k0 oder auch K0 gar nicht
auftauchen. :-) wie hast du denn das erreicht!
Deine Lösung um das Abzufangen werde ich übernehmen!
Das war wirklich Zufall, ich hatte nach dem Rechteck einen Kreis
zeichnen wollen und zwei Mal auf denselben Punkt geklickt statt die Maus
entsprechend der Größe zu verschieben.
Lutz S. schrieb:> Das war wirklich Zufall, ich hatte nach dem Rechteck einen Kreis> zeichnen wollen und zwei Mal auf denselben Punkt geklickt statt die Maus> entsprechend der Größe zu verschieben.
Puuuuuh, da muß ich dann noch einmal das Java-Script durchgehen, wie das
passieren kann (und das abfangen).
@Lutz
So, ich habe mir das jetzt angesehen und das "Problem" ist, dass bei
einem Klick auf den Ausgangspunkt (bei Circle und bei Rectangle), ein
einzelner Pixel auf diesen Ausgangspunkt gesetzt wird.
Diesen Sonderfall habe ich im Interpreter des Controllers nicht bedacht
und ich denke, dass ich das heute abend beheben werde und dann hier
einstellen.
Deine Lösung bei k0 und K0 das eben nicht zu zeichnen ist eine
Möglichkeit. Damit das aber konsistent mit dem Generator ist, werde ich
das so abändern, dass eben genau ein solcher einzelner Pixel gezeichnet
wird.
By the way: ich freue mich, dass Du den Generator getestet hast.