Browse Source

cycl. GetPacketLoss, bugfx alarm, rx wait optim.

pull/1080/head
no name 2 years ago
parent
commit
b22e4ff2d2
  1. 2
      src/hm/hmDefines.h
  2. 36
      src/hm/hmInverter.h
  3. 16
      src/hm/hmPayload.h
  4. 29
      src/hm/hmRadio.h

2
src/hm/hmDefines.h

@ -119,6 +119,8 @@ const byteAssign_t AlarmDataAssignment[] = {
#define HMALARMDATA_PAYLOAD_LEN 0 // 0: means check is off
#define ALARM_LOG_ENTRY_SIZE 12
#define HMGETLOSSRATE_PAYLOAD_LEN 4
//-------------------------------------
// HM300, HM350, HM400

36
src/hm/hmInverter.h

@ -31,6 +31,8 @@
// mark current test chan as 1st use during this test period
#define RF_TX_TEST_CHAN_1ST_USE 0xff
#define AHOY_GET_LOSS_INTERVAL 10
/**
* For values which are of interest and not transmitted by the inverter can be
* calculated automatically.
@ -146,6 +148,10 @@ class Inverter {
bool isConnected; // shows if inverter was successfully identified (fw version and hardware info)
uint32_t pac_sum; // average calc for chart: sum of ac power values for cur interval
uint16_t pac_cnt; // average calc for chart: number of ac power values for cur interval
uint16_t mIvRxCnt; // last iv rx frames (from GetLossRate)
uint16_t mIvTxCnt; // last iv tx frames (from GetLossRate)
uint16_t mDtuRxCnt; // cur dtu rx frames (since last GetLossRate)
uint16_t mDtuTxCnt; // cur dtu tx frames (since last getLoassRate)
uint16_t alarmCode; // last Alarm
uint32_t alarmStart;
uint32_t alarmEnd;
@ -157,6 +163,7 @@ class Inverter {
uint8_t mTestPeriodSendCnt; // increment of current test period
uint8_t mTestPeriodFailCnt; // no of fails during current test period
uint8_t mSaveOldTestChanQuality; // original quality of current TestTxChanIndex
uint8_t mGetLossInterval; // request iv every AHOY_GET_LOSS_INTERVAL RealTimeRunData_Debug
Inverter() {
ivGen = IV_HM;
@ -210,6 +217,12 @@ class Inverter {
} else if (alarmDataReqPending) {
enqueCommand<InfoCommand>(AlarmData); // alarm not answered
} else {
if ((mIvRxCnt || mIvTxCnt) && (mGetLossInterval < AHOY_GET_LOSS_INTERVAL)) { // initially mIvRxCnt = mIvTxCnt = 0
mGetLossInterval++;
} else {
mGetLossInterval = 1; // 1: RealTimeRunData_Debug will always be enqueued
enqueCommand<InfoCommand>(GetLossRate);
}
enqueCommand<InfoCommand>(RealTimeRunData_Debug); // live data
}
} else if (ivGen == IV_MI){
@ -533,7 +546,7 @@ class Inverter {
uint16_t parseAlarmLog(uint8_t id, uint8_t pyld[], uint8_t len, uint32_t *start, uint32_t *endTime) {
uint8_t startOff = 2 + id * ALARM_LOG_ENTRY_SIZE;
if (alarmDataReqPending) {
if (!id && alarmDataReqPending) { // evaluate if 1st of seq only
alarmDataReqPending--;
}
if((startOff + ALARM_LOG_ENTRY_SIZE) > len)
@ -558,6 +571,27 @@ class Inverter {
return alarmCode;
}
bool parseGetLossRate(uint8_t pyld[], uint8_t len) {
if (len == HMGETLOSSRATE_PAYLOAD_LEN) {
uint16_t rxCnt = (pyld[0] << 8) + pyld[1];
uint16_t txCnt = (pyld[2] << 8) + pyld[3];
if (mIvRxCnt || mIvTxCnt) { // there was successful GetLossRate in the past
DPRINT_IVID(DBG_INFO, id);
DBGPRINTLN("Inv loss: " + String (mDtuTxCnt - (rxCnt - mIvRxCnt)) + " of " +
String (mDtuTxCnt) + ", DTU loss: " +
String (txCnt - mIvTxCnt - mDtuRxCnt) + " of " +
String (txCnt - mIvTxCnt));
}
mIvRxCnt = rxCnt;
mIvTxCnt = txCnt;
mDtuRxCnt = 0; // start new interval
mDtuTxCnt = 0; // start new interval
return true;
}
return false;
}
String getAlarmStr(uint16_t alarmCode) {
switch (alarmCode) { // breaks are intentionally missing!
case 1: return String(F("Inverter start"));

16
src/hm/hmPayload.h

@ -157,6 +157,7 @@ class HmPayload {
DBGPRINT(F(" power limit "));
DBGPRINTLN(String(iv->powerLimit[0]));
}
iv->mDtuTxCnt++;
mSys->Radio.sendControlPacket(iv->radioId.u64, iv->getType(),
iv->getNextTxChanIndex(), iv->devControlCmd, iv->powerLimit, false);
mPayload[iv->id].txCmd = iv->devControlCmd;
@ -167,6 +168,7 @@ class HmPayload {
DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(cmd);
iv->mDtuTxCnt++;
mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getType(),
iv->getNextTxChanIndex(), cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false);
mPayload[iv->id].txCmd = cmd;
@ -174,6 +176,7 @@ class HmPayload {
}
void add(Inverter<> *iv, packet_t *p) {
iv->mDtuRxCnt++;
if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
mPayload[iv->id].txId = p->packet[0];
DPRINTLN(DBG_DEBUG, F("Response from info request received"));
@ -272,6 +275,7 @@ class HmPayload {
} else if(iv->devControlCmd == ActivePowerContr) {
DPRINT_IVID(DBG_INFO, iv->id);
DPRINTLN(DBG_INFO, F("retransmit power limit"));
iv->mDtuTxCnt++;
mSys->Radio.sendControlPacket(iv->radioId.u64, iv->getType(),
iv->getNextTxChanIndex(), iv->devControlCmd, iv->powerLimit, true);
} else {
@ -285,6 +289,7 @@ class HmPayload {
mPayload[iv->id].txCmd = iv->getQueuedCmd();
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX));
iv->mDtuTxCnt++;
mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getType(),
iv->getNextTxChanIndex(), mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true);
}
@ -295,6 +300,7 @@ class HmPayload {
DBGPRINT(F("Frame "));
DBGPRINT(String(i + 1));
DBGPRINTLN(F(" missing: Request Retransmit"));
iv->mDtuTxCnt++;
mSys->Radio.sendCmdPacket(iv->radioId.u64, iv->getType(),
iv->getNextTxChanIndex (), TX_REQ_INFO, (SINGLE_FRAME + i), true);
break; // only request retransmit one frame per loop
@ -316,6 +322,7 @@ class HmPayload {
DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(mPayload[iv->id].txCmd);
iv->mDtuTxCnt++;
mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getType(),
iv->getNextTxChanIndex (), mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true);
} else if (false == mPayload[iv->id].gotFragment) {
@ -358,7 +365,16 @@ class HmPayload {
#endif
if (NULL == rec) {
if(GetLossRate == mPayload[iv->id].txCmd) {
if ((mPayload[iv->id].txId == (TX_REQ_INFO + ALL_FRAMES)) &&
iv->parseGetLossRate (payload, payloadLen)) {
mStat->rxSuccess++;
} else {
mStat->rxFail++;
}
} else {
DPRINTLN(DBG_ERROR, F("record is NULL!"));
}
} else if ((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) {
if (mPayload[iv->id].txId == (TX_REQ_INFO + ALL_FRAMES))
mStat->rxSuccess++;

29
src/hm/hmRadio.h

@ -12,6 +12,8 @@
#include "../config/config.h"
#include "SPI.h"
// #define AHOY_RADIO_TX_PENDING_LOOP
#define SPI_SPEED 1000000
#define TX_REQ_INFO 0x15
@ -21,7 +23,7 @@
#define RX_ANSWER_TMO 400
#define RX_WAIT_SFR_TMO 40
#define RX_WAIT_SAFETY_MRGN 20
#define RX_WAIT_SAFETY_MRGN 10
#define RX_CHAN_TMO 5110
#define RX_CHAN_MHCH1_TMO 10220
@ -165,8 +167,18 @@ class HmRadio {
}
bool loop(void) {
#ifdef AHOY_RADIO_TX_PENDING_LOOP
if (!mTxPending) {
return false;
}
mTxPending = false;
while (!mIrqRcvd) {
yield();
}
#else
if (!mIrqRcvd)
return false; // nothing to do
#endif
mIrqRcvd = false;
bool tx_ok, tx_fail, rx_ready;
mNrf24.whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH
@ -183,7 +195,6 @@ class HmRadio {
if (mIrqRcvd) {
mIrqRcvd = false;
if (getReceived()) { // everything received
return true;
}
}
@ -259,8 +270,9 @@ class HmRadio {
DPRINTLN(DBG_DEBUG,String(cmd, HEX));
}
prepareReceive (invType, txChan,
// could be optimized for other inverter types as well
((cmd == RealTimeRunData_Debug) && (invType == INV_TYPE_HMCH1)) ? 2 : 10);
// could be optimized for other HM inverter types as well
((cmd == RealTimeRunData_Debug) && (invType == INV_TYPE_HMCH1)) ? 2 :
((invType == INV_TYPE_HMCH1) && ((cmd == InverterDevInform_All) || (cmd == SystemConfigPara) || (GetLossRate))) ? 1 : 10);
initPacket(invId, reqfld, ALL_FRAMES);
mTxBuf[10] = cmd; // cid
mTxBuf[11] = 0x00;
@ -314,8 +326,7 @@ class HmRadio {
if (invType == INV_TYPE_HMCH1) {
mRxChannels = (uint8_t *)(rf24RxHMCh1[txChan]);
mMaxRxChannels = RX_HMCH1_MAX_CHANNELS;
mRxAnswerTmo = rxFrameCnt * RX_WAIT_SFR_TMO; // typical inverter answer has 2 packets
mRxAnswerTmo += RX_WAIT_SAFETY_MRGN;
mRxAnswerTmo = rxFrameCnt * (RX_WAIT_SFR_TMO + RX_WAIT_SAFETY_MRGN); // current formula for hm inverters
if (mRxAnswerTmo > RX_ANSWER_TMO) {
mRxAnswerTmo = RX_ANSWER_TMO;
}
@ -409,6 +420,9 @@ class HmRadio {
mNrf24.stopListening();
mNrf24.setChannel(rf24ChLst[mTxChIdx]);
mNrf24.openWritingPipe(reinterpret_cast<uint8_t*>(&invId));
#ifdef AHOY_RADIO_TX_PENDING_LOOP
mTxPending = true;
#endif
mNrf24.startWrite(mTxBuf, len, false); // false = request ACK response
if(isRetransmit)
@ -429,6 +443,9 @@ class HmRadio {
uint8_t mMaxRxChannels; // actual size of mRxChannels; depends on inverter and previous tx channel
uint32_t mRxAnswerTmo; // max wait time in millis for answers of inverter
uint32_t mRxChanTmo; // max wait time in micros for a rx channel
#ifdef AHOY_RADIO_TX_PENDING_LOOP
bool mTxPending; // send has been started: wait in loop to setup receive without break
#endif
};
#endif /*__RADIO_H__*/

Loading…
Cancel
Save