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))
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();*/
}
//-----------------------------------------------------------------------------

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 (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)

2
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 {

2
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

79
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<frame_t, MAX_PAYLOAD_ENTRIES> mLocalBuf;
bool lastFound;
uint8_t mMaxFrameId;
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"));
}
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<uint8_t*>(&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;

6
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;

12
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__*/

Loading…
Cancel
Save