Browse Source

added millis to each packet for radio analysis

fixed several issue regarding communication
pull/1219/head
lumapu 1 year ago
parent
commit
b34e5a7416
  1. 27
      src/app.cpp
  2. 6
      src/app.h
  3. 2
      src/defines.h
  4. 2
      src/hm/CommQueue.h
  5. 79
      src/hm/Communication.h
  6. 11
      src/hm/hmRadio.h
  7. 6
      src/hm/radio.h
  8. 12
      src/hms/hmsRadio.h

27
src/app.cpp

@ -70,9 +70,6 @@ void app::setup() {
else if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen)) else if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen))
iv->radio = &mCmtRadio; iv->radio = &mCmtRadio;
#endif #endif
mCommunication.add(iv, 0x01);
mCommunication.add(iv, 0x05);
mCommunication.add(iv, 0x0b);
}); });
} }
@ -127,6 +124,10 @@ void app::loop(void) {
ah::Scheduler::loop(); ah::Scheduler::loop();
bool processPayload = false; bool processPayload = false;
mNrfRadio.loop();
#if defined(ESP32)
mCmtRadio.loop();
#endif
mCommunication.loop(); mCommunication.loop();
/*if (mNrfRadio.loop() && mConfig->nrf.enabled) { /*if (mNrfRadio.loop() && mConfig->nrf.enabled) {
@ -199,7 +200,8 @@ void app::onNetwork(bool gotIp) {
mNetworkConnected = gotIp; mNetworkConnected = gotIp;
ah::Scheduler::resetTicker(); ah::Scheduler::resetTicker();
regularTickers(); //reinstall regular tickers 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; mMqttReconnect = true;
mSunrise = 0; // needs to be set to 0, to reinstall sunrise and ivComm tickers! mSunrise = 0; // needs to be set to 0, to reinstall sunrise and ivComm tickers!
//once(std::bind(&app::tickNtpUpdate, this), 2, "ntp2"); //once(std::bind(&app::tickNtpUpdate, this), 2, "ntp2");
@ -290,7 +292,7 @@ void app::tickNtpUpdate(void) {
// immediately start communicating // immediately start communicating
if (isOK && mSendFirst) { if (isOK && mSendFirst) {
mSendFirst = false; mSendFirst = false;
once(std::bind(&app::tickSend, this), 2, "senOn"); //once(std::bind(&app::tickSend, this), 2, "senOn");
} }
mMqttReconnect = false; mMqttReconnect = false;
@ -402,6 +404,17 @@ void app::tickMidnight(void) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void app::tickSend(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(mConfig->nrf.enabled) {
if(!mNrfRadio.isChipConnected()) { if(!mNrfRadio.isChipConnected()) {
DPRINTLN(DBG_WARN, F("NRF24 not connected!")); DPRINTLN(DBG_WARN, F("NRF24 not connected!"));
@ -448,9 +461,9 @@ void app::tickSend(void) {
if (mConfig->serial.debug) if (mConfig->serial.debug)
DPRINTLN(DBG_WARN, F("Time not set or it is night time, therefore no communication to the inverter!")); DPRINTLN(DBG_WARN, F("Time not set or it is night time, therefore no communication to the inverter!"));
} }
yield();*/ yield();
updateLed(); updateLed();*/
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

6
src/app.h

@ -176,8 +176,8 @@ class app : public IApp, public ah::Scheduler {
if(mIVCommunicationOn) { // only send commands if communication is enabled if(mIVCommunicationOn) { // only send commands if communication is enabled
if (iv->ivGen == IV_MI) if (iv->ivGen == IV_MI)
mMiPayload.ivSendHighPrio(iv); mMiPayload.ivSendHighPrio(iv);
else //else
mPayload.ivSendHighPrio(iv); // mPayload.ivSendHighPrio(iv);
} }
} }
@ -319,7 +319,7 @@ class app : public IApp, public ah::Scheduler {
#endif /* defined(ETHERNET) */ #endif /* defined(ETHERNET) */
WebType mWeb; WebType mWeb;
RestApiType mApi; RestApiType mApi;
PayloadType mPayload; //PayloadType mPayload;
MiPayloadType mMiPayload; MiPayloadType mMiPayload;
PubSerialType mPubSerial; PubSerialType mPubSerial;
#if !defined(ETHERNET) #if !defined(ETHERNET)

2
src/defines.h

@ -21,7 +21,7 @@ typedef struct {
uint8_t len; uint8_t len;
int8_t rssi; int8_t rssi;
uint8_t packet[MAX_RF_PAYLOAD_SIZE]; uint8_t packet[MAX_RF_PAYLOAD_SIZE];
//uint32_t millis; uint16_t millis;
} packet_t; } packet_t;
typedef enum { typedef enum {

2
src/hm/CommQueue.h

@ -51,7 +51,7 @@ class CommQueue {
cb(true, &mQueue[mRdPtr]); cb(true, &mQueue[mRdPtr]);
} }
void pop(bool force = false) { void cmdDone(bool force = false) {
if(!mQueue[mRdPtr].delOnPop && !force) { if(!mQueue[mRdPtr].delOnPop && !force) {
mQueue[mRdPtr].attempts = 5; mQueue[mRdPtr].attempts = 5;
add(mQueue[mRdPtr]); // add to the end again add(mQueue[mRdPtr]); // add to the end again

79
src/hm/Communication.h

@ -23,7 +23,7 @@ class Communication : public CommQueue<> {
switch(mState) { switch(mState) {
case States::RESET: case States::RESET:
lastFound = false; mMaxFrameId = 0;
for(uint8_t i = 0; i < MAX_PAYLOAD_ENTRIES; i++) { for(uint8_t i = 0; i < MAX_PAYLOAD_ENTRIES; i++) {
mLocalBuf[i].len = 0; mLocalBuf[i].len = 0;
} }
@ -33,7 +33,7 @@ class Communication : public CommQueue<> {
case States::START: case States::START:
setTs(mTimestamp); setTs(mTimestamp);
q->iv->radio->prepareDevInformCmd(q->iv, q->cmd, q->ts, q->iv->alarmLastId, false); q->iv->radio->prepareDevInformCmd(q->iv, q->cmd, q->ts, q->iv->alarmLastId, false);
mWaitTimeout = millis() + 500; mWaitTimeout = millis() + 1500;
setAttempt(); setAttempt();
mState = States::WAIT; mState = States::WAIT;
break; break;
@ -45,20 +45,29 @@ class Communication : public CommQueue<> {
break; break;
case States::CHECK_FRAMES: { case States::CHECK_FRAMES: {
if(!q->iv->radio->loop()) { if(!q->iv->radio->get()) { // radio buffer empty
pop(); cmdDone();
DBGPRINTLN(F("request timeout"));
q->iv->radioStatistics.rxFailNoAnser++; // got nothing q->iv->radioStatistics.rxFailNoAnser++; // got nothing
mState = States::RESET; if((IV_HMS == q->iv->ivGen) || (IV_HMT == q->iv->ivGen)) {
break; // radio buffer empty 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; States nextState = States::RESET;
while(!q->iv->radio->mBufCtrl.empty()) { while(!q->iv->radio->mBufCtrl.empty()) {
packet_t *p = &q->iv->radio->mBufCtrl.front(); packet_t *p = &q->iv->radio->mBufCtrl.front();
q->iv->radio->mBufCtrl.pop();
DPRINT_IVID(DBG_INFO, q->iv->id); DPRINT_IVID(DBG_INFO, q->iv->id);
DPRINT(DBG_INFO, F("RX ")); DPRINT(DBG_INFO, F("RX "));
DBGPRINT(String(p->millis));
DBGPRINT(F("ms "));
DBGPRINT(String(p->len)); DBGPRINT(String(p->len));
DBGPRINT(F(" CH")); DBGPRINT(F(" CH"));
DBGPRINT(String(p->ch)); DBGPRINT(String(p->ch));
@ -67,29 +76,33 @@ class Communication : public CommQueue<> {
DBGPRINT(F("dBm | ")); DBGPRINT(F("dBm | "));
ah::dumpBuf(p->packet, p->len); ah::dumpBuf(p->packet, p->len);
if(!checkIvSerial(&p->packet[1], q->iv)) if(checkIvSerial(&p->packet[1], q->iv)) {
continue; // inverter ID incorrect q->iv->radioStatistics.frmCnt++;
q->iv->radioStatistics.frmCnt++;
if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
parseFrame(p); parseFrame(p);
nextState = States::CHECK_PACKAGE; nextState = States::CHECK_PACKAGE;
} else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) // response from dev control command } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) // response from dev control command
parseDevCtrl(p); parseDevCtrl(p);
}
q->iv->radio->mBufCtrl.pop();
yield(); yield();
} }
mState = nextState; mState = nextState;
} }
break; break;
case States::GAP:
if(millis() < mWaitTimeout)
return;
mState = States::RESET;
break;
case States::CHECK_PACKAGE: case States::CHECK_PACKAGE:
if(!lastFound) { if(0 == mMaxFrameId) {
DPRINT_IVID(DBG_WARN, q->iv->id); DPRINT_IVID(DBG_WARN, q->iv->id);
DBGPRINT(F("last frame ")); DBGPRINT(F("last frame missing: request retransmit"));
DBGPRINT(String(mMaxFrameId+1));
DBGPRINTLN(F(" missing: Request Retransmit"));
q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (SINGLE_FRAME + mMaxFrameId + 1), true); q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (SINGLE_FRAME + mMaxFrameId + 1), true);
setAttempt(); setAttempt();
@ -103,9 +116,9 @@ class Communication : public CommQueue<> {
DPRINT_IVID(DBG_WARN, q->iv->id); DPRINT_IVID(DBG_WARN, q->iv->id);
DBGPRINT(F("frame ")); DBGPRINT(F("frame "));
DBGPRINT(String(i + 1)); 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(); setAttempt();
mWaitTimeout = millis() + 100; mWaitTimeout = millis() + 100;
mState = States::WAIT; mState = States::WAIT;
@ -115,7 +128,7 @@ class Communication : public CommQueue<> {
compilePayload(q); compilePayload(q);
pop(true); // remove done request cmdDone(true); // remove done request
mState = States::RESET; // everything ok, next request mState = States::RESET; // everything ok, next request
break; break;
} }
@ -139,21 +152,22 @@ class Communication : public CommQueue<> {
inline void parseFrame(packet_t *p) { inline void parseFrame(packet_t *p) {
uint8_t *frameId = &p->packet[9]; uint8_t *frameId = &p->packet[9];
if(0x00 == *frameId) if(0x00 == *frameId) {
DPRINTLN(DBG_WARN, F("invalid frameId 0x00"));
return; // skip current packet return; // skip current packet
}
if((*frameId & 0x7f) > MAX_PAYLOAD_ENTRIES) { 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 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 return; // CRC8 is wrong, frame invalid
}
if((*frameId & ALL_FRAMES) == ALL_FRAMES) { if((*frameId & ALL_FRAMES) == ALL_FRAMES)
mMaxFrameId = (*frameId & 0x7f); mMaxFrameId = (*frameId & 0x7f);
if(*frameId > 0x81)
lastFound = true;
}
frame_t *f = &mLocalBuf[(*frameId & 0x7f) - 1]; frame_t *f = &mLocalBuf[(*frameId & 0x7f) - 1];
memcpy(f->buf, &p->packet[10], p->len-11); memcpy(f->buf, &p->packet[10], p->len-11);
@ -182,7 +196,7 @@ class Communication : public CommQueue<> {
if(q->attempts == 0) { if(q->attempts == 0) {
DBGPRINTLN(F("-> Fail")); DBGPRINTLN(F("-> Fail"));
q->iv->radioStatistics.rxFail++; // got fragments but not complete response q->iv->radioStatistics.rxFail++; // got fragments but not complete response
pop(); cmdDone();
} else } else
DBGPRINTLN(F("-> complete retransmit")); DBGPRINTLN(F("-> complete retransmit"));
mState = States::RESET; mState = States::RESET;
@ -220,7 +234,7 @@ class Communication : public CommQueue<> {
private: private:
enum class States : uint8_t { enum class States : uint8_t {
RESET, START, WAIT, CHECK_FRAMES, CHECK_PACKAGE RESET, START, WAIT, CHECK_FRAMES, CHECK_PACKAGE, GAP
}; };
typedef struct { typedef struct {
@ -234,7 +248,6 @@ class Communication : public CommQueue<> {
uint32_t *mTimestamp; uint32_t *mTimestamp;
uint32_t mWaitTimeout; uint32_t mWaitTimeout;
std::array<frame_t, MAX_PAYLOAD_ENTRIES> mLocalBuf; std::array<frame_t, MAX_PAYLOAD_ENTRIES> mLocalBuf;
bool lastFound;
uint8_t mMaxFrameId; uint8_t mMaxFrameId;
uint8_t mPayload[150]; uint8_t mPayload[150];
}; };

11
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")); DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring"));
} }
bool loop(void) { void loop(void) {
if (!mIrqRcvd) if (!mIrqRcvd)
return false; // nothing to do return; // nothing to do
mIrqRcvd = false; mIrqRcvd = false;
bool tx_ok, tx_fail, rx_ready; bool tx_ok, tx_fail, rx_ready;
mNrf24.whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH mNrf24.whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH
@ -124,7 +124,7 @@ class HmRadio : public Radio {
if (mIrqRcvd) { if (mIrqRcvd) {
mIrqRcvd = false; mIrqRcvd = false;
if (getReceived()) { // everything received if (getReceived()) { // everything received
return true; return;
} }
} }
yield(); yield();
@ -137,7 +137,7 @@ class HmRadio : public Radio {
yield(); yield();
} }
// not finished but time is over // not finished but time is over
return true; return;
} }
bool isChipConnected(void) { bool isChipConnected(void) {
@ -252,6 +252,7 @@ class HmRadio : public Radio {
p.ch = mRfChLst[mRxChIdx]; p.ch = mRfChLst[mRxChIdx];
p.len = (len > MAX_RF_PAYLOAD_SIZE) ? MAX_RF_PAYLOAD_SIZE : len; p.len = (len > MAX_RF_PAYLOAD_SIZE) ? MAX_RF_PAYLOAD_SIZE : len;
p.rssi = mNrf24.testRPD() ? -64 : -75; p.rssi = mNrf24.testRPD() ? -64 : -75;
p.millis = millis() - mMillis;
mNrf24.read(p.packet, p.len); mNrf24.read(p.packet, p.len);
if (p.packet[0] != 0x00) { if (p.packet[0] != 0x00) {
mBufCtrl.push(p); mBufCtrl.push(p);
@ -288,6 +289,7 @@ class HmRadio : public Radio {
mNrf24.setChannel(mRfChLst[mTxChIdx]); mNrf24.setChannel(mRfChLst[mTxChIdx]);
mNrf24.openWritingPipe(reinterpret_cast<uint8_t*>(&iv->radioId.u64)); mNrf24.openWritingPipe(reinterpret_cast<uint8_t*>(&iv->radioId.u64));
mNrf24.startWrite(mTxBuf, len, false); // false = request ACK response mNrf24.startWrite(mTxBuf, len, false); // false = request ACK response
mMillis = millis();
if(isRetransmit) if(isRetransmit)
iv->radioStatistics.retransmits++; iv->radioStatistics.retransmits++;
@ -303,6 +305,7 @@ class HmRadio : public Radio {
uint8_t mRfChLst[RF_CHANNELS]; uint8_t mRfChLst[RF_CHANNELS];
uint8_t mTxChIdx; uint8_t mTxChIdx;
uint8_t mRxChIdx; uint8_t mRxChIdx;
uint32_t mMillis;
SPIClass* mSpi; SPIClass* mSpi;
RF24 mNrf24; RF24 mNrf24;

6
src/hm/radio.h

@ -23,7 +23,11 @@ class Radio {
public: public:
virtual void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, uint16_t powerMax = 0) = 0; 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 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) { void handleIntr(void) {
mIrqRcvd = true; mIrqRcvd = true;

12
src/hms/hmsRadio.h

@ -29,18 +29,15 @@ class CmtRadio : public Radio {
reset(genDtuSn); reset(genDtuSn);
} }
bool loop() { void loop() {
mCmt.loop(); mCmt.loop();
if((!mIrqRcvd) && (!mRqstGetRx)) if((!mIrqRcvd) && (!mRqstGetRx))
return false; return;
getRx(); getRx();
if(CMT_SUCCESS == mCmt.goRx()) { if(CMT_SUCCESS == mCmt.goRx()) {
mIrqRcvd = false; mIrqRcvd = false;
mRqstGetRx = false; mRqstGetRx = false;
return true; }
} else
return false;
} }
bool isConnected() { bool isConnected() {
@ -90,6 +87,7 @@ class CmtRadio : public Radio {
} }
uint8_t status = mCmt.tx(mTxBuf, len); uint8_t status = mCmt.tx(mTxBuf, len);
mMillis = millis();
if(CMT_SUCCESS != status) { if(CMT_SUCCESS != status) {
DPRINT(DBG_WARN, F("CMT TX failed, code: ")); DPRINT(DBG_WARN, F("CMT TX failed, code: "));
DBGPRINTLN(String(status)); DBGPRINTLN(String(status));
@ -144,6 +142,7 @@ class CmtRadio : public Radio {
inline void getRx(void) { inline void getRx(void) {
packet_t p; packet_t p;
p.millis = millis() - mMillis;
uint8_t status = mCmt.getRx(p.packet, &p.len, 28, &p.rssi); uint8_t status = mCmt.getRx(p.packet, &p.len, 28, &p.rssi);
if(CMT_SUCCESS == status) if(CMT_SUCCESS == status)
mBufCtrl.push(p); mBufCtrl.push(p);
@ -152,6 +151,7 @@ class CmtRadio : public Radio {
CmtType mCmt; CmtType mCmt;
bool mRqstGetRx; bool mRqstGetRx;
bool mCmtAvail; bool mCmtAvail;
uint32_t mMillis;
}; };
#endif /*__HMS_RADIO_H__*/ #endif /*__HMS_RADIO_H__*/

Loading…
Cancel
Save