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

Information about Inverter communication #734

Closed
beegee3 opened this issue Mar 4, 2023 · 29 comments
Closed

Information about Inverter communication #734

beegee3 opened this issue Mar 4, 2023 · 29 comments

Comments

@beegee3
Copy link
Contributor

beegee3 commented Mar 4, 2023

wie hier angekündigt ein paar Informationen zur Inverter Kommunikation.
Das ist mit Absicht kein Feature Request, die Erkenntnisse beruhen alleine auf einer Reihe von Tests, die ich mit meinem Inverter durchgeführt habe und daher nicht notwendig allgemeingültig sind.

zum Inverter:

  1. die Kanäle werden in absteigender Frequenz gewechselt
  2. nach 100ms wird der Kanal gewechselt
  3. der erste RX Kanal ist zum TX Kanal zwei Kanäle versetzt (absteigend betrachtet)
  4. Frames kommen im Abstand vom 25-45ms (im Durchschnitt 35ms)

zur Kommunikation:
Bisher werden die RX Kanäle in aufsteigender Frequenz alle 4ms gewechselt. Dabei läuft man dem gerade aktuellen TX Kanal des Inverters entgegen, wodurch man eine gute Trefferquote beim Empfang erhält.
Allerdings wird beim Kanalwechsel zuerst ein stopListening und nach dem Wechsel ein startListening aufgerufen. Das ist unnötig (der NRF kann ohne Stopp den Kanal wechseln) und kostet Zeit, in der nicht gelauscht wird.
Wenn man den 'richtigen' Kanal gerade verpasst hat, dauerst es bis zum Empfang 16ms, wenn der Inverter zwischenzeitlich den Kanal wechselt, bzw. 20ms, wenn der Inverter nicht wechselt. Dadurch kann es zu 'missing Frames' oder auch 'no answer' kommen.
Beim Senden wird auf ein ACK gewartet, was aber nie kommt. Auch das kostet unnötig Zeit, in der der Inverter bereits antwortet, aber nicht gelauscht wird.

Habe nun versucht, all dies in eine neue Programmierung umzusetzen. Die sehr guten Werte von @knickohr waren mein Maßstab, wobei meine bisherigen Werte deutlich schlechter waren. Mit der neuen Methode sieht es allerdings anders aus:

  knickohr beegee3 (bisher) neue Methode
TX count 7565 4591 4899
RX success 6547 4046 4501
RX fail 0 51 1
RX no answer 1017 493 395
RX fragments 13080 12900 13497
TX retransmits 1692 2079 1105
       
TX sent (= count + retransmits) 9257 6670 6004
       
RX success / TX sent 70,7% 60,7% 75,0%
RX no answer / TX sent 11,0% 7,4% 6,6%
RX fragments / TX sent 1,41 1,93 2,25
TX retransmits / TX sent 18,3% 31,2% 18,4%

Die Konstellation für meine Werte:
1 Inverter mit 2 Panels, 2 Sekunden Intervall, max. 5 Wiederholungen pro Payload,
ohne zusätzliche Features, d.h. kein MQTT, kein Display.

Das Problem beim Lauschen ist, dass man nicht weiß, wann der Inverter seinen Kanal wechselt.
Daher genügt es nicht, 100ms lang auf nur einem Kanal zu lauschen. Stattdessen wird innerhalb der 100ms in einem 3ms Wechsel auf dem erwarteten und dem nächsten Kanal gelauscht, was die Trefferquote deutlich verbessert.
Stellt sich die Frage, ob die neue Methode auch für andere Inverter funktioniert, sprich HM mit weniger/mehr Panels sowie die MI Varianten. Wäre schön, wenn sich Leute finden, die das testen.
Für Interessierte, hier die Änderungen in hmRadio (switchRxCh() löschen!):

class HmRadio {
    public:
        HmRadio() : mNrf24(CE_PIN, CS_PIN, SPI_SPEED) {
            DPRINT(DBG_VERBOSE, F("hmRadio.h : HmRadio():mNrf24(CE_PIN: "));
            DPRINT(DBG_VERBOSE, String(CE_PIN));
            DPRINT(DBG_VERBOSE, F(", CS_PIN: "));
            DPRINT(DBG_VERBOSE, String(CS_PIN));
            DPRINT(DBG_VERBOSE, F(", SPI_SPEED: "));
            DPRINTLN(DBG_VERBOSE, String(SPI_SPEED) + ")");

            // Depending on the program, the module can work on 2403, 2423, 2440, 2461 or 2475MHz.
            // Channel List      2403, 2423, 2440, 2461, 2475MHz
            mRfChLst[0] = 75;
            mRfChLst[1] = 61;
            mRfChLst[2] = 40;
            mRfChLst[3] = 23;
            mRfChLst[4] = 03;

            // default channels
            mTxChIdx    = 2; // Start TX with 40
            mRxChIdx    = 4; // Start RX with 03

            mSendCnt        = 0;
            mRetransmits    = 0;

            mSerialDebug    = false;
            mIrqRcvd        = false;
            mAllFrames      = false;
        }

        ...

        bool loop(void) {
            if (!mIrqRcvd)
                return false;   // nothing to do

            whatHappened();
            mNrf24.flush_tx();  // empty TX FIFO

            // start listening
            mNrf24.setChannel(mRfChLst[mRxChIdx]);
            mNrf24.startListening();
            yield();

            uint32_t loopMillis = millis();
            uint32_t lastSwitchMillis = millis();
            uint32_t listenMillis;
            uint32_t startMillis;
            uint8_t nextRxChIdx = (mRxChIdx + 1) % RF_CHANNELS;

            while (millis() - loopMillis < ((mAllFrames) ? 300 : 100)) {
                listenMillis = millis();
                while (millis() - listenMillis < 100) {
                    mNrf24.setChannel(mRfChLst[mRxChIdx]);
                    startMillis = millis();
                    while (millis()-startMillis < 3) {
                        if (mIrqRcvd)
                            break;
                        yield();
                    }
                    if (!mIrqRcvd) {
                        mNrf24.setChannel(mRfChLst[nextRxChIdx]);
                        startMillis = millis();
                        while (millis()-startMillis < 3) {
                            if (mIrqRcvd) {
                                lastSwitchMillis = startMillis;
                                mRxChIdx = nextRxChIdx;
                                nextRxChIdx = (mRxChIdx + 1) % RF_CHANNELS;
                                break;
                            }
                            yield();
                        }
                    }
                    if (mIrqRcvd)
                        break;
                }
                if (mIrqRcvd) {
                    if (getReceived()) // everything received
                        return true;

                    if (millis() - lastSwitchMillis > 97) { // after 100ms at the latest, the inverter switches to the next channel
                        lastSwitchMillis = millis();
                        mRxChIdx = nextRxChIdx;
                        nextRxChIdx = (mRxChIdx + 1) % RF_CHANNELS;
                    }
                }
                else
                    break;  // nothing received within 100ms -> exit
                yield();
            }
            // not finished but time is over
            return true;
        }

        ...

    private:
        inline void whatHappened() {
            mIrqRcvd = false;
            bool tx_ok, tx_fail, rx_ready;
            mNrf24.whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH
            yield();
        }

        inline bool getReceived(void) {
            whatHappened();

            bool isLastPackage = false;
            while(mNrf24.available()) {
                uint8_t len;
                len = mNrf24.getDynamicPayloadSize(); // if payload size > 32, corrupt payload has been flushed
                if (len > 0) {
                    packet_t p;
                    p.ch = mRfChLst[mRxChIdx];
                    p.len = len;
                    mNrf24.read(p.packet, len);
                    if (p.packet[0] != 0x00) {              // ignore fragment number zero
                        mBufCtrl.push(p);
                        if (mAllFrames)
                            isLastPackage |= (p.packet[9] > ALL_FRAMES);  // > ALL_FRAMES indicates last packet received
                        else
                            isLastPackage = true;                         // response from dev control command
                    }
                }
                yield();
            }
            return isLastPackage;
        }

        ...

        void sendPacket(uint64_t invId, uint8_t len, bool isRetransmit, bool clear=false) {
            //DPRINTLN(DBG_VERBOSE, F("hmRadio.h:sendPacket"));
            //DPRINTLN(DBG_VERBOSE, "sent packet: #" + String(mSendCnt));

            // append crc's
            if (len > 10) {
                // crc control data
                uint16_t crc = ah::crc16(&mTxBuf[10], len - 10);
                mTxBuf[len++] = (crc >> 8) & 0xff;
                mTxBuf[len++] = (crc     ) & 0xff;
            }
            // crc over all
            mTxBuf[len] = ah::crc8(mTxBuf, len);
            len++;

            mAllFrames = ((mTxBuf[0] == TX_REQ_INFO) && (mTxBuf[9] == ALL_FRAMES));

            // set TX and RX channels
            mTxChIdx = (mRxChIdx + 4) % RF_CHANNELS;
            mRxChIdx = (mTxChIdx + 2) % RF_CHANNELS;

            if(mSerialDebug) {
                DPRINT(DBG_INFO, F("TX "));
                DBGPRINT(String(len));
                DBGPRINT("B Ch");
                DBGPRINT(String(mRfChLst[mTxChIdx]));
                DBGPRINT(F(" | "));
                dumpBuf(mTxBuf, len);
            }

            mNrf24.stopListening();
            mNrf24.flush_rx();                      // empty RX FIFO
            mNrf24.setChannel(mRfChLst[mTxChIdx]);
            mNrf24.openWritingPipe(reinterpret_cast<uint8_t*>(&invId));
            mNrf24.startWrite(mTxBuf, len, true);  // true = do not request ACK response

            if(isRetransmit)
                mRetransmits++;
            else
                mSendCnt++;
        }

        ...

        bool mAllFrames;
};
@knickohr
Copy link

knickohr commented Mar 4, 2023

Vorsicht, bei mir hängen 2 Inverter dran 😲

Da ich den Code nicht selber backen kann, wird’s wohl mit einem Test schlecht aussehen 🙁

@beegee3
Copy link
Contributor Author

beegee3 commented Mar 6, 2023

Vorsicht, bei mir hängen 2 Inverter dran

Bitte entschuldige, dass ich deine Werte hier zitiert habe. Sie waren mir nur als sehr gut aufgefallen und sollten hier eigentlich nicht zum direkten Vergleich herhalten. Natürlich hängen die RX Werte von der Verbindungsqualität eines jeden Inverters ab, da sie die Summenwerte über alle Inverter anzeigen. Der Vergleich ist ausschließlich bei meinen Werten zu sehen.

Hier ein zip mit den modifizierten ESP8266 und ESP32 .bin Dateien zum OTA Update.
Neben dem geänderten hmRadio sind noch eine leicht veränderte ahoywifi und angepasste Inverter isAvailable enthalten.

ahoy_0.5.93_modified.zip

@knickohr
Copy link

knickohr commented Mar 6, 2023

Schon OK 😉

Hier die Werte nach 1 Tag 20,5 Stunden bevor ich jetzt die modifizierte Version drauf knalle. Bin selber neugierig 😅

5148F329-569C-433F-B32B-EDC7AC72CA67

@beegee3
Copy link
Contributor Author

beegee3 commented Mar 6, 2023

Bitte bedenke, dass während der Schlafenszeit der Inverter TX count und RX no answer weitergezählt werden (solange das Polling aktiv ist). Das hat Einfluss auf die Trefferquote. Daher habe ich meine Tests nur am Tag gemacht solange der Inverter Online war.

@knickohr
Copy link

knickohr commented Mar 6, 2023

Was mir noch auffällt, der Haufenspeicher ist bei mir jetzt um 8000 weniger 😵

@beegee3
Copy link
Contributor Author

beegee3 commented Mar 7, 2023

Habe ich auch im Vergleich zur kompilierten dev. Version. Liegt am benutzten Compiler. Wenn ich die dev. unmodifiziert selbst kompiliere, ist der heap schon besagte 8000 Byte kleiner, also kein Unterschied zur modifizierten Version. 😅

@lumapu
Copy link
Owner

lumapu commented Mar 7, 2023

@beegee3 vielen Dank, ich werde es testen =)

@knickohr
Copy link

knickohr commented Mar 7, 2023

So, hier meine Werte mit der Mod. 93. uptime genau 1 Tag.

308C9C4C-4C66-4487-BF6D-810B2902FC22

Was sofort auffällt, die Retransmits sind wesentlich weniger 👍

Jetzt kommt ePaper 😉

@beegee3
Copy link
Contributor Author

beegee3 commented Mar 7, 2023

@knickohr vielen Dank fürs Testen 👍
Leider sind deine 'RX no answer' raufgegangen, so dass die Trefferquote sich nur unwesentlich von 57,6% auf 58,0% erhöht hat. Schade, hatte auf mehr gehofft.
Trotzdem sehe ich es als Erfolg. Neben den leichten Verbesserungen hat es vor allem gezeigt, dass auch deine HM gemäß den oben genannten Punkten 1. bis 4. senden!

@knickohr
Copy link

knickohr commented Mar 7, 2023

Es sind nicht nur leichte Verbesserungen, sondern gravierende. Neben den weniger Retransmits und den recht schnellen Melden der Inverter, gibt es auch das Problem mit den fehlenden SSIDs nicht mehr.

@beegee3
Copy link
Contributor Author

beegee3 commented Mar 7, 2023

Das mit den SSIDs ist natürlich unabhängig von der Inverter Kommunikation. Aber ich bin da ganz bei dir!
Genauso wie zur Frage, ob die MI Inverter mit der modifizierten Variante zurechtkommen, kann da eigentlich nur @lumapu etwas zu sagen.

@lumapu
Copy link
Owner

lumapu commented Mar 7, 2023

das kann ich auch nicht, ich habe nur die Basis dafür geschaffen und @rejoe2 oä befüllt es mit Leben, siehe PRs

@rejoe2
Copy link
Contributor

rejoe2 commented Mar 8, 2023

Ich werd's bei Gelegenheit testen, wobei das Problem sein wird, dass die Statistik so oder so noch einen review wegen der MI braucht und ich vermutlich auch noch nicht komplett verstanden habe, wie es funktioniert. Von daher wird das erst mal eher eine "Bauchgefühl"-Rückmeldung werden - allerdings dann eben mit der Info, ob der MI-600 damit klarkommt oder nicht. Bestimmt würden auch die anderen aktuellen MI-Tester (auch nur 300/600) eine Rückmeldung geben, ob das passen würde.
Vielleicht noch eine Anmerkung zu meinen Otimierungsversuchen vor einigen Monaten (mit ZiyatT's ein-Inverter-Code als Basis):
Da hatte ich nahe 100% "Treffer" mit einem abwechselnden 100ms-Sekunden-Wechsel. Start mit tx=rx-1, nach 100ms Wechsel auf rx=tx, dann 100ms später tx++. Gekoppelt mit einem schnelleren Wechsel von beiden Kanälen, wenn ein paar Fehlschläge da waren, lieferte das auch sehr schnell Daten.
Wobei das eben auch zur Folge hatte, dass sowohl die (frühere) Status-Message (0x88/0x92) wie auch die eigentliche Data-Message (0x89/0x91) auf eine einzige Anfrage empfangen werden konnte (ähnlich Multiframe, wenn ich das richtig sehe).

Mit dem aktuellen Code bis 0.5.93 waren die Treffer bei mir auch ziemlich gut, was ich dahingehend interpretiert hätte, dass die MI (bzw. alle Inverter) sehen, ob überhaupt eine Kommunikation stattfindet und ihr timing entsprechend anpassen (ich habe neben dem MI noch 6 3rd gen MI-1500, die wie normale HM-1500 kommunizieren).

(Mit 0.5.95 bzw. dem Vorgänger hatte ich teilweise das Problem, dass die Kommunikation mit den Invertern irgendwann abgebrochen ist. Im Moment gehe ich da aber eher von einem Hardwareproblem aus (ist teilweise noch ein breadboard-Aufbau), es könnte aber auch sein, dass irgendwie insgesamt das timing verrutscht).

Generelle Anmerkung zu der MI-Geschichte noch: vermutlich sind die MI im Antwortverhalten für die eigentlichen Produktionsdaten deutlich langsamer als die 3rd Gen. Modelle, eigentlich erfolgt im Moment die Folgeanfrage m.E. zu früh. (nur, falls jemand eine Idee hat, wie man das verbessern kann. Vielleicht versuche ich es mal mit einem Zähler, der bei jedem "process()"-Aufruf hochzählt und nur jeden 5. Aufruf abarbeitet?)

@beegee3
Copy link
Contributor Author

beegee3 commented Mar 8, 2023

@rejoe2 👍 danke, dass du das testen willst!
Ich hänge hier mal die komplette hmRadio.h ein, dann brauchst du sie bei dir nur austauschen.

hmRadio.zip

Da hatte ich nahe 100% "Treffer" mit einem abwechselnden 100ms-Sekunden-Wechsel. Start mit tx=rx-1, nach 100ms Wechsel auf rx=tx, dann 100ms später tx++. Gekoppelt mit einem schnelleren Wechsel von beiden Kanälen, wenn ein paar Fehlschläge da waren, lieferte das auch sehr schnell Daten.

Habe ich das richtig verstanden?
Du sendest z.B. auf Kanal 40, horchst dann für 100ms auf Kanal 23, wechselst dann für weitere 100ms auf Kanal 40 und wiederum 100ms später auf Kanal 61. (Ich gehe davon aus, dass die Kanalreihenfolge wie in der bisherigen hmRadio 03, 23, 40, 61, 75 ist.)
Ist ja ein ganz anderer Ansatz. Wundert mich, dass damit fast 100% Treffer erzielt werden. Werde ich auf jeden Fall mal ausprobieren.

@rejoe2
Copy link
Contributor

rejoe2 commented Mar 8, 2023

Thx.
Das mit dem Wechsel ist anders zu verstehen: die 100ms sind immer abwechselnd für rx und tx, also (Kanal, nicht index)
rx = 03, tx=23
100ms
rx = 23, tx=23
100ms
rx = 23, tx=40
usw.
Gesendet wurde dann nur, wenn der "bevorzugte Kanal" grade an der Reihe war, also der letzte, auf dem der Inverter reagiert hatte (Ausnahme: (ca.) 5x keine Rückmeldung, dann Beginn eines schnelleren Kanalwechsels rüf rx (tx folgte dann immer auf index rx-1) für die ersten 100ms, wenn ich mich recht entsinne).

@beegee3
Copy link
Contributor Author

beegee3 commented Mar 8, 2023

Ah, ok. Also nach 100ms ohne Empfang werden die Kanäle angepasst und erneut gesendet. Und Misserfolg ist erst, wenn 5x keine Rückmeldung. Das könnte die hohe Trefferquote erklären. Na, ich schau mal, ob ich das nachbilden kann 😁

@rejoe2
Copy link
Contributor

rejoe2 commented Mar 8, 2023

eher nach 1100ms... Und ob sich das nachbilden läßt für eine firmware, die mehr wie einen Inverter abfragt?
Ich hatte eigentlich den Eindruck, dass man mit der Methode den Inverter quasi auf einen Kanal "festnageln" kann, auf dem er mehr oder weniger immer hört. Zwischenzeitlich habe ich da starke Zweifel, weil ibei Ahoy dann auch bei dem MI Antworten auf Kanälen zu sehen waren, die es mit der "single-Inverter"-Lösung nie "gegeben" hatte (die also einfach wegen der entsprechenden Einstellungen gar nicht empfangbar waren).

M.E. spricht einiges für den sehr schnellen Wechsel des Empfangskanals, weil die nRF ja auch hardwaremäßig ein paar Wiederholungen machen, wenn kein Ack kommt (aber angefordert ist). Vollständig "durch" bin ich aber gedanklich mit dem ganzen auch noch nicht. Ich fand nur das "spammige" Verhalten der DTU (wie von ZiyatT geschildert) ziemlich merkwürdig für das, was die nRF eigentlich an Optionen bieten...

@beegee3
Copy link
Contributor Author

beegee3 commented Mar 8, 2023

Die Anzahl der Inverter ist egal. Es werden nie mehrere Inverter gleichzeitig abgefragt.
Meiner Erfahrung nach sendet der Inverter nie ein ACK, sondern sendet sofort die Daten. Umgekehrt wird aber der Empfang aber mit einem ACK quittiert, sonst werden bei Multiframe Abfragen keine (oder nur selten) weitere Frames gesendet. Die Logik habe ich auch noch nicht verstanden.
Beim 100ms Intervall für den Kanalwechsel des Inverters bin ich mir ziemlich sicher. Oft genug werden 3 Frames auf einem Kanal innerhalb von 100ms empfangen (dauert ca. 95ms). Spätestens nach 100ms wechselt der Inverter aber immer auf den nächsten Kanal (absteigend 75 -> 61 -> 40 -> ...). Das Problem ist festzustellen, wann der Kanalwechsel erfolgt. Wenn man das wüsste, könnte man entsprechend horchen. Vieles spricht dafür, dass die Inverter eine Art "Gazelle" Methode nutzen (s. https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk51.v9.0.0%2Fgzll_02_user_guide.html), was auch in früheren issues bzw. in https://www.mikrocontroller.net/topic/525778 bereits angesprochen wurde. Auch in der Richtung will ich noch forschen.

@lumapu
Copy link
Owner

lumapu commented Mar 8, 2023

@beegee3 leider verbindet sich deine Version nicht mit einem einzelnen AP. Ich verwende einen ESP8266

Log
reconnect in 2 seconds
reconnect in 1 seconds
try to connect to AP with BSSID: 50 e6 36 37 69 b3
reconnect in 9 seconds
reconnect in 8 seconds
reconnect in 7 seconds
reconnect in 6 seconds
reconnect in 5 seconds
reconnect in 4 seconds
reconnect in 3 seconds
reconnect in 2 seconds
reconnect in 1 seconds
connect to network 'durchsichtig' ...
I: [WiFi] Connection Lost
scanning APs with SSID durchsichtig.. completed
BSSID 0: 50 e6 36 37 69 b3
reconnect in 5 seconds
reconnect in 4 seconds
reconnect in 3 seconds
reconnect in 2 seconds
reconnect in 1 seconds
try to connect to AP with BSSID: 50 e6 36 37 69 b3
reconnect in 9 seconds
reconnect in 8 seconds
reconnect in 7 seconds
reconnect in 6 seconds
reconnect in 5 seconds
reconnect in 4 seconds
reconnect in 3 seconds
reconnect in 2 seconds
reconnect in 1 seconds
connect to network 'durchsichtig' ...
I: [WiFi] Connection Lost
scanning APs with SSID durchsichtig.. completed
BSSID 0: 50 e6 36 37 69 b3
reconnect in 5 seconds
reconnect in 4 seconds
reconnect in 3 seconds
reconnect in 2 seconds
reconnect in 1 seconds
try to connect to AP with BSSID: 50 e6 36 37 69 b3
reconnect in 9 seconds
reconnect in 8 seconds
reconnect in 7 seconds
reconnect in 6 seconds
reconnect in 5 seconds
reconnect in 4 seconds
reconnect in 3 seconds
reconnect in 2 seconds
reconnect in 1 seconds
connect to network 'durchsichtig' ...
I: [WiFi] Connection Lost
scanning APs with SSID durchsichtig.. completed
BSSID 0: 50 e6 36 37 69 b3
reconnect in 5 seconds
reconnect in 4 seconds
reconnect in 3 seconds
reconnect in 2 seconds
reconnect in 1 seconds
try to connect to AP with BSSID: 50 e6 36 37 69 b3
reconnect in 9 seconds
reconnect in 8 seconds
reconnect in 7 seconds
reconnect in 6 seconds
reconnect in 5 seconds
reconnect in 4 seconds
reconnect in 3 seconds
reconnect in 2 seconds
reconnect in 1 seconds
connect to network 'durchsichtig' ...
I: [WiFi] Connection Lost
scanning APs with SSID durchsichtig.. completed
BSSID 0: 50 e6 36 37 69 b3
reconnect in 5 seconds
reconnect in 4 seconds
reconnect in 3 seconds
reconnect in 2 seconds
reconnect in 1 seconds
try to connect to AP with BSSID: 50 e6 36 37 69 b3
reconnect in 9 seconds
reconnect in 8 seconds
reconnect in 7 seconds
reconnect in 6 seconds
reconnect in 5 seconds
reconnect in 4 seconds
reconnect in 3 seconds
reconnect in 2 seconds
reconnect in 1 seconds
connect to network 'durchsichtig' ...
I: [WiFi] Connection Lost
scanning APs with SSID durchsichtig.. completed
BSSID 0: 50 e6 36 37 69 b3
reconnect in 5 seconds
reconnect in 4 seconds

Hier ein Buidl mit deinen Änderungen von oben, basierend auf der 0.5.95:
ahoy_dev0.5.95_8266_modified.zip

@beegee3
Copy link
Contributor Author

beegee3 commented Mar 8, 2023

@lumapu 🤔 Habe keinen ESP8266, kann daher deinen Build nicht ausprobieren.
Aber offensichtlich bekommst du weder ein CONNECTED noch ein GOT_IP. Andererseits wird I: [WiFi] Connection Lost ausgegeben, wenn ein neuer Verbindungsversuch startet, also hat eine Verbindung bestanden.
Hast du den ESP mal vom Strom genommen, so dass er 'jungfräulich' startet?

Ist vielleicht besser, wenn wir das in #652 weiter diskutieren (auch wenn das schon geschlossen ist). Hatte es doch dort angefangen, in diesem issue geht es ja um die Inverter Kommunikation.

@rejoe2
Copy link
Contributor

rejoe2 commented Mar 8, 2023

Meine Kurz-Eindrücke zu der modifizierten hmRadio.h - Basis sind jeweils ein paar Minuten nach dem Start des ESP32 (weil ich parallel noch etwas in Richtung firmware-Infos und "Aussetzen bei process" gemacht habe):

  • für die HM scheint es keinen allzu großen Unterschied zu machen. Auch mit der modifizierten Version kommt es durchaus häufiger zur Nachforderung einzelner Pakete oder der eine oder andere Inverter antwortet scheinbar erst mal nicht
  • für die MI scheint es einen Ticken schlechter zu sein: Da ist in der Startsequenz grade ein Code-Teil drin, um direkt auf den eingehenden "ersten frame" der Hardware-Info zu reagieren. Bei drei oder vier Starts konnte ich da keinen Empfang des erwarteten 2. bzw. 3. frames sehen, beim Original sehe ich praktisch immer eine der beiden zusätzlichen "Frames" (wobei ich einmal nur den 3. gesehen habe, was eigentlich nur damit zu erklären ist, dass das tatsächlich Multiframe ist und alle Teile auch automatisch versendet werden...
    (Na ja, eines nach dem anderen).

@beegee3
Copy link
Contributor Author

beegee3 commented Mar 8, 2023

@rejoe2 herzlichen Dank für die Rückmeldung. D.h. prinzipiell senden auch die MI Inverter nach den im ersten Beitrag genannten Punkten 1. bis 3. Das ist eine Info mit der ich versuchen kann, meine Modifikation zu verbessern ("Gazelle" o.ä.). Würden die MI fast nicht (oder gar nicht) reagieren, würde das keinen Sinn machen.
Aber solange sich keine deutlicheren Verbesserungen ergeben (und es bei den MIs sogar etwas schlechter ist) wird daraus kein Feature Request!

@rejoe2
Copy link
Contributor

rejoe2 commented Mar 8, 2023

Das könnte hinhauen. Wollte erst widersprechen mit den 100ms, hatte aber auch Versuche gemacht mit "-2". Tatsächlich war die Teilantwort 0x88 (bzw. 0x92) auch auf diesem Kanal zu erhalten, und zwar zeitlich etwas früher wie auf "-1". Das könnte man auch so interpretieren, dass der Wechsel bei den MI (für denen Antwort-rx-Kanal) sogar noch etwas schneller erfolgt wie die 100ms, denn die "Hauptantwort" kam ca. 150ms später auf dem Kanal, auf dem die Anfrage gelegen hatte.
Ist aber alles schon ziemlich lange her, ich hoffe, dass meine Erinnerung da einigermaßen korrekt ist...

Das mit der Ack-Anforderung durch den WR macht m.E. übrigens Sinn, denn dann weiß er, dass er (diese Info) nicht mehr (weiter) senden muss. Das gilt bei den MI nach meinem Eindruck auch für die beiden Teilmessages, Man könnte daraus auch schließen, dass das (hardware-) Ack auch darüber entscheidet, auf welchem Kanal der WR (wann) das nächste Mal sendet.

@beegee3
Copy link
Contributor Author

beegee3 commented Mar 8, 2023

Das 'wann' ist sehr wahrscheinlich vom ACK beeinflusst. Und indirekt dadurch auch ein Kanalwechsel. Aber im eigentlichen Sinne geschieht das m.E. nur nach dem 100ms Zeitschema. Die Laufzeit zwischen Frame senden und ACK empfangen ist mitentscheidend. Sonst wäre nicht zu erklären, dass manchmal nach einem Frame gewechselt wird, manchmal gar nicht.
Deine Ausführungen zu "-2" und "-1" erklären sich dadurch, dass die Kanäle absteigend gewechselt werden kombiniert mit dem TX zu RX Abstand. Da ist "-2" früher dran als "-1" 😄

@rejoe2
Copy link
Contributor

rejoe2 commented Mar 8, 2023

Ja, das mit dem (relativ) starren Zeitschema paßt schon. Vermutlich machen die WR irgendeine Korrektur, wenn sie mehrere Versuche brauchen, damit die Funktion hinter der Beschreibung "share the same pipeline" paßt, aber das dürfte es gewesen sein.

Was ich auf alle Fälle aber mal testen würde wäre der Versuch, ohne stopListening und startListening auszukommen. Eventuell bringt alleine das schon was. Muss aber auch erst mal wieder meinen Code aufräumen...

@beegee3
Copy link
Contributor Author

beegee3 commented Mar 8, 2023

... ohne stopListening und startListening auszukommen

ist schon umgesetzt.

@rejoe2
Copy link
Contributor

rejoe2 commented Mar 8, 2023

Oh, ok, sorry. Habe die changes im allgemeinen Code nicht alle im Detail angeschaut, mir ist im Moment v.a. daran gelegen, dass "mein" MI-Code das ganze nicht aus dem Tritt bringt und halbwegs funktioniert...

@beegee3
Copy link
Contributor Author

beegee3 commented Mar 8, 2023

in der dev. Version ist's noch drin, nur bei meiner Modifikation ist's raus. Hatte es auch bei der dev. mal rausgenommen. Funktioniert genauso, wird nicht schlechter, aber auch nicht wesentlich besser. Die Zeit zwischen stopListening und startListening ist zu kurz um viele Frames zu verpassen.

@lumapu
Copy link
Owner

lumapu commented Sep 16, 2023

denke wir können hier zumachen, ist schon lange integriert und mit der neuen Heuristik von @oberfritze wird das Verhalten ja nochmals optimiert. Wir diskutieren in #1080 weiter

@lumapu lumapu closed this as completed Sep 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants