[OOP Problem] Bibliothek mit Diagrammen? Bewertung des selbst erstellten

  • Danke für den Hinweis, so weit war ich nur noch gar nicht. Wollte erst den ersten Teil abklären um bei Fehlern einfacher die Ursache zu finden.

    Hmm, aber genau das ist ja dein Problem und die Ursache des IndexError gewesen :conf:

    Du hast einen Fehler, bist aber noch nicht dabei gewesen, den zu beheben? Da kann ich nicht fogen.


    Wie dem auch sei... der Code von @__deets__ löst das ja (Zeile 7 in deinem Beispiel).

  • Mein Problem war, das wenn ich einen Viertel-Kreis um 90° gedreht habe, hatte ich wieder farbige Pixel neben dem Kreis.

    Um dieses Problem zu lösen, hat mir __deets__ die Lösung in zwei Schritten aufgeteilt und hat dabei den "Index-Error" schon vorhergesagt.

    Als erstes sollte ich den Code verallgemeinern und im zweiten Teil, dann die Schleife einbauen. Ich wollte dann erst meinen verallgemeinerten Code vorstellen, bevor ich noch eine Schleife einbaue. Den Index-Error-Fehler hatte ich eigentlich nur mit gepostet um die Vorhersage zu bestätigen.


    Also eigentlich wollte ich den Index-Error nach Bestätigung des verallgemeinerten Codes angehen. Vielleicht habe ich mich da schlecht ausgedrückt :blush:

    Habe mich natürlich trotzdem rießig über eure zwei Lösungsvorschläge gefreut :)


    Kann auch schon Erfolgserlebnisse mit dem farbigen Tacho melden :thumbup:



    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Guten Abend,


    ich warte noch auf meinen CO2- Sensor. Aber ansonsten läuft das Programm soweit. Werde alles vollständig vorstellen, wenn der Sensor da ist und funktioniert. Ich habe aber noch eine Frage zu den Farben des Displays. Sie sind so definiert:

    Wenn ich in 'main.py' beispielsweise RED aufrufe, dann ist mein Pixel auch rot. Lasse ich mir die Farbe mit 'print(TFT.RED)' ausgebe, dann erhalte ich

    63488 umgerechnet in Hexadezimal ergibt das 'F800'.

    Wenn ich in mein Array mit 'TFT.RED' fülle bekomme ich aber blaue Pixel, obwohl ich als print-Ausgabe von dem Pixel, dem ich RED zugewiesen habe, auch 63488 erhalte.

    Wie hängt das zusammen?


    Oder anders gefragt, kann mir jemand die oben gepostete Farbdefinition erklären? Das sind doch Hexadezimalzahlen? Also nach '0x'? Die F800 passt halt gar nicht in die Definition, da muss noch was umgerechnet werden? :conf:

    Aber irgendwas muss in dem Array passieren, dass die Farben nicht mehr stimmen. BLACK funktioniert aber.


    Vielen Dank und Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Code
    def TFTColor( aR, aG, aB ) :
      '''Create a 16 bit rgb value from the given R,G,B from 0-255.
         This assumes rgb 565 layout and will be incorrect for bgr.'''
      return ((aR & 0xF8) << 8) | ((aG & 0xFC) << 3) | (aB >> 3)

    https://github.com/boochow/Mic…/master/ST7735.py#L31-L34


    Das Ergebnis dieser Funktion ist demnach kein "üblicher" 24 bit RGB-Farbwert. Und wenn dein Display BGR verwendet, kommt für rot eben blau raus.

  • Danke für deine Antwort.

    Ich verstehe aber nicht, wieso die Farbe nur nicht stimmt, wenn ich einem Index eines Arrays zum Bsp TFT.RED zuweise, also so:

    array[index)] = TFT.RED


    Wenn ich aber einen Text schreibe und ihn ohne Umwege über ein Array auf den Bildschirm schreibe, dann stimmt die Farbe:

    tft.text((5, 60), temperature , TFT.RED, sysfont, 1, nowrap=True)


    Es wird doch jetzt beides mal die 'TFTColor/ aR, aG, aB )'-Funktion aufgerufen und trotzdem schreibt das Array blau und der Text ist rot.


    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Das lieght mit ziemlicher Sicherheit an dem von mir schon angesprochenen byte-swapping:


    https://github.com/boochow/Mic…fd9bf1cb40/ST7735.py#L414


    Das wird naemlich mit Farbwerten wie in dem Link zu sehen gemacht, bevor die dann gesetzt werden. Dadurch wird aus einem


    rrrrrggggggbbbbb


    Wert ein


    gggbbbbbgggrrrrr


    Wert. Wobei vor allem natuerlich die Gruentoene dann auch nochmal in sich verwuerfelt werden!


    Du musst also die gleiche Operation durchfuehren, bevor du das Array abschickst. Am sparsamsten ist es, das bereits zu tun, *bevor* man das array befuellt, also


    real_color = byteswap(color)


    bevor es dann ans setzen von Pixeln geht.

  • Danke für deine Antwort.


    Im ersten Moment hört sich das gar nicht so wild an. Da habe ich mir schwer getäuscht.


    Ich versuche mal aufzuschreiben, was ich an der Funktion '_setColor' verstanden habe


    Das 'self.ColorData' ist ein Bytarray mit 2 Bytes, also 16Bit.

    Was mit dem Index 0 passiert verstehe ich nicht.

    Index 1 bekommt die Farbe zugewiesen.

    'self.buff' ist dann die bytes des Bytarrays multipliziert mit 32.


    Tut mir leid ich kann das nicht anwenden, wenn ich nicht verstehe was da passiert. :(

    So bringt mir auch Google nicht wirklich viel. Was wird warum mit 32 multipliziert und was soll '>> 8' sein? Heißt dass, das Color ein größerer Wert wie 8 zugewiesen wird?


    real_color = byteswap(color)

    Mit 'byteswap' meinst du dann die Funktion, die ich noch nicht verstehe?


    Vielen Dank und Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Mit >> 8 wird die Farbe durch 256 geteilt bzw. das untere Byte weggeworfen und das obere Byte nach unten befördert. Und dann im Array an die erste Stelle geschrieben. Das untere Byte wird dann an die zweite geschrieben, und weil das Array ein Byte Array ist die oberen Bits Automatiisch entfernt. Danach das Array mal 32 genommen erzeugt eben 32 mal die Farbe. Das ist zur Effizienzsteigerung des SPI Verkehrs. Zb bei einer Linie wird die dann in Abschnitten von bis zu 32 Pixeln gemalt.


    Für dich reicht ein


    color = color >>8 | (color & 0xff) << 8

    Code
    def _setColor( self, aColor ) :
        self.colorData[0] = aColor >> 8
        self.colorData[1] = aColor
        self.buf = bytes(self.colorData) * 32
  • Vielen Dank für die Erklärung.


    Mal ehrlich, das ist mit einem Semester IT, in dem man uns den Makro-Recorder von Office gezeigt hat, wirklich schwer nach zu vollziehen was hier alles so abläuft. :no_sad:


    color = color >>8 | (color & 0xff) << 8

    Es funktioniert :)

    Ich habe verstanden das meine Farbe durch 256 geteilt wird. Dann "fehlen" mir 255 Bits und dafür ist dann '&0xff' zuständig? Das ist nämlich 255 Bits groß, damit werden die Bits dann verschoben und mit '<<8' wieder auf das Ausgangsformat dargestellt.


    Ich lass das obrige mal stehen, gerade habe ich noch was gelesen. Durch das '&0xff' wird eine Bitweise UND-Verkünpfung ausgeführt. Wenn eine 0 von color zu einer 0 von 0xff addiert wird bleibt die 0. Und an denen Stellen, an denen color eine 1 hat, wird der Wert von 0xff übernommen? Erreicht wird damit das nur die letzten 8 Bits übrig bleiben?

    Und man macht das um die Standard RGB-Werte zu erhalten?


    Einfach geht das nicht oder ist das schon einfach?


    Edit: Die Farben werden jetzt so angezeigt wie ich es wollte. Aber es ist so wie du ,__deets__, es gesagt hast, das Grüntöne nochmals verwürfelt waren. So musste ich manche Farben drei mal swappen(?). Damit ich bei meinem Funktionsaufruf beliebige Farben als Argumente übergeben kann, habe ich alle Farben drei mal geswappt. Wenn ich das richtig verstanden habe, dann kann da ja nichts schief gehen?

    Den Code könnte man aber bestimmt schöner schreiben:


    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

    Edited 2 times, last by Dennis89 ().

  • Mit dem Display läuft alles so wie gewollt.


    Warte allerdings immer noch auf den CO2-Sensor, wenn dieser da ist, werde ich das Projekt dann offiziell im 'Projekt'-Unterform vorstellen.


    Falls noch jemand die Fragen aus dem letzten Post beantworten mag, gerne:)


    Ansonsten möchte ich nochmal vielen Dank für die tolle Hilfe sagen:):)


    Es stehen schon wieder zwei Projekte (ESP32 und Pi zero) an, ihr habt mich infiziert :lol:


    PS: Da die Probleme gelöst sind, markiere ich das Thema gleich mal als erledigt.


    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Ich habe deinen Code oben mal auf das notwendige zusammen gedampft, und deine Beobachtung ist aus Verwirrung entstanden. So wie man wenn man einen Bierdeckel dreimal umdreht er auf der gleichen Seite landet wie bei nur einmal umdrehen, ist das auch hier:


    Code
    color_low = 0x2345
    print(color_low)
    color_low = color_low >>8 | (color_low & 0xff) << 8
    print(color_low)
    color_low = color_low >>8 | (color_low & 0xff) << 8
    print(color_low)
    color_low = color_low >>8 | (color_low & 0xff) << 8
    print(color_low)


    Und bei solchen Ausdrücken musst du dich NICHT x-mal das gleiche hinschreiben. Sondern eine Funktion machen. Das wird auch der Verwirrung vorbeugen.


    Das Byte swapping hat auch nichts mit Standard RGB zu tun. Was auch immer du genau als Standard da empfindest - ich denke da eher an RGB 8 Bit / Kanal, nicht 565.


    Sondern liegt einfach an der Art, wie das Display diese Daten eben haben will. Da kommt bei einem 16-Bit-Wort eben das höherwertige Byte zuerst. Das wird so im Datenblatt stehen.

  • Guten Abend @__deets__ und Danke für die Erklärung.


    Du hörst/liest das bestimmt hundert Mal, aber ich kann nur sagen jetzt funktionierts "auf einmal" :lol:

    Ich bin mir sicher, das ich das Grün erst grün auf dem Display hatte, nachdem ich das Swappen drei mal ausgeführt hatte.


    In dem Datenblatt das bei AZ-Delivery hinterlegt ist, steht leider nichts zu 8-Bits. Habe noch ein anderes gefunden. Hier stehen verschiedene Bit Angaben und einmal 16 Bit für 565, aber so ganz steige ich da noch nicht durch.


    Eine Funktion habe ich auch erstellt, beide Funktionen befinden sich in der Klasse 'Scala'


    Das funktioniert. Ich überlege gerade noch wie ich einen Funktionsaufruf gestalte, der die vier Aufrufe ersetzt. Denn jetzt ist es ja noch nicht viel kürzer. Dachte das ich die vier Farben in eine Listeart packe und dann in diese Richtung alle nacheinander aufrufe:

    Dieser Code funktioniert nicht, das Problem will ich auch hier nicht zur Diskussion stellen, ich wollte damit nur demonstrieren wie ich mir das vom Prinzip her vorstelle . Ich würde nur gerne wissen ob dir Idee die dahinter steckt die richtige ist? Wenn ja, dann erwarte ich von mir, das ich das selbst umsetzen kann. Aber heute nicht mehr :sleepy:


    Vielen Dank und Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Das steht hier:


    9.3.1 Command Write Mode


    The write mode of the interface means the micro controller writes commands and data to the LCD driver. 3-line serial data packet contains a control bit D/CX and a transmission byte. In 4-line serial interface, data packet contains just transmission byte and control bit D/CX is transferred by the D/CX pin. If D/CX is “low”, the transmission byte is interpreted as a command byte. If D/CX is “high”, the transmission byte is stored in the display data RAM (memory write command), or command register as parameter.

    Any instruction can be sent in any order to the driver. The MSB is transmitted first.


    Hervorhebung von mir. In den folgenden Seiten sind Timingdiagramme zu sehen, wo klar wird, dass vom höchstwertigen Bit zum niedrigsten hin übertragen wird.

  • Guten Morgen @__deets__


    Vielen Dank für deine Mühe:)

    Werde mich mal damit beschäftigen.




    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Guten Abend,

    Das funktioniert. Ich überlege gerade noch wie ich einen Funktionsaufruf gestalte, der die vier Aufrufe ersetzt

    Ich komme auf keinen Lösungsansatz. Ich muss ja zum einen zum Beispiel 'color_low' den Rückgabewert der byteswapping Funktion zuweisen und für den Funktionsaufruf brauche ich den "Inhalt" von 'self.color_low'. Dann dachte ich, das kann ich mit einem Dictonary lösen

    colors = {color_low: 'color_low', color_middle: 'color_middle', color_high: 'color_high', pointer_color: 'pointer_color'}


    Ich kann zwar mit 'values' und 'key' auf den Inhalt zugreifen. Ich brauche aber nur ein Schlüsselpaar. Das geht zwar mit 'pop' Aber wenn ich vier mal 'pop' aufrufe, kann ich gleich vier mal die Funktion aufrufen.


    Habt ihr mir bitte einen Hinweis?


    Edit: Ich glaube ich habe etwas gefunden, nicht antworten, ich melde mich wieder ^^


    Ne war nichts, dachte mit 'items' komme ich weiter, aber wenn ich die Paare damit auslese, habe ich wieder alle auf einmal und nich einen nach dem anderen.


    Danke und Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

    Edited 2 times, last by Dennis89 ().