Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HW Watchdog und Exceptions #564

Closed
Waldo56 opened this issue Jan 8, 2023 · 68 comments
Closed

HW Watchdog und Exceptions #564

Waldo56 opened this issue Jan 8, 2023 · 68 comments
Assignees
Labels
fixed dev fixed question Further information is requested

Comments

@Waldo56
Copy link

Waldo56 commented Jan 8, 2023

Hi,
sehe eigentlich schon seit der Installation von 0.5.66 immer wieder eine reboot_reason HW Watchdog oder Exception (siehe Screenshots). Das passiert eigentlich täglich.
Ich habe MQTT enabled. Ein HM800 ist ca. 40m von der DTU entfernt. Das führt immer wieder zu Wiederholungen beim Datentransfer. Die Daten beider HM800 scheinen aber trotzdem nahezu vollständig und plausibel. Leider weiss ich nicht wie ich bei der Ursachenfindung behilflich sein könnte. Habt Ihr dieses Verhalten auch schon beobachtet?
Screenshot_20230107_222024_Chrome
Screenshot_20230108_082020_Chrome

@knickohr
Copy link

knickohr commented Jan 8, 2023

Da Du ein recht kräftiges wifi_rssi hat, kann es daran nicht liegen. Aber mit dem Power Level high könnte das erklärbar sein. 40m ist schon ein Stück, geht auch weniger Leistung ? Kondensator verbaut ?

@dtuuser
Copy link

dtuuser commented Jan 8, 2023

Bei mir seit Version 0.5.66 habe ich auch fast täglich einen Reboot wegen dem Hardware Watchdog. Habe irgendwo gelesen, dass es bei den AZ Minis an der Nutzung von Port D1 oder am Stromverbrauch oder fehlendem bzw. zu kleinem Kondensator liegen kann.

@knickohr
Copy link

knickohr commented Jan 8, 2023

Das würde erklären das ich nur ca. Alle 2 Tage mal einen Reboot habe. Bei mir sind dicke Elkos zusätzlich mit verbaut 😉

was ist mit D1 ? Hast Du nähere Infos ?

@Gerri1
Copy link

Gerri1 commented Jan 8, 2023

Schaut bei mir so aus!
1
2

@knickohr
Copy link

knickohr commented Jan 8, 2023

Joo, Du bist auch nicht up to Date, wir sind schon bei 69 😅

Bei dem sieht es momentan so aus :

AA8C233B-53AF-4B3D-9AE8-F830FD32B2BA

Wenn Lukas nicht wieder vorher eine neue DEV hervorzaubert 😂

@Gerri1
Copy link

Gerri1 commented Jan 8, 2023

Ich kann erst wieder morgen Abend updaten! 😩

@dtuuser
Copy link

dtuuser commented Jan 8, 2023

Ich suche mal meinen Verlauf ab. Sobald ich die Infos zu Pin D1 gefunden habe, poste ich.

@Gerri1
Copy link

Gerri1 commented Jan 8, 2023

Am D1 hängt bei mir jetzt das Display mit SCL dran. Mit IRQ an D1 und CE an D2 st bei meiner NodeMCU V3 nichts mehr gegangen! 😭

@knickohr
Copy link

knickohr commented Jan 8, 2023

Ähhh, ich weiß gar nicht wie ich verdrahtet habe. Halt Standard Ahoy und eben Standard Nokia, bzw OLED

@Waldo56
Copy link
Author

Waldo56 commented Jan 8, 2023 via email

@Gerri1
Copy link

Gerri1 commented Jan 8, 2023

Bei der NodeMCU ist auch wieder alles Standard. Beim Wemos D1 mini muss ich mal schauen, wie da jetzt die Verdrahtung ist!
Aber Hauptsache es funktioniert. 😁

@dtuuser
Copy link

dtuuser commented Jan 8, 2023

Zu dünnes bzw. falsch geschirmtes USB Kabel könnte auch ein Problem sein.
Oder wie hier beschrieben.....
https://www.mikrocontroller.net/topic/408026 ist zwar schon älter
.... äußere Störeinflüsse über nicht genutzte Pins bzw. Leiterbahnen.
Habe bei mir unbewusst gestern noch ein dickeres USB Kabel genommen, da ich die Hardware in eine Abzweigdose gebaut habe. Seit gestern 12 Uhr kein Reset mehr.

@Waldo56
Copy link
Author

Waldo56 commented Jan 8, 2023

Das ist meine Konfiguration.
Screenshot_20230108_221242_Chrome

@Gerri1
Copy link

Gerri1 commented Jan 8, 2023

Die Kabel zum nRF wirken auch wie eine Antenne und sammeln auch was mit ein!

@Waldo56
Copy link
Author

Waldo56 commented Jan 8, 2023

100uF sind direkt an den Pins vom NRF.

@knickohr
Copy link

Bei der DEV70 knurrt die Bulldogge auch wieder öfters 😪

Keine Nacht ohne Reboot, unter Tags aber offenbar alles OK.

@Waldo56
Copy link
Author

Waldo56 commented Jan 10, 2023

Kann es sein, dass auch ein gesteuerter Reboot manchmal zu einer reboot_reason = Exception führen kann? Nachdem ich in der Vergangenheit Probleme mit der Erreichbarkeit der DTU hatte, habe ich eine Automatisierung eingebaut, die immer um Mitternacht einen reboot auslöst. Heute hatte ich Exception als reason. Komisch.

@knickohr
Copy link

Ja, beim OTA-Update habe ich auch hin und wieder Exception.

@lumapu
Copy link
Owner

lumapu commented Jan 11, 2023

ja man sieht beim reboot auf der Seriellen Konsole eine Exception, der ich nicht weiter nachgegangen bin

@stefan123t
Copy link
Collaborator

@Waldo56 Du hast den NRF24 auf Power Level HIGH, geht er mit LOW / MIN nicht auch genau so gut ?

@stefan123t stefan123t added the question Further information is requested label Jan 12, 2023
@Waldo56
Copy link
Author

Waldo56 commented Jan 12, 2023

Habe ich nicht probiert bei ca. 40m Entfernung.

@knickohr
Copy link

knickohr commented Jan 17, 2023

Ich habe da mal ein bißchen rum gespielt und kann den Pitbull richtig oft bellen lassen 😂

Je niedriger ich mit dem Abfrageintervall von den Invertern gehe, umso öfter knurrt der Wachhund. Ich frage mich nur warum ? Was ist das für ein Unterschied ob ich alle Minute meine Inverter abfrage oder alle 20s ? Ja klar, irgendwann wird die Zeit zu kurz bevor eine Antwort kommt, aber 20s sollte drin sein. Zumal er nicht in 20s alle Inverter abfragt, sondern nur einen nach dem anderen. Bei 6 oder gar 8 Invertern würde ich dann bei der voreingestellten Zeit für einen kompletten Abfragezyklus 3, respektiv 4 Minuten brauchen 😲

Was veranlaßt den Watchdog hier zu resetten ? Was hat der Watchdog denn für eine Zeit, ist sie vielleicht zu kurz ?

@Waldo56
Copy link
Author

Waldo56 commented Jan 17, 2023

Ich habe das Intervall auf 60s bei 5 retries und 2 Wechselrichter. Habe den Watchdog trotzdem.
Wie funktioniert eigentlich das WD Konzept bei der Ahoy? Könnte schon sein, dass die Überwachungszeit zu kurz gewählt ist.

@knickohr
Copy link

knickohr commented Jan 17, 2023

Ich weiß auch nicht wie der Hund bei Ahoy gefüttert wird. Meines Wissen beißt der spätestens nach 8 Sekunden. Könnte mir schon vorstellen das da irgendwelche Abfrageroutinen zum Wechselrichter länger dauern. Vielleicht muß man ihn einfach nur öfters mal füttern ? 🤔

@lumapu
Copy link
Owner

lumapu commented Jan 18, 2023

@knickohr wir füttern den Hund schon sehr viel, jedes yield() macht genau das. Evtl. ist er nach kurzer Zeit überfressen 🤣

@stefan123t
Copy link
Collaborator

stefan123t commented Jan 18, 2023

Ich vermute wenn er (aufgrund IRQ) nicht mehr dazu kommt seine normalen Aufgaben abzuarbeiten und der Stapel an wartenden RX-Paketen, neu zu sendenen Commands, zu sendenden MQTT Nachrichten und zu beantwortenden HTTP UI/API Anfragen zu groß wird, dann schnappt der Waldi halt irgendwann auch mal zu.
Wenn man nun nicht wie empfohlen alle 15-30 Sekunden eine Anfrage an den/die WR schickt, sondern gleich alle 5 Sekunden oder gar noch öfter, dann passiert das halt relativ schnell und der Hund wird dann einfach bissig.
Es ist also m.E. nicht eine Frage des Hundes sondern es kommt tatsächlich auch hier auf den Halter an.

@knickohr
Copy link

15 Sekunden funktioniert bei 2 WRs nich mehr, da die Zeit zum pollen, zumindest wenn die WRs offline sind, schon zu lange dauert. Bin deshalb auf 3 Retry runter, das reicht dann noch, zumindest sind dann bei mir noch ca. 3s Pause.

Wollte eigentlich erreichen das ich zumindest alle 30s von allen WRs eine Antwort bekomme. Scheint wohl nicht zu funktionieren. Leider sind das halt bei 6 WRs im Endausbau, vielleicht sogar 8 😲, schon mal 4 Minuten bis alle Daten von allen WRs up to date sind.

@knickohr
Copy link

Ich hab’s mal ein paar Tage beobachtet. 90% der Waldi-Reboots passieren bei mir in der Zeit zwischen dem „communication start“, bzw. „communication Stop“ und dem „online“ bzw. „Offline“. Also in der Zeit wo die DTU ins leere pollt.

@beegee3
Copy link
Contributor

beegee3 commented Jan 24, 2023

Um ausschließlich nicht antwortende Inverter zu simulieren habe ich mal 2 bei mir nicht exisitierende Inverter Seriennummern in die Settings eingetragen, so dass niemand antwortet. Knapp 2 Stunden laufen lassen, kein Waldi. Ist es doch ein ESP8266 Problem?

@knickohr
Copy link

OK, ich mach das mal mit meinem ESP32. Mal sehen ob ich da Waldi auch zum beißen bringe.

@stefan123t
Copy link
Collaborator

Auch wenn ich nicht alles verstehe:

  • wieso setzt man zunächst 'AutoAck' auf true und öffnet dann eine (merkwürdige) DUMMY_RADIO_ID Pipe, um 'AutoAck' auf false zu setzen?

Ich vermute mal man wollte das AutoAck abschalten und damit keine Pakete mit der richtigen DTU ID rausgehen hat man das mit der Dummy ID aktiviert und dann wieder deaktiviert.
Stammt entweder aus "Hubis Code" oder sogar aus dem NRF24 Send/Scan Beispielcode.
Vielleicht kann es auch weg 🤔 ?

  • braucht man mNrf24.whatHappened(tx_ok, tx_fail, rx_ready) nicht, wenn man nur sendet und nichts zurückkommt (der oben beschriebene WR offline Fall) ?

whatHappened speichert bzw exportiert doch das Ergebnis der drei Register/Flags tx_ok, tx_fail, rx_ready, damit wir die dann auswerten können und wissen wo die State Machine des NRF24 gerade rumhängt bzw welchen Zustand sie hat.
Wenn also nichts kommt, dann kommt da auch nichts. WhatHappened() eben ?

@knickohr
Copy link

Ich mache mir echt Sorgen um Waldi 😲 Lebt er noch ?

Der dritte Abend Gassi gehen und er beißt nicht mehr. Braves Hundi 🦮

Meiner Meinung nach kristallisiert es sich immer mehr heraus das es ein 8266-Problem ist. Was ist anders am ESP32, außer das er 2 Core hat, schneller ist und mehr Pins hat ? Ich schätze mal es sind die 2 Cires und deren Aufgsbenverteilung. Core 0 übernimmt ja die gesamte Hardwareaufgaben, währen im Core 1 die Applikation läuft.

@beegee3
Copy link
Contributor

beegee3 commented Jan 26, 2023

@knickohr super, dass Waldi beim Guru bleibt.

Was ist anders am ESP32?

Die Interruptsteuerung und deren Überwachung ist natürlich anders. Und in dem Umfeld such' ich gerade, da die Probleme vornehmlich beim Nichtantworten des/der WR entstehen. @lumapu hat in #83 ja deutliche Bilder mit der SPI 'Rushhour'.
Die kommt vom NRF24 write Befehl, der die SPI transaction startet und, da ja keine Rückmeldung kommt, 15 mal im Abstand von 750us versucht, die Payload rauszuschicken (so die aktuelle Vorgabe im Programm). Macht 15*(250us + 750us) = 15ms plus Wartezeit, bis der Fehlversuch festgestellt ist, in denen der CE PIN eingeschaltet ist.
Die Empfehlungen von Brendan und TmRh20 als Antwort auf @stefan123t's Nachfrage (nRF24/RF24#877) gehen auch in die Richtung. Hab' diese zum Anlass genommen, verschiedenes auszuprobieren, bin aber noch nicht fertig. Folgender Zwischenstand:

  • beim Senden braucht man kein auto-ack, es geht auch mit mNrf24.setAutoAck(false); mNrf24.write(buf, len, true);
    (true = do not request ACK response). mNrf24.openWritingPipe(DUMMY_RADIO_ID); wird dann auch nicht gebraucht!!!
  • anstelle von mNrf24.write(...); kann man auch mNrf24.writeFast(buf, len, true); mNrf24.txStandBy(); nutzen. Das stellt sicher, dass CE wieder auf low geht, was bei mNrf24.write(...); nicht unbedingt der Fall ist. Das ändert aber nichts an der Zeit, die CE auf high steht. Genauso wenig, wie die Empfehlung startWrite() mit TX IRQ zu nutzen. Da hilft m.E. nur da folgende:
  • beimNrf24.setRetries(...) die Anzahl der Wiederholungen reduzieren (teste ich morgen)
  • startWrite() mit TX IRQ erfordert mehr Programmieraufwand, der m.E. das Problem nicht löst und sich daher z.Zt. nicht lohnt
  • DISABLE_IRQ und RESTORE_IRQ beim CircularBuffer sind überflüssig. Früher wurden sie sicher mal gebraucht, aber die Interruptbehandlung erfolgt ja jetzt ausschließlich in Radio.h. Dort in der loop kann das 2. RESTORE_IRQ entfernt werden.
  • dynamic payloads beim Empfang funktionieren grundsätzlich, allerdings sind die Inhalte nicht checkPaketCrc tauglich. Erstens ist die im Byte 0 angegebene Länge immer 32 (obwohl getDynamicPayloadSize() das richtige liefert und auch nur soviel gelesen wurde) und selbst mit korrigierter Länge ist CRC falsch.
    Und da der Datenempfang eher unkritisch ist, kann der erstmal wie bisher bleiben.

@knickohr
Copy link

2 Tage 17 Stunden, und noch immer kein Waldi 😎

ich gebe noch zu Bedenken ob vielleicht auch das Nokia uns einen Streich spielt. Hängt ja auch am SPI und teilt sich diesen mit dem NRF.

Andreas (unser Display-Guru) hat gestern so eine Anmerkung gemacht das offenbar ein spiend() bei der NRF-Rouitine fehlt, bzw. vermißt wird.

vielleicht sollte man da auch mal genauer schauen 🤔

@beegee3
Copy link
Contributor

beegee3 commented Jan 27, 2023

spiend() ? wir wollen doch den SPI nicht abschalten. Vielleicht war SPI.endTransaction() gemeint. In der RF24 lib wird jeder SPI Transfer mit SPI.beginTransaction gestartet und mit SPI.endTransaction beendet. Das ist unproblematisch. Danach geht CE auf high und erst wieder auf low, wenn entweder TX_DS (TX data send = Daten vom WR empfangen) oder MAX_RT (maximum retries = Maximalanzahl der Sendeversuche erreicht) signalisiert wird. Da wird Zeit verbraucht. Insbesondere wenn der WR offline ist, da dann direkt wieder angefragt wird ("nothing received: Request Complete Retransmit"), was wohl die SPI 'Rushhour' erklärt. @stefan123t wollte ja noch den Timeout Calculation Code aus der Hoymiles DTU Pro raussuchen. Könnte weiterhelfen.
Keine Ahnung, ob zusätzliche Geräte am SPI Waldi eher knurren lassen, aber das Problem gab es ja auch schon bevor die Displays ins Spiel kamen.

@beegee3
Copy link
Contributor

beegee3 commented Jan 27, 2023

hier eine Wasserstandsmeldung:

  • DISABLE_IRQ und RESTORE_IRQ beim CircularBuffer sind überflüssig (s.o.), man könnte CB durch eine std::list ersetzen
  • Radio.h: Scheint egal zu sein, ob in der loop das 1. oder 2. RESTORE_IRQ entfernt wird
  • Senden geht ohne auto-ack, aber man bekommt sehr viel mehr "nothing received"
  • Empfangen mit auto-ack geht gar nicht, d.h. man muß auto-ack zwischen Senden und Empfangen immer Umschalten
  • die Reduktion der Anzahl der Wiederholungen bei Nrf24.setRetries(...) führt auch zu sehr viel mehr "nothing received"
  • die DUMMY_RADIO_ID Pipe wird definitiv nicht benötigt

Ist irgendwie ernüchternd, im Fazit habe ich die Zeile mNrf24.setRetries(3, 15); // 3*250us and 15 loops -> 11.25ms aus sendPacket ins setup verschoben und sendPacket verkürzt. Dabei write durch writeFast und txStandBy ersetzt, aber das ist (zumindest beim ESP32) eher unwesentlich (s.o.):

        void sendPacket(uint64_t invId, uint8_t buf[], uint8_t len, bool isRetransmit, bool clear=false) {
            ...
            mNrf24.setChannel(mRfChLst[mTxChIdx]);
            mTxCh = getTxNxtChannel(); // switch channel for next packet
            mNrf24.openWritingPipe(invId); // TODO: deprecated
            mNrf24.setCRCLength(RF24_CRC_16);
            mNrf24.enableDynamicPayloads();
            mNrf24.setAutoAck(true);
            mNrf24.writeFast(buf, len, false); // false = request ACK response
            mNrf24.txStandBy();
            mRxChIdx = 0;
            mNrf24.setChannel(mRfChLst[mRxChIdx]);
            mNrf24.setAutoAck(false);
            mNrf24.disableDynamicPayloads();
            mNrf24.setCRCLength(RF24_CRC_DISABLED);
            mNrf24.startListening();
            ...
        }

In Bezug auf Waldi hilft das nicht weiter.
Aber vielleicht hilft folgender Vorschlag: für den Fall, dass gar keine Rückmeldung vom WR kommt, nicht sofort eine neue Anfrage senden, sondern das nächste Intervall abwarten. D.h. in payload.h den 'Request Complete Retransmit' ersetzen durch

            if(false == mPayload[iv->id].gotFragment) {
              DPRINTLN(DBG_WARN, F("(#") + String(iv->id) + F(") nothing received"));
              mPayload[iv->id].retransmits = mMaxRetrans;
            else {
              ...

Das würde den SPI deutlich entspannen. @lumapu Wäre schön, wenn du davon Nachtaufnahmen machen könntest (z.B. mit Inverter Intervall 5s) 😃

@lumapu
Copy link
Owner

lumapu commented Jan 27, 2023

@beegee3 danke für deine Untersuchungen. Circular buffer durch eine std::list oder std::queue zu ersetzen klingt interessant. An der Stelle gehört auf jeden Fall was gemacht, da dies noch Urgesteine sind.

Die Aufnahme hab ich gerne machen. Ich hätte mir aus der Doku mehr versprochen aus startWrite als deine Analysen jetzt ergeben haben.

@beegee3
Copy link
Contributor

beegee3 commented Jan 27, 2023

@lumapu ok, ich Versuch mal startWrite umzusetzen. Vielleicht geht's doch einfacher als gedacht. Hab' Bedenken, da zwischen Senden und Empfangen immer auto-ack und dynamic payloads aktiviert bzw. deaktiviert werden. Z.Zt. wird das ja in sendPacket gemacht. Mal sehen, ob das so bleiben kann, oder per Interrupt gesteuert werden muß.

@knickohr
Copy link

Pegelstand Blaustein : Normal 😉

Waldi ist brav, keinen Beißer, kein Knurren. ESP32-Wachhunde sind gute Hunde 😅

Uptime fast 4 Tage.

@Waldo56
Copy link
Author

Waldo56 commented Jan 28, 2023

Das muss jetzt einmal geschrieben werden. Ihr seid der Wahnsinn betreffend Eurem Einsatz bei der Ursachenfindung und Verbesserungen.
Eines ist mir noch aufgefallen bei einem gesteuerten Web Reboot der DTU. Es gibt öfter mal als Restart Cause eine Exception. Wieso? Werden hier nicht vor dem eigentlichen Restart die Interrupts gesperrt?

@knickohr
Copy link

Hat doch Lukas schon mal ein Statement abgegeben :

#564 (comment)

@lumapu
Copy link
Owner

lumapu commented Jan 28, 2023

ja ich denke die Exception kommt von den Event Network lost und versucht dann noch Prozesse oder was auch immer zu starten die nicht mehr existieren. Ist nicht ganz sauber aber halt auch nicht Prio 1

@beegee3
Copy link
Contributor

beegee3 commented Jan 28, 2023

@lumapu wie vermutet ist startWrite problematisch. Die auto-ack und dynamic payloads Wechsel gehen noch, aber permanentes IRQ an- und ausschalten und das Channel Hopping machen Ärger. Zumindest dachte ich das, denn ich bekam immer wieder Reboots. Nach etlichem Umprogrammieren hab' ich mir erst jetzt mal genauer angesehen, was vor dem Reboot passiert. Und siehe da, die letzte Meldung ist "Alarm #2 'DTU command failed'...". Das kommt doch von parseAlarmLog und wird aus payload.h process aufgerufen. Darauf folgt der Aufruf (mCbAlarm)(code, start, end);. Da ich für die Tests Mqtt abgeklemmt habe, wird mCbAlarm nicht gesetzt und der Aufruf muss unweigerlich zum Reset führen!
payload.h : bitte im setup mCbAlarm = NULL; eintragen und den Aufruf nur für if (NULL != mCbAlarm) machen
(bei process und notify)!

@beegee3
Copy link
Contributor

beegee3 commented Jan 28, 2023

@lumapu die Sonne ist weg -> keine RX Tests möglich, daher noch 2 Bemerkungen:

  1. wenn oben genannte Exception von Network lost kommt, dann hilft in app.h:
       void tickReboot(void) {
            DPRINTLN(DBG_INFO, F("Rebooting..."));
            onWifi(false);
            ah::Scheduler::resetTicker();
            WiFi.disconnect();
            ESP.restart();
        }

kann man für OTA Update noch ausbauen (alle laufenden Prozesse vor dem Einspielen des Updates stoppen):
in appInterface.h die Zeile virtual void setOnUpdate() = 0; und inapp.h das zugehörende

        void setOnUpdate() {
            onWifi(false);
        }

sowie den Aufruf in web.h

       void onUpdate(AsyncWebServerRequest *request) {
            ...
            mApp->setOnUpdate();
        }
  1. (falls mal sonst nichts zu tun ist 😬) in main.cpp steht noch ein TODO: move to HmRadio
    das lässt sich so erledigen:
    in hmRadio letzte Zeile volatile bool mIrqRcvd; löschen, dafür hinter den Makros, aber vor class HmRadio die Zeile
    static volatile bool mIrqRcvd; schreiben. Dann noch in setup hinter pinMode(irq, INPUT_PULLUP); die Zeile attachInterrupt(digitalPinToInterrupt(irq), []()IRAM_ATTR{ mIrqRcvd = true; }, FALLING);
    Das war's. Nur noch in main attachInterrupt(...) und die Funktion IRAM_ATTR void handleIntr(void) löschen. Auch alle anderen handleIntr Funktionen in app.h, app.cpp und hmRadio.

lumapu added a commit that referenced this issue Jan 28, 2023
…AP with same SSID is there

fix endless loop in `zerovalues` #564
fix auto discover again #565
added total values to autodiscover #630
improved zero at midnight #625
@knickohr
Copy link

knickohr commented Jan 30, 2023

Ich behaupte jetzt einfach mal, es ist ein 8266-Problem !

Mit einem ESP32 ist folgender Stand aktuell :
C1C3E084-6D1B-4ECB-8C07-D130E991C0DF
Keine Waldi‘s, keine Reboots. Die DTU läuft rund und geschmeidig. Auch keine hängenden Webseiten wie hin und wieder berichtet wird. MQTT stört den Ablauf ebenfalls nicht.

Das ist jetzt die längste Uptime die ich jemals hatte, bin schon 2. Versionen hinten an und noch auf der 76 😲

@lumapu
Copy link
Owner

lumapu commented Jan 30, 2023

echt schade, dass der 8266 so zickig ist. Bei mir ist zur Zeit oft der halbe Webserver tot, die API liefert nur noch null aber ein /reboot geht noch 🤔

@knickohr
Copy link

Irgendwas beschäftigt den. Kein Wunder das Waldi beißt. Das muß man doch raus bekommen. Ist schon eigenartig. Als ich mit der 0.5.17 angefangen habe war der ESP32 das Problem, nun ist es umgekehrt 😉

Ach ja, hast eben eine neue 78 raus geballert 🤭

@beegee3
Copy link
Contributor

beegee3 commented Feb 3, 2023

neue Wasserstandsmeldung und Tests:

  • der Circular buffer kann ohne viel Aufwand durch eine lokale std::queue in hmRadio als RX Buffer ersetzt werden.
    Die CircularBuffer.h Datei ist damit überflüssig!
  • der Empfang mit auto-ack und und dynamic payloads funktioniert! checkPaketCrc war das Problem. Bei eingeschaltetem auto-ack wird die CRC Prüfung vom NRF selbst vorgenommen und nur gültige Pakete ohne das crc8 Byte im RX FIFO eingetragen. Dynamic Payload sorgt dafür, dass die Pakete bereits so vorhanden sind, wie wir sie brauchen. Sie können direkt und unverändert in unseren RX Buffer übertragen werden.
  • das liefert gleichzeitig die Möglichkeit, das Channel Hopping aus der app::loopStandard in die Radio loop zu verlegen und dort alle RX Pakete in einer Scheife zu empfangen. Für die TX_REQ_INFO + ALL_FRAMES Abfrage wird das 9. Byte der Pakete ausgewertet und man weiß, wann das letzte Paket empfangen wurde, sprich der Empfang beendet werden soll. Alle anderen Abfragen erwarten ja nur ein Paket (oder irre ich mich?). D.h. die Schleife wird beendet, sobald das empfangen wurde. Kommt nichts an, gibt es einen Timeout Ausstieg.
  • permanentes IRQ an- und ausschalten wird so nicht mehr benötigt, d.h. DISABLE_IRQ und RESTORE_IRQ sind auch in hmRadio überflüssig.
  • auch ah::checkTicker in app::loopStandard wird nicht mehr gebraucht und damit entfällt die ganze ahoyTimer.h Datei!
  • die Radio loop Schleife wird nur durchgeführt, wenn zuvor eine TX Abfrage gestartet wurde. Dementsprechend meldet sie "nichts zu tun", oder "Schleife durchlaufen" and app::loopStandard, wo nur im zweiten Fall der RX Buffer weiterverarbeitet wird.

Hab's erfolgreich getestet: die Schleife braucht für den Empfang aller Pakete zwischen 100 und 130 ms. Bei nur einem abgefragten Inverter konnte ich das Abfrageintervall auf 2 sek reduzieren, ohne großartig "retransmits" zu erzeugen. Ab und zu ein "Frame missing", wie bisher auch. Hab' allerdings auch eine stabile Verbindung zum WR (trotz NRF ohne externe Antenne, Amp. Power Level auf MIN, knapp 10 m Funkstrecke 😁). Bei mehreren Invertern ist so ein 1 sek Abfrageintervall möglich!

Ich will noch ein paar Sachen checken, bevor ich den Code liefern kann (wohl als "dev03 devil" Pull Request, zu viele Anpassungen für ein Posting. Wobei ein Pull Request wegen meines Systems nach wie vor schwierig ist 😞).
So frage ich mich, warum der NRF CRC Automatismus beim Empfang funktioniert, beim Senden aber nicht. Obwohl es laut nRF24L01+ Product Specification, Kapitel 7.3.6 möglich ist. Und ich würde gerne startWrite mit TX IRQ nutzen.

@knickohr
Copy link

knickohr commented Feb 3, 2023

Bei mehreren Invertern ist so ein 1 sek Abfrageintervall möglich!

Im Ernst ? 😲

das würde die Abfrage bei 6 Invertern um mindestens Faktor 200 beschleunigen 😎

Übrigens, Uptime mit dem ESP32 jetzt ganz knapp 10 Tage. Und er läuft und läuft und läuft. Braves Waldi !

@stefan123t
Copy link
Collaborator

stefan123t commented Feb 3, 2023

Laut https://www.sparkfun.com/datasheets/Wireless/Nordic/nRF24L01P_Product_Specification_1_0.pdf sind die CRC Polynome ja auch spezifiziert.
0b10001000 00010001 = x^16+x^12+x^5+1 = 0x8811
0b1 00000111 = x^8+x^2+x+1 = 0x107

Ich hatte mir vor zwei Wochen den Kopf zerbrochen wie wir auf das Reverse Polynom 0xA001 (für das CRC-16/ModBus 0x8005 Polynom) gekommen sind ;)

Siehe die Diskussion hier:
https://discord.com/channels/984173303147155506/993500210271629393/1068190371370254346

Vielleicht ist das Polynom für das Senden an den WR ja auch ein Anderes ?

@beegee3 Wir setzen in sendPacket() aktuell RF24_CRC_DISABLED vor dem Senden. Es gibt auch die beiden og RF24_CRC_8, RF24_CRC_16. Aber das sind wie geschrieben hart-codierte Polynome von Nordic Semiconductors.

Laut src/utils/crc.h verwenden wir hier 0x01 als CRC-8 Polynom und 0x00 als Initialisierungsvektor. Evtl schauen wir nochmal nach welche Polynome der Hersteller Hoymiles in der DTU Pro verbastelt hat, aber das ist mE ein anderes als das von Nordic Semicon.

@knickohr
Copy link

knickohr commented Feb 3, 2023

Ich schreibs jetzt mal dazu #643

@beegee3
Copy link
Contributor

beegee3 commented Feb 3, 2023

@stefan123t sorry, muss dir widersprechen: beim Senden wird RF24_CRC_16 benutzt, beim Empfang bisher RF24_CRC_DISABLED.
Beim Senden wird auch auto-ack und dynamic payload benutzt, daher kann nach Spezifikation CRC nicht disabled werden. Aber wir rechnen bei Control und bei Time Packets selbst das Reverse Polynom 0xA001 für die Packet Bytes nach PID (also ab Byte 10) und hängen diese beiden CRC16 Bytes ans Packet an. Cmd Packets haben nichts hinter PID, daher wird dort auch nichts gerechnet. Bei allen Packets wird zusätzlich ein über alle Bytes selbst gerechnetes CRC8 Byte angehängt. Diese ganzen Bytes werden in den Sendepuffer des NRF übertragen. Dazu erzeugt der NRF noch 1 Byte 'Preamble', 5 Bytes 'Address' und 9 Bit (nicht Byte!) 'Packet Control Field', die er dem Packet voranstellt. Und die 2 RF24_CRC_16 Bytes, die angehängt werden. Dann wird alles gesendet. Ein Debug mit nicht maskiertem TX IRQ liefert ein TX fail zurück, als wenn nichts oder nicht das richtige angekommen wäre. Doch der WR schickt die richtigen Antworten zurück 🤔
Habe bei mir nun auch für den Empfang auto-ack, dynamic payload und RF24_CRC_16 eingeschaltet und die richtigen Antworten kommen ohne angehängtes CRC8 Byte zurück. Bei auto-ack false, static payload und RF24_CRC_DISABLED wird das CRC8 geliefert. Die neue Vorgabe macht es einfacher, man muss selbst nichts rechnen, es werden sowieso nur CRC geprüfte Antworten durchgelassen. Merkwürdig ist, dass Senden und Empfangen so unterschiedlich sein sollen. Auch wenn es funktioniert, ist es evtl. total drüber, dass wir CRC16 und CRC8 rechnen und der NRF sein eigenes CRC16 auch noch anhängt? Lässt sich das vereinfachen? DTU Pro benutzt das eigene CRC16 und CRC8 beim Senden und Empfangen. Das ganze noch mit STX und ETX umrahmt. Diese Packets werden auch für Netzwerkkommunikation genutzt. Bisher habe ich noch nicht die Stellen gefunden, wo der NRF direkt angesprochen wird (Register, Feature, TX bzw. RX Buffer, usw.). Bin aber dran...

@beegee3 beegee3 mentioned this issue Feb 5, 2023
@lumapu
Copy link
Owner

lumapu commented Feb 24, 2023

sehr ähnlich wie #660, ich hoffe wir beheben das bald

@lumapu lumapu added the fixed dev fixed label Mar 8, 2023
@lumapu lumapu self-assigned this Mar 8, 2023
@lumapu lumapu closed this as completed Mar 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed dev fixed question Further information is requested
Projects
None yet
Development

No branches or pull requests

8 participants