Browse Source

different tx-offests for 4ch HM

* discord 0.8.6803
* tx+3 for 4ch-HM, tx+2 for other Inverters
pull/1394/head
rejoe2 12 months ago
committed by GitHub
parent
commit
bba82d8b3a
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      src/hm/CommQueue.h
  2. 9
      src/hm/Communication.h
  3. 15
      src/hm/HeuristicInv.h
  4. 21
      src/hm/hmInverter.h
  5. 43
      src/hm/hmRadio.h
  6. 7
      src/hm/hmSystem.h
  7. 6
      src/hms/cmt2300a.h

2
src/hm/CommQueue.h

@ -12,7 +12,7 @@
#include "../utils/dbg.h"
#define DEFAULT_ATTEMPS 5
#define MORE_ATTEMPS_ALARMDATA 0 // 8
#define MORE_ATTEMPS_ALARMDATA 3 // 8
#define MORE_ATTEMPS_GRIDONPROFILEPARA 0 // 5
template <uint8_t N=100>

9
src/hm/Communication.h

@ -140,7 +140,10 @@ class Communication : public CommQueue<> {
if(!q->iv->mGotFragment) {
if(INV_RADIO_TYPE_CMT == q->iv->ivRadioType) {
#if defined(ESP32)
q->iv->radio->switchFrequency(q->iv, q->iv->radio->getBootFreqMhz() * 1000, (q->iv->config->frequency*FREQ_STEP_KHZ + q->iv->radio->getBaseFreqMhz() * 1000));
if(!q->iv->radio->switchFrequency(q->iv, q->iv->radio->getBootFreqMhz() * 1000, (q->iv->config->frequency*FREQ_STEP_KHZ + q->iv->radio->getBaseFreqMhz() * 1000))) {
DPRINT_IVID(DBG_INFO, q->iv->id);
DBGPRINTLN(F("switch frequency failed!"));
}
mWaitTime.startTimeMonitor(1000);
#endif
} else {
@ -418,8 +421,8 @@ class Communication : public CommQueue<> {
if((*frameId & ALL_FRAMES) == ALL_FRAMES) {
mMaxFrameId = (*frameId & 0x7f);
/*if(mMaxFrameId > 8) // large payloads, e.g. AlarmData
incrAttempt(mMaxFrameId - 6);*/
if(mMaxFrameId > 8) // large payloads, e.g. AlarmData
incrAttempt(mMaxFrameId - 6);
}
frame_t *f = &mLocalBuf[(*frameId & 0x7f) - 1];

15
src/hm/HeuristicInv.h

@ -14,7 +14,22 @@
class HeuristicInv {
public:
HeuristicInv() {
clear();
}
void clear() {
memset(txRfQuality, 0, RF_MAX_CHANNEL_ID);
txRfChId = 0;
lastBestTxChId = 0;
testPeriodSendCnt = 0;
testPeriodFailCnt = 0;
testChId = 0;
saveOldTestQuality = -6;
lastRxFragments = 0;
}
bool isTxAtMax(void) const {
return (RF_MAX_QUALITY == txRfQuality[txRfChId]);
}
public:

21
src/hm/hmInverter.h

@ -193,6 +193,14 @@ class Inverter {
if(mNextLive)
cb(RealTimeRunData_Debug, false); // get live data
else {
if(INV_RADIO_TYPE_NRF == ivRadioType) {
// get live data until quality reaches maximum
if(!heuristics.isTxAtMax()) {
cb(RealTimeRunData_Debug, false); // get live data
return;
}
}
if(actPowerLimit == 0xffff) {
cb(SystemConfigPara, false); // power limit info
cb(RealTimeRunData_Debug, false);
@ -201,17 +209,18 @@ class Inverter {
devControlCmd = InitDataState;
mGetLossInterval = 1;
} else if(0 == getFwVersion()) {
cb(RealTimeRunData_Debug, false); // get live data
cb(InverterDevInform_All, false); // get firmware version
cb(RealTimeRunData_Debug, false); // get live data
}
else if(0 == getHwVersion()) {
cb(RealTimeRunData_Debug, false); // get live data
cb(InverterDevInform_Simple, false); // get hardware version
} else if((alarmLastId != alarmMesIndex) && (alarmMesIndex != 0)) {
cb(RealTimeRunData_Debug, false); // get live data
} else if((alarmLastId != alarmMesIndex) && (alarmMesIndex != 0)) {
cb(AlarmData, false); // get last alarms
cb(RealTimeRunData_Debug, false); // get live data
} else if((0 == mGridLen) && generalConfig->readGrid) { // read grid profile
cb(GridOnProFilePara, false);
cb(RealTimeRunData_Debug, false); // get live data
} else if (mGetLossInterval > AHOY_GET_LOSS_INTERVAL) { // get loss rate
mGetLossInterval = 1;
cb(RealTimeRunData_Debug, false); // get live data
@ -455,6 +464,12 @@ class Inverter {
status = InverterStatus::OFF;
actPowerLimit = 0xffff; // power limit will be read once inverter becomes available
alarmMesIndex = 0;
if(ivRadioType == INV_RADIO_TYPE_NRF) {
heuristics.clear();
#ifdef DYNAMIC_OFFSET
rxOffset = ivGen == IV_HM ? 13 : 12; // effective 3 (or 2), but can easily be recognized as default setting
#endif
}
}
else
status = InverterStatus::WAS_ON;

43
src/hm/hmRadio.h

@ -121,14 +121,14 @@ class HmRadio : public Radio {
if(!mNRFloopChannels && ((mTimeslotStart - mLastIrqTime) > (DURATION_TXFRAME))) //(DURATION_TXFRAME+DURATION_ONEFRAME)))
mNRFloopChannels = true;
rxPendular = !rxPendular;
mRxPendular = !mRxPendular;
//innerLoopTimeout = (rxPendular ? 1 : 2)*DURATION_LISTEN_MIN;
//innerLoopTimeout = DURATION_LISTEN_MIN;
innerLoopTimeout = DURATION_LISTEN_MIN;
if(mNRFloopChannels)
tempRxChIdx = (tempRxChIdx + 4) % RF_CHANNELS;
else
tempRxChIdx = (mRxChIdx + rxPendular*4) % RF_CHANNELS;
tempRxChIdx = (mRxChIdx + mRxPendular*4) % RF_CHANNELS;
mNrf24->setChannel(mRfChLst[tempRxChIdx]);
isRxInit = false;
@ -142,7 +142,7 @@ class HmRadio : public Radio {
if(tx_ok || tx_fail) { // tx related interrupt, basically we should start listening
mNrf24->flush_tx(); // empty TX FIFO
mTxSetupTime = millis() - mMillis;
//mTxSetupTime = millis() - mMillis;
if(mNRFisInRX) {
DPRINTLN(DBG_WARN, F("unexpected tx irq!"));
@ -153,17 +153,21 @@ class HmRadio : public Radio {
if(tx_ok)
mLastIv->mAckCount++;
//mRxChIdx = (mTxChIdx + 2) % RF_CHANNELS;
//#ifdef DYNAMIC_OFFSET
mRxChIdx = (mTxChIdx + mLastIv->rxOffset) % RF_CHANNELS;
/*#else
mRxChIdx = (mTxChIdx + 2) % RF_CHANNELS;
#endif*/
mNrf24->setChannel(mRfChLst[mRxChIdx]);
mNrf24->startListening();
mTimeslotStart = millis();
tempRxChIdx = mRxChIdx; // might be better to start off with one channel less?
rxPendular = false;
mRxPendular = false;
mNRFloopChannels = (mLastIv->ivGen == IV_MI);
//innerLoopTimeout = mLastIv->ivGen != IV_MI ? DURATION_TXFRAME : DURATION_ONEFRAME;
innerLoopTimeout = mLastIv->ivGen != IV_MI ? DURATION_LISTEN_MIN : 4;
//innerLoopTimeout = mLastIv->ivGen != IV_MI ? DURATION_LISTEN_MIN : 4;
innerLoopTimeout = (mLastIv->mIsSingleframeReq || mLastIv->ivGen == IV_MI) ? DURATION_LISTEN_MIN : DURATION_TXFRAME;
}
if(rx_ready) {
@ -176,7 +180,7 @@ class HmRadio : public Radio {
innerLoopTimeout = DURATION_LISTEN_MIN;
mTimeslotStart = millis();
if (!mNRFloopChannels) {
//rxPendular = true; // stay longer on the next rx channel
//mRxPendular = true; // stay longer on the next rx channel
if (isRxInit) {
isRxInit = false;
tempRxChIdx = (mRxChIdx + 4) % RF_CHANNELS;
@ -325,12 +329,14 @@ class HmRadio : public Radio {
isRetransmitAnswer = true;
if(isLastPackage)
setExpectedFrames(p.packet[9] - ALL_FRAMES);
#ifdef DYNAMIC_OFFSET
if(p.packet[9] == 1 && p.millis < DURATION_ONEFRAME)
mLastIv->rxOffset = (RF_CHANNELS + mTxChIdx - tempRxChIdx + 1) % RF_CHANNELS;
else if(mNRFloopChannels && mLastIv->rxOffset > RF_CHANNELS) { // unsure setting?
mLastIv->rxOffset = (RF_CHANNELS + mTxChIdx - tempRxChIdx + (isLastPackage ? mFramesExpected : p.packet[9])); // make clear it's not sure, start with one more offset
mNRFloopChannels = false;
}
#endif
}
if(IV_MI == mLastIv->ivGen) {
@ -338,8 +344,10 @@ class HmRadio : public Radio {
isLastPackage = (p.packet[9] > 0x10); // > 0x10 indicates last packet received
else if ((p.packet[0] != 0x88) && (p.packet[0] != 0x92)) // ignore MI status messages //#0 was p.packet[0] != 0x00 &&
isLastPackage = true; // response from dev control command
#ifdef DYNAMIC_OFFSET
if(p.packet[9] == 0x00 && p.millis < DURATION_ONEFRAME)
mLastIv->rxOffset = (RF_CHANNELS + mTxChIdx - tempRxChIdx - 1) % RF_CHANNELS;
#endif
}
rx_ready = true; //reset in case we first read messages from other inverter or ACK zero payloads
}
@ -347,9 +355,8 @@ class HmRadio : public Radio {
}
yield();
}
if(isLastPackage) {
if(isLastPackage)
mLastIv->mGotLastMsg = true;
}
return isLastPackage || isRetransmitAnswer;
}
@ -361,10 +368,7 @@ class HmRadio : public Radio {
mTxChIdx = iv->heuristics.txRfChId;
if(*mSerialDebug) {
/* remark rejoe2: imo this has no added value here.
As this belongs to the last tx cycle, we should print that info
directly when switching from tx to rx. Otherwise we might confuse users.
if(!isRetransmit) {
/*if(!isRetransmit) {
DPRINT(DBG_INFO, "last tx setup: ");
DBGPRINT(String(mTxSetupTime));
DBGPRINTLN("ms");
@ -374,13 +378,19 @@ class HmRadio : public Radio {
DBGPRINT(F("TX "));
DBGPRINT(String(len));
DBGPRINT(" CH");
if(mTxChIdx == 0)
DBGPRINT("0");
DBGPRINT(String(mRfChLst[mTxChIdx]));
DBGPRINT(F(", "));
DBGPRINT(String(mTxRetriesNext));
//DBGPRINT(F(" retries | "));
//#ifdef DYNAMIC_OFFSET
DBGPRINT(F(" ret., rx offset: "));
DBGPRINT(String(iv->rxOffset));
DBGPRINT(F(" | "));
/*#else
DBGPRINT(F(" ret. | "));
#endif*/
if(*mPrintWholeTrace) {
if(*mPrivacyMode)
ah::dumpBuf(mTxBuf, len, 1, 4);
@ -396,6 +406,7 @@ class HmRadio : public Radio {
}
mNrf24->stopListening();
mNrf24->flush_rx();
if(!isRetransmit && mTxRetries != mTxRetriesNext) {
mNrf24->setRetries(3, mTxRetriesNext);
mTxRetries = mTxRetriesNext;
@ -439,9 +450,9 @@ class HmRadio : public Radio {
bool mNRFloopChannels = false;
bool mNRFisInRX = false;
bool isRxInit = true;
bool rxPendular = false;
bool mRxPendular = false;
uint32_t innerLoopTimeout = DURATION_LISTEN_MIN;
uint8_t mTxSetupTime = 0;
//uint8_t mTxSetupTime = 0;
uint8_t mTxRetries = 15; // memorize last setting for mNrf24->setRetries(3, 15);
std::unique_ptr<SPIClass> mSpi;

7
src/hm/hmSystem.h

@ -28,7 +28,6 @@ class HmSystem {
iv->config = &mInverter[0].generalConfig->iv[id];
DPRINT(DBG_VERBOSE, "SERIAL: " + String(iv->config->serial.b[5], HEX));
DPRINTLN(DBG_VERBOSE, " " + String(iv->config->serial.b[4], HEX));
iv->rxOffset = 13; // effective 3, but can easily be recognized as default setting
if((iv->config->serial.b[5] == 0x11) || (iv->config->serial.b[5] == 0x10)) {
switch(iv->config->serial.b[4]) {
case 0x24: // HMS-500
@ -96,6 +95,12 @@ class HmSystem {
if((iv->config->serial.b[5] == 0x10) && ((iv->config->serial.b[4] & 0x03) == 0x01))
DPRINTLN(DBG_WARN, F("MI Inverter, has some restrictions!"));
#ifdef DYNAMIC_OFFSET
iv->rxOffset = iv->ivGen == IV_HM ? 13 : 12; // effective 3 (or 2), but can easily be recognized as default setting
#else
iv->rxOffset = (iv->ivGen == IV_HM && iv->type == INV_TYPE_4CH) ? 3 : 2; // effective 3 (or 2), but can easily be recognized as default setting
#endif
cb(iv);
}

6
src/hms/cmt2300a.h

@ -356,11 +356,11 @@ class Cmt2300a {
if((freqKhz % FREQ_STEP_KHZ) != 0)
return 0xff; // error
std::pair<uint8_t, uint8_t> range = getFreqRangeMhz();
if((freqKhz < range.first) || (freqKhz > range.second))
std::pair<uint16_t, uint16_t> range = getFreqRangeMhz();
if((freqKhz < (range.first * 1000)) || (freqKhz > (range.second * 1000)))
return 0xff; // error
return (freqKhz - getBaseFreqMhz() * 1000) / FREQ_STEP_KHZ;
return (freqKhz - (getBaseFreqMhz() * 1000)) / FREQ_STEP_KHZ;
}
inline void switchChannel(uint8_t ch) {

Loading…
Cancel
Save