From bba82d8b3a9a634381dfdf128f1fa11e72b163a8 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Tue, 30 Jan 2024 13:32:55 +0100 Subject: [PATCH] different tx-offests for 4ch HM * discord 0.8.6803 * tx+3 for 4ch-HM, tx+2 for other Inverters --- src/hm/CommQueue.h | 2 +- src/hm/Communication.h | 9 ++++++--- src/hm/HeuristicInv.h | 15 +++++++++++++++ src/hm/hmInverter.h | 21 ++++++++++++++++++--- src/hm/hmRadio.h | 43 ++++++++++++++++++++++++++---------------- src/hm/hmSystem.h | 7 ++++++- src/hms/cmt2300a.h | 6 +++--- 7 files changed, 76 insertions(+), 27 deletions(-) diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index d7cc5642..acbe9a35 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -12,7 +12,7 @@ #include "../utils/dbg.h" #define DEFAULT_ATTEMPS 5 -#define MORE_ATTEMPS_ALARMDATA 0 // 8 +#define MORE_ATTEMPS_ALARMDATA 3 // 8 #define MORE_ATTEMPS_GRIDONPROFILEPARA 0 // 5 template diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 9219bb8e..8887a4a2 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -140,7 +140,10 @@ class Communication : public CommQueue<> { if(!q->iv->mGotFragment) { if(INV_RADIO_TYPE_CMT == q->iv->ivRadioType) { #if defined(ESP32) - q->iv->radio->switchFrequency(q->iv, q->iv->radio->getBootFreqMhz() * 1000, (q->iv->config->frequency*FREQ_STEP_KHZ + q->iv->radio->getBaseFreqMhz() * 1000)); + if(!q->iv->radio->switchFrequency(q->iv, q->iv->radio->getBootFreqMhz() * 1000, (q->iv->config->frequency*FREQ_STEP_KHZ + q->iv->radio->getBaseFreqMhz() * 1000))) { + DPRINT_IVID(DBG_INFO, q->iv->id); + DBGPRINTLN(F("switch frequency failed!")); + } mWaitTime.startTimeMonitor(1000); #endif } else { @@ -418,8 +421,8 @@ class Communication : public CommQueue<> { if((*frameId & ALL_FRAMES) == ALL_FRAMES) { mMaxFrameId = (*frameId & 0x7f); - /*if(mMaxFrameId > 8) // large payloads, e.g. AlarmData - incrAttempt(mMaxFrameId - 6);*/ + if(mMaxFrameId > 8) // large payloads, e.g. AlarmData + incrAttempt(mMaxFrameId - 6); } frame_t *f = &mLocalBuf[(*frameId & 0x7f) - 1]; diff --git a/src/hm/HeuristicInv.h b/src/hm/HeuristicInv.h index e9c7084e..505562e3 100644 --- a/src/hm/HeuristicInv.h +++ b/src/hm/HeuristicInv.h @@ -14,7 +14,22 @@ class HeuristicInv { public: HeuristicInv() { + clear(); + } + + void clear() { memset(txRfQuality, 0, RF_MAX_CHANNEL_ID); + txRfChId = 0; + lastBestTxChId = 0; + testPeriodSendCnt = 0; + testPeriodFailCnt = 0; + testChId = 0; + saveOldTestQuality = -6; + lastRxFragments = 0; + } + + bool isTxAtMax(void) const { + return (RF_MAX_QUALITY == txRfQuality[txRfChId]); } public: diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index a74ad02f..e6e22fb7 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -193,6 +193,14 @@ class Inverter { if(mNextLive) cb(RealTimeRunData_Debug, false); // get live data else { + if(INV_RADIO_TYPE_NRF == ivRadioType) { + // get live data until quality reaches maximum + if(!heuristics.isTxAtMax()) { + cb(RealTimeRunData_Debug, false); // get live data + return; + } + } + if(actPowerLimit == 0xffff) { cb(SystemConfigPara, false); // power limit info cb(RealTimeRunData_Debug, false); @@ -201,17 +209,18 @@ class Inverter { devControlCmd = InitDataState; mGetLossInterval = 1; } else if(0 == getFwVersion()) { - cb(RealTimeRunData_Debug, false); // get live data cb(InverterDevInform_All, false); // get firmware version + cb(RealTimeRunData_Debug, false); // get live data } else if(0 == getHwVersion()) { - cb(RealTimeRunData_Debug, false); // get live data cb(InverterDevInform_Simple, false); // get hardware version - } else if((alarmLastId != alarmMesIndex) && (alarmMesIndex != 0)) { cb(RealTimeRunData_Debug, false); // get live data + } else if((alarmLastId != alarmMesIndex) && (alarmMesIndex != 0)) { cb(AlarmData, false); // get last alarms + cb(RealTimeRunData_Debug, false); // get live data } else if((0 == mGridLen) && generalConfig->readGrid) { // read grid profile cb(GridOnProFilePara, false); + cb(RealTimeRunData_Debug, false); // get live data } else if (mGetLossInterval > AHOY_GET_LOSS_INTERVAL) { // get loss rate mGetLossInterval = 1; cb(RealTimeRunData_Debug, false); // get live data @@ -455,6 +464,12 @@ class Inverter { status = InverterStatus::OFF; actPowerLimit = 0xffff; // power limit will be read once inverter becomes available alarmMesIndex = 0; + if(ivRadioType == INV_RADIO_TYPE_NRF) { + heuristics.clear(); + #ifdef DYNAMIC_OFFSET + rxOffset = ivGen == IV_HM ? 13 : 12; // effective 3 (or 2), but can easily be recognized as default setting + #endif + } } else status = InverterStatus::WAS_ON; diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index e759576c..0dcbccb3 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -121,14 +121,14 @@ class HmRadio : public Radio { if(!mNRFloopChannels && ((mTimeslotStart - mLastIrqTime) > (DURATION_TXFRAME))) //(DURATION_TXFRAME+DURATION_ONEFRAME))) mNRFloopChannels = true; - rxPendular = !rxPendular; + mRxPendular = !mRxPendular; //innerLoopTimeout = (rxPendular ? 1 : 2)*DURATION_LISTEN_MIN; - //innerLoopTimeout = DURATION_LISTEN_MIN; + innerLoopTimeout = DURATION_LISTEN_MIN; if(mNRFloopChannels) tempRxChIdx = (tempRxChIdx + 4) % RF_CHANNELS; else - tempRxChIdx = (mRxChIdx + rxPendular*4) % RF_CHANNELS; + tempRxChIdx = (mRxChIdx + mRxPendular*4) % RF_CHANNELS; mNrf24->setChannel(mRfChLst[tempRxChIdx]); isRxInit = false; @@ -142,7 +142,7 @@ class HmRadio : public Radio { if(tx_ok || tx_fail) { // tx related interrupt, basically we should start listening mNrf24->flush_tx(); // empty TX FIFO - mTxSetupTime = millis() - mMillis; + //mTxSetupTime = millis() - mMillis; if(mNRFisInRX) { DPRINTLN(DBG_WARN, F("unexpected tx irq!")); @@ -153,17 +153,21 @@ class HmRadio : public Radio { if(tx_ok) mLastIv->mAckCount++; - //mRxChIdx = (mTxChIdx + 2) % RF_CHANNELS; + //#ifdef DYNAMIC_OFFSET mRxChIdx = (mTxChIdx + mLastIv->rxOffset) % RF_CHANNELS; + /*#else + mRxChIdx = (mTxChIdx + 2) % RF_CHANNELS; + #endif*/ mNrf24->setChannel(mRfChLst[mRxChIdx]); mNrf24->startListening(); mTimeslotStart = millis(); tempRxChIdx = mRxChIdx; // might be better to start off with one channel less? - rxPendular = false; + mRxPendular = false; mNRFloopChannels = (mLastIv->ivGen == IV_MI); //innerLoopTimeout = mLastIv->ivGen != IV_MI ? DURATION_TXFRAME : DURATION_ONEFRAME; - innerLoopTimeout = mLastIv->ivGen != IV_MI ? DURATION_LISTEN_MIN : 4; + //innerLoopTimeout = mLastIv->ivGen != IV_MI ? DURATION_LISTEN_MIN : 4; + innerLoopTimeout = (mLastIv->mIsSingleframeReq || mLastIv->ivGen == IV_MI) ? DURATION_LISTEN_MIN : DURATION_TXFRAME; } if(rx_ready) { @@ -176,7 +180,7 @@ class HmRadio : public Radio { innerLoopTimeout = DURATION_LISTEN_MIN; mTimeslotStart = millis(); if (!mNRFloopChannels) { - //rxPendular = true; // stay longer on the next rx channel + //mRxPendular = true; // stay longer on the next rx channel if (isRxInit) { isRxInit = false; tempRxChIdx = (mRxChIdx + 4) % RF_CHANNELS; @@ -325,12 +329,14 @@ class HmRadio : public Radio { isRetransmitAnswer = true; if(isLastPackage) setExpectedFrames(p.packet[9] - ALL_FRAMES); + #ifdef DYNAMIC_OFFSET if(p.packet[9] == 1 && p.millis < DURATION_ONEFRAME) mLastIv->rxOffset = (RF_CHANNELS + mTxChIdx - tempRxChIdx + 1) % RF_CHANNELS; else if(mNRFloopChannels && mLastIv->rxOffset > RF_CHANNELS) { // unsure setting? mLastIv->rxOffset = (RF_CHANNELS + mTxChIdx - tempRxChIdx + (isLastPackage ? mFramesExpected : p.packet[9])); // make clear it's not sure, start with one more offset mNRFloopChannels = false; } + #endif } if(IV_MI == mLastIv->ivGen) { @@ -338,8 +344,10 @@ class HmRadio : public Radio { isLastPackage = (p.packet[9] > 0x10); // > 0x10 indicates last packet received else if ((p.packet[0] != 0x88) && (p.packet[0] != 0x92)) // ignore MI status messages //#0 was p.packet[0] != 0x00 && isLastPackage = true; // response from dev control command + #ifdef DYNAMIC_OFFSET if(p.packet[9] == 0x00 && p.millis < DURATION_ONEFRAME) mLastIv->rxOffset = (RF_CHANNELS + mTxChIdx - tempRxChIdx - 1) % RF_CHANNELS; + #endif } rx_ready = true; //reset in case we first read messages from other inverter or ACK zero payloads } @@ -347,9 +355,8 @@ class HmRadio : public Radio { } yield(); } - if(isLastPackage) { + if(isLastPackage) mLastIv->mGotLastMsg = true; - } return isLastPackage || isRetransmitAnswer; } @@ -361,10 +368,7 @@ 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) { + /*if(!isRetransmit) { DPRINT(DBG_INFO, "last tx setup: "); DBGPRINT(String(mTxSetupTime)); DBGPRINTLN("ms"); @@ -374,13 +378,19 @@ class HmRadio : public Radio { DBGPRINT(F("TX ")); DBGPRINT(String(len)); DBGPRINT(" CH"); + if(mTxChIdx == 0) + DBGPRINT("0"); DBGPRINT(String(mRfChLst[mTxChIdx])); DBGPRINT(F(", ")); DBGPRINT(String(mTxRetriesNext)); //DBGPRINT(F(" retries | ")); + //#ifdef DYNAMIC_OFFSET DBGPRINT(F(" ret., rx offset: ")); DBGPRINT(String(iv->rxOffset)); DBGPRINT(F(" | ")); + /*#else + DBGPRINT(F(" ret. | ")); + #endif*/ if(*mPrintWholeTrace) { if(*mPrivacyMode) ah::dumpBuf(mTxBuf, len, 1, 4); @@ -396,6 +406,7 @@ class HmRadio : public Radio { } mNrf24->stopListening(); + mNrf24->flush_rx(); if(!isRetransmit && mTxRetries != mTxRetriesNext) { mNrf24->setRetries(3, mTxRetriesNext); mTxRetries = mTxRetriesNext; @@ -439,9 +450,9 @@ class HmRadio : public Radio { bool mNRFloopChannels = false; bool mNRFisInRX = false; bool isRxInit = true; - bool rxPendular = false; + bool mRxPendular = false; uint32_t innerLoopTimeout = DURATION_LISTEN_MIN; - uint8_t mTxSetupTime = 0; + //uint8_t mTxSetupTime = 0; uint8_t mTxRetries = 15; // memorize last setting for mNrf24->setRetries(3, 15); std::unique_ptr mSpi; diff --git a/src/hm/hmSystem.h b/src/hm/hmSystem.h index 26d0ea5d..b727e0bb 100644 --- a/src/hm/hmSystem.h +++ b/src/hm/hmSystem.h @@ -28,7 +28,6 @@ class HmSystem { iv->config = &mInverter[0].generalConfig->iv[id]; DPRINT(DBG_VERBOSE, "SERIAL: " + String(iv->config->serial.b[5], HEX)); DPRINTLN(DBG_VERBOSE, " " + String(iv->config->serial.b[4], HEX)); - iv->rxOffset = 13; // effective 3, but can easily be recognized as default setting if((iv->config->serial.b[5] == 0x11) || (iv->config->serial.b[5] == 0x10)) { switch(iv->config->serial.b[4]) { case 0x24: // HMS-500 @@ -96,6 +95,12 @@ class HmSystem { if((iv->config->serial.b[5] == 0x10) && ((iv->config->serial.b[4] & 0x03) == 0x01)) DPRINTLN(DBG_WARN, F("MI Inverter, has some restrictions!")); + #ifdef DYNAMIC_OFFSET + iv->rxOffset = iv->ivGen == IV_HM ? 13 : 12; // effective 3 (or 2), but can easily be recognized as default setting + #else + iv->rxOffset = (iv->ivGen == IV_HM && iv->type == INV_TYPE_4CH) ? 3 : 2; // effective 3 (or 2), but can easily be recognized as default setting + #endif + cb(iv); } diff --git a/src/hms/cmt2300a.h b/src/hms/cmt2300a.h index 3cdc2660..e6456f5b 100644 --- a/src/hms/cmt2300a.h +++ b/src/hms/cmt2300a.h @@ -356,11 +356,11 @@ class Cmt2300a { if((freqKhz % FREQ_STEP_KHZ) != 0) return 0xff; // error - std::pair range = getFreqRangeMhz(); - if((freqKhz < range.first) || (freqKhz > range.second)) + std::pair range = getFreqRangeMhz(); + if((freqKhz < (range.first * 1000)) || (freqKhz > (range.second * 1000))) return 0xff; // error - return (freqKhz - getBaseFreqMhz() * 1000) / FREQ_STEP_KHZ; + return (freqKhz - (getBaseFreqMhz() * 1000)) / FREQ_STEP_KHZ; } inline void switchChannel(uint8_t ch) {