From 2d65854dfbb9a5488543f1b808deca87c0211354 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Fri, 15 Dec 2023 08:59:48 +0100 Subject: [PATCH 1/5] restrict rx channels and change timings for hmRadio-rx --- src/defines.h | 2 +- src/hm/Communication.h | 8 ++++++- src/hm/hmInverter.h | 9 +++++++ src/hm/hmRadio.h | 54 +++++++++++++++++++++++++++++++++++++----- src/hm/radio.h | 1 + src/hms/hmsRadio.h | 4 ++++ 6 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/defines.h b/src/defines.h index c4559891..8939a8f8 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 23 +#define VERSION_PATCH 2301 //------------------------------------- typedef struct { diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 51db6418..43b57426 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -86,6 +86,9 @@ class Communication : public CommQueue<> { if(NULL == q->iv->radio) cmdDone(true); // can't communicate while radio is not defined! mState = States::START; + + q->iv->radio->prepareReceive(q->iv, q->cmd, false); + break; case States::START: @@ -246,6 +249,9 @@ class Communication : public CommQueue<> { DBGPRINT(String(q->attempts)); DBGPRINTLN(F(" attempts left)")); } + if (!mIsRetransmit) + q->iv->radio->prepareReceive(q->iv, q->cmd, true); + sendRetransmit(q, (framnr-1)); mIsRetransmit = true; mlastTO_min = timeout_min; @@ -505,7 +511,7 @@ class Communication : public CommQueue<> { q->iv->mGotFragment = false; q->iv->mGotLastMsg = false; q->iv->miMultiParts = 0; - mIsRetransmit = false; + mIsRetransmit = false; mFirstTry = false; // for correct reset mState = States::RESET; DBGPRINTLN(F("-----")); diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index 3e3e1c08..34024f0d 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -131,6 +131,11 @@ class Inverter { bool mGotFragment; // shows if inverter has sent at least one fragment uint8_t curFrmCnt; // count received frames in current loop bool mGotLastMsg; // shows if inverter has already finished transmission cycle + uint8_t mRxChannels; // number of rx channels to listen to, defaults to 3; + uint32_t mRxTmoOuterLoop; // timeout for entire listening loop after sending, defaults to 400 (ms); + uint32_t mRxTmoInnerLoop; // timeout for each listening channel, defaults to 5110 (us) + uint8_t lastCmd; // holds the last sent command, defaults to 0xFF + Radio *radio; // pointer to associated radio class statistics_t radioStatistics; // information about transmitted, failed, ... packets HeuristicInv heuristics; @@ -156,7 +161,11 @@ class Inverter { alarmLastId = 0; rssi = -127; miMultiParts = 0; + lastCmd = 0xFF; mGotLastMsg = false; + mRxChannels = 3; + mRxTmoOuterLoop = 400; + mRxTmoInnerLoop = 5110; radio = NULL; commEnabled = true; diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 14146830..a2094d86 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -104,6 +104,41 @@ class HmRadio : public Radio { DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring")); } + void prepareReceive(Inverter<> *iv, uint8_t cmd, bool singleframe = false) { + if (singleframe) { + iv->mRxTmoOuterLoop = 65; // SINGLEFR_TIMEOUT + iv->lastCmd = 0xFF; + return; + } + + if ( (iv->lastCmd == cmd) || ((iv->ivGen == IV_MI) && (iv->lastCmd != 0xFF)) ) + return; // nothing to be changed.... + + iv->lastCmd = cmd; + if (iv->ivGen != IV_MI) { + if (cmd == RealTimeRunData_Debug) { + if (iv->type == INV_TYPE_4CH) { + iv->mRxChannels = 3; + iv->mRxTmoOuterLoop = 300; + iv->mRxTmoInnerLoop = 5110; + } else { + iv->mRxChannels = 2; + iv->mRxTmoOuterLoop = 250; + iv->mRxTmoInnerLoop = 10220; + } + } else { //3rd gen defaults + iv->mRxChannels = 3; + iv->mRxTmoOuterLoop = 500; + iv->mRxTmoInnerLoop = 5110; + } + } else { // 2nd gen defaults + iv->mRxChannels = 2; + iv->mRxTmoOuterLoop = 250; + iv->mRxTmoInnerLoop = 5110; + } + } + + void loop(void) { if (!mIrqRcvd) return; // nothing to do @@ -121,8 +156,8 @@ class HmRadio : public Radio { uint32_t startMicros = micros(); uint32_t loopMillis = millis(); - while ((millis() - loopMillis) < 400) { - while ((micros() - startMicros) < 5110) { // listen (4088us or?) 5110us to each channel + while ((millis() - loopMillis) < mLastIv->mRxTmoOuterLoop) { + while ((micros() - startMicros) < mLastIv->mRxTmoInnerLoop) { // listen (4088us or?) 5110us to each channel if (mIrqRcvd) { mIrqRcvd = false; @@ -133,9 +168,16 @@ class HmRadio : public Radio { yield(); } // switch to next RX channel - if(++mRxChIdx >= RF_CHANNELS) + /*if(++mRxChIdx >= RF_CHANNELS) + mRxChIdx = 0;*/ + + if(++mRxChIdx >= mLastIv->mRxChannels) mRxChIdx = 0; - mNrf24->setChannel(mRfChLst[mRxChIdx]); + + uint8_t nextRxCh = (mRxChIdx + mTxChIdx + 1) % RF_MAX_CHANNEL_ID; + + //mNrf24->setChannel(mRfChLst[mRxChIdx]); + mNrf24->setChannel(mRfChLst[nextRxCh]); startMicros = micros(); } // not finished but time is over @@ -337,8 +379,8 @@ class HmRadio : public Radio { uint64_t DTU_RADIO_ID; uint8_t mRfChLst[RF_CHANNELS] = {03, 23, 40, 61, 75}; // channel List:2403, 2423, 2440, 2461, 2475MHz - uint8_t mTxChIdx = 0; - uint8_t mRxChIdx = 0; + uint8_t mTxChIdx = 0; + uint8_t mRxChIdx = 0; bool mGotLastMsg = false; uint32_t mMillis; diff --git a/src/hm/radio.h b/src/hm/radio.h index 2fe4f640..19e891c3 100644 --- a/src/hm/radio.h +++ b/src/hm/radio.h @@ -22,6 +22,7 @@ class Inverter; class Radio { public: virtual void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit) = 0; + virtual void prepareReceive(Inverter<> *iv, uint8_t cmd, bool singleframe = false) = 0; virtual bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { return true; } virtual bool switchFrequencyCh(Inverter<> *iv, uint8_t fromCh, uint8_t toCh) { return true; } virtual bool isChipConnected(void) { return false; } diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index 40200085..c7b031e0 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -26,6 +26,10 @@ class CmtRadio : public Radio { mPrintWholeTrace = printWholeTrace; } + void prepareReceive(Inverter<> *iv, uint8_t cmd, bool singleframe = false) { + return; // only relevant for nRF type inverters + } + void loop() { mCmt.loop(); if((!mIrqRcvd) && (!mRqstGetRx)) From 3f77b5e26dfb5954fc26f06cc1e7bc9c4848eb23 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Fri, 15 Dec 2023 12:43:49 +0100 Subject: [PATCH 2/5] fix inverter restrictions (choose the correct channels and the correct amount...) --- src/defines.h | 2 +- src/hm/Communication.h | 5 +++-- src/hm/hmRadio.h | 8 +++++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/defines.h b/src/defines.h index 8939a8f8..cf552aa0 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 2301 +#define VERSION_PATCH 2304 //------------------------------------- typedef struct { diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 43b57426..07ded1bf 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -202,6 +202,7 @@ class Communication : public CommQueue<> { if(q->iv->miMultiParts < 6) { mState = States::WAIT; } else { + mHeu.evalTxChQuality(q->iv, true, (4 - q->attempts), q->iv->curFrmCnt); if(((q->cmd == 0x39) && (q->iv->type == INV_TYPE_4CH)) || ((q->cmd == MI_REQ_CH2) && (q->iv->type == INV_TYPE_2CH)) || ((q->cmd == MI_REQ_CH1) && (q->iv->type == INV_TYPE_1CH))) { @@ -686,19 +687,19 @@ class Communication : public CommQueue<> { miStsConsolidate(q, datachan, rec, p->packet[23], p->packet[24]); if (p->packet[0] < (0x39 + ALL_FRAMES) ) { + mHeu.evalTxChQuality(q->iv, true, (4 - q->attempts), 1); miNextRequest((p->packet[0] - ALL_FRAMES + 1), q); } else { q->iv->miMultiParts = 7; // indicate we are ready - //miComplete(q->iv); } } else if((p->packet[0] == (MI_REQ_CH1 + ALL_FRAMES)) && (q->iv->type == INV_TYPE_2CH)) { //addImportant(q->iv, MI_REQ_CH2); miNextRequest(MI_REQ_CH2, q); //use also miMultiParts here for better statistics? //mHeu.setGotFragment(q->iv); + mHeu.evalTxChQuality(q->iv, true, (4 - q->attempts), q->iv->curFrmCnt); } else { // first data msg for 1ch, 2nd for 2ch q->iv->miMultiParts += 6; // indicate we are ready - //miComplete(q->iv); } } diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index a2094d86..abf68048 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -108,6 +108,7 @@ class HmRadio : public Radio { if (singleframe) { iv->mRxTmoOuterLoop = 65; // SINGLEFR_TIMEOUT iv->lastCmd = 0xFF; + //DPRINTLN(DBG_INFO, F("1 frm")); return; } @@ -121,20 +122,24 @@ class HmRadio : public Radio { iv->mRxChannels = 3; iv->mRxTmoOuterLoop = 300; iv->mRxTmoInnerLoop = 5110; + //DPRINTLN(DBG_INFO, F("4ch data")); } else { iv->mRxChannels = 2; iv->mRxTmoOuterLoop = 250; iv->mRxTmoInnerLoop = 10220; + //DPRINTLN(DBG_INFO, F("1/2ch data")); } } else { //3rd gen defaults iv->mRxChannels = 3; iv->mRxTmoOuterLoop = 500; iv->mRxTmoInnerLoop = 5110; + //DPRINTLN(DBG_INFO, F("3rd gen default")); } } else { // 2nd gen defaults iv->mRxChannels = 2; iv->mRxTmoOuterLoop = 250; iv->mRxTmoInnerLoop = 5110; + //DPRINTLN(DBG_INFO, F("2nd gen default")); } } @@ -171,10 +176,11 @@ class HmRadio : public Radio { /*if(++mRxChIdx >= RF_CHANNELS) mRxChIdx = 0;*/ + //if(++mRxChIdx >= mLastIv->mRxChannels) if(++mRxChIdx >= mLastIv->mRxChannels) mRxChIdx = 0; - uint8_t nextRxCh = (mRxChIdx + mTxChIdx + 1) % RF_MAX_CHANNEL_ID; + uint8_t nextRxCh = (mRxChIdx + mTxChIdx + 4) % RF_MAX_CHANNEL_ID; // let 3 channels in shifting out; might cause problems for tx channel 75, see Oberfritze remark to his array //mNrf24->setChannel(mRfChLst[mRxChIdx]); mNrf24->setChannel(mRfChLst[nextRxCh]); From 8ba318fb6dc30b098e2addfd922e967eaa8b87d5 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Fri, 15 Dec 2023 15:30:58 +0100 Subject: [PATCH 3/5] add "fastNext" logic discord ".2305" --- src/hm/Communication.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 07ded1bf..a0c630d1 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -199,6 +199,7 @@ class Communication : public CommQueue<> { if(q->iv->ivGen != IV_MI) { mState = States::CHECK_PACKAGE; } else { + bool fastNext = true; if(q->iv->miMultiParts < 6) { mState = States::WAIT; } else { @@ -207,8 +208,16 @@ class Communication : public CommQueue<> { || ((q->cmd == MI_REQ_CH2) && (q->iv->type == INV_TYPE_2CH)) || ((q->cmd == MI_REQ_CH1) && (q->iv->type == INV_TYPE_1CH))) { miComplete(q->iv); + fastNext = false; } closeRequest(q, true); + if(fastNext) { + // immediately send out regular production data request + // and reset mWaitTimeout + mWaitTimeout = mWaitTimeout - *mInverterGap; + chgCmd((q->iv->type == INV_TYPE_4CH) ? MI_REQ_4CH : MI_REQ_CH1); + mState = States::RESET; + } } } @@ -264,7 +273,20 @@ class Communication : public CommQueue<> { if(NULL != mCbPayload) (mCbPayload)(q->cmd, q->iv); + bool fastNext = false; + if ((q->cmd < 11) || (q->cmd > 18)) + fastNext = true; + closeRequest(q, true); + + if(fastNext) { + // immediately send out regular production data request + // and reset mWaitTimeout + mWaitTimeout = mWaitTimeout - *mInverterGap; + chgCmd(RealTimeRunData_Debug); + mState = States::RESET; + } + break; } }); From 90e3f27eb3c744d2837b67d716c0a6af2cdcdba3 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Sat, 16 Dec 2023 12:05:13 +0100 Subject: [PATCH 4/5] discord ".2401" - based on 0.8.24 - timings/rx basically only changed for 2ch - always start off in rx with hard relative rx channel --- src/hm/CommQueue.h | 1 + src/hm/hmRadio.h | 26 +++++++++++++++----------- src/hm/nrfHal.h | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index 5d6f9bd0..d1beedfc 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -31,6 +31,7 @@ class CommQueue { } uint8_t getFillState(void) { + DPRINTLN(DBG_INFO, "wr: " + String(mWrPtr) + ", rd: " + String(mRdPtr)); return abs(mRdPtr - mWrPtr); } diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index abf68048..7977844a 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -10,7 +10,7 @@ #include "SPI.h" #include "radio.h" #include "../config/config.h" -#if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET) +#if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) #include "nrfHal.h" #endif @@ -35,8 +35,8 @@ class HmRadio : public Radio { HmRadio() { mDtuSn = DTU_SN; mIrqRcvd = false; - #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET) - mNrf24.reset(new RF24()); + #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) + //mNrf24.reset(new RF24()); #else mNrf24.reset(new RF24(CE_PIN, CS_PIN, SPI_SPEED)); #endif @@ -56,8 +56,8 @@ class HmRadio : public Radio { DTU_RADIO_ID = ((uint64_t)(((mDtuSn >> 24) & 0xFF) | ((mDtuSn >> 8) & 0xFF00) | ((mDtuSn << 8) & 0xFF0000) | ((mDtuSn << 24) & 0xFF000000)) << 8) | 0x01; #ifdef ESP32 - #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET) - mNrfHal.init(mosi, miso, sclk, cs, ce); + #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) + mNrfHal.init(mosi, miso, sclk, cs, ce, SPI_SPEED); mNrf24.reset(new RF24(&mNrfHal)); #else #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 @@ -73,7 +73,7 @@ class HmRadio : public Radio { mSpi->begin(); #endif - #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET) + #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) mNrf24->begin(); #else mNrf24->begin(mSpi.get(), ce, cs); @@ -123,14 +123,18 @@ class HmRadio : public Radio { iv->mRxTmoOuterLoop = 300; iv->mRxTmoInnerLoop = 5110; //DPRINTLN(DBG_INFO, F("4ch data")); - } else { + } else if (iv->type == INV_TYPE_2CH) { iv->mRxChannels = 2; iv->mRxTmoOuterLoop = 250; iv->mRxTmoInnerLoop = 10220; //DPRINTLN(DBG_INFO, F("1/2ch data")); + } else { // INV_TYPE_1CH + iv->mRxChannels = 5; + iv->mRxTmoOuterLoop = 400; + iv->mRxTmoInnerLoop = 5110; } } else { //3rd gen defaults - iv->mRxChannels = 3; + iv->mRxChannels = 5; iv->mRxTmoOuterLoop = 500; iv->mRxTmoInnerLoop = 5110; //DPRINTLN(DBG_INFO, F("3rd gen default")); @@ -187,8 +191,8 @@ class HmRadio : public Radio { startMicros = micros(); } // not finished but time is over - if(++mRxChIdx >= RF_CHANNELS) - mRxChIdx = 0; + //if(++mRxChIdx >= RF_CHANNELS) // rejoe2: for testing now always start with the first (relative) rx channel + mRxChIdx = 1; return; } @@ -392,7 +396,7 @@ class HmRadio : public Radio { std::unique_ptr mSpi; std::unique_ptr mNrf24; - #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET) + #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) nrfHal mNrfHal; #endif Inverter<> *mLastIv = NULL; diff --git a/src/hm/nrfHal.h b/src/hm/nrfHal.h index d4db9f92..c9fbcdc7 100644 --- a/src/hm/nrfHal.h +++ b/src/hm/nrfHal.h @@ -118,7 +118,7 @@ class nrfHal: public RF24_hal, public SpiPatcherHandle { uint8_t write(uint8_t cmd, const uint8_t* buf, uint8_t data_len, uint8_t blank_len) override { uint8_t data[NRF_MAX_TRANSFER_SZ]; data[0] = cmd; - memset(data, 0, NRF_MAX_TRANSFER_SZ); + memset(&data[1], 0, (NRF_MAX_TRANSFER_SZ-1)); std::copy(&buf[0], &buf[data_len], &data[1]); request_spi(); From 09dd32c28c7da67d0c91f7f4a9ad49a1d1776434 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Sat, 16 Dec 2023 17:45:52 +0100 Subject: [PATCH 5/5] restrict rx for 1ch devices - timing should be reviewed as well for 1ch - 4ch is just a guess; needs testing! --- src/hm/hmRadio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 7977844a..fca482ef 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -129,7 +129,7 @@ class HmRadio : public Radio { iv->mRxTmoInnerLoop = 10220; //DPRINTLN(DBG_INFO, F("1/2ch data")); } else { // INV_TYPE_1CH - iv->mRxChannels = 5; + iv->mRxChannels = 2; iv->mRxTmoOuterLoop = 400; iv->mRxTmoInnerLoop = 5110; }