USBserLCD: T6963C basierte LCDs an USB betreiben

  • Hi,

    Wäre auch mit esp32 interessant.

    Grüße, Dieter :-)

  • Im Zusammenhang mit einem Arduino-Board (bevorzugt Nano, dann auch nicht zwingend einen mit FT232RL-USB-Wandler) durchaus möglich.

    Meine Firmware läuft nicht direkt auf einem esp32. Macht auch keinen Sinn das portieren zu wollen:

    • Die LCDs brauchen zwingend 5V-Logik. Der esp32 macht aber nur 3,3V
    • Um das LCD zu steuern brauchst du 12 digitale IOs. Macht also durchaus Sinn das dann auf einem eigenen Chip zu machen.

    Was durchaus geht, ist es den Arduino von einem esp32 seriell anzusteuern. Kann durchaus sein, dass du eine TX-Leitung vom esp32 direkt an die RX-Leitung vom Arduino hängen kannst. Eigentlich sollte der Arduino die 3,3V als "logisch High" erkennen.


    Das ist übrigens auch für den Anschluss eines "usbserlcd"-Displays an einen Raspberry eine Option. Hier müsste kein USB-Port verwendet werden. Das LCD würde auch am seriellen Port des Raspberry laufen.

  • Die Arduino-Boards mit integriertem USB-Kontroller (ATmega xxUy) könne auch erkennen ob der Computer an ist oder nicht.

    Und das rein Software mässig ohne löten.

    Ausserdem kann man die auch direkt am USB programmieren.


    Ich meine hier die Boards, die auf den "U"-Uc basieren, nicht die, die so einen als USB-Seriell-Wandler einsetzen.

    So wie dieses: Sparkfun Pro Micro. Clone gibt es ab ~4€.

    Gruss
    SHF


  • Besonders interessant ist der Atmega 32u4. Hier bevorzugt in Form eines "Arduino Pro Micro". Der wurde von Arduino selbst aufgegeben, von Sparkfun wieder aufgegriffen und wird jetzt als China-Nachbau verkauft:

    https://www.amazon.de/dp/B01D0OI90U/


    Ich habe den selber in allerlei Projekten am Laufen. Natürlich bevorzugt da wo man ein USB-Gerät aufbauen will (HID-Gamepad, USB-Midi, ...)


    Ich habe versucht herauszufinden, wo ich da reingreifen müsste um herauszufinden ob der PC noch "läuft", bin aber nicht fündig geworden. Man müsste wohl erstmal rausfinden wo genau in den Arduino-Libraries das "Serial"-Modul für den 32u4 zu suchen ist. Auf die Schnelle konnte ich das nicht finden. Dieses müsste man dann wohl zumindest zum Teil ins eigene Projekt kopieren und entsprechend anpassen.


    Dazu kommt, dass ich gewisse Bedenken wegen der Geschwindigkeit habe. Ich habe alles ziemlich auf's Limit getrieben (hohe Optimierung, "DigitalWriteFast", "Custom-Baudrate" um möglichst schnell zu kommunizieren, ...). Ich bin mir nicht so sicher ob der 32u4, der ja genau so hoch getaktet ist wie die Arduinos ohne USB, hier noch mitkommt, da er ja auch Zeug zu erledigen hat, das auf den "klassischen" Arduinos der FT232RL macht.

  • Besonders interessant ist der Atmega 32u4. Hier bevorzugt in Form eines "Arduino Pro Micro". Der wurde von Arduino selbst aufgegeben, von Sparkfun wieder aufgegriffen und wird jetzt als China-Nachbau verkauft:

    Genau so einen China-Clone habe ich am laufen.

    Das das Design original von Arduino selbst stammt wusste ich aber nicht.

    Ich habe versucht herauszufinden, wo ich da reingreifen müsste um herauszufinden ob der PC noch "läuft", bin aber nicht fündig geworden.

    Das ist mir auch eher zufällig aufgefallen, als ich mit den Timern experimentiert habe. Im Endeffekt ist es aber extrem simpel:


    Der USB-Kern löst sobald der Hostcontroller eingeschaltet ist (mindestens) einen Interrupt pro Millisekunde aus. Da braucht man nur mit zählen und auswerten.

    Das ist übrigens so genau, dass man den Controller-Reset beim Laden des Kernel-Moduls mir bekommt. Daher muss man es über etwas längere Zeit betrachten.

    Zu beachten ist, dass ich bei den Timern einiges geändert habe. Bei mir läuft der mainloop nur (exakt) alle 10ms. Unter Umständen ist also was anzupassen!


    Dazu kommt, dass ich gewisse Bedenken wegen der Geschwindigkeit habe.

    Das müsste man probieren.

    Ich hatte aber über USB eher einen besseren Durchsatz als über den UART.

    DigitalWriteFast

    Ich mach es noch immer direkt via "PORTx".

    Gruss
    SHF


  • Guter Ansatz. Ähnelt der Lösung die ich für "IRMP_STM32" genutzt habe. Frage ist nur wie man da "rein" kommt ohne das der Benutzer seine lokalen Arduino-Libraries patchen muss. Da habe ich aktuell noch keine Idee zu. Kann man den Interrupt auch ein zweites Mal im eigenen Code abfangen?

  • Frage ist nur wie man da "rein" kommt ohne das der Benutzer seine lokalen Arduino-Libraries patchen muss.

    Ich habe mein Projekt von der der Arduino-IDE abgelöst und benutze die modifizierten Arduino-Libraries nur dafür. Gebaut wird mittels Make.


    Da ich auch die Timer anders, den Watchchdog und Sleepmode verwenden wollte blieb mir auch eigentlich gar nichts anderes übrig.

    Die Arduino-Umgebung ist da leider extrem unflexibel, da waren einige Änderungen an deren Libs nötig.



    Kann man den Interrupt auch ein zweites Mal im eigenen Code abfangen?

    AFAIK nein.

    Aus der Interrupt-Funktion soll man nicht mal andere Funktionen aufrufen.


    Was eventuell möglich wäre, ist das Ersetzen der Funktion oder der ganzen Datei mit einer eigenen Version.

    Das habe ich aber noch nicht versucht.


    Sollte man mit einigen #ifdef oder ähnlichem eigentlich beides in einem Projekt vereinen können.

    Das sollte gehen.

    Die USB-Lib ist sowieso nur bei Controllern mit USB verfügbar.

    Gruss
    SHF


  • Es gibt möglicherweise eine Möglichkeit die Funktionalität ohne Anpassungen an den Core-Libraries zu bekommen. Hier:

    https://github.com/arduino/Ard…/arduino/USBCore.cpp#L773

    wird je nachdem ob USB "aktiv" oder "suspended" ist je ein anderer Interrupt ein, bzw. ausgeschaltet. Man könnte also einfach prüfen welcher Interrupt von der Core-Library aktiviert wurde. Immer wenn das Interrupt-Bit für "SUSPE" gesetzt ist, müsste der Rechner laufen. Ja, das ist ein Workaround, aber solange es keine "richtige" Lösung gibt ist das vielleicht besser als nichts.

    Allerdings habe ich aktuell keine LCD-Module mehr da um das auszuprobieren.

  • Das könnte man versuche.

    Ich würde dazu einfach, alle Sekunde oder, so eine Meldung am UART ausgeben lassen. Und die von einem anderen PC aus verfolgen.


    Alternativ könnte man auch die Gesamtinterrupts zählen.

    Ohne USB müssten das 1000/s vom Timer sein plus 100 oder so vom PWM.

    Der USB allein verursacht auch 1000/s. das macht bei aktivem USB >2000/s zusammen.

    Wenn es keine so kritische Anwendung wie bei meinem Watchdog ist, dürfte das sicher genug sein.


    Da fällt mir aber eben auf, dass man das vielleicht noch viel einfacher gestalten kann.

    Der Computer sendet doch Daten an das LCD. Das muss doch in einer gewissen Regelmässigkeit passieren?

    Wenn eine Uhr dargestellt wird, muss mindestens einmal die Minute was kommen.

    Damit kann man doch was anfangen. Wenn 5 Minuten nichts kommt, ist der Computer zwangsläufig aus.

    Gruss
    SHF


  • Ich würde dazu einfach, alle Sekunde oder, so eine Meldung am UART ausgeben lassen. Und die von einem anderen PC aus verfolgen.


    Wäre machbar. Arduino und UART-Adapter hätte ich da. Wenn ich die Zeit finde, teste ich das mal.


    Damit kann man doch was anfangen. Wenn 5 Minuten nichts kommt, ist der Computer zwangsläufig aus.

    Nein. Ich habe auch ein "Splash-Screen-Feature" in der Firmware. Der soll möglichst früh in der Bootfolge auf dem LCD landen. Außerdem soll es mit grafischen LCDs auch möglich sein, dass man einfach ein Bild mit "showpic" draufsendet und das dann stehen bleibt. Ich will nicht von einem permanenten Datenstrom abhängig sein beim Entscheiden ob ich das LCD "ausschalte".

  • Geht viel einfacher, das mit dem Testen.



    Und ja: Das geht so wirklich.


    Rote LED an: PC aus.

    Grüne LED an: PC an.

    Komischerweise auch: Grüne LED an wenn mit USB-Netzteil versorgt.


    Ich nehme diese Testschaltung jetzt mal mit zu einem Bekannten bei dem aus bisher noch unbekanntem Grund die Erkennung via FTDI-Pin nicht geht. Vermutung meinerseits ist "komisches Verhalten vom Mainboard". Bin gespannt ob die Testschaltung an diesem Mainboard auch sauber funktioniert.

  • Nachtrag zu dem Fall be meinem Bekannten mit Nicht-Funktionieren der FTDI-Status-Pins: Hier geht auch mein oben gezeigter Test-Code nicht. Es gibt also wirklich Mainboards bei denen eine Erkennung des PC-Zustands schlicht unmöglich ist. In dem Fall ist es aber ein ziemlich altes Board (laut meinem Bekannten 8 Jahre alt?).


    Wir haben als "Not-Hack" schon vor längerem ein USB-Slotblech eingebaut, dessen Power-Pins über eine 1A-Sicherung an einem Laufwerksstecker hängen. Mit diesem "Hack" wird USB-Geräten, die nicht durchlaufen sollen, einfach der Saft abgedreht.

  • Die Variablen "WAKEUPE" "SUSPE" gab es bei mir noch nicht. Oder hast du da was selber gebaut?



    Komischerweise auch: Grüne LED an wenn mit USB-Netzteil versorgt.

    Könnte mit den Pullup / Pulldown-Widerständen an den Datenleitungen zusammen hängen.

    Da gibt es so komische "Standards", wie die die mögliche Ladeleistung an Handys übermitteln. Google weiss da mehr.


    Beim Mainboard könnte es das Gleiche sein, oder der USB-Controller wird nicht abgeschaltet. Eventuell bringt der Blick ins BIOS da was.



    Ich weiss jetzt nicht, wo die Variablen "WAKEUPE" "SUSPE" her kommen.

    Die Interrupts, die der USB-Teil im AVR auslöst, werden AFAIK aber immer nach dem Empfang eines bestimmten Pakets vom USB-Host.

    Man sollte also eigentlich sicher sein, dass USB-Host aktiv ist. Da wäre es jetzt interessant zu wissen, ob es einen Unterschied macht, wenn man Interrupt auswertet.


    Leider habe ich momentan kein freies Board da, mit dem ich das probieren könnte.

    Das kann man auch gut per LED machen, einfach den Takt entsprechend teilen, dann sollte die LED blinken.



    Gruss
    SHF


  • Die Konstanten sollten da sein wenn man als Board "Arduino Leonardo" wählt.

    Auch mit der Textsuche konnte ich die im gesamten Arduino-Verzeichnis nicht finden.

    Ich muss wohl mal updaten :gap.


    Wir würde das mit den Interrupts gehen?

    Mit dem Zähler, wie ich es gemacht hatte s.o..

    Der zählt genau diese Interrupts.


    Für den Test müsste man die Lib halt temporär mal patchen.

    Wobei es sinnvoller wäre die Zählervariable im dazugehörigen Header zu definieren, dann wären andere Programme mit der Lib weiterhin lauffähig.

    Gruss
    SHF


  • Wenn man an der Arduino Lib basteln muss bringt mir das halt nix...

    Man wüsste dann aber, ob die Auswertung der Interrupts zuverlässiger ist.


    Wenn ja könnte man einen Vorschlag zur Optimierung der Variablen "WAKEUPE" "SUSPE" machen.

    Gruss
    SHF


  • Das mit den Variablen ist ein Hack um zu vermeiden, dass man die Arduino Libs anpassen muss.

    Es handelt sich um Interrupt Enable flags die in den Arduino Libs umgeschaltet werden.

    Das mit den Start Of Frame Ereignissen wird gehen. Am gleichen Mainboard habe ich einen IRMP_STM32 laufen und da ist die Erkennung genau so gelöst.

    Eventuell habe ich aber auch dafür einen Workaround. In den Arduino Libs wird das SOF Ereignis genutzt um die RX und TX LEDs auszuschalten. Meine Vermutung nach kurzer Recherche im Code ist, dass die RX LED bei ausgeschaltetem Rechner dauerhaft leuchtet. Und das könnte man eventuell auswerten.