mirror of
https://github.com/lumapu/ahoy.git
synced 2025-07-17 08:17:12 +02:00
0.8.68
* fix HMS / HMT startup * added `flush_rx` to NRF on TX * start with heuristics set to `0` * added warning for WiFi channel 12-14 (ESP8266 only) #1381
This commit is contained in:
parent
6b305651af
commit
163a9e485e
13 changed files with 78 additions and 19 deletions
|
@ -1,5 +1,11 @@
|
||||||
# Development Changes
|
# Development Changes
|
||||||
|
|
||||||
|
## 0.8.68 - 2024-01-29
|
||||||
|
* fix HMS / HMT startup
|
||||||
|
* added `flush_rx` to NRF on TX
|
||||||
|
* start with heuristics set to `0`
|
||||||
|
* added warning for WiFi channel 12-14 (ESP8266 only) #1381
|
||||||
|
|
||||||
## 0.8.67 - 2024-01-29
|
## 0.8.67 - 2024-01-29
|
||||||
* fix HMS frequency
|
* fix HMS frequency
|
||||||
* fix display of inverter id in serial log (was displayed twice)
|
* fix display of inverter id in serial log (was displayed twice)
|
||||||
|
|
|
@ -182,6 +182,10 @@ class app : public IApp, public ah::Scheduler {
|
||||||
return mWifi.getStationIp();
|
return mWifi.getStationIp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool getWasInCh12to14(void) const {
|
||||||
|
return mWifi.getWasInCh12to14();
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !defined(ETHERNET) */
|
#endif /* !defined(ETHERNET) */
|
||||||
|
|
||||||
void setRebootFlag() {
|
void setRebootFlag() {
|
||||||
|
|
|
@ -35,6 +35,7 @@ class IApp {
|
||||||
virtual void setupStation(void) = 0;
|
virtual void setupStation(void) = 0;
|
||||||
virtual void setStopApAllowedMode(bool allowed) = 0;
|
virtual void setStopApAllowedMode(bool allowed) = 0;
|
||||||
virtual String getStationIp(void) = 0;
|
virtual String getStationIp(void) = 0;
|
||||||
|
virtual bool getWasInCh12to14(void) const = 0;
|
||||||
#endif /* defined(ETHERNET) */
|
#endif /* defined(ETHERNET) */
|
||||||
|
|
||||||
virtual uint32_t getUptime() = 0;
|
virtual uint32_t getUptime() = 0;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 8
|
#define VERSION_MINOR 8
|
||||||
#define VERSION_PATCH 67
|
#define VERSION_PATCH 68
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -139,7 +139,10 @@ class Communication : public CommQueue<> {
|
||||||
if(!q->iv->mGotFragment) {
|
if(!q->iv->mGotFragment) {
|
||||||
if(INV_RADIO_TYPE_CMT == q->iv->ivRadioType) {
|
if(INV_RADIO_TYPE_CMT == q->iv->ivRadioType) {
|
||||||
#if defined(ESP32)
|
#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);
|
mWaitTime.startTimeMonitor(1000);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// 2023 Ahoy, https://github.com/lumpapu/ahoy
|
// 2024 Ahoy, https://github.com/lumpapu/ahoy
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -14,7 +14,22 @@
|
||||||
class HeuristicInv {
|
class HeuristicInv {
|
||||||
public:
|
public:
|
||||||
HeuristicInv() {
|
HeuristicInv() {
|
||||||
memset(txRfQuality, -6, RF_MAX_CHANNEL_ID);
|
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:
|
public:
|
||||||
|
|
|
@ -192,6 +192,14 @@ class Inverter {
|
||||||
if(mNextLive)
|
if(mNextLive)
|
||||||
cb(RealTimeRunData_Debug, false); // get live data
|
cb(RealTimeRunData_Debug, false); // get live data
|
||||||
else {
|
else {
|
||||||
|
if(INV_RADIO_TYPE_NRF == ivRadioType) {
|
||||||
|
// get live data until quility reaches maximum
|
||||||
|
if(!heuristics.isTxAtMax()) {
|
||||||
|
cb(RealTimeRunData_Debug, false); // get live data
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(actPowerLimit == 0xffff)
|
if(actPowerLimit == 0xffff)
|
||||||
cb(SystemConfigPara, false); // power limit info
|
cb(SystemConfigPara, false); // power limit info
|
||||||
else if(InitDataState != devControlCmd) {
|
else if(InitDataState != devControlCmd) {
|
||||||
|
@ -449,6 +457,7 @@ class Inverter {
|
||||||
status = InverterStatus::OFF;
|
status = InverterStatus::OFF;
|
||||||
actPowerLimit = 0xffff; // power limit will be read once inverter becomes available
|
actPowerLimit = 0xffff; // power limit will be read once inverter becomes available
|
||||||
alarmMesIndex = 0;
|
alarmMesIndex = 0;
|
||||||
|
heuristics.clear();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
status = InverterStatus::WAS_ON;
|
status = InverterStatus::WAS_ON;
|
||||||
|
|
|
@ -77,7 +77,7 @@ class HmRadio : public Radio {
|
||||||
#else
|
#else
|
||||||
mNrf24->begin(mSpi.get(), ce, cs);
|
mNrf24->begin(mSpi.get(), ce, cs);
|
||||||
#endif
|
#endif
|
||||||
mNrf24->setRetries(3, 15); // wait 3*250 = 750us, 16 * 250us -> 4000us = 4ms
|
mNrf24->setRetries(3, 9); // wait 3*250 = 750us, 16 * 250us -> 4000us = 4ms
|
||||||
|
|
||||||
mNrf24->setDataRate(RF24_250KBPS);
|
mNrf24->setDataRate(RF24_250KBPS);
|
||||||
//mNrf24->setAutoAck(true); // enabled by default
|
//mNrf24->setAutoAck(true); // enabled by default
|
||||||
|
@ -120,14 +120,14 @@ class HmRadio : public Radio {
|
||||||
if(!mNRFloopChannels && ((mTimeslotStart - mLastIrqTime) > (DURATION_TXFRAME+DURATION_ONEFRAME)))
|
if(!mNRFloopChannels && ((mTimeslotStart - mLastIrqTime) > (DURATION_TXFRAME+DURATION_ONEFRAME)))
|
||||||
mNRFloopChannels = true;
|
mNRFloopChannels = true;
|
||||||
|
|
||||||
rxPendular = !rxPendular;
|
mRxPendular = !mRxPendular;
|
||||||
//innerLoopTimeout = (rxPendular ? 1 : 2)*DURATION_LISTEN_MIN;
|
//innerLoopTimeout = (mRxPendular ? 1 : 2)*DURATION_LISTEN_MIN;
|
||||||
innerLoopTimeout = DURATION_LISTEN_MIN;
|
innerLoopTimeout = DURATION_LISTEN_MIN;
|
||||||
|
|
||||||
if(mNRFloopChannels)
|
if(mNRFloopChannels)
|
||||||
tempRxChIdx = (tempRxChIdx + 4) % RF_CHANNELS;
|
tempRxChIdx = (tempRxChIdx + 4) % RF_CHANNELS;
|
||||||
else
|
else
|
||||||
tempRxChIdx = (mRxChIdx + rxPendular*4) % RF_CHANNELS;
|
tempRxChIdx = (mRxChIdx + mRxPendular*4) % RF_CHANNELS;
|
||||||
|
|
||||||
mNrf24->setChannel(mRfChLst[tempRxChIdx]);
|
mNrf24->setChannel(mRfChLst[tempRxChIdx]);
|
||||||
isRxInit = false;
|
isRxInit = false;
|
||||||
|
@ -141,7 +141,7 @@ class HmRadio : public Radio {
|
||||||
|
|
||||||
if(tx_ok || tx_fail) { // tx related interrupt, basically we should start listening
|
if(tx_ok || tx_fail) { // tx related interrupt, basically we should start listening
|
||||||
mNrf24->flush_tx(); // empty TX FIFO
|
mNrf24->flush_tx(); // empty TX FIFO
|
||||||
mTxSetupTime = millis() - mMillis;
|
//mTxSetupTime = millis() - mMillis;
|
||||||
|
|
||||||
if(mNRFisInRX) {
|
if(mNRFisInRX) {
|
||||||
DPRINTLN(DBG_WARN, F("unexpected tx irq!"));
|
DPRINTLN(DBG_WARN, F("unexpected tx irq!"));
|
||||||
|
@ -157,7 +157,7 @@ class HmRadio : public Radio {
|
||||||
mNrf24->startListening();
|
mNrf24->startListening();
|
||||||
mTimeslotStart = millis();
|
mTimeslotStart = millis();
|
||||||
tempRxChIdx = mRxChIdx;
|
tempRxChIdx = mRxChIdx;
|
||||||
rxPendular = false;
|
mRxPendular = false;
|
||||||
mNRFloopChannels = (mLastIv->ivGen == IV_MI);
|
mNRFloopChannels = (mLastIv->ivGen == IV_MI);
|
||||||
|
|
||||||
innerLoopTimeout = DURATION_TXFRAME;
|
innerLoopTimeout = DURATION_TXFRAME;
|
||||||
|
@ -168,11 +168,12 @@ class HmRadio : public Radio {
|
||||||
mNRFisInRX = false;
|
mNRFisInRX = false;
|
||||||
mRadioWaitTime.startTimeMonitor(DURATION_PAUSE_LASTFR); // let the inverter first end his transmissions
|
mRadioWaitTime.startTimeMonitor(DURATION_PAUSE_LASTFR); // let the inverter first end his transmissions
|
||||||
mNrf24->stopListening();
|
mNrf24->stopListening();
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
innerLoopTimeout = DURATION_LISTEN_MIN;
|
innerLoopTimeout = DURATION_LISTEN_MIN;
|
||||||
mTimeslotStart = millis();
|
mTimeslotStart = millis();
|
||||||
if (!mNRFloopChannels) {
|
if (!mNRFloopChannels) {
|
||||||
//rxPendular = true; // stay longer on the next rx channel
|
//mRxPendular = true; // stay longer on the next rx channel
|
||||||
if (isRxInit) {
|
if (isRxInit) {
|
||||||
isRxInit = false;
|
isRxInit = false;
|
||||||
tempRxChIdx = (mRxChIdx + 4) % RF_CHANNELS;
|
tempRxChIdx = (mRxChIdx + 4) % RF_CHANNELS;
|
||||||
|
@ -180,8 +181,8 @@ class HmRadio : public Radio {
|
||||||
} else
|
} else
|
||||||
mRxChIdx = tempRxChIdx;
|
mRxChIdx = tempRxChIdx;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return mNRFisInRX;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,11 +342,11 @@ class HmRadio : public Radio {
|
||||||
mTxChIdx = iv->heuristics.txRfChId;
|
mTxChIdx = iv->heuristics.txRfChId;
|
||||||
|
|
||||||
if(*mSerialDebug) {
|
if(*mSerialDebug) {
|
||||||
if(!isRetransmit) {
|
/*if(!isRetransmit) {
|
||||||
DPRINT(DBG_INFO, "last tx setup: ");
|
DPRINT(DBG_INFO, "last tx setup: ");
|
||||||
DBGPRINT(String(mTxSetupTime));
|
DBGPRINT(String(mTxSetupTime));
|
||||||
DBGPRINTLN("ms");
|
DBGPRINTLN("ms");
|
||||||
}
|
}*/
|
||||||
|
|
||||||
DPRINT_IVID(DBG_INFO, iv->id);
|
DPRINT_IVID(DBG_INFO, iv->id);
|
||||||
DBGPRINT(F("TX "));
|
DBGPRINT(F("TX "));
|
||||||
|
@ -368,6 +369,7 @@ class HmRadio : public Radio {
|
||||||
}
|
}
|
||||||
|
|
||||||
mNrf24->stopListening();
|
mNrf24->stopListening();
|
||||||
|
mNrf24->flush_rx();
|
||||||
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
|
||||||
|
@ -407,9 +409,9 @@ class HmRadio : public Radio {
|
||||||
bool mNRFloopChannels = false;
|
bool mNRFloopChannels = false;
|
||||||
bool mNRFisInRX = false;
|
bool mNRFisInRX = false;
|
||||||
bool isRxInit = true;
|
bool isRxInit = true;
|
||||||
bool rxPendular = false;
|
bool mRxPendular = false;
|
||||||
uint32_t innerLoopTimeout = DURATION_LISTEN_MIN;
|
uint32_t innerLoopTimeout = DURATION_LISTEN_MIN;
|
||||||
uint8_t mTxSetupTime = 0;
|
//uint8_t mTxSetupTime = 0;
|
||||||
|
|
||||||
std::unique_ptr<SPIClass> mSpi;
|
std::unique_ptr<SPIClass> mSpi;
|
||||||
std::unique_ptr<RF24> mNrf24;
|
std::unique_ptr<RF24> mNrf24;
|
||||||
|
|
|
@ -356,11 +356,11 @@ class Cmt2300a {
|
||||||
if((freqKhz % FREQ_STEP_KHZ) != 0)
|
if((freqKhz % FREQ_STEP_KHZ) != 0)
|
||||||
return 0xff; // error
|
return 0xff; // error
|
||||||
|
|
||||||
std::pair<uint8_t, uint8_t> range = getFreqRangeMhz();
|
std::pair<uint16_t, uint16_t> range = getFreqRangeMhz();
|
||||||
if((freqKhz < range.first) || (freqKhz > range.second))
|
if((freqKhz < (range.first * 1000)) || (freqKhz > (range.second * 1000)))
|
||||||
return 0xff; // error
|
return 0xff; // error
|
||||||
|
|
||||||
return (freqKhz - getBaseFreqMhz() * 1000) / FREQ_STEP_KHZ;
|
return (freqKhz - (getBaseFreqMhz() * 1000)) / FREQ_STEP_KHZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void switchChannel(uint8_t ch) {
|
inline void switchChannel(uint8_t ch) {
|
||||||
|
|
|
@ -754,6 +754,12 @@ class RestApi {
|
||||||
warn.add(F(REBOOT_ESP_APPLY_CHANGES));
|
warn.add(F(REBOOT_ESP_APPLY_CHANGES));
|
||||||
if(0 == mApp->getTimestamp())
|
if(0 == mApp->getTimestamp())
|
||||||
warn.add(F(TIME_NOT_SET));
|
warn.add(F(TIME_NOT_SET));
|
||||||
|
#if !defined(ETHERNET)
|
||||||
|
#if !defined(ESP32)
|
||||||
|
if(mApp->getWasInCh12to14())
|
||||||
|
warn.add(F(WAS_IN_CH_12_TO_14));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void getSetup(AsyncWebServerRequest *request, JsonObject obj) {
|
void getSetup(AsyncWebServerRequest *request, JsonObject obj) {
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
#define TIME_NOT_SET "time not set. No communication to inverter possible"
|
#define TIME_NOT_SET "time not set. No communication to inverter possible"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LANG_DE
|
||||||
|
#define WAS_IN_CH_12_TO_14 "Der ESP war in WLAN Kanal 12 bis 14, was uU. zu Abstürzen führt"
|
||||||
|
#else /*LANG_EN*/
|
||||||
|
#define WAS_IN_CH_12_TO_14 "Your ESP was in wifi channel 12 to 14. It may cause reboots of your AhoyDTU"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LANG_DE
|
#ifdef LANG_DE
|
||||||
#define INV_INDEX_INVALID "Wechselrichterindex ungültig; "
|
#define INV_INDEX_INVALID "Wechselrichterindex ungültig; "
|
||||||
#else /*LANG_EN*/
|
#else /*LANG_EN*/
|
||||||
|
|
|
@ -92,6 +92,8 @@ void ahoywifi::tickWifiLoop() {
|
||||||
}
|
}
|
||||||
#if !defined(ESP32)
|
#if !defined(ESP32)
|
||||||
MDNS.update();
|
MDNS.update();
|
||||||
|
if(WiFi.channel() > 11)
|
||||||
|
mWasInCh12to14 = true;
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
case IN_AP_MODE:
|
case IN_AP_MODE:
|
||||||
|
|
|
@ -37,6 +37,10 @@ class ahoywifi {
|
||||||
}
|
}
|
||||||
void setupStation(void);
|
void setupStation(void);
|
||||||
|
|
||||||
|
bool getWasInCh12to14() const {
|
||||||
|
return mWasInCh12to14;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef enum WiFiStatus {
|
typedef enum WiFiStatus {
|
||||||
DISCONNECTED = 0,
|
DISCONNECTED = 0,
|
||||||
|
@ -86,6 +90,7 @@ class ahoywifi {
|
||||||
bool mGotDisconnect;
|
bool mGotDisconnect;
|
||||||
std::list<uint8_t> mBSSIDList;
|
std::list<uint8_t> mBSSIDList;
|
||||||
bool mStopApAllowed;
|
bool mStopApAllowed;
|
||||||
|
bool mWasInCh12to14 = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*__AHOYWIFI_H__*/
|
#endif /*__AHOYWIFI_H__*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue