From b34e5a7416d0dde8764434b8f7afa9f8ef108556 Mon Sep 17 00:00:00 2001 From: lumapu Date: Wed, 11 Oct 2023 21:07:03 +0200 Subject: [PATCH] added millis to each packet for radio analysis fixed several issue regarding communication --- src/app.cpp | 27 +++++++++++---- src/app.h | 6 ++-- src/defines.h | 2 +- src/hm/CommQueue.h | 2 +- src/hm/Communication.h | 79 ++++++++++++++++++++++++------------------ src/hm/hmRadio.h | 11 +++--- src/hm/radio.h | 6 +++- src/hms/hmsRadio.h | 12 +++---- 8 files changed, 89 insertions(+), 56 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index 684914e2..2255aa14 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -70,9 +70,6 @@ void app::setup() { else if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen)) iv->radio = &mCmtRadio; #endif - mCommunication.add(iv, 0x01); - mCommunication.add(iv, 0x05); - mCommunication.add(iv, 0x0b); }); } @@ -127,6 +124,10 @@ void app::loop(void) { ah::Scheduler::loop(); bool processPayload = false; + mNrfRadio.loop(); + #if defined(ESP32) + mCmtRadio.loop(); + #endif mCommunication.loop(); /*if (mNrfRadio.loop() && mConfig->nrf.enabled) { @@ -199,7 +200,8 @@ void app::onNetwork(bool gotIp) { mNetworkConnected = gotIp; ah::Scheduler::resetTicker(); regularTickers(); //reinstall regular tickers - every(std::bind(&app::tickSend, this), mConfig->nrf.sendInterval, "tSend"); + //every(std::bind(&app::tickSend, this), mConfig->nrf.sendInterval, "tSend"); + once(std::bind(&app::tickSend, this), 20, "tSend"); mMqttReconnect = true; mSunrise = 0; // needs to be set to 0, to reinstall sunrise and ivComm tickers! //once(std::bind(&app::tickNtpUpdate, this), 2, "ntp2"); @@ -290,7 +292,7 @@ void app::tickNtpUpdate(void) { // immediately start communicating if (isOK && mSendFirst) { mSendFirst = false; - once(std::bind(&app::tickSend, this), 2, "senOn"); + //once(std::bind(&app::tickSend, this), 2, "senOn"); } mMqttReconnect = false; @@ -402,6 +404,17 @@ void app::tickMidnight(void) { //----------------------------------------------------------------------------- void app::tickSend(void) { + DPRINTLN(DBG_INFO, "tickSend"); + + for (uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { + Inverter<> *iv = mSys.getInverterByPos(i); + if(NULL != iv) { + mCommunication.add(iv, 0x01); + mCommunication.add(iv, 0x05); + mCommunication.add(iv, 0x0b, false); + }; + } + /*if(mConfig->nrf.enabled) { if(!mNrfRadio.isChipConnected()) { DPRINTLN(DBG_WARN, F("NRF24 not connected!")); @@ -448,9 +461,9 @@ void app::tickSend(void) { if (mConfig->serial.debug) DPRINTLN(DBG_WARN, F("Time not set or it is night time, therefore no communication to the inverter!")); } - yield();*/ + yield(); - updateLed(); + updateLed();*/ } //----------------------------------------------------------------------------- diff --git a/src/app.h b/src/app.h index 9cc90100..d1a13a6a 100644 --- a/src/app.h +++ b/src/app.h @@ -176,8 +176,8 @@ class app : public IApp, public ah::Scheduler { if(mIVCommunicationOn) { // only send commands if communication is enabled if (iv->ivGen == IV_MI) mMiPayload.ivSendHighPrio(iv); - else - mPayload.ivSendHighPrio(iv); + //else + // mPayload.ivSendHighPrio(iv); } } @@ -319,7 +319,7 @@ class app : public IApp, public ah::Scheduler { #endif /* defined(ETHERNET) */ WebType mWeb; RestApiType mApi; - PayloadType mPayload; + //PayloadType mPayload; MiPayloadType mMiPayload; PubSerialType mPubSerial; #if !defined(ETHERNET) diff --git a/src/defines.h b/src/defines.h index 860231ba..80ecf9c0 100644 --- a/src/defines.h +++ b/src/defines.h @@ -21,7 +21,7 @@ typedef struct { uint8_t len; int8_t rssi; uint8_t packet[MAX_RF_PAYLOAD_SIZE]; - //uint32_t millis; + uint16_t millis; } packet_t; typedef enum { diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index d9745eb1..5f13d03d 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -51,7 +51,7 @@ class CommQueue { cb(true, &mQueue[mRdPtr]); } - void pop(bool force = false) { + void cmdDone(bool force = false) { if(!mQueue[mRdPtr].delOnPop && !force) { mQueue[mRdPtr].attempts = 5; add(mQueue[mRdPtr]); // add to the end again diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 65dd2d5c..ecb28ce0 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -23,7 +23,7 @@ class Communication : public CommQueue<> { switch(mState) { case States::RESET: - lastFound = false; + mMaxFrameId = 0; for(uint8_t i = 0; i < MAX_PAYLOAD_ENTRIES; i++) { mLocalBuf[i].len = 0; } @@ -33,7 +33,7 @@ class Communication : public CommQueue<> { case States::START: setTs(mTimestamp); q->iv->radio->prepareDevInformCmd(q->iv, q->cmd, q->ts, q->iv->alarmLastId, false); - mWaitTimeout = millis() + 500; + mWaitTimeout = millis() + 1500; setAttempt(); mState = States::WAIT; break; @@ -45,20 +45,29 @@ class Communication : public CommQueue<> { break; case States::CHECK_FRAMES: { - if(!q->iv->radio->loop()) { - pop(); + if(!q->iv->radio->get()) { // radio buffer empty + cmdDone(); + DBGPRINTLN(F("request timeout")); q->iv->radioStatistics.rxFailNoAnser++; // got nothing - mState = States::RESET; - break; // radio buffer empty + if((IV_HMS == q->iv->ivGen) || (IV_HMT == q->iv->ivGen)) { + q->iv->radio->switchFrequency(q->iv, HOY_BOOT_FREQ_KHZ, WORK_FREQ_KHZ); + mWaitTimeout = millis() + 2000; + mState = States::GAP; + break; + } else { + mState = States::RESET; + break; + } } States nextState = States::RESET; while(!q->iv->radio->mBufCtrl.empty()) { packet_t *p = &q->iv->radio->mBufCtrl.front(); - q->iv->radio->mBufCtrl.pop(); DPRINT_IVID(DBG_INFO, q->iv->id); DPRINT(DBG_INFO, F("RX ")); + DBGPRINT(String(p->millis)); + DBGPRINT(F("ms ")); DBGPRINT(String(p->len)); DBGPRINT(F(" CH")); DBGPRINT(String(p->ch)); @@ -67,29 +76,33 @@ class Communication : public CommQueue<> { DBGPRINT(F("dBm | ")); ah::dumpBuf(p->packet, p->len); - if(!checkIvSerial(&p->packet[1], q->iv)) - continue; // inverter ID incorrect - - q->iv->radioStatistics.frmCnt++; + if(checkIvSerial(&p->packet[1], q->iv)) { + q->iv->radioStatistics.frmCnt++; - if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command - parseFrame(p); - nextState = States::CHECK_PACKAGE; - } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) // response from dev control command - parseDevCtrl(p); + if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command + parseFrame(p); + nextState = States::CHECK_PACKAGE; + } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) // response from dev control command + parseDevCtrl(p); + } + q->iv->radio->mBufCtrl.pop(); yield(); } mState = nextState; } break; + case States::GAP: + if(millis() < mWaitTimeout) + return; + mState = States::RESET; + break; + case States::CHECK_PACKAGE: - if(!lastFound) { + if(0 == mMaxFrameId) { DPRINT_IVID(DBG_WARN, q->iv->id); - DBGPRINT(F("last frame ")); - DBGPRINT(String(mMaxFrameId+1)); - DBGPRINTLN(F(" missing: Request Retransmit")); + DBGPRINT(F("last frame missing: request retransmit")); q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (SINGLE_FRAME + mMaxFrameId + 1), true); setAttempt(); @@ -103,9 +116,9 @@ class Communication : public CommQueue<> { DPRINT_IVID(DBG_WARN, q->iv->id); DBGPRINT(F("frame ")); DBGPRINT(String(i + 1)); - DBGPRINTLN(F(" missing: Request Retransmit")); + DBGPRINTLN(F(" missing: request retransmit")); - q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (SINGLE_FRAME + i), true); + q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (ALL_FRAMES + i), true); setAttempt(); mWaitTimeout = millis() + 100; mState = States::WAIT; @@ -115,7 +128,7 @@ class Communication : public CommQueue<> { compilePayload(q); - pop(true); // remove done request + cmdDone(true); // remove done request mState = States::RESET; // everything ok, next request break; } @@ -139,21 +152,22 @@ class Communication : public CommQueue<> { inline void parseFrame(packet_t *p) { uint8_t *frameId = &p->packet[9]; - if(0x00 == *frameId) + if(0x00 == *frameId) { + DPRINTLN(DBG_WARN, F("invalid frameId 0x00")); return; // skip current packet + } if((*frameId & 0x7f) > MAX_PAYLOAD_ENTRIES) { - DPRINTLN(DBG_WARN, F("local buffer to small for payload fragments!")); + DPRINTLN(DBG_WARN, F("local buffer to small for payload fragments")); return; // local storage is to small for id } - if(!checkFrameCrc(p->packet, p->len)) + if(!checkFrameCrc(p->packet, p->len)) { + DPRINTLN(DBG_WARN, F("frame CRC is wrong")); return; // CRC8 is wrong, frame invalid + } - if((*frameId & ALL_FRAMES) == ALL_FRAMES) { + if((*frameId & ALL_FRAMES) == ALL_FRAMES) mMaxFrameId = (*frameId & 0x7f); - if(*frameId > 0x81) - lastFound = true; - } frame_t *f = &mLocalBuf[(*frameId & 0x7f) - 1]; memcpy(f->buf, &p->packet[10], p->len-11); @@ -182,7 +196,7 @@ class Communication : public CommQueue<> { if(q->attempts == 0) { DBGPRINTLN(F("-> Fail")); q->iv->radioStatistics.rxFail++; // got fragments but not complete response - pop(); + cmdDone(); } else DBGPRINTLN(F("-> complete retransmit")); mState = States::RESET; @@ -220,7 +234,7 @@ class Communication : public CommQueue<> { private: enum class States : uint8_t { - RESET, START, WAIT, CHECK_FRAMES, CHECK_PACKAGE + RESET, START, WAIT, CHECK_FRAMES, CHECK_PACKAGE, GAP }; typedef struct { @@ -234,7 +248,6 @@ class Communication : public CommQueue<> { uint32_t *mTimestamp; uint32_t mWaitTimeout; std::array mLocalBuf; - bool lastFound; uint8_t mMaxFrameId; uint8_t mPayload[150]; }; diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 45278e6b..7e76644d 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -105,9 +105,9 @@ class HmRadio : public Radio { DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring")); } - bool loop(void) { + void loop(void) { if (!mIrqRcvd) - return false; // nothing to do + return; // nothing to do mIrqRcvd = false; bool tx_ok, tx_fail, rx_ready; mNrf24.whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH @@ -124,7 +124,7 @@ class HmRadio : public Radio { if (mIrqRcvd) { mIrqRcvd = false; if (getReceived()) { // everything received - return true; + return; } } yield(); @@ -137,7 +137,7 @@ class HmRadio : public Radio { yield(); } // not finished but time is over - return true; + return; } bool isChipConnected(void) { @@ -252,6 +252,7 @@ class HmRadio : public Radio { p.ch = mRfChLst[mRxChIdx]; p.len = (len > MAX_RF_PAYLOAD_SIZE) ? MAX_RF_PAYLOAD_SIZE : len; p.rssi = mNrf24.testRPD() ? -64 : -75; + p.millis = millis() - mMillis; mNrf24.read(p.packet, p.len); if (p.packet[0] != 0x00) { mBufCtrl.push(p); @@ -288,6 +289,7 @@ class HmRadio : public Radio { mNrf24.setChannel(mRfChLst[mTxChIdx]); mNrf24.openWritingPipe(reinterpret_cast(&iv->radioId.u64)); mNrf24.startWrite(mTxBuf, len, false); // false = request ACK response + mMillis = millis(); if(isRetransmit) iv->radioStatistics.retransmits++; @@ -303,6 +305,7 @@ class HmRadio : public Radio { uint8_t mRfChLst[RF_CHANNELS]; uint8_t mTxChIdx; uint8_t mRxChIdx; + uint32_t mMillis; SPIClass* mSpi; RF24 mNrf24; diff --git a/src/hm/radio.h b/src/hm/radio.h index 8e9f5ef4..2096f108 100644 --- a/src/hm/radio.h +++ b/src/hm/radio.h @@ -23,7 +23,11 @@ class Radio { public: virtual void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, uint16_t powerMax = 0) = 0; virtual bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { return true; } - virtual bool loop(void) = 0; + virtual void loop(void) {}; + + bool get() { + return !mBufCtrl.empty(); + } void handleIntr(void) { mIrqRcvd = true; diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index 5cee324b..c01a95bc 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -29,18 +29,15 @@ class CmtRadio : public Radio { reset(genDtuSn); } - bool loop() { + void loop() { mCmt.loop(); - if((!mIrqRcvd) && (!mRqstGetRx)) - return false; + return; getRx(); if(CMT_SUCCESS == mCmt.goRx()) { mIrqRcvd = false; mRqstGetRx = false; - return true; - } else - return false; + } } bool isConnected() { @@ -90,6 +87,7 @@ class CmtRadio : public Radio { } uint8_t status = mCmt.tx(mTxBuf, len); + mMillis = millis(); if(CMT_SUCCESS != status) { DPRINT(DBG_WARN, F("CMT TX failed, code: ")); DBGPRINTLN(String(status)); @@ -144,6 +142,7 @@ class CmtRadio : public Radio { inline void getRx(void) { packet_t p; + p.millis = millis() - mMillis; uint8_t status = mCmt.getRx(p.packet, &p.len, 28, &p.rssi); if(CMT_SUCCESS == status) mBufCtrl.push(p); @@ -152,6 +151,7 @@ class CmtRadio : public Radio { CmtType mCmt; bool mRqstGetRx; bool mCmtAvail; + uint32_t mMillis; }; #endif /*__HMS_RADIO_H__*/