Moin!
Einleitung:
Ich habe mir von Waveshare folgendes 7,5" E-Paper Version 2 800x480 mit
HAT Module gekauft: https://www.amazon.de/dp/B075R4QY3L
Datenblatt:
https://www.waveshare.com/w/upload/6/60/7.5inch_e-Paper_V2_Specification.pdf
und möchte dieses mit einem ESP8266 MOD nodeMCU v3 betreiben.
Problem:
Das E-Paper regt sich gar nicht. Es passiert auf dem E-Paper überhaupt
nichts. Es blinkt nicht, es flackiert nicht, es ändern sich keine Pixel.
Test mit einem Arduino UNO:
Um die Funktionstüchtigkeit des Bildschirmes zu testen, habe ich mir das
Testprogramm von der Waveshare-Website für den Arduino Uno runtergeladen
womit das E-Paper auch auf Anhieb funktionierte. (Dadurch auch das
angezeigte Bild)
Code: https://github.com/waveshare/e-Paper ->
e-Paper-master\Arduino\epd7in5_V2
Bearbeitungen am Programmcode:
Anschließend habe ich das Uno-Programm genommen und es abgewandelt,
sodass es auf dem ESP laufen kann:
1. Anpassung der Anschlussbelegung (Definition in der epdif.h):
VCC - 3V3
GND - GND
DIN - GPIO13 (D7, MOSI)
CLK - GPIO14 (D5, SCLK)
CS - GPIO15 (D8, CS)
DC - GPIO4 (D2)
Reset - GPIO5 (D1)
BUSY - GPIO10 (SDD3)
(Die Belegung anhand folgendes Bildes:
https://i2.wp.com/randomnerdtutorials.com/wp-content/uploads/2019/05/ESP8266-NodeMCU-kit-12-E-pinout-gpio-pin.png)
2. Einsetzen einiger "wdt_reset();" in der epd7in5_V2.cpp bei den großen
Schleifen, um zu verhindern, dass der Watchdog aktiv wird. Dies
geschieht in folgenden Funktionen:
1
Epd::WaitUntilIdle
2
Epd::DisplayFrame
3
Epd::Displaypart
4
Epd::Clear
Ich hatte wdt_reset vorerst in die Schleifen getan, allerdings war meine
Befürchtung, dass die zeitliche Verzögerung durch das reseten dazu
führen könnte, dass das Display nicht funktionierte, weshalb es jetzt im
Anschluss aufgerufen wird. Seit dem schlägt der Watchdog nicht mehr an,
die gesamte Initialisierung und auch das Schreiben der Bilddaten läuft
durch.
3. In der epd7in5_V2.h ist in Zeile 49
1
voidEpd::Displaypart(...);
definiert. Beim Kompilieren für den ESP warf das einen Fehler auf,
weshalb ich das Epd:: entfernte (wie es auch bei allen anderen
Funktionen ist).
4. In der epd7in5_V2.ino habe ich zwei weitere Serial.print(...)
hinzugefügt, um präziser zu sehen, wie weit das Programm durchläuft.
5. Zudem habe ich das Test-Bild abgeändert, sodass ich auf jeden Fall
einen Unterschied zum aktuellen Zustand erkenne.
Test mit dem ESP8266:
Anschließend habe ich den ESP mit dem E-Paper entsprechend verdrahtet
(siehe Gesamtaufbau.jpg und Verdrahtung.jpg), das Programm kompiliert
und übertragen und geschaut was passiert.
Die Ausgabe in der Konsole ist folgende:
1
e-PaperClear
2
e-PaperCleared
3
Pictureprinted
Hierbei fällt auf, dass das "e-Paper init \r\n " nicht mit angezeigt
wird. Mit einer zusätzlichen Pause direkt nach dem Starten wird
allerdings auch diese Zeile erfolgreich übertragen. Keine Ahnung, wieso
das ohne Pause nicht klappt?
Auf dem E-Paper regt sich leider, wie oben bereits beschrieben, gar
nichts!
Tests mit dem Oszi:
Ich habe mit dem Oszi versucht alle Verbindungen und das SPI zu
überpüfen. In der Reset.png kann man erkennen, dass das Reset-Signal für
ca. 100 ms auf LOW gezogen wird (von -300 ms bis -200 ms) und
anschließend auf HIGH bleibt. Nach weiteren ca. 200 ms (bei 0 ms)
beginnt die erste SPI-Übertragung (siehe Initialisierung.png und
Initialisierung_Daten.png, Achtung Pin-Belegung am Oszi geändert, Reset
mit CS getauscht!) bestehend aus insgesamt 6 Bytes. Initiator der
Übertragung ist die Funktion
1
intEpd::Init(void)
in der epd7in5_V2.cpp. Die vom Oszi erkannten übertragenen Daten
entsprechen exakt denen aus der Funktion und auch das Chip-Select-Signal
arbeitet korrekt. Anschließend gibt es weitere 100ms Pause und dann wird
laut Oszi einmalig 0x71 übertragen (Reset.png, +100 ms, Initiator:
1
voidEpd::WaitUntilIdle(void)
). Da das Busy-Signal High ist, bricht die Warteschleife direkt wieder
ab und nach weiteren 200 ms Wartezeit, beginnt die eigentliche
Konfiguration des Panels, welche laut Oszi ebenfalls korrekt übertragen
wird. (Siehe Konfiguration.png, Beginn Warteschleife bei -250 ms, Ende
Warteschleife bei -150 ms, Übertragung der Daten bei +50 ms)
In der Clear.png und in der Clear_Daten.png sieht man den Beginn des
Löschens des Bildschirmes. Beginnend mit 0x10 und anschließend 0x00 für
jedes Bit. Achtung, in dem Bild ist erneut die Pin-Belegung am Oszi
geändert, um zu prüfen, dass auch das DC-Signal korrekt arbeitet. Wie
man sieht, ist es für das Kommando 0x10 low und für die anschließenden
Daten 0x00 high, also ebenfalls nach Datenblatt Seite 26 und
Waveshare-Website korrekt.
Alternative Problemmöglichkeiten:
Jetzt bin ich ratlos, wieso es mit dem Arduino UNO so problems
funktioniert und mit dem ESP so gar nicht. Die wesentlichen
Unterschiede, die mir jetzt zwischen den beiden ICs bewusst wären sind:
Anderer Takt (Arduino Uno 16 MHz, ESP 80 MHz), allerdings wird das
SPI-Interface bereits mit einem festen Takt initialisiert (epdif.cpp,
Zeile 61):
Keine Ahnung, wieso so ein krummer Takt von 7 MHz gewählt wird, aber
wenn dieser auf dem Uno funktioniert, müsste er doch auf dem ESP alle
Male funktionieren?
Andere Spannung:
Der ESP arbeitet mit 3,3V der Uno mit 5 V. Der Uno hat das Display mit
5V versorgt und auch alle Datenpins mit 5 V angesteuert. Aufgrund des
Level-Converters auf der HAT-Platine sind die 5V vom Uno kein Problem,
das Display selbst arbeitet eigentlich nur mit 3,3V. So wie ich das
Datenblatt des verbauten Voltage-Level-Translators (YE08) verstehe,
müsste es für diesen allerdings kein Problem sein, mit 3,3V zu arbeiten.
Zudem steht auf der Website von Waveshare
(https://www.waveshare.com/wiki/7.5inch_e-Paper_HAT) dass das HAT mit
3,3V zurecht kommt. Entsprechend dürfte dies m.E. kein Problem sein.
Schluss:
Habt ihr womöglich weitere Ideen, seht ihr etwas auf den Fotos oder im
bearbeiteten Code (ist angehängt einzelnd und als zusammen als Zip), was
dazu führen könnte, dass das Display nicht funktioniert? Ich sitze jetzt
bereits einige Tage dran, habe diverses ausprobiert, Pins
durchgetauscht, andere geteilte Bibliotheken gestestet, anderen ESP8266
genommen, neu verdrahtet, mehrfach mit dem Oszi gemessen, Übertragungen
verglichen mit dem Arduino Uno, SPI-Frequenz erhöht gesenkt, usw. und
meine Befürchtung ist, dass es irgendein super dummer Fehler ist, den
ich einfach nicht sehe...
Ich weiß, dass ist jetzt sehr viel Text geworden, allerdings möchte ich
euch möglichst viele Informationen liefern und zudem zeigen, dass ich
bereits einiges versucht habe und wirklich keinen Ansatz mehr habe,
woran es noch liegen könnte. Also wer gute Ideen hat, sehr gerne her
damit!
Liebe Grüße
Julian
PS: Die Schiebeschalter-Einstellung ist auf dem Bild nicht so gut zu
erkennen, wie erwartet. Die stehen wie folgt:
Display Config: B (=> Kein 1.54, 2.13 oder 2.9" E-Paper)
Interface Config: 0 (=> 4-line SPI)
Julian schrieb:> Nach weiteren ca. 200 ms (bei 0 ms) beginnt die erste SPI-Übertragung
Und wie sieht so ein einzelnes SPI-Telegramm ab SS#=low bis SS#=high
aus?
Sind die Pegel und Flanken der Signale sauber? Passt das Timing zu dem,
was das Display erwartet und braucht?
BTW: mit einem etwas besseren Masseanschluss der Tastköpfe (jeder
Tastkopf mit seinem eigenen Masseclip auf kürzestem Weg zur
µC-Masse) würden die dargestellten Signale nicht so übel überschwingen.
Und wenn sie es trotzdem tun, dann könnte das ein Problem sein.
Hallo,
Julian schrieb:> BUSY - GPIO10 (SDD3)
ist der nicht vom Flash des ESP9266 benutzt?
Ich habe zwar nur kleine E-Paper am ESP8266, die Arduino-Libs von
https://github.com/ZinggJM/GxEPD
liefen aber eigentlich immer mit dem ESP8266 ohne Eingriffe.
Eigentlich sollte es doch auch sinnvoller sein, statt den WDT
zurückzusetzen besser yield() azfzurufen, es geht ja vor allem darum,
daß die anderen Funktionen nicht zulange blockiert werden.
Gruß aus Berlin
Michael
Lothar M. schrieb:> Julian schrieb:>> Nach weiteren ca. 200 ms (bei 0 ms) beginnt die erste SPI-Übertragung> Und wie sieht so ein einzelnes SPI-Telegramm ab SS#=low bis SS#=high> aus?> Sind die Pegel und Flanken der Signale sauber? Passt das Timing zu dem,> was das Display erwartet und braucht?
Moin Lothar,
Danke für deine Antwort!
Habe mir mal eine Übertragung rausgepickt und im Detail angeschaut
(siehe angehängte Bilder):
Die Timings:
Nachdem das CS bzw. SS-Signal von 3,39V auf 6mV fällt, vergehen ca.
1,5us bis die Clock anspringt. Mindestzeit (t_css, Chip Select Setup
Time) ist mind. 100 ns -> passt!
Die Frequenz von der Clock liegt bei ca. 6,6 MHz. Low-Signal ist 36mV
und High 3,31 V. Laut Datenblatt vom E-Paper liegt die "Serial clock
cycle (write)" - Time bei mind. 100 ns -> 10 MHz wären möglich -> passt!
Das Datensignal ändert sich direkt mit der fallenden Flanke der Clock
und hat praktisch identische Spannungsüegel. t_sds (Data setup time) und
t_sdh (Data hold time) liegen bei mind. 30ns. Da mit der steigenden
Clock-Flanke gelesen ausgewertet wird, habe ich für beide Werte 150 ns
-> passt!
Ca. 1,5us nach der Übertragung steigt dann das CS-Signal wieder auf High
(3,39 V). t_csh (Chip Select Hold Time) wird mit mind. 100 ns angegeben
-> passt dicke!
Spannungen: (Verglichen mit dem Datenblatt vom verbauten
Voltage-Level-Converter)
Versorgungsspannung: 1,65 V < V_CCB <= 5,5 V -> V_CCB = 3,3V -> passt!
High-Level-Input Voltage: 0.65V * 3,3V=2,145V < V_IH <= 3,3V liegen ->
V_IH ist überall größer -> passt
Low-Level-Input Voltage: 0V < V_IL < 3,3V*0.35=1,155 V liegen -> V_IL
ist überall ~0V -> passt
Also auf jeden Fall ein guter Gedanke, aber leider sieht mir das alles
in Ordnung aus! Ich habe testweise nochmal die SPISetting auf 1MHz
eingestellt mit praktisch dem gleichen Ergebnis, nur das die Frequenz
von 1MHz ziemlich exakt getroffen wird. E-Paper-technisch keine
Änderung.
Ich werde gleich nochmal den Arduino-Uno ranpacken und schauen, wie die
Werte dort aussehen. Womöglich funktioniert der SPI_MODE0 beim ESP auch
anders als beim UNO...?
> BTW: mit einem etwas besseren Masseanschluss der Tastköpfe (jeder> Tastkopf mit seinem eigenen Masseclip auf kürzestem Weg zur> µC-Masse) würden die dargestellten Signale nicht so übel überschwingen.> Und wenn sie es trotzdem tun, dann könnte das ein Problem sein.
Das stimmt! Habe jetzt alle Masse-Anschlüsse wieder angeschlossen und
die Signale sehen außer nem recht ordentlichen Überschwinger nach einem
Pegelwechsel meines Erachtens in Ordnung aus. (Siehe Bilder)
Moin Michael!
Michael U. schrieb:>> BUSY - GPIO10 (SDD3)> ist der nicht vom Flash des ESP9266 benutzt?
Ja, da hast du Recht. Man kann ihn wohl als Ausnahme nutzen und ich habe
mich da auf einer Website falsch leiten lassen. Habe es nochmal mit GPIO
16 (WAKE) ausprobiert, dann habe ich wieder die gleiche Belegung wie in
der von dir genannten Bibliothek. Leider ebenfalls kein Erfolg.
> Ich habe zwar nur kleine E-Paper am ESP8266, die Arduino-Libs von> https://github.com/ZinggJM/GxEPD> liefen aber eigentlich immer mit dem ESP8266 ohne Eingriffe.
Habe diese Bibliothek ebenfalls ausprobiert und auf ESP8266 und 7,5"
E-Paper angepasst, leider kein Erfolg :/ Die angepasste Version ist im
Anhang. Die Ausgabe ist:
fest, die darauf wartet, dass der Busy-Pin wieder auf High geht.
Messungen mit dem Oszi haben ergeben, dass alle Signale vom ESP am HAT
ankommen. Das Busy-Signal ist allerdings durchgehend LOW :/
> Eigentlich sollte es doch auch sinnvoller sein, statt den WDT> zurückzusetzen besser yield() azfzurufen, es geht ja vor allem darum,> daß die anderen Funktionen nicht zulange blockiert werden.
Da hast du recht, das wusste ich nicht. Habe entsprechend die
wdt_reset(); zu yield(); geändert ...
und
ES FUNKTIONIERT!!!
Ich werde jetzt nochmal ein wenig weiter rumprobieren, ob es wirklich
nur am yield lag oder ob ich hier nicht doch irgendwo einen
Wackelkontakt habe, etc. So oder so schon Mal:
VIELEN VIELEN DANK!
Ich habe echt schon nicht mehr daran geglaubt, dass es noch klappen
würde :/
Ja, die Methode des unbekuemmerten
> rumprobieren
fuehrt gelegentlich zum Erfolg.
Aber eben nur gelegentlich.
Verbunden mit allgemeiner Ahnungslosigkeit ueber die
"Innereien" des Systems, siehe yield(), lassen das
gelegentlich schnell zu einem eher selten werden.
> I wanted to know where to put> yield() in the program to get rid of the busy timeout?
As always: You should read the source.
Eventually you may find the wdt_reset...
And replace it.
I will not do it for you.
Another approach would be to understand what
the function yield is good for.
Erstmal vielen Dank - ich habe echt viel probiert und gesucht bis ich
die Lösung von euch gefunden habe. 👌
@Riaz Ahmed you have to change "wdt_reset()" to "yield()" inside the
epd7in5_V2.cpp provides by @Julian