Transreflexives OBS-Display

Hallo,

in Absprache mit @fabian habe ich mich mal dem Thema eines (trans-) reflexiven Displays zugewendet – also ein Display, welches etwa Sonnenlicht nutzt und somit auch bei hoher Umgebungshelligkeit abgelesen werden kann.

@fabian hatte schon ein Display beim Hersteller JHDLCM herausgesucht, nämlich das JHD12864-G156BTW (Foto auch unten).
Dieses wird über über 4-Wire-SPI angesteuert, was eine kleine Änderung der OBS-Hauptplatine notwendig machen würde.
Ich habe noch das JHD12864-G98BTW herausgesucht, vom gleichen Hersteller, aber mit Ansteuerung über I2C, so wie das bisher beim OBS verwendete SSD1306-Display.
Wie das bisher verwendete Display haben beide eine Auflösung von 128x64 Pixel. Beide Displays sind transreflexiv, i.d.R. also allein durch die Umgebungshelligkeit ablesbar, haben aber zusätzlich auch noch eine Hintergrundbeleuchtung, die man etwa bei Dunkelheit aktivieren könnte.

Ich habe von beiden Displays drei Stück bestellt und sie zum Laufen gebracht. Die OBS-Firmware musste dafür natürlich etwas angepasst werden, insbesondere habe ich die bisher für das Display verwendete Bibliothek durch die U8g2-Bibliothek ersetzt.
Das habe ich auf Github gestellt und auch schon einen Pull-Request erstellt. (Edit: leider ist der PR aus mir unbekannten Gründen nicht abrufbar, daher zusätzlich hier auf Codeberg) Ganz fertig ist es aber noch nicht, da die U8g2-Bibliothek ein anderes Format für die Schriften erfordert – ich habe daher erstmal von U8g2 mitgelieferte Schriften genommen, die von der Größe noch nicht ganz passen.

Hier ein Eindruck, wie die beiden Displays aussehen; die als Größenreferenz darüber liegende Knopfzelle hat etwa die Größe einer 2-Euro-Münze.

Links das JHD12864-G156BTW-Display (SPI) rechts das JHD12864-G98BTW-Display (I2C):

Wie zu sehen ist, ist das JHD12864-G98BTW-Display (I2C) etwas größer; aus meiner Sicht sind aber beide von der Größe her gut passend.

Zu tun ist nun noch die Anpassung der Schriften, denn wie auch auf den Bildern zu sehen ist, passt diese gerade noch nicht ganz. Hierfür würde mich von den für die Firmware „zuständigen“ interessieren, ob ihr eher bei der bisherigen OpenSans-Schrift bleiben möchtet, oder auf eine bei U8g2 mitgelieferte Schrift wechseln möchtet. Vielleicht tauschen wir uns dafür aber besser in einem separaten Thread oder auf Github aus.

Da beide Displays von JHDLCM ohne Platine kommen, und ich vermute, dass es die auch nicht nicht Platine gibt, stünde wohl des weiteren an, eine Platine für die Displayeinheit zu entwerfen. Das könnte ich auch machen, vorher warte ich aber auf euer Feedback, welches Display ihr vorziehen würdet.

Für das JHD12864-G156BTW-Display (SPI) spricht, dass die Ansteuerung über SPI i.d.R. robuster ist. Dagegen spricht, dass mehr Adern zur Displayeinheit benötigt werden (6 + 1 statt wie bisher 4 + 1 (Display + Button)).
Für das JHD12864-G98BTW-Display (I2C) spricht, dass es ohne Änderung der OBS-Hauptplatine einsatzfähig wäre und somit auch bei bestehenden OBS nachgerüstet werden könnte. Gegen dieses Display spricht, dass man mir bei JHDLCM mitgeteilt hat, dass sie es möglicherweise nicht mehr lang produzieren.

Ich persönlich würde die Entscheidung davon abhängig machen, wie viel Nachfrage bzgl. Nachrüstung es gibt – wenn das für ~100 OBS infrage käme, könnte man ja erstmal auf das JHD12864-G98BTW-Display (I2C) setzen, und parallel eine OBS-Variante mit dem JHD12864-G156BTW-Display (SPI) für die Zukunft entwickeln.

3 „Gefällt mir“

Mega gut Arbeit @j000bs!
Ich würde für den OBSPro die SPI Variante nehmen/bevorzugen. Es spricht aber meiner Meinung nach überhaupt nichts dagegen da einfach zwei Varianten zu machen, eine als Upgrade bzw. neue Variante für den OBS classic und eine für den OBSPro.
Ich denke die Gründe dass die i2c Version evtl irgendwann nicht mehr verfügbar ist und die schon erwähnte höhere Robustheit von spi sind da ausschlaggebend. Da sind die zwei Adern mehr dann auch egal.

2 „Gefällt mir“

Ziemlich cool, dass es beim transflexiven Display voran geht. @andreas ist unser haupt-Firmware Maintainer, sozusagen der „für die Firmware zuständige“. Ich mentione ihn mal, damit er mitreden kann.

OpenSans

Die OpenSans ist zwar unsere CI Schrift, aber in dieser Größe macht es kaum einen Unterschied, man sieht ja auch am Logo auf dem Display, dass das auch nicht die OpenSans ist. Meine zwei cent wären also: Wenns eine hinreichend kleine U8g2 Schrift gibt, und die zu nutzen einfacher ist, wäre die schon OK. Ich habe aber trotzem mal einen Versuch gewagt, die OpenSans in u8g2 font zu konvertieren. Konnte ich aber nicht blind testen, mangels hardware. opensans.zip (26,3 KB)

I2c vs SPI

Wenn es das I2C-Display auf absehbare Zeit nicht mehr gibt, fällt das natürlich für den OBS Pro aus - Für den Classic denke ich, ist es unrealistisch, noch die SPI-Variante anzudenken - Wenn der Pro gut funktioniert, weiß ich nicht so genau wie viele OBS Classic noch gebaut werden, und davor die Platine noch mal umzudesignen, um das SPI-Display anzubinden… Da ist das i2c-Display realistischer. Außerdem werden kaum OpenBikeSensor Classic nutzer in der Lage sein, ihr Display aufzurüsten, weil die meisten sich an den Konnektor nicht heran trauen werden.

1 „Gefällt mir“

Cool! Danke auch für den PR - kannst Du mir einen Link Posten - ich sehe den PR nicht. Gerade beim Display ist es wichtig, dass wir die Variante automatisch erkennen. Denke das sollte machbar gut machbar sein. Speicher für verschiedene Fonts sollte vorhanden sein.
Gruß, Andreas.

So, nun sollten auch die Schriften quasi so wie bei der bisher verwendeten Bibliothek sein.
Ich bin zunächst diverse bei U8g2 mitgelieferten Schriften ausprobiert, aber nur eine der kleinen (timR08) war auch so schmal wie die bisherige OpenSans, und diese hat mir aufgrund von Serifen nicht zugesagt. Daher habe ich die konvertieren OpenSans von @gluap probiert, hier waren aber die Schrifen zu groß. Offenbar ist die Einheit der Schriftgröße zwischen den beiden Displaybibliotheken verschieden.
Durch Ausprobieren und Rechnen kam ich dann aber auf gute Werte für TINY_FONT, SMALL_FONT, MEDIUM_FONT, LARGE_FONT. Nur bei HUGE_FONT bin ich mir nicht ganz sicher, da ich noch nicht herausfinden konnte, wann diese überhaupt verwendet wird.

Tatsächlich kann auch ich meinen PR auf Github nicht aufrufen, wenn ich nicht eingeloggt bin. Wohl irgendein Problem bei Github, das ich nicht lösen kann. Daher habe ich meinen Fork nun zusätzlich auf Codeberg gepusht: j000bs/OpenBikeSensorFirmware: Fork of https://github.com/openbikesensor/OpenBikeSensorFirmware/ - Codeberg.org

Man könnte wohl zur Erkennung des Displays beim Start der Firmware einen kurzen I2C-Scan der infrage kommenden Adressen machen, und falls keines gefunden wird SPI wählen. Da es bei SPI keinen Rückkanal gibt (MISO ist ungenutzt) gibt es hier jedoch keine Möglichkeit, das Display zu erkennen.

1 „Gefällt mir“

Ich glaube @andreas meinte auch: Idealerweise müssten wir in der Firmware erkennen, ob wir mit einem transflexiven oder einem OLED-Display reden müssen, und dann den richtigen Codepfad wählen. Zumindest, wenn wir nicht zahlreiche verschiedene Firmwares gleichzeitig pflegen wollen. Eine Alternative wäre noch, das beim Firmwareupdate zu erkennen und im Buildprozess firmware für verschiedene Displayvarianten auszugeben, während die jeweils anderen codepfade z.B. aus-ge-ifdefed werden, aber optimal wäre natürlich eine Firmware, die merkt, ob sie i2c transflexiv, i2c oled oder i2c SPI macht, und dann das Display auf die richtige Art und Weise ansteuert.

Ja, so hatte ich @andreas auch verstanden – tut mir leid ich das in meiner letzten Nachricht nicht klar formuliert habe.
Ich denke auch, dass es besser ist, wenn die Firmware automatisch das Display erkennen kann und zur
Laufzeit die entsprechende Ansteuerung wählt, dafür also nicht unterschiedliche FW-Versionen notwendig sind.
Die über I2C angeschlossenen Displays kann man relativ gut erkennen, da diese ja spezifische I2C-Adressen haben – somit kann man einfach einen Lesebefehl an die Adresse schicken, und schauen, ob eine Antwort kommt. Und wenn sie kommt eben dieses Display verwenden.
Das SPI-Display muss dagegen dann als Rückfalloption gewählt werden. SPI hat eigentlich eine separate Leitung als Kommunikation vom Gerät zum Host (MISO), diese ist aber bei dem JHD12864-G156-Display nicht vorhanden – bei einem Display reicht es ja grundsätzlich auch, wenn Daten nur in eine Richtung fließen können. Nur ist es dadurch eben dann nicht möglich, etwas an das Display zu schicken und anhand des Antwortverhaltens zu erkennen, ob bzw. welches Display angeschlossen ist. Solange wir aber nur ein SPI-Display haben ist das noch kein Problem.

Ich werde schauen, dass ich diese Logik in den nächsten Tagen in meinen Fork einbaue, und gebe dann wieder hier Bescheid.

1 „Gefällt mir“

Cool, das schaut ja schon fertig aus ;). Bei weiteren Varianten müssten wir eventuell freie GPIOs verwenden um die Variante automatisch zu erkennen.

Wie bekommen wir das am besten auf Github, idealerweise auch den PR für u8g2.

Ja, theoretisch ist es quasi fertig, aber ich kann es erst Mitte nächster Woche mit den Displays testen. Daher noch die Todos im Code.
Ich habe es gerade nochmal mit Github probiert, 2-Faktor-Auth aktiviert und den PR neu erstellt, will aber immer noch nicht. Vielleicht ist über den Github-Support noch etwas zu machen, könnte ich nächste Woche mal probieren.
Ich bin aber auch bereit meine Patches unter CC0 / Public Domain zu stellen, dann könnte jemand mit funktionierendem Github-Zugang die Branches auf seinen Account pushen und die PRs erstellen.

1 „Gefällt mir“

Ich denke, die git-native Methode wäre, dass jemand lokal @j000bs’ codeberg repo als zusätzliche remote zu einem ausgecheckten github-fork von OpenBikeSensorFirmware hinzufügt, den branch holt und auf github pusht und wir dann von diesem Branch den PR machen können. Ich bin nicht ganz sicher, wie man pull requests zwischen unterschiedlichen git-hostern sonst angehen würde. Von welchem gh-account + Repo kommt denn der nicht funktionierende PR?

In meinem fork von OpenBikeSensorFirmware ging das so::

git remote add j000bs https://codeberg.org/j000bs/OpenBikeSensorFirmware.git 
git pull j000bs u8g2-displaylib
git checkout u8g2-displaylib
git push origin u8g2-displaylib

Ein test-PR auf diesem Weg hat für mich funktioniert.

…oder im Zweifel ein gutes altes diff erzeugen? Das kann jeder einfach einspielen.

1 „Gefällt mir“

Das wäre dieses Repo und dieser PR. Liefert bei mir aber beides, wenn ich nicht eingeloggt bin, ein 404.

Ich habe heute noch die Display-Invertierung gefixt und mit allen drei Displays getestet. Ich denke, dass nun alles geht.
Dennoch ist es wahrscheinlich (noch) nicht sinnvoll, meinen Branch so zu mergen, da der OBS Pro ja aller Voraussicht nach doch eine separat gebaute FW-Variante bekommt (siehe hier), und damit die automatische Displayerkennung ja gar nicht mehr notwendig oder sinnvoll wäre.
Es sei denn, dass wir doch noch das transreflexive I2C-Display (JHD12864-G98BTW) mit unterstützen wollen…

Ansonsten könnten wir aber überlegen, ob wir schon den Wechsel auf U8g2 machen wollen. Ich habe dafür gerade mal schnell einen neuen Branch erstellt, auf dem nur die fünf Commits für den Wechsel auf U8g2 drauf sind, aber noch nicht die Unterstützung für die beiden anderen Displays.

Welche der beiden genannten Möglichkeiten zum Übertragen der Änderungen auf Github wir nehmen, ist mir egal. Mir ist im Prinzip auch egal wer am Ende als Autor da dran steht.

1 „Gefällt mir“

Wieder in Absprache mit @fabian habe ich ein PCB für das SPI-Display (JHD12864-G156BT) entworfen, welche mit der aktuellen OBSPro-Version (2.0) verwendet werden könnte. Das Ergebnis findet sich wieder auf Codeberg.

Die Orientierung ist in KiCAD quasi um 180° um die X-Achse gedreht. Die Anschlüsse und der Schiebeschalter für die Hintergrundbeleuchtung sind also unten, sodass das Gehäuse nur da eine Öffnung bräuchte und ansonsten die Elektronik halbwegs vor Wasser schützen kann.

Ich habe mich entschieden, den Push-Button nicht auf dem PCB vorzusehen. Es hätte sonst ein recht flacher werden müssen, in wasserdicht habe ich da nichts passendes gefunden. Stattdessen hat das PCB nun eine Buchse, über die dann mit Kabeln ein Button angeschlossen werden kann. Damit dieser ggf. direkt neben dem Display sitzen kann habe ich auf beiden Seiten der Platine Einkerbung vorgesehen.

Bis auf die Platzierung von den 0603-Bauteilen und dem Routing ist die Platine aus meiner Sicht fertig. Bin aber auch noch für Änderungen offen, auch noch, nachdem ich vrstl. morgen das Routing gemacht habe.

EDIT: Das Routing ist nun auch fertig. Ich habe dabei nochmal die Position vom Schiebeschalter und Button-Stecker getauscht, da sich das fürs Routing als günstiger herausstellte.

Das sieht doch schon mal gut aus.
Was mir jetzt noch nicht so ganz klar ist: Wir hatten ja darüber gesprochen das Kabel abnehmbar zu machen und deshalb schaut die 8-pol Buchse über die Platine hinaus. Aber warum sitzt die Buchse für den Button an der gleichen Stelle? Dann kommt das Kabel doch auch aus dem Gehäuse raus, oder?

Was die Wasserdichtigkeit angeht habe ich jetzt auch keine gute Idee. Aber nen schicken SMD-Taster findet man schon - immer noch besser als tausend von den Dingern krimpen zu müssen. Bei Reichelt wäre z.B. „KAPPE 1ZCS SW“ in Kombination mit „MEC5E SMD“ ne schöne Lösung, finde ich.

Meine Überlegung war zum einen, dass die Displayeinheit halbwegs wassergeschützt sein sollte, also zumindest kein Regenwasser durch oder am Button vorbei zum PCB laufen können sollte. Daher hatte ich auf LCSC nach Button geschaut, die einen entsprechen IP-Schutz haben. Da gibt es zwar auch ein paar wasserfeste SMD-Taster, aber die gegen das Gehäuse abzudichten schien mir dann schwieg.
Daher schien mir dann ein größerer Button, der separat ist (also etwa neben dem PCB im Gehäuse), die bessere Lösung zu sein. Ein dafür infrage kommender Button wäre dieser.

Wenn man diese JST-Stecker schon fertig mit mit Kabeln kauft müsste man wahrscheinlich doch „nur“ die Buttons mit dem Kabel verbinden?

Wir könnten natürlich auch auf Wasserschutz fürs erste ganz verzichten und zugunsten einfacherer Herstellung so einen SMD-Taster mit Kappe verwenden. Wäre dein Vorschlag, die über Reichelt zu beziehen, oder war das nur ein Beispiel?

Ich hatte auch noch die Idee, eine Möglichkeit vorzusehen, den Button separat am Fahrrad montieren zu können. Dann könnte der z.B. in Griffnähe sein, das Display aber mittig am Lenker. Zusammen mit der Überlegung zum Wasserschutz folgte daher für mich die Position der JST-Buchse unten neben 8-Pol-Anschluss zur Hauptplatine.

Hmm, ok. Wenn man den fest verbaut im gleichen Gehäuse, könnte man natürlich auf die Buchse auf der Platine verzichten und einfach direkt einlöten. Sind halt ne Menge mehr Arbeitsschritte als nur den Dome drauf zu drücken. Vom externen Button würde ich erst mal weit Abstand nehmen wollen :wink:

Wenn wir es wasserdicht hinbekommen wollen, müssen wir aber das Display auch dicht bekommen. Entweder mit Klebestreifen zwischen Display und Gehäuse - keine Ahnung ob man das so wasserdicht bekommt - oder nen Glas ins Gehäuse einkleben. Letzteres wäre vermutlich sogar möglich, ich bekomme Montag meine CNC-Fräse mit der man nen Polycarbonat-Fenster zurechtfräsen könnte. Ein schneller Check mit der Uhu-Klebeberatung sagt aber, dass das nicht so einfach ist (keine Ergebnisse).

Dazu kommt: Wenn das Display wasserdicht ist, macht es keinen Sinn den Stecker am Display zu haben. Das Kabel soll ja am ehesten am Rad bleiben.

Noch was: Wenn man den Stecker von LCSC dafür nimmt, könnte man es trotzdem so machen, dass der durch die Platine durch geht und diese gleichzeitig fest hält. Also von oben nach unten: Stecker, Gehäuse-Deckel, Platine, Mutter.

Ich würde eigentlich die Variante mit einer Kunstoffglasplatte bevorzugen. Neben Polycarbonat kämen vieleicht auch noch Acrylglas, Plexiglas oder andere infrage – da kenne ich mich aber leider nicht aus.
Es gibt auch diverse Anbieter, die einem solche Platten zuschneiden – bei den ersten, die ich online gefunden habe (expresszuschnitt.de, kunststoffplattenonline.de, plattenzuschnitt24.de) ist die Mindestgröße aber 50x50 mm. Wir brauchen wohl ca. 38x33.5 mm, und max. 1 mm dick. Ich würde nochmal nach anderen Anbietern suchen.
Ich denke, dass sich da auch ein geeigneter Kleber für findet.

Stimmt, man müsste dann eigentlich keinen Stecker mehr rausführen, sondern könnte eher einen Kabeldurchgang unten im Gehäuse machen. An der Platine selbst würde ich aber schon noch einen (einfacheren) Stecker vorsehen und das Kabel nicht direkt anlöten, sodass es z.B. einfach möglich ist etwas zu tauschen.

Vermutlich meinst du statt Stecker den (oben verlinkten) Button? Welchen Vorteil hätte es, den auch durch die Platine hindurchzuführen?

Ja, da wird man auch jemanden finden der kleine machen kann. Einfach schneiden reicht aber nicht. Das muss schräg geschnitten werden oder besser mit ner Kante drin, damit das Glas wirklich drin sitzt und der Kleber es nur in Position hält. Also ist da nichts mit einfach ausschneiden/lasern.

Ja, meinte ich. Vor allem etwas Platz-Ersparniss weil man kein Abstand von Platine zu Mutter braucht. Und evtl. könnte es den Zusammenbau erleichtern, wenn man zwei Schrauben weniger rein drehen muss.