mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-14 17:36:38 +02:00
added millis to each packet for radio analysis
fixed several issue regarding communication
This commit is contained in:
parent
c7f3f21469
commit
b34e5a7416
8 changed files with 90 additions and 57 deletions
27
src/app.cpp
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();*/
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
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; // radio buffer empty
|
||||
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,9 +76,7 @@ class Communication : public CommQueue<> {
|
|||
DBGPRINT(F("dBm | "));
|
||||
ah::dumpBuf(p->packet, p->len);
|
||||
|
||||
if(!checkIvSerial(&p->packet[1], q->iv))
|
||||
continue; // inverter ID incorrect
|
||||
|
||||
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
|
||||
|
@ -77,19 +84,25 @@ class Communication : public CommQueue<> {
|
|||
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,22 +152,23 @@ 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) {
|
||||
mMaxFrameId = (*frameId & 0x7f);
|
||||
if(*frameId > 0x81)
|
||||
lastFound = true;
|
||||
}
|
||||
|
||||
if((*frameId & ALL_FRAMES) == ALL_FRAMES)
|
||||
mMaxFrameId = (*frameId & 0x7f);
|
||||
|
||||
frame_t *f = &mLocalBuf[(*frameId & 0x7f) - 1];
|
||||
memcpy(f->buf, &p->packet[10], p->len-11);
|
||||
f->len = 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];
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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…
Add table
Add a link
Reference in a new issue