mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-10 15:36:38 +02:00
* fix EPS32 GPIO names #286
* fix negative temperature (OpenDTU issue 246) * added plausibility check based on payload length * prepared project for splitting into library and end-user-esp * added donation link to index.html * deactivated disclaimer temporarily
This commit is contained in:
parent
202d883f38
commit
6ed2dfde9c
12 changed files with 163 additions and 119 deletions
|
@ -40,7 +40,7 @@ void app::setup(uint32_t timeout) {
|
||||||
#ifndef AP_ONLY
|
#ifndef AP_ONLY
|
||||||
setupMqtt();
|
setupMqtt();
|
||||||
#endif
|
#endif
|
||||||
mSys->setup(&mConfig);
|
mSys->setup(mConfig.amplifierPower, mConfig.pinIrq, mConfig.pinCe, mConfig.pinCs);
|
||||||
|
|
||||||
mWebInst = new web(this, &mSysConfig, &mConfig, &mStat, mVersion);
|
mWebInst = new web(this, &mSysConfig, &mConfig, &mStat, mVersion);
|
||||||
mWebInst->setup();
|
mWebInst->setup();
|
||||||
|
@ -291,12 +291,12 @@ bool app::buildPayload(uint8_t id) {
|
||||||
for(uint8_t i = 0; i < mPayload[id].maxPackId; i ++) {
|
for(uint8_t i = 0; i < mPayload[id].maxPackId; i ++) {
|
||||||
if(mPayload[id].len[i] > 0) {
|
if(mPayload[id].len[i] > 0) {
|
||||||
if(i == (mPayload[id].maxPackId-1)) {
|
if(i == (mPayload[id].maxPackId-1)) {
|
||||||
crc = Ahoy::crc16(mPayload[id].data[i], mPayload[id].len[i] - 2, crc);
|
crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i] - 2, crc);
|
||||||
crcRcv = (mPayload[id].data[i][mPayload[id].len[i] - 2] << 8)
|
crcRcv = (mPayload[id].data[i][mPayload[id].len[i] - 2] << 8)
|
||||||
| (mPayload[id].data[i][mPayload[id].len[i] - 1]);
|
| (mPayload[id].data[i][mPayload[id].len[i] - 1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
crc = Ahoy::crc16(mPayload[id].data[i], mPayload[id].len[i], crc);
|
crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i], crc);
|
||||||
}
|
}
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
|
@ -367,28 +367,30 @@ void app::processPayload(bool retransmit) {
|
||||||
DPRINTLN(DBG_DEBUG, F("procPyld: max: ") + String(mPayload[iv->id].maxPackId));
|
DPRINTLN(DBG_DEBUG, F("procPyld: max: ") + String(mPayload[iv->id].maxPackId));
|
||||||
record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser
|
record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser
|
||||||
mPayload[iv->id].complete = true;
|
mPayload[iv->id].complete = true;
|
||||||
if(mPayload[iv->id].txId == (TX_REQ_INFO + 0x80))
|
|
||||||
mStat.rxSuccess++;
|
|
||||||
|
|
||||||
uint8_t payload[128];
|
uint8_t payload[128];
|
||||||
uint8_t offs = 0;
|
uint8_t payloadLen = 0;
|
||||||
|
|
||||||
memset(payload, 0, 128);
|
memset(payload, 0, 128);
|
||||||
|
|
||||||
for(uint8_t i = 0; i < (mPayload[iv->id].maxPackId); i ++) {
|
for(uint8_t i = 0; i < (mPayload[iv->id].maxPackId); i ++) {
|
||||||
memcpy(&payload[offs], mPayload[iv->id].data[i], (mPayload[iv->id].len[i]));
|
memcpy(&payload[payloadLen], mPayload[iv->id].data[i], (mPayload[iv->id].len[i]));
|
||||||
offs += (mPayload[iv->id].len[i]);
|
payloadLen += (mPayload[iv->id].len[i]);
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
offs-=2;
|
payloadLen-=2;
|
||||||
|
|
||||||
if(mConfig.serialDebug) {
|
if(mConfig.serialDebug) {
|
||||||
DPRINT(DBG_INFO, F("Payload (") + String(offs) + "): ");
|
DPRINT(DBG_INFO, F("Payload (") + String(payloadLen) + "): ");
|
||||||
mSys->Radio.dumpBuf(NULL, payload, offs);
|
mSys->Radio.dumpBuf(NULL, payload, payloadLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NULL == rec)
|
if(NULL == rec)
|
||||||
DPRINTLN(DBG_ERROR, F("record is NULL!"));
|
DPRINTLN(DBG_ERROR, F("record is NULL!"));
|
||||||
else {
|
else if((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) {
|
||||||
|
if(mPayload[iv->id].txId == (TX_REQ_INFO + 0x80))
|
||||||
|
mStat.rxSuccess++;
|
||||||
|
|
||||||
rec->ts = mPayload[iv->id].ts + ((TIMEZONE + offsetDayLightSaving(mUtcTimestamp)) * 3600);
|
rec->ts = mPayload[iv->id].ts + ((TIMEZONE + offsetDayLightSaving(mUtcTimestamp)) * 3600);
|
||||||
for(uint8_t i = 0; i < rec->length; i++) {
|
for(uint8_t i = 0; i < rec->length; i++) {
|
||||||
iv->addValue(i, payload, rec);
|
iv->addValue(i, payload, rec);
|
||||||
|
@ -420,7 +422,7 @@ void app::processPayload(bool retransmit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(iv->isProducing(mTimestamp, rec)){
|
if(iv->isProducing(mTimestamp, rec)){
|
||||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available_text", iv->name);
|
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available_text", iv->name);
|
||||||
snprintf(val, 32, DEF_MQTT_IV_MESSAGE_INVERTER_AVAIL_AND_PRODUCED);
|
snprintf(val, 32, DEF_MQTT_IV_MESSAGE_INVERTER_AVAIL_AND_PRODUCED);
|
||||||
|
@ -440,11 +442,11 @@ void app::processPayload(bool retransmit) {
|
||||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/last_success", iv->name);
|
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/last_success", iv->name);
|
||||||
snprintf(val, 48, "%i", iv->getLastTs(rec) * 1000);
|
snprintf(val, 48, "%i", iv->getLastTs(rec) * 1000);
|
||||||
mMqtt.sendMsg(topic, val);
|
mMqtt.sendMsg(topic, val);
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// total values (sum of all inverters)
|
// total values (sum of all inverters)
|
||||||
|
@ -466,6 +468,10 @@ void app::processPayload(bool retransmit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
DPRINTLN(DBG_ERROR, F("plausibility check failed, expected ") + String(rec->pyldLen) + F(" bytes"));
|
||||||
|
mStat.rxFail++;
|
||||||
|
}
|
||||||
|
|
||||||
iv->setQueuedCmdFinished();
|
iv->setQueuedCmdFinished();
|
||||||
|
|
||||||
|
@ -736,9 +742,9 @@ void app::loadDefaultConfig(void) {
|
||||||
// nrf24
|
// nrf24
|
||||||
mConfig.sendInterval = SEND_INTERVAL;
|
mConfig.sendInterval = SEND_INTERVAL;
|
||||||
mConfig.maxRetransPerPyld = DEF_MAX_RETRANS_PER_PYLD;
|
mConfig.maxRetransPerPyld = DEF_MAX_RETRANS_PER_PYLD;
|
||||||
mConfig.pinCs = DEF_RF24_CS_PIN;
|
mConfig.pinCs = DEF_CS_PIN;
|
||||||
mConfig.pinCe = DEF_RF24_CE_PIN;
|
mConfig.pinCe = DEF_CE_PIN;
|
||||||
mConfig.pinIrq = DEF_RF24_IRQ_PIN;
|
mConfig.pinIrq = DEF_IRQ_PIN;
|
||||||
mConfig.amplifierPower = DEF_AMPLIFIERPOWER & 0x03;
|
mConfig.amplifierPower = DEF_AMPLIFIERPOWER & 0x03;
|
||||||
|
|
||||||
// ntp
|
// ntp
|
||||||
|
|
|
@ -37,10 +37,7 @@
|
||||||
#define __MQTT_AFTER_RX__ // versendet die MQTT Daten sobald die WR daten Aufbereitet wurden ( gehört eigentlich ins Setup )
|
#define __MQTT_AFTER_RX__ // versendet die MQTT Daten sobald die WR daten Aufbereitet wurden ( gehört eigentlich ins Setup )
|
||||||
// #define __MQTT_NO_DISCOVERCONFIG__ // das versenden der MQTTDiscoveryConfig abschalten ( gehört eigentlich ins Setup )
|
// #define __MQTT_NO_DISCOVERCONFIG__ // das versenden der MQTTDiscoveryConfig abschalten ( gehört eigentlich ins Setup )
|
||||||
|
|
||||||
typedef CircularBuffer<packet_t, PACKET_BUFFER_SIZE> BufferType;
|
typedef HmSystem<MAX_NUM_INVERTERS> HmSystemType;
|
||||||
typedef HmRadio<DEF_RF24_CE_PIN, DEF_RF24_CS_PIN, BufferType> RadioType;
|
|
||||||
typedef Inverter<float> InverterType;
|
|
||||||
typedef HmSystem<RadioType, BufferType, MAX_NUM_INVERTERS, InverterType> HmSystemType;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -190,7 +187,6 @@ class app {
|
||||||
|
|
||||||
bool buildPayload(uint8_t id);
|
bool buildPayload(uint8_t id);
|
||||||
void processPayload(bool retransmit);
|
void processPayload(bool retransmit);
|
||||||
void processPayload(bool retransmit, uint8_t cmd);
|
|
||||||
|
|
||||||
const char* getFieldDeviceClass(uint8_t fieldId);
|
const char* getFieldDeviceClass(uint8_t fieldId);
|
||||||
const char* getFieldStateClass(uint8_t fieldId);
|
const char* getFieldStateClass(uint8_t fieldId);
|
||||||
|
@ -204,7 +200,7 @@ class app {
|
||||||
while(length > 0) {
|
while(length > 0) {
|
||||||
len = (length < 32) ? length : 32;
|
len = (length < 32) ? length : 32;
|
||||||
mEep->read(start, buf, len);
|
mEep->read(start, buf, len);
|
||||||
crc = Ahoy::crc16(buf, len, crc);
|
crc = ah::crc16(buf, len, crc);
|
||||||
start += len;
|
start += len;
|
||||||
length -= len;
|
length -= len;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,9 +41,9 @@
|
||||||
#define DEF_DEVICE_NAME "AHOY-DTU"
|
#define DEF_DEVICE_NAME "AHOY-DTU"
|
||||||
|
|
||||||
// default pinout (GPIO Number)
|
// default pinout (GPIO Number)
|
||||||
#define DEF_RF24_CS_PIN 15
|
#define DEF_CS_PIN 15
|
||||||
#define DEF_RF24_CE_PIN 2
|
#define DEF_CE_PIN 2
|
||||||
#define DEF_RF24_IRQ_PIN 0
|
#define DEF_IRQ_PIN 0
|
||||||
|
|
||||||
// default NRF24 power, possible values (0 - 3)
|
// default NRF24 power, possible values (0 - 3)
|
||||||
#define DEF_AMPLIFIERPOWER 1
|
#define DEF_AMPLIFIERPOWER 1
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778
|
// 2022 Ahoy, https://github.com/lumpapu/ahoy
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
|
||||||
namespace Ahoy {
|
namespace ah {
|
||||||
uint8_t crc8(uint8_t buf[], uint8_t len) {
|
uint8_t crc8(uint8_t buf[], uint8_t len) {
|
||||||
uint8_t crc = CRC8_INIT;
|
uint8_t crc = CRC8_INIT;
|
||||||
for(uint8_t i = 0; i < len; i++) {
|
for(uint8_t i = 0; i < len; i++) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778
|
// 2022 Ahoy, https://github.com/lumpapu/ahoy
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#define CRC16_MODBUS_POLYNOM 0xA001
|
#define CRC16_MODBUS_POLYNOM 0xA001
|
||||||
|
|
||||||
namespace Ahoy {
|
namespace ah {
|
||||||
uint8_t crc8(uint8_t buf[], uint8_t len);
|
uint8_t crc8(uint8_t buf[], uint8_t len);
|
||||||
uint16_t crc16(uint8_t buf[], uint8_t len, uint16_t start = 0xffff);
|
uint16_t crc16(uint8_t buf[], uint8_t len, uint16_t start = 0xffff);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 5
|
#define VERSION_MINOR 5
|
||||||
#define VERSION_PATCH 20
|
#define VERSION_PATCH 21
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778
|
// 2022 Ahoy, https://github.com/lumpapu/ahoy
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -98,6 +98,7 @@ const byteAssign_t InfoAssignment[] = {
|
||||||
{ FLD_HW_ID, UNIT_NONE, CH0, 8, 2, 1 }
|
{ FLD_HW_ID, UNIT_NONE, CH0, 8, 2, 1 }
|
||||||
};
|
};
|
||||||
#define HMINFO_LIST_LEN (sizeof(InfoAssignment) / sizeof(byteAssign_t))
|
#define HMINFO_LIST_LEN (sizeof(InfoAssignment) / sizeof(byteAssign_t))
|
||||||
|
#define HMINFO_PAYLOAD_LEN 14
|
||||||
|
|
||||||
const byteAssign_t SystemConfigParaAssignment[] = {
|
const byteAssign_t SystemConfigParaAssignment[] = {
|
||||||
{ FLD_ACT_ACTIVE_PWR_LIMIT, UNIT_PCT, CH0, 2, 2, 10 }/*,
|
{ FLD_ACT_ACTIVE_PWR_LIMIT, UNIT_PCT, CH0, 2, 2, 10 }/*,
|
||||||
|
@ -105,11 +106,13 @@ const byteAssign_t SystemConfigParaAssignment[] = {
|
||||||
{ FLD_ACT_PF, UNIT_NONE, CH0, 6, 2, 1000 }*/
|
{ FLD_ACT_PF, UNIT_NONE, CH0, 6, 2, 1000 }*/
|
||||||
};
|
};
|
||||||
#define HMSYSTEM_LIST_LEN (sizeof(SystemConfigParaAssignment) / sizeof(byteAssign_t))
|
#define HMSYSTEM_LIST_LEN (sizeof(SystemConfigParaAssignment) / sizeof(byteAssign_t))
|
||||||
|
#define HMSYSTEM_PAYLOAD_LEN 0 // 0: means check off
|
||||||
|
|
||||||
const byteAssign_t AlarmDataAssignment[] = {
|
const byteAssign_t AlarmDataAssignment[] = {
|
||||||
{ FLD_LAST_ALARM_CODE, UNIT_NONE, CH0, 0, 2, 1 }
|
{ FLD_LAST_ALARM_CODE, UNIT_NONE, CH0, 0, 2, 1 }
|
||||||
};
|
};
|
||||||
#define HMALARMDATA_LIST_LEN (sizeof(AlarmDataAssignment) / sizeof(byteAssign_t))
|
#define HMALARMDATA_LIST_LEN (sizeof(AlarmDataAssignment) / sizeof(byteAssign_t))
|
||||||
|
#define HMALARMDATA_PAYLOAD_LEN 0 // 0: means check off
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,7 +140,8 @@ const byteAssign_t hm1chAssignment[] = {
|
||||||
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
||||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
||||||
};
|
};
|
||||||
#define HM1CH_LIST_LEN (sizeof(hm1chAssignment) / sizeof(byteAssign_t))
|
#define HM1CH_LIST_LEN (sizeof(hm1chAssignment) / sizeof(byteAssign_t))
|
||||||
|
#define HM1CH_PAYLOAD_LEN 30
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
@ -172,7 +176,8 @@ const byteAssign_t hm2chAssignment[] = {
|
||||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
||||||
|
|
||||||
};
|
};
|
||||||
#define HM2CH_LIST_LEN (sizeof(hm2chAssignment) / sizeof(byteAssign_t))
|
#define HM2CH_LIST_LEN (sizeof(hm2chAssignment) / sizeof(byteAssign_t))
|
||||||
|
#define HM2CH_PAYLOAD_LEN 42
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
@ -220,7 +225,8 @@ const byteAssign_t hm4chAssignment[] = {
|
||||||
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
{ FLD_PDC, UNIT_W, CH0, CALC_PDC_CH0, 0, CMD_CALC },
|
||||||
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
{ FLD_EFF, UNIT_PCT, CH0, CALC_EFF_CH0, 0, CMD_CALC }
|
||||||
};
|
};
|
||||||
#define HM4CH_LIST_LEN (sizeof(hm4chAssignment) / sizeof(byteAssign_t))
|
#define HM4CH_LIST_LEN (sizeof(hm4chAssignment) / sizeof(byteAssign_t))
|
||||||
|
#define HM4CH_PAYLOAD_LEN 62
|
||||||
|
|
||||||
|
|
||||||
#endif /*__HM_DEFINES_H__*/
|
#endif /*__HM_DEFINES_H__*/
|
||||||
|
|
|
@ -61,6 +61,7 @@ struct record_t {
|
||||||
uint8_t length; // length of the assignment list
|
uint8_t length; // length of the assignment list
|
||||||
T *record; // data pointer
|
T *record; // data pointer
|
||||||
uint32_t ts; // timestamp of last received payload
|
uint32_t ts; // timestamp of last received payload
|
||||||
|
uint8_t pyldLen; // expected payload length for plausibility check
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommandAbstract {
|
class CommandAbstract {
|
||||||
|
@ -242,10 +243,16 @@ class Inverter {
|
||||||
val <<= 8;
|
val <<= 8;
|
||||||
val |= buf[ptr];
|
val |= buf[ptr];
|
||||||
} while(++ptr != end);
|
} while(++ptr != end);
|
||||||
if ((REC_TYP)(div) > 1)
|
if(FLD_T == rec->assign[pos].fieldId) {
|
||||||
rec->record[pos] = (REC_TYP)(val) / (REC_TYP)(div);
|
// temperature is a signed value!
|
||||||
else
|
rec->record[pos] = (REC_TYP)((int16_t)val) / (REC_TYP)(div);
|
||||||
rec->record[pos] = (REC_TYP)(val);
|
}
|
||||||
|
else {
|
||||||
|
if ((REC_TYP)(div) > 1)
|
||||||
|
rec->record[pos] = (REC_TYP)(val) / (REC_TYP)(div);
|
||||||
|
else
|
||||||
|
rec->record[pos] = (REC_TYP)(val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,37 +355,44 @@ class Inverter {
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case RealTimeRunData_Debug:
|
case RealTimeRunData_Debug:
|
||||||
if (INV_TYPE_1CH == type) {
|
if (INV_TYPE_1CH == type) {
|
||||||
rec->length = (uint8_t)(HM1CH_LIST_LEN);
|
rec->length = (uint8_t)(HM1CH_LIST_LEN);
|
||||||
rec->assign = (byteAssign_t *)hm1chAssignment;
|
rec->assign = (byteAssign_t *)hm1chAssignment;
|
||||||
channels = 1;
|
rec->pyldLen = HM1CH_PAYLOAD_LEN;
|
||||||
|
channels = 1;
|
||||||
}
|
}
|
||||||
else if (INV_TYPE_2CH == type) {
|
else if (INV_TYPE_2CH == type) {
|
||||||
rec->length = (uint8_t)(HM2CH_LIST_LEN);
|
rec->length = (uint8_t)(HM2CH_LIST_LEN);
|
||||||
rec->assign = (byteAssign_t *)hm2chAssignment;
|
rec->assign = (byteAssign_t *)hm2chAssignment;
|
||||||
channels = 2;
|
rec->pyldLen = HM2CH_PAYLOAD_LEN;
|
||||||
|
channels = 2;
|
||||||
}
|
}
|
||||||
else if (INV_TYPE_4CH == type) {
|
else if (INV_TYPE_4CH == type) {
|
||||||
rec->length = (uint8_t)(HM4CH_LIST_LEN);
|
rec->length = (uint8_t)(HM4CH_LIST_LEN);
|
||||||
rec->assign = (byteAssign_t *)hm4chAssignment;
|
rec->assign = (byteAssign_t *)hm4chAssignment;
|
||||||
channels = 4;
|
rec->pyldLen = HM4CH_PAYLOAD_LEN;
|
||||||
|
channels = 4;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rec->length = 0;
|
rec->length = 0;
|
||||||
rec->assign = NULL;
|
rec->assign = NULL;
|
||||||
channels = 0;
|
rec->pyldLen = 0;
|
||||||
|
channels = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InverterDevInform_All:
|
case InverterDevInform_All:
|
||||||
rec->length = (uint8_t)(HMINFO_LIST_LEN);
|
rec->length = (uint8_t)(HMINFO_LIST_LEN);
|
||||||
rec->assign = (byteAssign_t *)InfoAssignment;
|
rec->assign = (byteAssign_t *)InfoAssignment;
|
||||||
|
rec->pyldLen = HMINFO_PAYLOAD_LEN;
|
||||||
break;
|
break;
|
||||||
case SystemConfigPara:
|
case SystemConfigPara:
|
||||||
rec->length = (uint8_t)(HMSYSTEM_LIST_LEN);
|
rec->length = (uint8_t)(HMSYSTEM_LIST_LEN);
|
||||||
rec->assign = (byteAssign_t *)SystemConfigParaAssignment;
|
rec->assign = (byteAssign_t *)SystemConfigParaAssignment;
|
||||||
|
rec->pyldLen = HMSYSTEM_PAYLOAD_LEN;
|
||||||
break;
|
break;
|
||||||
case AlarmData:
|
case AlarmData:
|
||||||
rec->length = (uint8_t)(HMALARMDATA_LIST_LEN);
|
rec->length = (uint8_t)(HMALARMDATA_LIST_LEN);
|
||||||
rec->assign = (byteAssign_t *)AlarmDataAssignment;
|
rec->assign = (byteAssign_t *)AlarmDataAssignment;
|
||||||
|
rec->pyldLen = HMALARMDATA_PAYLOAD_LEN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DPRINTLN(DBG_INFO, F("initAssignment: Parser not implemented"));
|
DPRINTLN(DBG_INFO, F("initAssignment: Parser not implemented"));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778
|
// 2022 Ahoy, https://github.com/lumpapu/ahoy
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -8,9 +8,20 @@
|
||||||
|
|
||||||
#include "dbg.h"
|
#include "dbg.h"
|
||||||
#include <RF24.h>
|
#include <RF24.h>
|
||||||
#include <RF24_config.h>
|
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
#ifndef DISABLE_IRQ
|
||||||
|
#if defined(ESP8266) || defined(ESP32)
|
||||||
|
#define DISABLE_IRQ noInterrupts()
|
||||||
|
#define RESTORE_IRQ interrupts()
|
||||||
|
#else
|
||||||
|
#define DISABLE_IRQ \
|
||||||
|
uint8_t sreg = SREG; \
|
||||||
|
cli();
|
||||||
|
|
||||||
|
#define RESTORE_IRQ \
|
||||||
|
SREG = sreg;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
//#define CHANNEL_HOP // switch between channels or use static channel to send
|
//#define CHANNEL_HOP // switch between channels or use static channel to send
|
||||||
|
|
||||||
#define DEFAULT_RECV_CHANNEL 3
|
#define DEFAULT_RECV_CHANNEL 3
|
||||||
|
@ -54,7 +65,7 @@ const char* const rf24AmpPowerNames[] = {"MIN", "LOW", "HIGH", "MAX"};
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// HM Radio class
|
// HM Radio class
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template <uint8_t CE_PIN, uint8_t CS_PIN, class BUFFER>
|
template <class BUFFER, uint8_t IRQ_PIN = DEF_IRQ_PIN, uint8_t CE_PIN = DEF_CE_PIN, uint8_t CS_PIN = DEF_CS_PIN, uint8_t AMP_PWR = RF24_PA_LOW>
|
||||||
class HmRadio {
|
class HmRadio {
|
||||||
public:
|
public:
|
||||||
HmRadio() : mNrf24(CE_PIN, CS_PIN, SPI_SPEED) {
|
HmRadio() : mNrf24(CE_PIN, CS_PIN, SPI_SPEED) {
|
||||||
|
@ -84,32 +95,31 @@ class HmRadio {
|
||||||
}
|
}
|
||||||
~HmRadio() {}
|
~HmRadio() {}
|
||||||
|
|
||||||
void setup(config_t *config, BUFFER *ctrl) {
|
void setup(BUFFER *ctrl, uint8_t ampPwr = RF24_PA_LOW, uint8_t irq = IRQ_PIN, uint8_t ce = CE_PIN, uint8_t cs = CS_PIN) {
|
||||||
DPRINTLN(DBG_VERBOSE, F("hmRadio.h:setup"));
|
DPRINTLN(DBG_VERBOSE, F("hmRadio.h:setup"));
|
||||||
pinMode(config->pinIrq, INPUT_PULLUP);
|
pinMode(irq, INPUT_PULLUP);
|
||||||
|
|
||||||
mBufCtrl = ctrl;
|
mBufCtrl = ctrl;
|
||||||
mSerialDebug = config->serialDebug;
|
|
||||||
|
|
||||||
uint32_t DTU_SN = 0x87654321;
|
|
||||||
|
uint32_t dtuSn = 0x87654321;
|
||||||
uint32_t chipID = 0; // will be filled with last 3 bytes of MAC
|
uint32_t chipID = 0; // will be filled with last 3 bytes of MAC
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
uint64_t MAC = ESP.getEfuseMac();
|
uint64_t MAC = ESP.getEfuseMac();
|
||||||
chipID = ((MAC >> 8) & 0xFF0000) | ((MAC >> 24) & 0xFF00) | ((MAC >> 40) & 0xFF);
|
chipID = ((MAC >> 8) & 0xFF0000) | ((MAC >> 24) & 0xFF00) | ((MAC >> 40) & 0xFF);
|
||||||
#else
|
#else
|
||||||
chipID = ESP.getChipId();
|
chipID = ESP.getChipId();
|
||||||
#endif
|
#endif
|
||||||
if(chipID) {
|
if(chipID) {
|
||||||
DTU_SN = 0x80000000; // the first digit is an 8 for DTU production year 2022, the rest is filled with the ESP chipID in decimal
|
dtuSn = 0x80000000; // the first digit is an 8 for DTU production year 2022, the rest is filled with the ESP chipID in decimal
|
||||||
for(int i = 0; i < 7; i++) {
|
for(int i = 0; i < 7; i++) {
|
||||||
DTU_SN |= (chipID % 10) << (i * 4);
|
dtuSn |= (chipID % 10) << (i * 4);
|
||||||
chipID /= 10;
|
chipID /= 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// change the byte order of the DTU serial number and append the required 0x01 at the end
|
// change the byte order of the DTU serial number and append the required 0x01 at the end
|
||||||
DTU_RADIO_ID = ((uint64_t)(((DTU_SN >> 24) & 0xFF) | ((DTU_SN >> 8) & 0xFF00) | ((DTU_SN << 8) & 0xFF0000) | ((DTU_SN << 24) & 0xFF000000)) << 8) | 0x01;
|
DTU_RADIO_ID = ((uint64_t)(((dtuSn >> 24) & 0xFF) | ((dtuSn >> 8) & 0xFF00) | ((dtuSn << 8) & 0xFF0000) | ((dtuSn << 24) & 0xFF000000)) << 8) | 0x01;
|
||||||
|
|
||||||
mNrf24.begin(config->pinCe, config->pinCs);
|
mNrf24.begin(ce, cs);
|
||||||
mNrf24.setRetries(0, 0);
|
mNrf24.setRetries(0, 0);
|
||||||
|
|
||||||
mNrf24.setChannel(DEFAULT_RECV_CHANNEL);
|
mNrf24.setChannel(DEFAULT_RECV_CHANNEL);
|
||||||
|
@ -125,8 +135,8 @@ class HmRadio {
|
||||||
mNrf24.maskIRQ(true, true, false);
|
mNrf24.maskIRQ(true, true, false);
|
||||||
|
|
||||||
DPRINT(DBG_INFO, F("RF24 Amp Pwr: RF24_PA_"));
|
DPRINT(DBG_INFO, F("RF24 Amp Pwr: RF24_PA_"));
|
||||||
DPRINTLN(DBG_INFO, String(rf24AmpPowerNames[config->amplifierPower]));
|
DPRINTLN(DBG_INFO, String(rf24AmpPowerNames[ampPwr]));
|
||||||
mNrf24.setPALevel(config->amplifierPower & 0x03);
|
mNrf24.setPALevel(ampPwr & 0x03);
|
||||||
mNrf24.startListening();
|
mNrf24.startListening();
|
||||||
|
|
||||||
DPRINTLN(DBG_INFO, F("Radio Config:"));
|
DPRINTLN(DBG_INFO, F("Radio Config:"));
|
||||||
|
@ -169,6 +179,10 @@ class HmRadio {
|
||||||
RESTORE_IRQ;
|
RESTORE_IRQ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void enableDebug() {
|
||||||
|
mSerialDebug = true;
|
||||||
|
}
|
||||||
|
|
||||||
void handleIntr(void) {
|
void handleIntr(void) {
|
||||||
//DPRINTLN(DBG_VERBOSE, F("hmRadio.h:handleIntr"));
|
//DPRINTLN(DBG_VERBOSE, F("hmRadio.h:handleIntr"));
|
||||||
mIrqRcvd = true;
|
mIrqRcvd = true;
|
||||||
|
@ -195,12 +209,12 @@ class HmRadio {
|
||||||
}
|
}
|
||||||
|
|
||||||
// crc control data
|
// crc control data
|
||||||
uint16_t crc = Ahoy::crc16(&mTxBuf[10], cnt);
|
uint16_t crc = ah::crc16(&mTxBuf[10], cnt);
|
||||||
mTxBuf[10 + cnt++] = (crc >> 8) & 0xff;
|
mTxBuf[10 + cnt++] = (crc >> 8) & 0xff;
|
||||||
mTxBuf[10 + cnt++] = (crc ) & 0xff;
|
mTxBuf[10 + cnt++] = (crc ) & 0xff;
|
||||||
|
|
||||||
// crc over all
|
// crc over all
|
||||||
mTxBuf[10 + cnt] = Ahoy::crc8(mTxBuf, 10 + cnt);
|
mTxBuf[10 + cnt] = ah::crc8(mTxBuf, 10 + cnt);
|
||||||
|
|
||||||
sendPacket(invId, mTxBuf, 10 + cnt + 1, true);
|
sendPacket(invId, mTxBuf, 10 + cnt + 1, true);
|
||||||
}
|
}
|
||||||
|
@ -215,10 +229,10 @@ class HmRadio {
|
||||||
mTxBuf[18] = (alarmMesId >> 8) & 0xff;
|
mTxBuf[18] = (alarmMesId >> 8) & 0xff;
|
||||||
mTxBuf[19] = (alarmMesId ) & 0xff;
|
mTxBuf[19] = (alarmMesId ) & 0xff;
|
||||||
}
|
}
|
||||||
uint16_t crc = Ahoy::crc16(&mTxBuf[10], 14);
|
uint16_t crc = ah::crc16(&mTxBuf[10], 14);
|
||||||
mTxBuf[24] = (crc >> 8) & 0xff;
|
mTxBuf[24] = (crc >> 8) & 0xff;
|
||||||
mTxBuf[25] = (crc ) & 0xff;
|
mTxBuf[25] = (crc ) & 0xff;
|
||||||
mTxBuf[26] = Ahoy::crc8(mTxBuf, 26);
|
mTxBuf[26] = ah::crc8(mTxBuf, 26);
|
||||||
|
|
||||||
sendPacket(invId, mTxBuf, 27, true);
|
sendPacket(invId, mTxBuf, 27, true);
|
||||||
}
|
}
|
||||||
|
@ -231,7 +245,7 @@ class HmRadio {
|
||||||
CP_U32_BigEndian(&mTxBuf[5], (DTU_RADIO_ID >> 8));
|
CP_U32_BigEndian(&mTxBuf[5], (DTU_RADIO_ID >> 8));
|
||||||
mTxBuf[9] = pid;
|
mTxBuf[9] = pid;
|
||||||
if(calcCrc) {
|
if(calcCrc) {
|
||||||
mTxBuf[10] = Ahoy::crc8(mTxBuf, 10);
|
mTxBuf[10] = ah::crc8(mTxBuf, 10);
|
||||||
sendPacket(invId, mTxBuf, 11, false);
|
sendPacket(invId, mTxBuf, 11, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,7 +259,7 @@ class HmRadio {
|
||||||
buf[i-1] = (buf[i] << 1) | (buf[i+1] >> 7);
|
buf[i-1] = (buf[i] << 1) | (buf[i+1] >> 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t crc = Ahoy::crc8(buf, *len-1);
|
uint8_t crc = ah::crc8(buf, *len-1);
|
||||||
bool valid = (crc == buf[*len-1]);
|
bool valid = (crc == buf[*len-1]);
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778
|
// 2022 Ahoy, https://github.com/lumpapu/ahoy
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -7,12 +7,13 @@
|
||||||
#define __HM_SYSTEM_H__
|
#define __HM_SYSTEM_H__
|
||||||
|
|
||||||
#include "hmInverter.h"
|
#include "hmInverter.h"
|
||||||
#ifndef NO_RADIO
|
|
||||||
#include "hmRadio.h"
|
#include "hmRadio.h"
|
||||||
#endif
|
#include "CircularBuffer.h"
|
||||||
|
|
||||||
|
typedef CircularBuffer<packet_t, PACKET_BUFFER_SIZE> BufferType;
|
||||||
|
typedef HmRadio<BufferType> RadioType;
|
||||||
|
|
||||||
template <class RADIO, class BUFFER, uint8_t MAX_INVERTER=3, class INVERTERTYPE=Inverter<float>>
|
template <uint8_t MAX_INVERTER=3, class RADIO = RadioType, class BUFFER = BufferType, class INVERTERTYPE=Inverter<float>>
|
||||||
class HmSystem {
|
class HmSystem {
|
||||||
public:
|
public:
|
||||||
typedef RADIO RadioType;
|
typedef RADIO RadioType;
|
||||||
|
@ -28,9 +29,12 @@ class HmSystem {
|
||||||
// TODO: cleanup
|
// TODO: cleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(config_t *config) {
|
void setup() {
|
||||||
DPRINTLN(DBG_VERBOSE, F("hmSystem.h:setup"));
|
Radio.setup(&BufCtrl);
|
||||||
Radio.setup(config, &BufCtrl);
|
}
|
||||||
|
|
||||||
|
void setup(uint8_t ampPwr, uint8_t irqPin, uint8_t cePin, uint8_t csPin) {
|
||||||
|
Radio.setup(&BufCtrl, ampPwr, irqPin, cePin, csPin);
|
||||||
}
|
}
|
||||||
|
|
||||||
INVERTERTYPE *addInverter(const char *name, uint64_t serial, uint16_t chMaxPwr[]) {
|
INVERTERTYPE *addInverter(const char *name, uint64_t serial, uint16_t chMaxPwr[]) {
|
||||||
|
@ -96,6 +100,10 @@ class HmSystem {
|
||||||
return mNumInv;
|
return mNumInv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void enableDebug() {
|
||||||
|
Radio.enableDebug();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
INVERTERTYPE mInverter[MAX_INVERTER];
|
INVERTERTYPE mInverter[MAX_INVERTER];
|
||||||
uint8_t mNumInv;
|
uint8_t mNumInv;
|
||||||
|
|
|
@ -46,15 +46,15 @@
|
||||||
<p>Every <span id="refresh"></span> seconds the values are updated</p>
|
<p>Every <span id="refresh"></span> seconds the values are updated</p>
|
||||||
|
|
||||||
<div id="note">
|
<div id="note">
|
||||||
This project was started from <a href="https://www.mikrocontroller.net/topic/525778" target="_blank">this discussion. (Mikrocontroller.net)</a><br/>
|
|
||||||
New updates can be found on Github: <a href="https://github.com/lumapu/ahoy" target="_blank">https://github.com/lumapu/ahoy</a><br/>
|
New updates can be found on Github: <a href="https://github.com/lumapu/ahoy" target="_blank">https://github.com/lumapu/ahoy</a><br/>
|
||||||
<br/>
|
<br/>
|
||||||
Please report issues using the feature provided by <a href="https://github.com/lumapu/ahoy/issues">Github</a><br/>
|
Please report issues in <a href="https://github.com/lumapu/ahoy/issues">Github</a><br/>
|
||||||
<br/>
|
Discuss with us on <a href="https://discord.gg/WzhxEY62mB">Discord</a><br/>
|
||||||
Discuss with us on <a href="https://discord.gg/WzhxEY62mB">Discord</a>
|
Support this project: <a href="https://paypal.me/lupusch">Donate</a><br/>
|
||||||
<br/>
|
|
||||||
<p class="lic"><a href="https://creativecommons.org/licenses/by-nc-sa/3.0/de">Creative Commons - https://creativecommons.org/licenses/by-nc-sa/3.0/de/</a><br/>
|
<p class="lic"><a href="https://creativecommons.org/licenses/by-nc-sa/3.0/de">Creative Commons - https://creativecommons.org/licenses/by-nc-sa/3.0/de/</a><br/>
|
||||||
Check the licenses which are published on <a href="https://github.com/lumapu/ahoy">https://github.com/lumapu/ahoy</a> as well</p>
|
Check the licenses which are published on <a href="https://github.com/lumapu/ahoy">https://github.com/lumapu/ahoy</a> as well</p><br/>
|
||||||
|
|
||||||
|
This project was started from <a href="https://www.mikrocontroller.net/topic/525778" target="_blank">this discussion. (Mikrocontroller.net)</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="footer">
|
<div id="footer">
|
||||||
|
@ -87,7 +87,7 @@
|
||||||
|
|
||||||
function parseSys(obj) {
|
function parseSys(obj) {
|
||||||
// Disclaimer
|
// Disclaimer
|
||||||
if(obj["disclaimer"] == false) sessionStorage.setItem("gDisclaimer", promptFunction());
|
//if(obj["disclaimer"] == false) sessionStorage.setItem("gDisclaimer", promptFunction());
|
||||||
|
|
||||||
document.getElementById("version").innerHTML = "Git SHA: " + obj["build"] + " :: " + obj["version"];
|
document.getElementById("version").innerHTML = "Git SHA: " + obj["build"] + " :: " + obj["version"];
|
||||||
document.getElementById("wifi_rssi").innerHTML = obj["wifi_rssi"];
|
document.getElementById("wifi_rssi").innerHTML = obj["wifi_rssi"];
|
||||||
|
|
|
@ -319,29 +319,29 @@
|
||||||
else {
|
else {
|
||||||
e.appendChild(sel(p[1], [
|
e.appendChild(sel(p[1], [
|
||||||
[0, "GPIO0"],
|
[0, "GPIO0"],
|
||||||
[1, "TXD (GPIO1)"],
|
[1, "TX (GPIO1)"],
|
||||||
[2, "D2 (LED)"],
|
[2, "GPIO2 (LED)"],
|
||||||
[3, "RXD (GPIO3)"],
|
[3, "RX (GPIO3)"],
|
||||||
[4, "D4"],
|
[4, "GPIO4"],
|
||||||
[5, "D5"],
|
[5, "GPIO5"],
|
||||||
[12, "D12"],
|
[12, "GPIO12"],
|
||||||
[13, "D13"],
|
[13, "GPIO13"],
|
||||||
[14, "D14"],
|
[14, "GPIO14"],
|
||||||
[15, "D15"],
|
[15, "GPIO15"],
|
||||||
[16, "RX2 (GPIO16)"],
|
[16, "GPIO16"],
|
||||||
[17, "TX2 (GPIO17)"],
|
[17, "GPIO17"],
|
||||||
[18, "D18"],
|
[18, "GPIO18"],
|
||||||
[19, "D19"],
|
[19, "GPIO19"],
|
||||||
[21, "D21"],
|
[21, "GPIO21"],
|
||||||
[22, "D22"],
|
[22, "GPIO22"],
|
||||||
[23, "D23"],
|
[23, "GPIO23"],
|
||||||
[25, "D25"],
|
[25, "GPIO25"],
|
||||||
[26, "D26"],
|
[26, "GPIO26"],
|
||||||
[27, "D27"],
|
[27, "GPIO27"],
|
||||||
[32, "D32"],
|
[32, "GPIO32"],
|
||||||
[33, "D33"],
|
[33, "GPIO33"],
|
||||||
[34, "D34"],
|
[34, "GPIO34"],
|
||||||
[35, "D35"],
|
[35, "GPIO35"],
|
||||||
[36, "VP (GPIO36)"],
|
[36, "VP (GPIO36)"],
|
||||||
[39, "VN (GPIO39)"]
|
[39, "VN (GPIO39)"]
|
||||||
], obj[p[0]]));
|
], obj[p[0]]));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue