diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 98dd06e1..60e87918 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -148,6 +148,7 @@ class Communication : public CommQueue<> { q->iv->radio->switchFrequency(q->iv, HOY_BOOT_FREQ_KHZ, (q->iv->config->frequency*FREQ_STEP_KHZ + HOY_BASE_FREQ_KHZ)); mWaitTime.startTimeMonitor(1000); } else { + mHeu.setIvRetriesBad(q->iv); if(IV_MI == q->iv->ivGen) q->iv->mIvTxCnt++; @@ -180,8 +181,11 @@ class Communication : public CommQueue<> { q->iv->mDtuRxCnt++; if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command - if(parseFrame(p)) + if(parseFrame(p)) { q->iv->curFrmCnt++; + if(!mIsRetransmit && p->packet[9] == 2 && p->millis < 85) + mHeu.setIvRetriesGood(q->iv,p->millis < 70); + } } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command if(parseDevCtrl(p, q)) closeRequest(q, true); @@ -417,6 +421,8 @@ class Communication : public CommQueue<> { } inline bool parseMiFrame(packet_t *p, const queue_s *q) { + if(!mIsRetransmit && p->packet[9] == 0x00 && p->millis < 35) //first frame is fast? + mHeu.setIvRetriesGood(q->iv,p->millis < 22); if ((p->packet[0] == MI_REQ_CH1 + ALL_FRAMES) || (p->packet[0] == MI_REQ_CH2 + ALL_FRAMES) || ((p->packet[0] >= (MI_REQ_4CH + ALL_FRAMES)) @@ -527,7 +533,7 @@ class Communication : public CommQueue<> { len -= 2; - DPRINT_IVID(DBG_INFO, q->iv->id); + //DPRINT_IVID(DBG_INFO, q->iv->id); DBGPRINT(F("Payload (")); DBGPRINT(String(len)); if(*mPrintWholeTrace) { diff --git a/src/hm/Heuristic.h b/src/hm/Heuristic.h index 64c78cc8..642eca13 100644 --- a/src/hm/Heuristic.h +++ b/src/hm/Heuristic.h @@ -23,8 +23,8 @@ class Heuristic { public: uint8_t getTxCh(Inverter<> *iv) { - if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen)) - return 0; // not used for these inverter types + if(iv->ivRadioType != INV_RADIO_TYPE_NRF) + return 0; // not used for other than nRF inverter types HeuristicInv *ih = &iv->heuristics; @@ -66,6 +66,8 @@ class Heuristic { ih->testPeriodFailCnt = 0; } + iv->radio->mTxRetriesNext = getIvRetries(iv); + return id2Ch(ih->txRfChId); } @@ -155,6 +157,48 @@ class Heuristic { DBGPRINTLN(String(iv->config->powerLevel)); } + uint8_t getIvRetries(Inverter<> *iv) { + if(iv->heuristics.rxSpeeds[0]) + return 5; + if(iv->heuristics.rxSpeeds[1]) + return 10; + return 15; + } + + void setIvRetriesGood(Inverter<> *iv, bool veryGood) { + if(iv->ivRadioType != INV_RADIO_TYPE_NRF) + return; // not used for other than nRF inverter types + + if(iv->heuristics.rxSpeedCnt[veryGood] > 9) + return; + iv->heuristics.rxSpeedCnt[veryGood]++; + iv->heuristics.rxSpeeds[veryGood] = true; + } + + void setIvRetriesBad(Inverter<> *iv) { + if(iv->ivRadioType != INV_RADIO_TYPE_NRF) + return; // not used for other than nRF inverter types + + if(iv->heuristics.rxSpeedCnt[0]) { + iv->heuristics.rxSpeedCnt[0]--; + return; + } + if(iv->heuristics.rxSpeeds[0]) { + iv->heuristics.rxSpeeds[0] = false; + return; + } + + if(iv->heuristics.rxSpeedCnt[1]) { + iv->heuristics.rxSpeedCnt[1]--; + return; + } + if(iv->heuristics.rxSpeeds[1]) { + iv->heuristics.rxSpeeds[1] = false; + return; + } + return; + } + private: bool isNewTxCh(HeuristicInv *ih) { return ih->txRfChId != ih->lastBestTxChId; diff --git a/src/hm/HeuristicInv.h b/src/hm/HeuristicInv.h index e7ad6edd..fc782a7b 100644 --- a/src/hm/HeuristicInv.h +++ b/src/hm/HeuristicInv.h @@ -27,6 +27,9 @@ class HeuristicInv { uint8_t testChId = 0; int8_t saveOldTestQuality = -6; uint8_t lastRxFragments = 0; + bool rxSpeeds[2] = {false,false}; // is inverter responding very fast respective fast? + uint8_t rxSpeedCnt[2] = {0,0}; // count how many messages had been received very fast respective fast (10 max) + }; #endif /*__HEURISTIC_INV_H__*/ diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index ef37e266..d41dc36a 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -161,7 +161,7 @@ class HmRadio : public Radio { rxPendular = false; mNRFloopChannels = (mLastIv->ivGen == IV_MI); - innerLoopTimeout = DURATION_TXFRAME; + innerLoopTimeout = mLastIv->ivGen != IV_MI ? DURATION_TXFRAME : DURATION_ONEFRAME; } if(rx_ready) { @@ -356,11 +356,14 @@ class HmRadio : public Radio { mTxChIdx = iv->heuristics.txRfChId; if(*mSerialDebug) { + /* remark rejoe2: imo this has no added value here. + As this belongs to the last tx cycle, we should print that info + directly when switching from tx to rx. Otherwise we might confuse users. if(!isRetransmit) { DPRINT(DBG_INFO, "last tx setup: "); DBGPRINT(String(mTxSetupTime)); DBGPRINTLN("ms"); - } + }*/ DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("TX ")); @@ -383,6 +386,10 @@ class HmRadio : public Radio { } mNrf24->stopListening(); + if(!isRetransmit && mTxRetries != mTxRetriesNext) { + mNrf24->setRetries(3, mTxRetriesNext); + mTxRetries = mTxRetriesNext; + } mNrf24->setChannel(mRfChLst[mTxChIdx]); mNrf24->openWritingPipe(reinterpret_cast(&iv->radioId.u64)); mNrf24->startWrite(mTxBuf, len, false); // false = request ACK response @@ -425,6 +432,7 @@ class HmRadio : public Radio { bool rxPendular = false; uint32_t innerLoopTimeout = DURATION_LISTEN_MIN; uint8_t mTxSetupTime = 0; + uint8_t mTxRetries = 15; // memorize last setting for mNrf24->setRetries(3, 15); std::unique_ptr mSpi; std::unique_ptr mNrf24; diff --git a/src/hm/radio.h b/src/hm/radio.h index a71e24c7..e11d8682 100644 --- a/src/hm/radio.h +++ b/src/hm/radio.h @@ -78,6 +78,7 @@ class Radio { std::queue mBufCtrl; uint8_t mIrqOk = IRQ_UNKNOWN; TimeMonitor mRadioWaitTime = TimeMonitor(0, true); // start as expired (due to code in RESET state) + uint8_t mTxRetriesNext = 15; // let heuristics tell us the next reties count (for nRF type radios only) protected: virtual void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) = 0;