mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-10 15:36:38 +02:00
* complete payload processed (and crc checked)
* inverter type is defined by serial number * serial debug can be switched live (using setup) -> Note: only one inverter is supported for now!
This commit is contained in:
parent
2dcf948d60
commit
724f0ab83a
10 changed files with 261 additions and 209 deletions
|
@ -25,6 +25,11 @@ app::app() : Main() {
|
||||||
|
|
||||||
memset(mPacketIds, 0, sizeof(uint32_t)*DBG_CMD_LIST_LEN);
|
memset(mPacketIds, 0, sizeof(uint32_t)*DBG_CMD_LIST_LEN);
|
||||||
|
|
||||||
|
memset(mPayload, 0, (MAX_PAYLOAD_ENTRIES * MAX_RF_PAYLOAD_SIZE));
|
||||||
|
memset(mPayloadLen, 0, MAX_PAYLOAD_ENTRIES);
|
||||||
|
mPayloadComplete = true;
|
||||||
|
mMaxPackId = 0;
|
||||||
|
|
||||||
mSys = new HmSystemType();
|
mSys = new HmSystemType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,21 +55,20 @@ void app::setup(uint32_t timeout) {
|
||||||
if(mSettingsValid) {
|
if(mSettingsValid) {
|
||||||
uint64_t invSerial;
|
uint64_t invSerial;
|
||||||
char invName[MAX_NAME_LENGTH + 1] = {0};
|
char invName[MAX_NAME_LENGTH + 1] = {0};
|
||||||
uint8_t invType;
|
|
||||||
|
|
||||||
// inverter
|
// inverter
|
||||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
||||||
mEep->read(ADDR_INV_ADDR + (i * 8), &invSerial);
|
mEep->read(ADDR_INV_ADDR + (i * 8), &invSerial);
|
||||||
mEep->read(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), invName, MAX_NAME_LENGTH);
|
mEep->read(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), invName, MAX_NAME_LENGTH);
|
||||||
mEep->read(ADDR_INV_TYPE + i, &invType);
|
|
||||||
if(0ULL != invSerial) {
|
if(0ULL != invSerial) {
|
||||||
mSys->addInverter(invName, invSerial, invType);
|
mSys->addInverter(invName, invSerial);
|
||||||
DPRINTLN("add inverter: " + String(invName) + ", SN: " + String(invSerial, HEX) + ", type: " + String(invType));
|
DPRINTLN("add inverter: " + String(invName) + ", SN: " + String(invSerial, HEX));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mEep->read(ADDR_INV_INTERVAL, &mSendInterval);
|
mEep->read(ADDR_INV_INTERVAL, &mSendInterval);
|
||||||
if(mSendInterval < 5)
|
if(mSendInterval < 5)
|
||||||
mSendInterval = 5;
|
mSendInterval = 5;
|
||||||
|
mSendTicker = mSendInterval;
|
||||||
|
|
||||||
// pinout
|
// pinout
|
||||||
mEep->read(ADDR_PINOUT, &mSys->Radio.pinCs);
|
mEep->read(ADDR_PINOUT, &mSys->Radio.pinCs);
|
||||||
|
@ -84,6 +88,7 @@ void app::setup(uint32_t timeout) {
|
||||||
mSerialDebug = (tmp == 0x01);
|
mSerialDebug = (tmp == 0x01);
|
||||||
if(mSerialInterval < 1)
|
if(mSerialInterval < 1)
|
||||||
mSerialInterval = 1;
|
mSerialInterval = 1;
|
||||||
|
mSys->Radio.mSerialDebug = mSerialDebug;
|
||||||
|
|
||||||
|
|
||||||
// mqtt
|
// mqtt
|
||||||
|
@ -134,31 +139,39 @@ void app::loop(void) {
|
||||||
Main::loop();
|
Main::loop();
|
||||||
|
|
||||||
if(checkTicker(&mRxTicker, 5)) {
|
if(checkTicker(&mRxTicker, 5)) {
|
||||||
mSys->Radio.switchRxCh();
|
bool rcvRdy = mSys->Radio.switchRxCh();
|
||||||
|
|
||||||
if(!mSys->BufCtrl.empty()) {
|
if(!mSys->BufCtrl.empty()) {
|
||||||
uint8_t len, rptCnt;
|
uint8_t len;
|
||||||
packet_t *p = mSys->BufCtrl.getBack();
|
packet_t *p = mSys->BufCtrl.getBack();
|
||||||
|
|
||||||
//if(mSerialDebug)
|
if(mSys->Radio.checkPaketCrc(p->packet, &len, p->rxCh)) {
|
||||||
// mSys->Radio.dumpBuf("RAW ", p->packet, MAX_RF_PAYLOAD_SIZE);
|
|
||||||
|
|
||||||
if(mSys->Radio.checkPaketCrc(p->packet, &len, &rptCnt, p->rxCh)) {
|
|
||||||
// process buffer only on first occurrence
|
// process buffer only on first occurrence
|
||||||
if((0 != len) && (0 == rptCnt)) {
|
if(mSerialDebug) {
|
||||||
uint8_t *packetId = &p->packet[9];
|
DPRINT("Received " + String(len) + " bytes channel " + String(p->rxCh) + ": ");
|
||||||
//DPRINTLN("CMD " + String(*packetId, HEX));
|
mSys->Radio.dumpBuf(NULL, p->packet, len);
|
||||||
if(mSerialDebug)
|
}
|
||||||
mSys->Radio.dumpBuf("Payload ", p->packet, len);
|
|
||||||
|
|
||||||
Inverter<> *iv = mSys->findInverter(&p->packet[1]);
|
if(0 != len) {
|
||||||
|
uint8_t *packetId = &p->packet[9];
|
||||||
|
if((*packetId & 0x7F) < 5) {
|
||||||
|
memcpy(mPayload[(*packetId & 0x7F) - 1], &p->packet[10], len-11);
|
||||||
|
mPayloadLen[(*packetId & 0x7F) - 1] = len-11;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((*packetId & 0x80) == 0x80) {
|
||||||
|
if((*packetId & 0x7f) > mMaxPackId)
|
||||||
|
mMaxPackId = (*packetId & 0x7f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Inverter<> *iv = mSys->findInverter(&p->packet[1]);
|
||||||
if(NULL != iv) {
|
if(NULL != iv) {
|
||||||
for(uint8_t i = 0; i < iv->listLen; i++) {
|
for(uint8_t i = 0; i < iv->listLen; i++) {
|
||||||
if(iv->assign[i].cmdId == *packetId)
|
if(iv->assign[i].cmdId == *packetId)
|
||||||
iv->addValue(i, &p->packet[9]);
|
iv->addValue(i, &p->packet[9]);
|
||||||
}
|
}
|
||||||
iv->doCalculations();
|
iv->doCalculations();
|
||||||
//memcpy(mPayload[(*packetId & 0x7F) - 1], &p->packet[9], MAX_RF_PAYLOAD_SIZE - 11);
|
}*/
|
||||||
}
|
|
||||||
|
|
||||||
if(*packetId == 0x01) mPacketIds[0]++;
|
if(*packetId == 0x01) mPacketIds[0]++;
|
||||||
else if(*packetId == 0x02) mPacketIds[1]++;
|
else if(*packetId == 0x02) mPacketIds[1]++;
|
||||||
|
@ -170,8 +183,49 @@ void app::loop(void) {
|
||||||
else mPacketIds[7]++;
|
else mPacketIds[7]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mSys->BufCtrl.popBack();
|
mSys->BufCtrl.popBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: support more than one inverter!
|
||||||
|
if(rcvRdy && (!mPayloadComplete)) {
|
||||||
|
Inverter<> *iv = mSys->getInverterByPos(0);
|
||||||
|
if(!buildPayload()) {
|
||||||
|
if(mMaxPackId != 0) {
|
||||||
|
for(uint8_t i = 0; i < (mMaxPackId-1); i ++) {
|
||||||
|
// retransmit
|
||||||
|
if(mPayloadLen[i] == 0) {
|
||||||
|
if(mSerialDebug)
|
||||||
|
DPRINTLN("Error while retrieving data: Frame " + String(i+1) + " missing: Request Retransmit");
|
||||||
|
mSys->Radio.sendCmdPacket(iv->radioId.u64, 0x15, (0x81+i), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mSys->Radio.switchRxCh(200);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mPayloadComplete = true;
|
||||||
|
uint8_t payload[256] = {0};
|
||||||
|
uint8_t offs = 0;
|
||||||
|
for(uint8_t i = 0; i < (mMaxPackId); i ++) {
|
||||||
|
memcpy(&payload[offs], mPayload[i], (mPayloadLen[i]));
|
||||||
|
offs += (mPayloadLen[i]);
|
||||||
|
}
|
||||||
|
offs-=2;
|
||||||
|
if(mSerialDebug) {
|
||||||
|
DPRINT("Payload (" + String(offs) + "): ");
|
||||||
|
mSys->Radio.dumpBuf(NULL, payload, offs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(NULL != iv) {
|
||||||
|
for(uint8_t i = 0; i < iv->listLen; i++) {
|
||||||
|
iv->addValue(i, payload);
|
||||||
|
}
|
||||||
|
iv->doCalculations();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(checkTicker(&mTicker, 1000)) {
|
if(checkTicker(&mTicker, 1000)) {
|
||||||
|
@ -220,8 +274,18 @@ void app::loop(void) {
|
||||||
if(++mSendTicker >= mSendInterval) {
|
if(++mSendTicker >= mSendInterval) {
|
||||||
mSendTicker = 0;
|
mSendTicker = 0;
|
||||||
|
|
||||||
if(!mSys->BufCtrl.empty())
|
memset(mPayloadLen, 0, MAX_PAYLOAD_ENTRIES);
|
||||||
|
mMaxPackId = 0;
|
||||||
|
if(mSerialDebug) {
|
||||||
|
if(!mPayloadComplete)
|
||||||
|
DPRINTLN("no Payload received!");
|
||||||
|
}
|
||||||
|
mPayloadComplete = false;
|
||||||
|
|
||||||
|
if(!mSys->BufCtrl.empty()) {
|
||||||
|
if(mSerialDebug)
|
||||||
DPRINTLN("recbuf not empty! #" + String(mSys->BufCtrl.getFill()));
|
DPRINTLN("recbuf not empty! #" + String(mSys->BufCtrl.getFill()));
|
||||||
|
}
|
||||||
Inverter<> *inv;
|
Inverter<> *inv;
|
||||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
||||||
inv = mSys->getInverterByPos(i);
|
inv = mSys->getInverterByPos(i);
|
||||||
|
@ -242,6 +306,30 @@ void app::handleIntr(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool app::buildPayload() {
|
||||||
|
//DPRINTLN("Payload");
|
||||||
|
uint16_t crc = 0xffff, crcRcv;
|
||||||
|
if(mMaxPackId > MAX_PAYLOAD_ENTRIES)
|
||||||
|
mMaxPackId = MAX_PAYLOAD_ENTRIES;
|
||||||
|
|
||||||
|
for(uint8_t i = 0; i < mMaxPackId; i ++) {
|
||||||
|
if(mPayloadLen[i] > 0) {
|
||||||
|
if(i == (mMaxPackId-1)) {
|
||||||
|
crc = crc16(mPayload[i], mPayloadLen[i] - 2, crc);
|
||||||
|
crcRcv = (mPayload[i][mPayloadLen[i] - 2] << 8)
|
||||||
|
| (mPayload[i][mPayloadLen[i] - 1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
crc = crc16(mPayload[i], mPayloadLen[i], crc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(crc == crcRcv)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void app::showIndex(void) {
|
void app::showIndex(void) {
|
||||||
String html = FPSTR(index_html);
|
String html = FPSTR(index_html);
|
||||||
|
@ -276,7 +364,6 @@ void app::showSetup(void) {
|
||||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
||||||
mEep->read(ADDR_INV_ADDR + (i * 8), &invSerial);
|
mEep->read(ADDR_INV_ADDR + (i * 8), &invSerial);
|
||||||
mEep->read(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), invName, MAX_NAME_LENGTH);
|
mEep->read(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), invName, MAX_NAME_LENGTH);
|
||||||
mEep->read(ADDR_INV_TYPE + i, &invType);
|
|
||||||
inv += "<p class=\"subdes\">Inverter "+ String(i) + "</p>";
|
inv += "<p class=\"subdes\">Inverter "+ String(i) + "</p>";
|
||||||
|
|
||||||
inv += "<label for=\"inv" + String(i) + "Addr\">Address</label>";
|
inv += "<label for=\"inv" + String(i) + "Addr\">Address</label>";
|
||||||
|
@ -289,16 +376,6 @@ void app::showSetup(void) {
|
||||||
inv += "<input type=\"text\" class=\"text\" name=\"inv" + String(i) + "Name\" value=\"";
|
inv += "<input type=\"text\" class=\"text\" name=\"inv" + String(i) + "Name\" value=\"";
|
||||||
inv += String(invName);
|
inv += String(invName);
|
||||||
inv += "\"/ maxlength=\"" + String(MAX_NAME_LENGTH) + "\">";
|
inv += "\"/ maxlength=\"" + String(MAX_NAME_LENGTH) + "\">";
|
||||||
|
|
||||||
inv += "<label for=\"inv" + String(i) + "Type\">Type</label>";
|
|
||||||
inv += "<select name=\"inv" + String(i) + "Type\">";
|
|
||||||
for(uint8_t t = 0; t < NUM_INVERTER_TYPES; t++) {
|
|
||||||
inv += "<option value=\"" + String(t) + "\"";
|
|
||||||
if(invType == t)
|
|
||||||
inv += " selected";
|
|
||||||
inv += ">" + String(invTypes[t]) + "</option>";
|
|
||||||
}
|
|
||||||
inv += "</select>";
|
|
||||||
}
|
}
|
||||||
html.replace("{INVERTERS}", String(inv));
|
html.replace("{INVERTERS}", String(inv));
|
||||||
|
|
||||||
|
@ -371,7 +448,7 @@ void app::showSetup(void) {
|
||||||
html.replace("{MQTT_PORT}", "1883");
|
html.replace("{MQTT_PORT}", "1883");
|
||||||
html.replace("{MQTT_USER}", "");
|
html.replace("{MQTT_USER}", "");
|
||||||
html.replace("{MQTT_PWD}", "");
|
html.replace("{MQTT_PWD}", "");
|
||||||
html.replace("{MQTT_TOPIC}", "/inverter");
|
html.replace("{MQTT_TOPIC}", "inverter");
|
||||||
html.replace("{MQTT_INTVL}", "10");
|
html.replace("{MQTT_INTVL}", "10");
|
||||||
|
|
||||||
html.replace("{SER_INTVL}", "10");
|
html.replace("{SER_INTVL}", "10");
|
||||||
|
@ -441,9 +518,9 @@ void app::showLiveData(void) {
|
||||||
uint8_t modNum, pos;
|
uint8_t modNum, pos;
|
||||||
switch(iv->type) {
|
switch(iv->type) {
|
||||||
default: modNum = 1; break;
|
default: modNum = 1; break;
|
||||||
case INV_TYPE_HM600:
|
case INV_TYPE_1CH:
|
||||||
case INV_TYPE_HM800: modNum = 2; break;
|
case INV_TYPE_2CH: modNum = 2; break;
|
||||||
case INV_TYPE_HM1200: modNum = 4; break;
|
case INV_TYPE_4CH: modNum = 4; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
modHtml += "<div class=\"iv\">";
|
modHtml += "<div class=\"iv\">";
|
||||||
|
@ -524,11 +601,6 @@ void app::saveValues(bool webSend = true) {
|
||||||
// name
|
// name
|
||||||
mWeb->arg("inv" + String(i) + "Name").toCharArray(buf, 20);
|
mWeb->arg("inv" + String(i) + "Name").toCharArray(buf, 20);
|
||||||
mEep->write(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), buf, MAX_NAME_LENGTH);
|
mEep->write(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), buf, MAX_NAME_LENGTH);
|
||||||
|
|
||||||
// type
|
|
||||||
mWeb->arg("inv" + String(i) + "Type").toCharArray(buf, 20);
|
|
||||||
uint8_t type = atoi(buf);
|
|
||||||
mEep->write(ADDR_INV_TYPE + i, type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interval = mWeb->arg("invInterval").toInt();
|
interval = mWeb->arg("invInterval").toInt();
|
||||||
|
@ -578,15 +650,18 @@ void app::saveValues(bool webSend = true) {
|
||||||
mEep->write(ADDR_SER_INTERVAL, interval);
|
mEep->write(ADDR_SER_INTERVAL, interval);
|
||||||
tmp = (mWeb->arg("serEn") == "on");
|
tmp = (mWeb->arg("serEn") == "on");
|
||||||
mEep->write(ADDR_SER_ENABLE, (uint8_t)((tmp) ? 0x01 : 0x00));
|
mEep->write(ADDR_SER_ENABLE, (uint8_t)((tmp) ? 0x01 : 0x00));
|
||||||
tmp = (mWeb->arg("serDbg") == "on");
|
mSerialDebug = (mWeb->arg("serDbg") == "on");
|
||||||
mEep->write(ADDR_SER_DEBUG, (uint8_t)((tmp) ? 0x01 : 0x00));
|
mEep->write(ADDR_SER_DEBUG, (uint8_t)((mSerialDebug) ? 0x01 : 0x00));
|
||||||
|
DPRINT("Info: Serial debug is ");
|
||||||
|
if(mSerialDebug) DPRINTLN("on"); else DPRINTLN("off");
|
||||||
|
mSys->Radio.mSerialDebug = mSerialDebug;
|
||||||
|
|
||||||
updateCrc();
|
updateCrc();
|
||||||
if((mWeb->arg("reboot") == "on"))
|
if((mWeb->arg("reboot") == "on"))
|
||||||
showReboot();
|
showReboot();
|
||||||
else {
|
else {
|
||||||
mShowRebootRequest = true;
|
mShowRebootRequest = true;
|
||||||
mWeb->send(200, "text/html", "<!doctype html><html><head><title>Setup saved</title><meta http-equiv=\"refresh\" content=\"3; URL=/setup\"></head><body>"
|
mWeb->send(200, "text/html", "<!doctype html><html><head><title>Setup saved</title><meta http-equiv=\"refresh\" content=\"1; URL=/setup\"></head><body>"
|
||||||
"<p>saved</p></body></html>");
|
"<p>saved</p></body></html>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,8 @@ class app : public Main {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool buildPayload();
|
||||||
|
|
||||||
void showIndex(void);
|
void showIndex(void);
|
||||||
void showSetup(void);
|
void showSetup(void);
|
||||||
void showSave(void);
|
void showSave(void);
|
||||||
|
@ -75,6 +77,10 @@ class app : public Main {
|
||||||
|
|
||||||
uint32_t mPacketIds[DBG_CMD_LIST_LEN+1];
|
uint32_t mPacketIds[DBG_CMD_LIST_LEN+1];
|
||||||
uint32_t mRecCnt;
|
uint32_t mRecCnt;
|
||||||
|
uint8_t mPayload[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE];
|
||||||
|
uint8_t mPayloadLen[MAX_PAYLOAD_ENTRIES];
|
||||||
|
bool mPayloadComplete;
|
||||||
|
uint8_t mMaxPackId;
|
||||||
|
|
||||||
// timer
|
// timer
|
||||||
uint32_t mTicker;
|
uint32_t mTicker;
|
||||||
|
|
|
@ -38,6 +38,9 @@
|
||||||
// maximum buffer length of packet received / sent to RF24 module
|
// maximum buffer length of packet received / sent to RF24 module
|
||||||
#define MAX_RF_PAYLOAD_SIZE 32
|
#define MAX_RF_PAYLOAD_SIZE 32
|
||||||
|
|
||||||
|
// maximum total payload size
|
||||||
|
#define MAX_PAYLOAD_ENTRIES 4
|
||||||
|
|
||||||
// changes the style of "/setup" page, visualized = nicer
|
// changes the style of "/setup" page, visualized = nicer
|
||||||
#define LIVEDATA_VISUALIZED
|
#define LIVEDATA_VISUALIZED
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ uint8_t crc8(uint8_t buf[], uint8_t len) {
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t crc16(uint8_t buf[], uint8_t len) {
|
uint16_t crc16(uint8_t buf[], uint8_t len, uint16_t start) {
|
||||||
uint16_t crc = 0xffff;
|
uint16_t crc = start;
|
||||||
uint8_t shift = 0;
|
uint8_t shift = 0;
|
||||||
|
|
||||||
for(uint8_t i = 0; i < len; i ++) {
|
for(uint8_t i = 0; i < len; i ++) {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#define CRC16_NRF24_POLYNOM 0x1021
|
#define CRC16_NRF24_POLYNOM 0x1021
|
||||||
|
|
||||||
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 crc16(uint8_t buf[], uint8_t len, uint16_t start = 0xffff);
|
||||||
uint16_t crc16nrf24(uint8_t buf[], uint16_t lenBits, uint16_t startBit = 0, uint16_t crcIn = 0xffff);
|
uint16_t crc16nrf24(uint8_t buf[], uint16_t lenBits, uint16_t startBit = 0, uint16_t crcIn = 0xffff);
|
||||||
|
|
||||||
#endif /*__CRC_H__*/
|
#endif /*__CRC_H__*/
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
// VERSION
|
// VERSION
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 3
|
#define VERSION_MINOR 4
|
||||||
#define VERSION_PATCH 9
|
#define VERSION_PATCH 0
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
@ -68,7 +68,7 @@ typedef struct {
|
||||||
|
|
||||||
#define ADDR_INV_ADDR ADDR_RF24_AMP_PWR + RF24_AMP_PWR_LEN
|
#define ADDR_INV_ADDR ADDR_RF24_AMP_PWR + RF24_AMP_PWR_LEN
|
||||||
#define ADDR_INV_NAME ADDR_INV_ADDR + INV_ADDR_LEN
|
#define ADDR_INV_NAME ADDR_INV_ADDR + INV_ADDR_LEN
|
||||||
#define ADDR_INV_TYPE ADDR_INV_NAME + INV_NAME_LEN
|
#define ADDR_INV_TYPE ADDR_INV_NAME + INV_NAME_LEN // obsolete
|
||||||
#define ADDR_INV_INTERVAL ADDR_INV_TYPE + INV_TYPE_LEN
|
#define ADDR_INV_INTERVAL ADDR_INV_TYPE + INV_TYPE_LEN
|
||||||
|
|
||||||
#define ADDR_MQTT_ADDR ADDR_INV_INTERVAL + INV_INTERVAL_LEN
|
#define ADDR_MQTT_ADDR ADDR_INV_INTERVAL + INV_INTERVAL_LEN
|
||||||
|
|
|
@ -25,26 +25,22 @@ const char* const fields[] = {"U_DC", "I_DC", "P_DC", "YieldDay", "YieldWeek", "
|
||||||
|
|
||||||
// indices to calculation functions, defined in hmInverter.h
|
// indices to calculation functions, defined in hmInverter.h
|
||||||
enum {CALC_YT_CH0 = 0, CALC_YD_CH0, CALC_UDC_CH};
|
enum {CALC_YT_CH0 = 0, CALC_YD_CH0, CALC_UDC_CH};
|
||||||
|
enum {CMD_CALC = 0xffff};
|
||||||
|
|
||||||
|
|
||||||
// CH0 is default channel (freq, ac, temp)
|
// CH0 is default channel (freq, ac, temp)
|
||||||
enum {CH0 = 0, CH1, CH2, CH3, CH4};
|
enum {CH0 = 0, CH1, CH2, CH3, CH4};
|
||||||
// received command ids, special command CMDFF for calculations
|
|
||||||
enum {CMD01 = 0x01, CMD02, CMD03, CMD82 = 0x82, CMD83, CMD84, CMDFF=0xff};
|
|
||||||
|
|
||||||
enum {INV_TYPE_HM600 = 0, INV_TYPE_HM1200, INV_TYPE_HM400, INV_TYPE_HM800};
|
enum {INV_TYPE_1CH = 0, INV_TYPE_2CH, INV_TYPE_4CH};
|
||||||
const char* const invTypes[] = {"HM600", "HM1200 / HM1500", "HM400", "HM800"};
|
|
||||||
#define NUM_INVERTER_TYPES 4
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t fieldId; // field id
|
uint8_t fieldId; // field id
|
||||||
uint8_t unitId; // uint id
|
uint8_t unitId; // uint id
|
||||||
uint8_t ch; // channel 0 - 3
|
uint8_t ch; // channel 0 - 4
|
||||||
uint8_t cmdId; // received command id
|
|
||||||
uint8_t start; // pos of first byte in buffer
|
uint8_t start; // pos of first byte in buffer
|
||||||
uint8_t num; // number of bytes in buffer
|
uint8_t num; // number of bytes in buffer
|
||||||
uint16_t div; // divisor
|
uint16_t div; // divisor / calc command
|
||||||
} byteAssign_t;
|
} byteAssign_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,106 +50,88 @@ typedef struct {
|
||||||
* */
|
* */
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
// HM400 HM350?, HM300?
|
// HM300, HM350, HM400
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
const byteAssign_t hm400assignment[] = {
|
const byteAssign_t hm1chAssignment[] = {
|
||||||
{ FLD_UDC, UNIT_V, CH1, CMD01, 3, 2, 10 },
|
{ FLD_UDC, UNIT_V, CH1, 2, 2, 10 },
|
||||||
{ FLD_IDC, UNIT_A, CH1, CMD01, 5, 2, 100 },
|
{ FLD_IDC, UNIT_A, CH1, 4, 2, 100 },
|
||||||
{ FLD_PDC, UNIT_W, CH1, CMD01, 7, 2, 10 },
|
{ FLD_PDC, UNIT_W, CH1, 6, 2, 10 },
|
||||||
{ FLD_YT, UNIT_KWH, CH1, CMD01, 9, 4, 1000 },
|
{ FLD_YD, UNIT_WH, CH1, 12, 2, 1 },
|
||||||
{ FLD_YD, UNIT_WH, CH1, CMD01, 13, 2, 1 },
|
{ FLD_YT, UNIT_KWH, CH1, 8, 4, 1000 },
|
||||||
{ FLD_UAC, UNIT_V, CH0, CMD01, 15, 2, 10 },
|
|
||||||
{ FLD_F, UNIT_HZ, CH0, CMD82, 1, 2, 100 },
|
{ FLD_UAC, UNIT_V, CH0, 14, 2, 10 },
|
||||||
{ FLD_PAC, UNIT_W, CH0, CMD82, 3, 2, 10 },
|
{ FLD_IAC, UNIT_A, CH0, 22, 2, 100 },
|
||||||
{ FLD_IAC, UNIT_A, CH0, CMD82, 7, 2, 100 },
|
{ FLD_PAC, UNIT_W, CH0, 18, 2, 10 },
|
||||||
{ FLD_T, UNIT_C, CH0, CMD82, 11, 2, 10 }
|
{ FLD_F, UNIT_HZ, CH0, 16, 2, 100 },
|
||||||
|
{ FLD_T, UNIT_C, CH0, 26, 2, 10 }
|
||||||
};
|
};
|
||||||
#define HM400_LIST_LEN (sizeof(hm400assignment) / sizeof(byteAssign_t))
|
#define HM1CH_LIST_LEN (sizeof(hm1chAssignment) / sizeof(byteAssign_t))
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
// HM600, HM700
|
// HM600, HM700, HM800
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
const byteAssign_t hm600assignment[] = {
|
const byteAssign_t hm2chAssignment[] = {
|
||||||
{ FLD_UDC, UNIT_V, CH1, CMD01, 3, 2, 10 },
|
{ FLD_UDC, UNIT_V, CH1, 2, 2, 10 },
|
||||||
{ FLD_IDC, UNIT_A, CH1, CMD01, 5, 2, 100 },
|
{ FLD_IDC, UNIT_A, CH1, 4, 2, 100 },
|
||||||
{ FLD_PDC, UNIT_W, CH1, CMD01, 7, 2, 10 },
|
{ FLD_PDC, UNIT_W, CH1, 6, 2, 10 },
|
||||||
{ FLD_UDC, UNIT_V, CH2, CMD01, 9, 2, 10 },
|
{ FLD_YD, UNIT_WH, CH1, 22, 2, 1 },
|
||||||
{ FLD_IDC, UNIT_A, CH2, CMD01, 11, 2, 100 },
|
{ FLD_YD, UNIT_KWH, CH1, 14, 4, 1000 },
|
||||||
{ FLD_PDC, UNIT_W, CH2, CMD01, 13, 2, 10 },
|
|
||||||
{ FLD_YW, UNIT_WH, CH0, CMD02, 1, 2, 1 },
|
{ FLD_UDC, UNIT_V, CH2, 8, 2, 10 },
|
||||||
{ FLD_YT, UNIT_KWH, CH0, CMD02, 3, 4, 1000 },
|
{ FLD_IDC, UNIT_A, CH2, 10, 2, 100 },
|
||||||
{ FLD_YD, UNIT_WH, CH1, CMD02, 7, 2, 1 },
|
{ FLD_PDC, UNIT_W, CH2, 12, 2, 10 },
|
||||||
{ FLD_YD, UNIT_WH, CH2, CMD02, 9, 2, 1 },
|
{ FLD_YD, UNIT_WH, CH2, 18, 2, 1 },
|
||||||
{ FLD_UAC, UNIT_V, CH0, CMD02, 11, 2, 10 },
|
{ FLD_YD, UNIT_KWH, CH2, 24, 4, 1000 },
|
||||||
{ FLD_F, UNIT_HZ, CH0, CMD02, 13, 2, 100 },
|
|
||||||
{ FLD_PAC, UNIT_W, CH0, CMD02, 15, 2, 10 },
|
{ FLD_UAC, UNIT_V, CH0, 26, 2, 10 },
|
||||||
{ FLD_IAC, UNIT_A, CH0, CMD83, 3, 2, 100 },
|
{ FLD_IAC, UNIT_A, CH0, 34, 2, 10 },
|
||||||
{ FLD_T, UNIT_C, CH0, CMD83, 7, 2, 10 }
|
{ FLD_PAC, UNIT_W, CH0, 30, 2, 10 },
|
||||||
|
{ FLD_F, UNIT_HZ, CH0, 28, 2, 100 },
|
||||||
|
{ FLD_T, UNIT_C, CH0, 38, 2, 10 }
|
||||||
|
|
||||||
};
|
};
|
||||||
#define HM600_LIST_LEN (sizeof(hm600assignment) / sizeof(byteAssign_t))
|
#define HM2CH_LIST_LEN (sizeof(hm2chAssignment) / sizeof(byteAssign_t))
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------
|
|
||||||
// HM800
|
|
||||||
//-------------------------------------
|
|
||||||
const byteAssign_t hm800assignment[] = {
|
|
||||||
|
|
||||||
{ FLD_UDC, UNIT_V, CH1, CMD01, 3, 2, 10 },
|
|
||||||
{ FLD_IDC, UNIT_A, CH1, CMD01, 5, 2, 100 },
|
|
||||||
{ FLD_PDC, UNIT_W, CH1, CMD01, 7, 2, 10 },
|
|
||||||
{ FLD_UDC, UNIT_V, CH2, CMD01, 9, 2, 10 },
|
|
||||||
{ FLD_IDC, UNIT_A, CH2, CMD01, 11, 2, 100 },
|
|
||||||
{ FLD_PDC, UNIT_W, CH2, CMD01, 13, 2, 10 },
|
|
||||||
{ FLD_YW, UNIT_WH, CH0, CMD02, 1, 2, 1 },
|
|
||||||
{ FLD_YT, UNIT_KWH, CH0, CMD02, 3, 4, 1000 },
|
|
||||||
{ FLD_YD, UNIT_WH, CH1, CMD02, 7, 2, 1 },
|
|
||||||
{ FLD_YD, UNIT_WH, CH2, CMD02, 9, 2, 1 },
|
|
||||||
{ FLD_UAC, UNIT_V, CH0, CMD02, 11, 2, 10 },
|
|
||||||
{ FLD_F, UNIT_HZ, CH0, CMD02, 13, 2, 100 },
|
|
||||||
{ FLD_PAC, UNIT_W, CH0, CMD02, 15, 2, 10 },
|
|
||||||
{ FLD_IAC, UNIT_A, CH0, CMD83, 3, 2, 100 },
|
|
||||||
{ FLD_T, UNIT_C, CH0, CMD83, 7, 2, 10 }
|
|
||||||
};
|
|
||||||
#define HM800_LIST_LEN (sizeof(hm800assignment) / sizeof(byteAssign_t))
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
// HM1200, HM1500
|
// HM1200, HM1500
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
const byteAssign_t hm1200assignment[] = {
|
const byteAssign_t hm4chAssignment[] = {
|
||||||
{ FLD_UDC, UNIT_V, CH1, CMD01, 3, 2, 10 },
|
{ FLD_UDC, UNIT_V, CH1, 2, 2, 10 },
|
||||||
{ FLD_IDC, UNIT_A, CH1, CMD01, 5, 2, 100 },
|
{ FLD_IDC, UNIT_A, CH1, 4, 2, 100 },
|
||||||
{ FLD_PDC, UNIT_W, CH1, CMD01, 9, 2, 10 },
|
{ FLD_PDC, UNIT_W, CH1, 8, 2, 10 },
|
||||||
{ FLD_YD, UNIT_WH, CH1, CMD02, 5, 2, 1 },
|
{ FLD_YD, UNIT_WH, CH1, 20, 2, 1 },
|
||||||
{ FLD_YT, UNIT_KWH, CH1, CMD01, 13, 4, 1000 },
|
{ FLD_YT, UNIT_KWH, CH1, 12, 4, 1000 },
|
||||||
{ FLD_UDC, UNIT_V, CH3, CMD02, 9, 2, 10 },
|
|
||||||
{ FLD_IDC, UNIT_A, CH2, CMD01, 7, 2, 100 },
|
{ FLD_UDC, UNIT_V, CH2, CALC_UDC_CH, CH1, CMD_CALC },
|
||||||
{ FLD_PDC, UNIT_W, CH2, CMD01, 11, 2, 10 },
|
{ FLD_IDC, UNIT_A, CH2, 6, 2, 100 },
|
||||||
{ FLD_YD, UNIT_WH, CH2, CMD02, 7, 2, 1 },
|
{ FLD_PDC, UNIT_W, CH2, 10, 2, 10 },
|
||||||
{ FLD_YT, UNIT_KWH, CH2, CMD02, 1, 4, 1000 },
|
{ FLD_YD, UNIT_WH, CH2, 22, 2, 1 },
|
||||||
{ FLD_IDC, UNIT_A, CH3, CMD02, 11, 2, 100 },
|
{ FLD_YT, UNIT_KWH, CH2, 16, 4, 1000 },
|
||||||
{ FLD_PDC, UNIT_W, CH3, CMD02, 15, 2, 10 },
|
|
||||||
{ FLD_YD, UNIT_WH, CH3, CMD03, 11, 2, 1 },
|
{ FLD_UDC, UNIT_V, CH3, 24, 2, 10 },
|
||||||
{ FLD_YT, UNIT_KWH, CH3, CMD03, 3, 4, 1000 },
|
{ FLD_IDC, UNIT_A, CH3, 26, 2, 100 },
|
||||||
{ FLD_IDC, UNIT_A, CH4, CMD02, 13, 2, 100 },
|
{ FLD_PDC, UNIT_W, CH3, 30, 2, 10 },
|
||||||
{ FLD_PDC, UNIT_W, CH4, CMD03, 1, 2, 10 },
|
{ FLD_YD, UNIT_WH, CH3, 42, 2, 1 },
|
||||||
{ FLD_YD, UNIT_WH, CH4, CMD03, 13, 2, 1 },
|
{ FLD_YT, UNIT_KWH, CH3, 34, 4, 1000 },
|
||||||
{ FLD_YT, UNIT_KWH, CH4, CMD03, 7, 4, 1000 },
|
|
||||||
{ FLD_UAC, UNIT_V, CH0, CMD03, 15, 2, 10 },
|
{ FLD_UDC, UNIT_V, CH4, CALC_UDC_CH, CH3, CMD_CALC },
|
||||||
{ FLD_IAC, UNIT_A, CH0, CMD84, 7, 2, 100 },
|
{ FLD_IDC, UNIT_A, CH4, 28, 2, 100 },
|
||||||
{ FLD_PAC, UNIT_W, CH0, CMD84, 3, 2, 10 },
|
{ FLD_PDC, UNIT_W, CH4, 32, 2, 10 },
|
||||||
{ FLD_F, UNIT_HZ, CH0, CMD84, 1, 2, 100 },
|
{ FLD_YD, UNIT_WH, CH4, 44, 2, 1 },
|
||||||
{ FLD_PCT, UNIT_PCT, CH0, CMD84, 9, 2, 10 },
|
{ FLD_YT, UNIT_KWH, CH4, 38, 4, 1000 },
|
||||||
{ FLD_T, UNIT_C, CH0, CMD84, 11, 2, 10 },
|
|
||||||
{ FLD_YD, UNIT_WH, CH0, CMDFF, CALC_YD_CH0, 0, 0 },
|
{ FLD_UAC, UNIT_V, CH0, 46, 2, 10 },
|
||||||
{ FLD_YT, UNIT_KWH, CH0, CMDFF, CALC_YT_CH0, 0, 0 },
|
{ FLD_IAC, UNIT_A, CH0, 54, 2, 100 },
|
||||||
{ FLD_UDC, UNIT_V, CH2, CMDFF, CALC_UDC_CH, CH1, 0 },
|
{ FLD_PAC, UNIT_W, CH0, 50, 2, 10 },
|
||||||
{ FLD_UDC, UNIT_V, CH4, CMDFF, CALC_UDC_CH, CH3, 0 }
|
{ FLD_F, UNIT_HZ, CH0, 48, 2, 100 },
|
||||||
|
{ FLD_PCT, UNIT_PCT, CH0, 56, 2, 10 },
|
||||||
|
{ FLD_T, UNIT_C, CH0, 58, 2, 10 },
|
||||||
|
{ FLD_YD, UNIT_WH, CH0, CALC_YD_CH0, 0, CMD_CALC },
|
||||||
|
{ FLD_YT, UNIT_KWH, CH0, CALC_YT_CH0, 0, CMD_CALC }
|
||||||
};
|
};
|
||||||
#define HM1200_LIST_LEN (sizeof(hm1200assignment) / sizeof(byteAssign_t))
|
#define HM4CH_LIST_LEN (sizeof(hm4chAssignment) / sizeof(byteAssign_t))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*__HM_DEFINES_H__*/
|
#endif /*__HM_DEFINES_H__*/
|
||||||
|
|
|
@ -95,15 +95,12 @@ class Inverter {
|
||||||
return assign[pos].ch;
|
return assign[pos].ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t getCmdId(uint8_t pos) {
|
|
||||||
return assign[pos].cmdId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addValue(uint8_t pos, uint8_t buf[]) {
|
void addValue(uint8_t pos, uint8_t buf[]) {
|
||||||
uint8_t ptr = assign[pos].start;
|
uint8_t ptr = assign[pos].start;
|
||||||
uint8_t end = ptr + assign[pos].num;
|
uint8_t end = ptr + assign[pos].num;
|
||||||
uint16_t div = assign[pos].div;
|
uint16_t div = assign[pos].div;
|
||||||
|
|
||||||
|
if(CMD_CALC != div) {
|
||||||
uint32_t val = 0;
|
uint32_t val = 0;
|
||||||
do {
|
do {
|
||||||
val <<= 8;
|
val <<= 8;
|
||||||
|
@ -112,6 +109,7 @@ class Inverter {
|
||||||
|
|
||||||
record[pos] = (RECORDTYPE)(val) / (RECORDTYPE)(div);
|
record[pos] = (RECORDTYPE)(val) / (RECORDTYPE)(div);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RECORDTYPE getValue(uint8_t pos) {
|
RECORDTYPE getValue(uint8_t pos) {
|
||||||
return record[pos];
|
return record[pos];
|
||||||
|
@ -119,7 +117,7 @@ class Inverter {
|
||||||
|
|
||||||
void doCalculations(void) {
|
void doCalculations(void) {
|
||||||
for(uint8_t i = 0; i < listLen; i++) {
|
for(uint8_t i = 0; i < listLen; i++) {
|
||||||
if(CMDFF == assign[i].cmdId) {
|
if(CMD_CALC == assign[i].div) {
|
||||||
record[i] = calcFunctions<RECORDTYPE>[assign[i].start].func(this, assign[i].num);
|
record[i] = calcFunctions<RECORDTYPE>[assign[i].start].func(this, assign[i].num);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,24 +134,19 @@ class Inverter {
|
||||||
}
|
}
|
||||||
|
|
||||||
void getAssignment(void) {
|
void getAssignment(void) {
|
||||||
if(INV_TYPE_HM400 == type) {
|
if(INV_TYPE_1CH == type) {
|
||||||
listLen = (uint8_t)(HM400_LIST_LEN);
|
listLen = (uint8_t)(HM1CH_LIST_LEN);
|
||||||
assign = (byteAssign_t*)hm400assignment;
|
assign = (byteAssign_t*)hm1chAssignment;
|
||||||
channels = 1;
|
channels = 1;
|
||||||
}
|
}
|
||||||
else if(INV_TYPE_HM600 == type) {
|
else if(INV_TYPE_2CH == type) {
|
||||||
listLen = (uint8_t)(HM600_LIST_LEN);
|
listLen = (uint8_t)(HM2CH_LIST_LEN);
|
||||||
assign = (byteAssign_t*)hm600assignment;
|
assign = (byteAssign_t*)hm2chAssignment;
|
||||||
channels = 2;
|
channels = 2;
|
||||||
}
|
}
|
||||||
else if(INV_TYPE_HM800 == type) {
|
else if(INV_TYPE_4CH == type) {
|
||||||
listLen = (uint8_t)(HM800_LIST_LEN);
|
listLen = (uint8_t)(HM4CH_LIST_LEN);
|
||||||
assign = (byteAssign_t*)hm800assignment;
|
assign = (byteAssign_t*)hm4chAssignment;
|
||||||
channels = 2;
|
|
||||||
}
|
|
||||||
else if(INV_TYPE_HM1200 == type) {
|
|
||||||
listLen = (uint8_t)(HM1200_LIST_LEN);
|
|
||||||
assign = (byteAssign_t*)hm1200assignment;
|
|
||||||
channels = 4;
|
channels = 4;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -58,14 +58,14 @@ class HmRadio {
|
||||||
mRxChIdx = 0;
|
mRxChIdx = 0;
|
||||||
mRxLoopCnt = RX_LOOP_CNT;
|
mRxLoopCnt = RX_LOOP_CNT;
|
||||||
|
|
||||||
//calcDtuCrc();
|
|
||||||
|
|
||||||
pinCs = CS_PIN;
|
pinCs = CS_PIN;
|
||||||
pinCe = CE_PIN;
|
pinCe = CE_PIN;
|
||||||
pinIrq = IRQ_PIN;
|
pinIrq = IRQ_PIN;
|
||||||
|
|
||||||
AmplifierPower = 1;
|
AmplifierPower = 1;
|
||||||
mSendCnt = 0;
|
mSendCnt = 0;
|
||||||
|
|
||||||
|
mSerialDebug = false;
|
||||||
}
|
}
|
||||||
~HmRadio() {}
|
~HmRadio() {}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ class HmRadio {
|
||||||
if(!mBufCtrl->full()) {
|
if(!mBufCtrl->full()) {
|
||||||
p = mBufCtrl->getFront();
|
p = mBufCtrl->getFront();
|
||||||
memset(p->packet, 0xcc, MAX_RF_PAYLOAD_SIZE);
|
memset(p->packet, 0xcc, MAX_RF_PAYLOAD_SIZE);
|
||||||
p->rxCh = mRxChIdx;
|
p->rxCh = mRxChLst[mRxChIdx];
|
||||||
len = mNrf24.getPayloadSize();
|
len = mNrf24.getPayloadSize();
|
||||||
if(len > MAX_RF_PAYLOAD_SIZE)
|
if(len > MAX_RF_PAYLOAD_SIZE)
|
||||||
len = MAX_RF_PAYLOAD_SIZE;
|
len = MAX_RF_PAYLOAD_SIZE;
|
||||||
|
@ -156,19 +156,19 @@ class HmRadio {
|
||||||
sendPacket(invId, mTxBuf, 27, true);
|
sendPacket(invId, mTxBuf, 27, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendCmdPacket(uint64_t invId, uint8_t mid, uint8_t cmd, bool calcCrc = true) {
|
void sendCmdPacket(uint64_t invId, uint8_t mid, uint8_t pid, bool calcCrc = true) {
|
||||||
memset(mTxBuf, 0, MAX_RF_PAYLOAD_SIZE);
|
memset(mTxBuf, 0, MAX_RF_PAYLOAD_SIZE);
|
||||||
mTxBuf[0] = mid; // message id
|
mTxBuf[0] = mid; // message id
|
||||||
CP_U32_BigEndian(&mTxBuf[1], (invId >> 8));
|
CP_U32_BigEndian(&mTxBuf[1], (invId >> 8));
|
||||||
CP_U32_BigEndian(&mTxBuf[5], (DTU_ID >> 8));
|
CP_U32_BigEndian(&mTxBuf[5], (DTU_ID >> 8));
|
||||||
mTxBuf[9] = cmd;
|
mTxBuf[9] = pid;
|
||||||
if(calcCrc) {
|
if(calcCrc) {
|
||||||
mTxBuf[10] = crc8(mTxBuf, 10);
|
mTxBuf[10] = crc8(mTxBuf, 10);
|
||||||
sendPacket(invId, mTxBuf, 11, false);
|
sendPacket(invId, mTxBuf, 11, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkPaketCrc(uint8_t buf[], uint8_t *len, uint8_t *rptCnt, uint8_t rxCh) {
|
bool checkPaketCrc(uint8_t buf[], uint8_t *len, uint8_t rxCh) {
|
||||||
*len = (buf[0] >> 2);
|
*len = (buf[0] >> 2);
|
||||||
if(*len > (MAX_RF_PAYLOAD_SIZE - 2))
|
if(*len > (MAX_RF_PAYLOAD_SIZE - 2))
|
||||||
*len = MAX_RF_PAYLOAD_SIZE - 2;
|
*len = MAX_RF_PAYLOAD_SIZE - 2;
|
||||||
|
@ -179,17 +179,10 @@ class HmRadio {
|
||||||
uint8_t crc = crc8(buf, *len-1);
|
uint8_t crc = crc8(buf, *len-1);
|
||||||
bool valid = (crc == buf[*len-1]);
|
bool valid = (crc == buf[*len-1]);
|
||||||
|
|
||||||
if(valid) {
|
//if(valid) {
|
||||||
if(mLastCrc == crc)
|
//mRxStat[(buf[9] & 0x7F)-1]++;
|
||||||
*rptCnt = (++mRptCnt);
|
//mRxChStat[(buf[9] & 0x7F)-1][rxCh & 0x7]++;
|
||||||
else {
|
//}
|
||||||
mRptCnt = 0;
|
|
||||||
*rptCnt = 0;
|
|
||||||
mLastCrc = crc;
|
|
||||||
}
|
|
||||||
mRxStat[(buf[9] & 0x7F)-1]++;
|
|
||||||
mRxChStat[(buf[9] & 0x7F)-1][rxCh & 0x7]++;
|
|
||||||
}
|
|
||||||
/*else {
|
/*else {
|
||||||
DPRINT("CRC wrong: ");
|
DPRINT("CRC wrong: ");
|
||||||
DHEX(crc);
|
DHEX(crc);
|
||||||
|
@ -215,6 +208,7 @@ class HmRadio {
|
||||||
}
|
}
|
||||||
|
|
||||||
void dumpBuf(const char *info, uint8_t buf[], uint8_t len) {
|
void dumpBuf(const char *info, uint8_t buf[], uint8_t len) {
|
||||||
|
if(NULL != info)
|
||||||
DPRINT(String(info));
|
DPRINT(String(info));
|
||||||
for(uint8_t i = 0; i < len; i++) {
|
for(uint8_t i = 0; i < len; i++) {
|
||||||
DHEX(buf[i]);
|
DHEX(buf[i]);
|
||||||
|
@ -234,16 +228,22 @@ class HmRadio {
|
||||||
uint8_t AmplifierPower;
|
uint8_t AmplifierPower;
|
||||||
uint32_t mSendCnt;
|
uint32_t mSendCnt;
|
||||||
|
|
||||||
|
bool mSerialDebug;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void sendPacket(uint64_t invId, uint8_t buf[], uint8_t len, bool clear=false) {
|
void sendPacket(uint64_t invId, uint8_t buf[], uint8_t len, bool clear=false) {
|
||||||
//DPRINTLN("sent packet: #" + String(mSendCnt));
|
//DPRINTLN("sent packet: #" + String(mSendCnt));
|
||||||
//dumpBuf("SEN ", buf, len);
|
//dumpBuf("SEN ", buf, len);
|
||||||
|
if(mSerialDebug) {
|
||||||
|
DPRINT("Transmit " + String(len) + " | ");
|
||||||
|
dumpBuf(NULL, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
DISABLE_IRQ;
|
DISABLE_IRQ;
|
||||||
mNrf24.stopListening();
|
mNrf24.stopListening();
|
||||||
|
|
||||||
if(clear) {
|
if(clear) {
|
||||||
uint8_t cnt = 4;
|
/*uint8_t cnt = 4;
|
||||||
for(uint8_t i = 0; i < 4; i ++) {
|
for(uint8_t i = 0; i < 4; i ++) {
|
||||||
DPRINT(String(mRxStat[i]) + " (");
|
DPRINT(String(mRxStat[i]) + " (");
|
||||||
for(uint8_t j = 0; j < 4; j++) {
|
for(uint8_t j = 0; j < 4; j++) {
|
||||||
|
@ -258,7 +258,7 @@ class HmRadio {
|
||||||
else
|
else
|
||||||
DPRINTLN(" -> missing: " + String(cnt));
|
DPRINTLN(" -> missing: " + String(cnt));
|
||||||
memset(mRxStat, 0, 4);
|
memset(mRxStat, 0, 4);
|
||||||
memset(mRxChStat, 0, 4*8);
|
memset(mRxChStat, 0, 4*8);*/
|
||||||
mRxLoopCnt = RX_LOOP_CNT;
|
mRxLoopCnt = RX_LOOP_CNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,34 +295,19 @@ class HmRadio {
|
||||||
return mRxChLst[mRxChIdx];
|
return mRxChLst[mRxChIdx];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*void calcDtuCrc(void) {
|
|
||||||
uint64_t addr = DTU_RADIO_ID;
|
|
||||||
uint8_t tmp[5];
|
|
||||||
for(int8_t i = 4; i >= 0; i--) {
|
|
||||||
tmp[i] = addr;
|
|
||||||
addr >>= 8;
|
|
||||||
}
|
|
||||||
mDtuIdCrc = crc16nrf24(tmp, BIT_CNT(5));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
uint8_t mTxCh;
|
uint8_t mTxCh;
|
||||||
uint8_t mTxChLst[1];
|
uint8_t mTxChLst[1];
|
||||||
//uint8_t mTxChIdx;
|
//uint8_t mTxChIdx;
|
||||||
|
|
||||||
uint8_t mRxChLst[4];
|
uint8_t mRxChLst[4];
|
||||||
uint8_t mRxChIdx;
|
uint8_t mRxChIdx;
|
||||||
uint8_t mRxStat[4];
|
//uint8_t mRxStat[4];
|
||||||
uint8_t mRxChStat[4][8];
|
//uint8_t mRxChStat[4][8];
|
||||||
uint16_t mRxLoopCnt;
|
uint16_t mRxLoopCnt;
|
||||||
|
|
||||||
//uint16_t mDtuIdCrc;
|
|
||||||
uint16_t mLastCrc;
|
|
||||||
uint8_t mRptCnt;
|
|
||||||
|
|
||||||
RF24 mNrf24;
|
RF24 mNrf24;
|
||||||
BUFFER *mBufCtrl;
|
BUFFER *mBufCtrl;
|
||||||
uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE];
|
uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*__RADIO_H__*/
|
#endif /*__RADIO_H__*/
|
||||||
|
|
|
@ -27,7 +27,7 @@ class HmSystem {
|
||||||
Radio.setup(&BufCtrl);
|
Radio.setup(&BufCtrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
INVERTERTYPE *addInverter(const char *name, uint64_t serial, uint8_t type) {
|
INVERTERTYPE *addInverter(const char *name, uint64_t serial) {
|
||||||
if(MAX_INVERTER <= mNumInv) {
|
if(MAX_INVERTER <= mNumInv) {
|
||||||
DPRINT("max number of inverters reached!");
|
DPRINT("max number of inverters reached!");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -35,7 +35,19 @@ class HmSystem {
|
||||||
INVERTERTYPE *p = &mInverter[mNumInv];
|
INVERTERTYPE *p = &mInverter[mNumInv];
|
||||||
p->id = mNumInv;
|
p->id = mNumInv;
|
||||||
p->serial.u64 = serial;
|
p->serial.u64 = serial;
|
||||||
p->type = type;
|
DPRINT("SERIAL: " + String(p->serial.b[5], HEX));
|
||||||
|
DPRINTLN(" " + String(p->serial.b[4], HEX));
|
||||||
|
if(p->serial.b[5] == 0x11) {
|
||||||
|
switch(p->serial.b[4]) {
|
||||||
|
case 0x21: p->type = INV_TYPE_1CH; break;
|
||||||
|
case 0x41: p->type = INV_TYPE_2CH; break;
|
||||||
|
case 0x61: p->type = INV_TYPE_4CH; break;
|
||||||
|
default: DPRINTLN("unknown inverter type: 11" + String(p->serial.b[4], HEX)); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DPRINTLN("inverter type can't be detected!");
|
||||||
|
|
||||||
p->init();
|
p->init();
|
||||||
uint8_t len = (uint8_t)strlen(name);
|
uint8_t len = (uint8_t)strlen(name);
|
||||||
strncpy(p->name, name, (len > MAX_NAME_LENGTH) ? MAX_NAME_LENGTH : len);
|
strncpy(p->name, name, (len > MAX_NAME_LENGTH) ? MAX_NAME_LENGTH : len);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue