Closed lumapu closed 8 months ago
Hallo Lukas, das mit Sonnenuntergang deckt sich mit meinen Erfahrungen und Beobachtungen. Nach Sonnenuntergang kann der WR nicht mehr antworten, dh der ESP steckt in seiner TX/RX Schleife und verbringt viel (zu viel?) Zeit damit auf Antworten zu warten die aber nicht kommen. Wenn er dann teilweise andere Aufgaben startet (wie MQTT Nachrichten oder gar WiFi Requests) dann wird er manchmal evtl. doch noch durch gelegentliche Antworten oder Fragmente durch angeforderte Retransmits unterbrochen.
Alles in allem scheint er die Zeit für die Routineaufgaben nachts nicht mehr so sauber und gut aug alle „Prozesse“ zu verteilen woe tagsüber wenn er auch antwortrn bekommt. Am nächsten Morgen wenn der WR auch wieder antwortet scheint auch meist wieder alles eitel Sonnenschein.
Einer der Punkte die mir prinzipiell auf/eingefallen sind, wäre statt dem ESP8266WebServer wie in Thomas B.‘s OpenDTU auch den AsyncWebServer zu verwenden. Drg sollte prinzipiell nicht-blockierend sein und kann ggf aucb mehrere Clients/Requests quasi „parallel“ abhandeln/beantworten. Ich hatte gestern versucht seinen OpenDTU Code auf den ESP8266 bzw die dafür benötigten Bibliothrken zu portieren, bin aber an den beiden Interrupt-Handlern als Klassen-Methoden gedcheitert. Ich muss die vermutlich aus der Klasse herauslösen damit es mit dem ESP8266 klappt.
Der Einsatz von nbSPI_writeBytes klingt sinnvoll und mit 64Bytes scheint der Buffer für die üblichen nRF24 Pakete auch mehr als ausreichend. Eine Anpassung der nRF24 Bibliothek sollte evtl auch nicht allzu aufwändig sein ? Ggf könnten wir auch Upstream beim nRF24 Entwickler ein issue aufmachen. Hast Du vom Oszi oder Logik Analyzer irgendwelche Screenshots o.a. die die Auslastung des SPI Bus zeigen ? Das wäre ja ein Ansatzpunkt den man ggf überprüfen könnte.
Ich schaue mir Mal an was man an der Lib ändern müsste. So wie ich nbSpi verstehe kann man das 1:1 einsetzen.
Bzgl. Oszi habe leider nichts gespeichert, das kann ich die Tage noch nachholen, zur Doku.
@stefan123t jetzt habe ich ein paar Aufnahmen gemacht, allerdings mal wieder im dunkeln. Der IRQ bleibt dauerhaft auf 0, trotzdem ist auf dem SPI irgendwie 'Rushhour'. Ich habe die Lib noch nicht gecheckt, wo und warum diese Daten gesendet werden. (Ob MISO und MOSI richtig sind weiß ich auch nicht)
Capture mit 5ms/div
Detail View of some packages
Long Package (comes from time to time)
and its data (between rulers): 110630_longTransmission.csv
Edit: Der SPI Bus läuft mit 1MHz, siehe 'Detail View'
Edit2: Ich glaube ich habe bit Bitorder falsch rum eingestellt, ich denke lt. Nordic Semi Datenblatt eher, dass ständig das Statusregister 0x07
gepollt wird.
Edit3: .... aber gedreht würde ja 0x70
heißen ...
@lumapu danke für das Update und die Bildchen.
Dass der IRQ dauerhaft bei 0 bleibt wär ja Nachts logisch, da er ja nichts empfängt, für das er den IRQ auslösen muss.
Bitorder umgekehrt würde bedeuten: 0b00000111 bzw. 0x07 => 0b11100000 = 0xE0 Bei Dir steht aber 0x0E also 0x00001110 => 0b01110000 oder 0x70 ?
Auf dem "langen Paket" kann man in der Tat ein bißchen was von einer Payload erkennen:
A0 >15< <72 21 41 59> <78 56 34 12> >80< <0B> 00 <62 BE 2A 88> <00 00 00 05> <00 00 00 00> <EB 51> <1C>
edit <>
passend zum Protokoll
Das sieht zumindest in Teilen wie eine Debug Status Message des Ahoy DTU an den nicht erreichbaren Wechselrichter aus.
Offenbar sendet er auch noch weitere Daten nach der CRC8, ist das gewollt / notwendig ?
Andererseits beginnt das Paket mit 0xA0
also 0b1010 0000 und nicht mit SOF 0x7E
/ 0b1111 1110
Das Stop Byte sollte 0x7F
oder 0b1111 1111 sein.
Vielleicht muß die Variable die gesendet werden soll auch vorher auf NULL gesetzt werden, bevor man sie an den NRF übergibt ?
Auf jeden Fall sollte ich auch mal mein Loqic Squid anschließen, wenn da so hübsche Bildchen rauskommen =^D Ich versuche das noch geistig farblich zuzuordnen, vielleicht kannst Du mich korrigieren / aufschlauen ?:
SOF
, genauso das EOF
warum wird das NRF24 Modul die ganze Zeit gepollt, wir haben doch einen IRQ ... da verstehe ich dann den IRQ nicht
Das Datenblatt habe ich hier gefunden: Sparkfun - NRF24L01
0x0E
Status Register (In parallel to the SPI command word applied on the MOSI pin, the STATUS registeris shifted serially out on the MISO pin)
Bzgl. dem langen Paket: für mich sieht es so aus, als würde das Register 0x0A
gelesen (Receive address data pipe 0), 5 bytes. Danach wird wohl automatisch das Payloadregister gelesen (dieses hat keine eigene Adresse). Habe im Datenblatt aber noch keine Beschreibung hierfür gesehen.
Fazit: Ich denke in der von uns genutzen Lib kann man auf jeden Fall noch Performance / Stabilität / Integrität schaffen.
Hallo Lukas, bei mir kommen einige Status Kommandos immer wieder und alle dreißig Sekunden die konfigurierte Abfrage an den Wechselrichter:
Einen IRQ konnte ich glaub noch nicht aufnehmen. Und er ist mehrere Sekunden sehr beschäftigt mit dieser langen Sequenz.
Also die anderen Implementierungen DTU-PRO, OpenDTU, etc. setzen den SendBuffer immer komplett auf 0x00 bevor sie ein neues Paket zusammensetzen. Die DTU-PRO setzt sogar eine Dummy CRC-16 Summe bevor sie die dann wieder mit der berechneten überschreibt.
Dabei werden die Daten auch immer wieder vor dem Senden mit ForwardSubstitution() zwischen RS485/Net Schnittstelle und NRF24 (usart_nrf.c/.h) escaped. Bei den Antworten erfolgt dann mit UsartNrf_Backward_substitution1() das Gegenteil mit den empfangenen Daten. Hierbei werden die Escape/SOF/EOF Bytes durch "Escape"-Sequenzen ersetzt, also die zu sendenden Daten ggf auch länger. 0x7d -> 0x7d5d 0x7e -> 0x7d5e 0x7f -> 0x7d5f
Ja spricht aktuell nicht für die Lib. Evtl. wurde sie vorher nur wenig oder gar nicht mit dem ESP8266 getestet. Wir können zwei Ansätze verfolgen:
Ich bin persönlich ein Verfechter von Interrupts, ihre Effizienz im Vergleich zu den unsinnig vielen Poll-Anfragen überzeugt mich. Gut könnte ich mir auch vorstellen genau diesen Punkt konfigurierbar zu machen
- ohne IRQ und nach unserem Zeitplan / Statemachine pollen
Das ist zumindest die Vorgehensweise, die auch die DTU verwendet.
Schau mal in UsartNrf_SendLoop_SetPackageTimeOut()
dort finden sich die diversen Timeouts.
Das sind bei nRF24 mit 250kHz meist nicht mehr als 300-500 ms je nach Anfrage / Antwort.
Die Sache mit den Interrupts ist halt, daß der normale Programmablauf komplett unterbrochen wird. Und es ist auch nicht 100% sicher, ob nicht während einer unserer Interrupthandler läuft nicht bereits der nächste IRQ hereinkommt ? Das erinnert mich ein bißchen an die "Goto is Evil"-Debatte, wobei wir an der Stelle ein nicht-deterministisches Goto eingebaut haben, das vom NRF24 getriggert wird. D.h. es kann auch mitten in einer MQTT / WiFi / WebServer Aktion mal kurz die CPU kapern.
Ich bin mir nicht sicher, ob pollen richtig ist, es wäre halt tagsüber wie nachts identisch. Ich glaube nicht, das viele IRQs unseren Ablauf stören, denn wir setzen ja nur noch ein Flag, das wir asynchron abfragen (nach unserem Zeitplan). Was mich an der aktuellen Implementierung stört ist die Dauerkommunikation trotz aktiviertem IRQ.
@stefan123t Ich habe mal eine Version mit dem AsyncWebServer
in einen extra Branch geladen: https://github.com/lumapu/ahoy/tree/asyncWeb
Leider habe ich folgende Probleme, daher mit Vorsicht genießen (Kopie aus commit-log):
/setup
does not work!?/update
does not work for Wemos D1_mini (ERROR[4]: Not Enough Space
), binary is 572kB vs. 371kB beforeIch habe es mit einem ESP-07 (1MB Flash) getestet, daher kann wahrscheinlich für einen Wemos D1 in der platform.ini
folgendes entfernt werden:
board_upload.maximum_size = 1048576
build_flags = -Wl,-Teagle.flash.1m64.ld
@lumapu ich schaue es mir mal bei Gelegenheit an. Der AsyncWebServer sollte m.W. auch im AP Modus funktionieren. Das mit dem Platz auf dem D1 mini (EPS-07) kann ich mir vorstellen / erklären der hat ja auch nur 1MB Flash. Vielleicht sollten wir 4MB Flash als Minimum annehmen / vorraussetzen oder wir müssen ein paar unserer Pages im Flashmem kleiner machen ? +1 für 4MB minimum flash, aber wir können auch eine kleine Umfrage im Forum starten, wer überhaupt einen Flash mit 1MB nutzt.
Ich denke nach deiner Liste in https://github.com/grindylow/ahoy/issues/36#issuecomment-1179792033 können wir von einem Wemos D1 Mini (v3) mit 4MB Flash als Quasi-Standard für dieses Projekt ausgehen.
Yes, that would mean we unsupport the Wemos D1 mini LITE v1 version. Lets first ask the number of users of this specific model on the forum ... and decide in a week or two.
ESP8266 bei mir 4 MB Flash
Nutze auch einen 4mb !
Nutze einen Wemos D1 Mini v3 4 mb
Ich meine, die HTML-Seiten sind schön und recht aber ihr könnt niemals alle wünsche erfüllen, irgend wann wollen die noch Grafiken;-)
I understand it like this: It is being considered whether the Wemos D1 mini LITE v1 will no longer be supported. Especially the Wemos D1 Mini v3 4 mb will continue to be supported.
IRQ: ich habe bei mir beide Versionen, also mit und ohne irq laenger getestet. Es laeuft mit polling definitiv besser, fast keine Abstürze und erwischst mehr Daten. Ich denke die irq in der Lib ist nicht ganz sauber. RX-CH-hopping: mein WR sendet an machen Tagen nur noch über CH61/CH75, also nix mit CH03
@Ziyatoe sprichst du über MI-1500 oder HM-1500? Wahrscheinlich ist es sogar egal, aber trotzdem wäre es interessant.
@lumapu ja ich habe MI-1500. Aber auch einige HM user haben berichtet, dass es manchmal halben Tag nichts empfangen und danach gings wieder: https://www.mikrocontroller.net/topic/525778?page=single#7128706 Ich bin ziemlich sicher, dass nur auf CH3 hören ist zu wenig.
@stefan123t ich habe mal angefangen eine Debug-Firmware zu bauen, um besser zu verstehen was das NRF24 Modul im Hintergrund wirklich macht. Wie wir schon am Oszi gesehen haben wird sehr oft das Statusregister abgefragt, im Schnitt ca. 1000x pro Schreibbefehl - ich weiß nicht ob das die feine Art ist, evtl. sollte man auch hier auf Interrupts setzten, da der ESP für diese Zyklen in einer while-loop hängt. Ein yield
in dieser Loop führt zu einen nicht mehr per WebUI erreichbaren ESP.
@lumapu wollen wir das Issue umbenennen in "NRF24 Status Abfrage 0x07 trotz Interrupt -> Stabilität ESP8266" ?
@stefan123t hab's umbenannt, finde ich auch besser so
Zusammenfassung der im Discord gesammelten Informationen zu diesem Issue.
Symptome:
1 Via SPI wird das NRF-Modul gepollt, vor allem in den Abendstunden, wenn die Wechselrichter ausgehen.
2 Der ESP8266 bleibt dann hängen, vermutlich, weil der WDT nicht zurück gesetzt wird.
Mögliche Ursachen:
Zu 1)
Es wurde beobachtet, dass 0xFF
via SPI an das NRF-Modul gesendet wird.
0xFF
ist in https://github.com/nRF24/RF24/blob/master/nRF24L01.h#L115 als RF24_NOP hinterlegt (Null Operation).
Verwendet wird es in RF24.cpp an 9 Stellen, unter anderem in der Funktion RF24::get_status(void)
https://github.com/nRF24/RF24/blob/master/RF24.cpp#L499
Diese Funktion wird an mehreren weiteren Stellen genutzt. Es wird ein NOP Byte gesendet und das Statusregister wird vom NRF-Modul als Antwort zurück erwartet. Damit wird scheinbar u.A. festgestellt, ob das Modul verfügbar ist (wenn es eine Antwort erhält), ob eine Pipe verfügbar ist ( RF24::available(uint8_t* pipe_num)
) oder ob Payload verfügbar ist ( RF24::isAckPayloadAvailable(void)
)
Von @lumapu kam der Hinweis, dass die Quelle des polling hier zu suchen ist:
https://github.com/lumapu/ahoy/blob/nrfdebug/tools/esp8266/nrf24/RF24.cpp#L1255
In dieser Funktion wird get_status()
in einer Schleife aufgerufen, was wiederum den NOP-Befehl schickt.
Zu 2) Vermutlich sorgt das in 1) beschriebene Problem dafür, dass der Core des ESP8266 blockiert wird und nicht mehr die utility functions ( -> siehe yield() ) ausführen kann, was zu einem reset durch den WDT führen kann.
Meine Vermutung: Die in 1) beschriebene Schleife wird deswegen abends zum Problem, weil die Gegenstelle (Wechselrichter) nicht mehr antwortet.
Für mich zu prüfen:
@thfcm issue ist wieder offen
Mir ist noch was eingefallen. Wir sollten uns mal die Möglichkeit anschauen auch den TX interrupt zu aktivieren.
Das Problem sollte doch auch bei einer invaliden Inverter Serial ID auftreten. Wenn wir geklärt haben an welchen Methoden das Status oder NOP von der RF24 Bibliothek gesendet wird können wir das entweder vermeiden oder upstream ein issue (preferably in english) für nrf24/rf24 aufmachen und vermutlich auch schnell eine Antwort vom aktuellen Maintainer der Bibliothek @ 2bndy5 bekommen.
@aschiffler warum ist eigentlich #83 zu. Wurde das durch das veränderte MQTT reconnect #139 ebenfalls behoben ?
@thfcm @lumapu#4369 oder liegt das an der nRF24 Bibliothek die einfach immer wieder den Status 0xFF RF24_NOP
des nRF24 prüft / pollt anstatt auf den IRQ zu warten ?
das Thema steht noch aus, bitte noch nicht schließen
@lumapu Dein Vorschlag auch TX per IRQ zu handlen klingt logisch und gut. Hast Du das schon mal umgestellt und Nachts mit dem Oszi nachgemessen. Da sollten ja nur TX Pakete rausgehen und kein RX IRQ ausgelöst werden da der Wechselrichter schläft. Also wäre logisch dass er vermehrt pollt wenn er keinen TX IRQ verwenden soll/kann.
nein habe ich noch nicht, steht noch aus
Hallo, was muss hier genau gemacht werden? Wie kann ich hier Unterstützen?
glaube nicht, man muss die Software auf Interrupts umstellen (auch für write) und dann mit einem Oszilloskop prüfen, ob noch eine Dauerkommunikation besteht
@DanielR92 & @lumapu hier sollten wir prüfen ob das Problem dem Polling im TX Modus (vor allem im Nachtbetrieb aufgefallen) behoben werden kann:
Laut TMRh20 geht dies ganz einfach wenn wir die startWrite()
Funktion anstelle der write()
Funktion verwenden.
Beim Empfang sollten wir nach dem Aufruf von enableDynamicPayloads()
die Funktion getDynamicPayloadSize()
anstelle der statischen setPayloadSize()
und getPayloadSize()
verwenden. Ansonsten kann es bei Paketen mit kürzerer Payload vermutlich zu Buffer Overflows oder Ähnlichem mehr kommen, das ist also auch ein valider Punkt den wir leicht ändern könnten.
Wenn das Problem danach trotzdem noch auftritt, sollten wir uns definitiv Alles von Brendan beschriebene genauer ansehen:
app::loop()
im Nachtmodus dazu neigt konstant TX Versuche zu senden erscheint mir sogar einigermaßen richtig, da die meisten anderen Anwendungsteile (RX, MQTT, etc.) in diesem Zustand ja übersprungen werden. whatHappened()
und maskIRQ
Routine in DISABLE_IRQ/RESTORE_IRQ
angepaßt oder beachtet werden müssen wäre noch abzuklären. Aber vorher würde ich die anderen o.g. Punkte anpassen.
@DanielR92 ja Model und die RF Data Rate und RF Power Amplifier sind die Punkte auf die ich immer schaue.
Auto Retry Delay und Auto Retry Attempts bestimmen glaube unsere TX/RX Timeouts.
Und mir war als hätten Brendan und TmRh20 uns noch was zu der Static Payload Lenght mit 32 Byte als Aufgabe mitgegeben ?
Deren Empfehlungen waren hier https://github.com/nRF24/RF24/issues/877 verlinkt
@stefan123t ich habe am WE den interrupt für tx_ok und tx_fail testweise aktiviert und die startWrite Funktion verwendet. Leider kam weder ein TX interrupt noch ein RX interrupt.
Weißt du, ob es ein Beispiel mit startWrite gibt?
Ja verdammt, das lese ich erst jetzt. Würde ja zu meinen Beobachtungen mit der Pause zwischen dem 2. und 3. retransmit passen, oder ?
Würde in meinen Augen auch erklären warum es bei aktivierter Night Communication öfters auftritt, und auch bei mehreren WRs. Denn je mehr WRs und je öfter wir pollen, umso höher ist die Wahrscheinlichkeit das Waldi beißt 😵
Ich habe jetzt mal die Retransmits auf nur 2 eingestellt, also genau da aufhören wo die Pause ist. Vielleicht bringt’s was. Wir werden sehen.
@knickohr ja das ist ein bereits seit langem offenes Ticket. Das deckt sich natürlich mit dem was Du bisher in #564 herausgefunden hast. Ich hatte auch in der Vergangenheit im TX only Modus die meisten WDT Resets.
@lumapu nein ich weiß nicht sicher wie wir die startWrite Funktion richtig verwenden. Ich glaube aber es gab in der RF24 Bibliothek auch ein paar Beispiele die zeigen sollten wie es richtig geht. Eventuell sollte hier auch noch das eine oder andere yield() eingebaut werden, damit der ESP im TX only Modus nicht vergißt Waldi den Watchdog zu füttern.
@beegee3 hier sind die Verbindungen zur RF24 Bibliothek und unserem Issue upstream bzgl. dem Polling im TX Modus. M.E. müssten wir hier die Timeouts für die mögliche Antwort des WR auch einbauen, da wir sonst einfach nur senden und gar nicht warten ob evtl. etwas zurück kommt. So überlasten wir vermutlich den ESP wenn wir die ganze Zeit nur den NRF24 pollen.
Macht mal langsam, nicht gleich eine neue DEV pushen. Wie gesagt, ich habe mal die Retransmits auf 2 runter gedreht weil ich eben zwischen dem zweiten und dritten TX eine „größere“ Pause beobachte. Vielleicht hilft das auf die Sprünge,bzw kann man Waldi hier noch ein Leckerli geben.
Aber vielleicht ist das mit der 76 ja schon gefixt. So eine flüssige DEV gab es seit der 66 nicht mehr 👍
wait and see 🙃
Vielleicht auch hier relevant : #643
@stefan123t Heute habe ich mir gedacht, ob eigentlich alle libraries die wir nutzen 'echt' ESP8266 tauglich sind. Insbesondere schaue ich auf die NRF24 Lib. Im Bezug auf SPI liest man immer wieder, das ESPs einen Watchdog Reset haben. Das könnte dich am den blockenden Kommandos liegen, da hier evtl. am und an zu viel Zeit verbraucht wird. Durch kurzes recherchieren bin ich auf dieses Repository gestoßen: https://github.com/xsrf/nbSPI
Auf dem SPI Bus ist für mein Gefühl auch etwas viel Traffic, habe aber nur kurz mit dem Oszi drauf geschaut.
Evtl. baue ich mir Mal testweise eine NRF24 Version damit. Am WE habe ich meine Ahoy DTU komplett neu aufgebaut, mit Wemos D1 und geschirmten NRF24 (wir in Forum beschrieben). Leider sind die Abstürze gleich geblieben - vor allem bei Sonnenuntergang habe ich verlässlich einen. Mit ist immer noch nicht klar wo es da klemmt.