diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index 7eee08bf..472aeeb3 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -25,6 +25,11 @@ app::app() : Main() { 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(); } @@ -50,21 +55,20 @@ void app::setup(uint32_t timeout) { if(mSettingsValid) { uint64_t invSerial; char invName[MAX_NAME_LENGTH + 1] = {0}; - uint8_t invType; // inverter for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { 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_TYPE + i, &invType); if(0ULL != invSerial) { - mSys->addInverter(invName, invSerial, invType); - DPRINTLN("add inverter: " + String(invName) + ", SN: " + String(invSerial, HEX) + ", type: " + String(invType)); + mSys->addInverter(invName, invSerial); + DPRINTLN("add inverter: " + String(invName) + ", SN: " + String(invSerial, HEX)); } } mEep->read(ADDR_INV_INTERVAL, &mSendInterval); if(mSendInterval < 5) mSendInterval = 5; + mSendTicker = mSendInterval; // pinout mEep->read(ADDR_PINOUT, &mSys->Radio.pinCs); @@ -84,6 +88,7 @@ void app::setup(uint32_t timeout) { mSerialDebug = (tmp == 0x01); if(mSerialInterval < 1) mSerialInterval = 1; + mSys->Radio.mSerialDebug = mSerialDebug; // mqtt @@ -134,31 +139,39 @@ void app::loop(void) { Main::loop(); if(checkTicker(&mRxTicker, 5)) { - mSys->Radio.switchRxCh(); + bool rcvRdy = mSys->Radio.switchRxCh(); + if(!mSys->BufCtrl.empty()) { - uint8_t len, rptCnt; + uint8_t len; packet_t *p = mSys->BufCtrl.getBack(); - //if(mSerialDebug) - // mSys->Radio.dumpBuf("RAW ", p->packet, MAX_RF_PAYLOAD_SIZE); - - if(mSys->Radio.checkPaketCrc(p->packet, &len, &rptCnt, p->rxCh)) { + if(mSys->Radio.checkPaketCrc(p->packet, &len, p->rxCh)) { // process buffer only on first occurrence - if((0 != len) && (0 == rptCnt)) { + if(mSerialDebug) { + DPRINT("Received " + String(len) + " bytes channel " + String(p->rxCh) + ": "); + mSys->Radio.dumpBuf(NULL, p->packet, len); + } + + if(0 != len) { uint8_t *packetId = &p->packet[9]; - //DPRINTLN("CMD " + String(*packetId, HEX)); - if(mSerialDebug) - mSys->Radio.dumpBuf("Payload ", p->packet, len); + 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]); + /*Inverter<> *iv = mSys->findInverter(&p->packet[1]); if(NULL != iv) { for(uint8_t i = 0; i < iv->listLen; i++) { if(iv->assign[i].cmdId == *packetId) iv->addValue(i, &p->packet[9]); } iv->doCalculations(); - //memcpy(mPayload[(*packetId & 0x7F) - 1], &p->packet[9], MAX_RF_PAYLOAD_SIZE - 11); - } + }*/ if(*packetId == 0x01) mPacketIds[0]++; else if(*packetId == 0x02) mPacketIds[1]++; @@ -170,8 +183,49 @@ void app::loop(void) { else mPacketIds[7]++; } } + 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)) { @@ -220,8 +274,18 @@ void app::loop(void) { if(++mSendTicker >= mSendInterval) { mSendTicker = 0; - if(!mSys->BufCtrl.empty()) - DPRINTLN("recbuf not empty! #" + String(mSys->BufCtrl.getFill())); + 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())); + } Inverter<> *inv; for(uint8_t i = 0; i < MAX_NUM_INVERTERS; 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) { String html = FPSTR(index_html); @@ -276,7 +364,6 @@ void app::showSetup(void) { for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { 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_TYPE + i, &invType); inv += "

Inverter "+ String(i) + "

"; inv += ""; @@ -289,16 +376,6 @@ void app::showSetup(void) { inv += ""; - - inv += ""; - inv += ""; } html.replace("{INVERTERS}", String(inv)); @@ -371,7 +448,7 @@ void app::showSetup(void) { html.replace("{MQTT_PORT}", "1883"); html.replace("{MQTT_USER}", ""); html.replace("{MQTT_PWD}", ""); - html.replace("{MQTT_TOPIC}", "/inverter"); + html.replace("{MQTT_TOPIC}", "inverter"); html.replace("{MQTT_INTVL}", "10"); html.replace("{SER_INTVL}", "10"); @@ -440,10 +517,10 @@ void app::showLiveData(void) { #ifdef LIVEDATA_VISUALIZED uint8_t modNum, pos; switch(iv->type) { - default: modNum = 1; break; - case INV_TYPE_HM600: - case INV_TYPE_HM800: modNum = 2; break; - case INV_TYPE_HM1200: modNum = 4; break; + default: modNum = 1; break; + case INV_TYPE_1CH: + case INV_TYPE_2CH: modNum = 2; break; + case INV_TYPE_4CH: modNum = 4; break; } modHtml += "
"; @@ -524,11 +601,6 @@ void app::saveValues(bool webSend = true) { // name mWeb->arg("inv" + String(i) + "Name").toCharArray(buf, 20); 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(); @@ -578,15 +650,18 @@ void app::saveValues(bool webSend = true) { mEep->write(ADDR_SER_INTERVAL, interval); tmp = (mWeb->arg("serEn") == "on"); mEep->write(ADDR_SER_ENABLE, (uint8_t)((tmp) ? 0x01 : 0x00)); - tmp = (mWeb->arg("serDbg") == "on"); - mEep->write(ADDR_SER_DEBUG, (uint8_t)((tmp) ? 0x01 : 0x00)); + mSerialDebug = (mWeb->arg("serDbg") == "on"); + 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(); if((mWeb->arg("reboot") == "on")) showReboot(); else { mShowRebootRequest = true; - mWeb->send(200, "text/html", "Setup saved" + mWeb->send(200, "text/html", "Setup saved" "

saved

"); } } diff --git a/tools/esp8266/app.h b/tools/esp8266/app.h index 26efc6e7..e1047a80 100644 --- a/tools/esp8266/app.h +++ b/tools/esp8266/app.h @@ -40,6 +40,8 @@ class app : public Main { } private: + bool buildPayload(); + void showIndex(void); void showSetup(void); void showSave(void); @@ -75,6 +77,10 @@ class app : public Main { uint32_t mPacketIds[DBG_CMD_LIST_LEN+1]; 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 uint32_t mTicker; diff --git a/tools/esp8266/config.h b/tools/esp8266/config.h index c37f979a..e96ab5cb 100644 --- a/tools/esp8266/config.h +++ b/tools/esp8266/config.h @@ -38,6 +38,9 @@ // maximum buffer length of packet received / sent to RF24 module #define MAX_RF_PAYLOAD_SIZE 32 +// maximum total payload size +#define MAX_PAYLOAD_ENTRIES 4 + // changes the style of "/setup" page, visualized = nicer #define LIVEDATA_VISUALIZED diff --git a/tools/esp8266/crc.cpp b/tools/esp8266/crc.cpp index be2d8a57..7694dadd 100644 --- a/tools/esp8266/crc.cpp +++ b/tools/esp8266/crc.cpp @@ -11,8 +11,8 @@ uint8_t crc8(uint8_t buf[], uint8_t len) { return crc; } -uint16_t crc16(uint8_t buf[], uint8_t len) { - uint16_t crc = 0xffff; +uint16_t crc16(uint8_t buf[], uint8_t len, uint16_t start) { + uint16_t crc = start; uint8_t shift = 0; for(uint8_t i = 0; i < len; i ++) { diff --git a/tools/esp8266/crc.h b/tools/esp8266/crc.h index 90baa548..349146b3 100644 --- a/tools/esp8266/crc.h +++ b/tools/esp8266/crc.h @@ -10,7 +10,7 @@ #define CRC16_NRF24_POLYNOM 0x1021 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); #endif /*__CRC_H__*/ diff --git a/tools/esp8266/defines.h b/tools/esp8266/defines.h index 459125a8..bcad6275 100644 --- a/tools/esp8266/defines.h +++ b/tools/esp8266/defines.h @@ -15,8 +15,8 @@ // VERSION //------------------------------------- #define VERSION_MAJOR 0 -#define VERSION_MINOR 3 -#define VERSION_PATCH 9 +#define VERSION_MINOR 4 +#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_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_MQTT_ADDR ADDR_INV_INTERVAL + INV_INTERVAL_LEN diff --git a/tools/esp8266/hmDefines.h b/tools/esp8266/hmDefines.h index 1c27ced3..1f8c9389 100644 --- a/tools/esp8266/hmDefines.h +++ b/tools/esp8266/hmDefines.h @@ -25,26 +25,22 @@ const char* const fields[] = {"U_DC", "I_DC", "P_DC", "YieldDay", "YieldWeek", " // indices to calculation functions, defined in hmInverter.h enum {CALC_YT_CH0 = 0, CALC_YD_CH0, CALC_UDC_CH}; +enum {CMD_CALC = 0xffff}; // CH0 is default channel (freq, ac, temp) 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}; -const char* const invTypes[] = {"HM600", "HM1200 / HM1500", "HM400", "HM800"}; -#define NUM_INVERTER_TYPES 4 +enum {INV_TYPE_1CH = 0, INV_TYPE_2CH, INV_TYPE_4CH}; typedef struct { uint8_t fieldId; // field id uint8_t unitId; // uint id - uint8_t ch; // channel 0 - 3 - uint8_t cmdId; // received command id + uint8_t ch; // channel 0 - 4 uint8_t start; // pos of first byte in buffer uint8_t num; // number of bytes in buffer - uint16_t div; // divisor + uint16_t div; // divisor / calc command } byteAssign_t; @@ -54,106 +50,88 @@ typedef struct { * */ //------------------------------------- -// HM400 HM350?, HM300? +// HM300, HM350, HM400 //------------------------------------- -const byteAssign_t hm400assignment[] = { - { 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_YT, UNIT_KWH, CH1, CMD01, 9, 4, 1000 }, - { FLD_YD, UNIT_WH, CH1, CMD01, 13, 2, 1 }, - { FLD_UAC, UNIT_V, CH0, CMD01, 15, 2, 10 }, - { FLD_F, UNIT_HZ, CH0, CMD82, 1, 2, 100 }, - { FLD_PAC, UNIT_W, CH0, CMD82, 3, 2, 10 }, - { FLD_IAC, UNIT_A, CH0, CMD82, 7, 2, 100 }, - { FLD_T, UNIT_C, CH0, CMD82, 11, 2, 10 } +const byteAssign_t hm1chAssignment[] = { + { FLD_UDC, UNIT_V, CH1, 2, 2, 10 }, + { FLD_IDC, UNIT_A, CH1, 4, 2, 100 }, + { FLD_PDC, UNIT_W, CH1, 6, 2, 10 }, + { FLD_YD, UNIT_WH, CH1, 12, 2, 1 }, + { FLD_YT, UNIT_KWH, CH1, 8, 4, 1000 }, + + { FLD_UAC, UNIT_V, CH0, 14, 2, 10 }, + { FLD_IAC, UNIT_A, CH0, 22, 2, 100 }, + { FLD_PAC, UNIT_W, CH0, 18, 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[] = { - { 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 HM600_LIST_LEN (sizeof(hm600assignment) / sizeof(byteAssign_t)) - +const byteAssign_t hm2chAssignment[] = { + { FLD_UDC, UNIT_V, CH1, 2, 2, 10 }, + { FLD_IDC, UNIT_A, CH1, 4, 2, 100 }, + { FLD_PDC, UNIT_W, CH1, 6, 2, 10 }, + { FLD_YD, UNIT_WH, CH1, 22, 2, 1 }, + { FLD_YD, UNIT_KWH, CH1, 14, 4, 1000 }, + + { FLD_UDC, UNIT_V, CH2, 8, 2, 10 }, + { FLD_IDC, UNIT_A, CH2, 10, 2, 100 }, + { FLD_PDC, UNIT_W, CH2, 12, 2, 10 }, + { FLD_YD, UNIT_WH, CH2, 18, 2, 1 }, + { FLD_YD, UNIT_KWH, CH2, 24, 4, 1000 }, + + { FLD_UAC, UNIT_V, CH0, 26, 2, 10 }, + { FLD_IAC, UNIT_A, CH0, 34, 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 } -//------------------------------------- -// 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)) +#define HM2CH_LIST_LEN (sizeof(hm2chAssignment) / sizeof(byteAssign_t)) //------------------------------------- // HM1200, HM1500 //------------------------------------- -const byteAssign_t hm1200assignment[] = { - { FLD_UDC, UNIT_V, CH1, CMD01, 3, 2, 10 }, - { FLD_IDC, UNIT_A, CH1, CMD01, 5, 2, 100 }, - { FLD_PDC, UNIT_W, CH1, CMD01, 9, 2, 10 }, - { FLD_YD, UNIT_WH, CH1, CMD02, 5, 2, 1 }, - { FLD_YT, UNIT_KWH, CH1, CMD01, 13, 4, 1000 }, - { FLD_UDC, UNIT_V, CH3, CMD02, 9, 2, 10 }, - { FLD_IDC, UNIT_A, CH2, CMD01, 7, 2, 100 }, - { FLD_PDC, UNIT_W, CH2, CMD01, 11, 2, 10 }, - { FLD_YD, UNIT_WH, CH2, CMD02, 7, 2, 1 }, - { FLD_YT, UNIT_KWH, CH2, CMD02, 1, 4, 1000 }, - { FLD_IDC, UNIT_A, CH3, CMD02, 11, 2, 100 }, - { FLD_PDC, UNIT_W, CH3, CMD02, 15, 2, 10 }, - { FLD_YD, UNIT_WH, CH3, CMD03, 11, 2, 1 }, - { FLD_YT, UNIT_KWH, CH3, CMD03, 3, 4, 1000 }, - { FLD_IDC, UNIT_A, CH4, CMD02, 13, 2, 100 }, - { FLD_PDC, UNIT_W, CH4, CMD03, 1, 2, 10 }, - { FLD_YD, UNIT_WH, CH4, CMD03, 13, 2, 1 }, - { FLD_YT, UNIT_KWH, CH4, CMD03, 7, 4, 1000 }, - { FLD_UAC, UNIT_V, CH0, CMD03, 15, 2, 10 }, - { FLD_IAC, UNIT_A, CH0, CMD84, 7, 2, 100 }, - { FLD_PAC, UNIT_W, CH0, CMD84, 3, 2, 10 }, - { FLD_F, UNIT_HZ, CH0, CMD84, 1, 2, 100 }, - { FLD_PCT, UNIT_PCT, CH0, CMD84, 9, 2, 10 }, - { FLD_T, UNIT_C, CH0, CMD84, 11, 2, 10 }, - { FLD_YD, UNIT_WH, CH0, CMDFF, CALC_YD_CH0, 0, 0 }, - { FLD_YT, UNIT_KWH, CH0, CMDFF, CALC_YT_CH0, 0, 0 }, - { FLD_UDC, UNIT_V, CH2, CMDFF, CALC_UDC_CH, CH1, 0 }, - { FLD_UDC, UNIT_V, CH4, CMDFF, CALC_UDC_CH, CH3, 0 } +const byteAssign_t hm4chAssignment[] = { + { FLD_UDC, UNIT_V, CH1, 2, 2, 10 }, + { FLD_IDC, UNIT_A, CH1, 4, 2, 100 }, + { FLD_PDC, UNIT_W, CH1, 8, 2, 10 }, + { FLD_YD, UNIT_WH, CH1, 20, 2, 1 }, + { FLD_YT, UNIT_KWH, CH1, 12, 4, 1000 }, + + { FLD_UDC, UNIT_V, CH2, CALC_UDC_CH, CH1, CMD_CALC }, + { FLD_IDC, UNIT_A, CH2, 6, 2, 100 }, + { FLD_PDC, UNIT_W, CH2, 10, 2, 10 }, + { FLD_YD, UNIT_WH, CH2, 22, 2, 1 }, + { FLD_YT, UNIT_KWH, CH2, 16, 4, 1000 }, + + { FLD_UDC, UNIT_V, CH3, 24, 2, 10 }, + { FLD_IDC, UNIT_A, CH3, 26, 2, 100 }, + { FLD_PDC, UNIT_W, CH3, 30, 2, 10 }, + { FLD_YD, UNIT_WH, CH3, 42, 2, 1 }, + { FLD_YT, UNIT_KWH, CH3, 34, 4, 1000 }, + + { FLD_UDC, UNIT_V, CH4, CALC_UDC_CH, CH3, CMD_CALC }, + { FLD_IDC, UNIT_A, CH4, 28, 2, 100 }, + { FLD_PDC, UNIT_W, CH4, 32, 2, 10 }, + { FLD_YD, UNIT_WH, CH4, 44, 2, 1 }, + { FLD_YT, UNIT_KWH, CH4, 38, 4, 1000 }, + + { FLD_UAC, UNIT_V, CH0, 46, 2, 10 }, + { FLD_IAC, UNIT_A, CH0, 54, 2, 100 }, + { FLD_PAC, UNIT_W, CH0, 50, 2, 10 }, + { 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__*/ diff --git a/tools/esp8266/hmInverter.h b/tools/esp8266/hmInverter.h index f5e823e8..5b1ffd23 100644 --- a/tools/esp8266/hmInverter.h +++ b/tools/esp8266/hmInverter.h @@ -95,22 +95,20 @@ class Inverter { return assign[pos].ch; } - uint8_t getCmdId(uint8_t pos) { - return assign[pos].cmdId; - } - void addValue(uint8_t pos, uint8_t buf[]) { uint8_t ptr = assign[pos].start; uint8_t end = ptr + assign[pos].num; uint16_t div = assign[pos].div; - uint32_t val = 0; - do { - val <<= 8; - val |= buf[ptr]; - } while(++ptr != end); + if(CMD_CALC != div) { + uint32_t val = 0; + do { + val <<= 8; + val |= buf[ptr]; + } while(++ptr != end); - record[pos] = (RECORDTYPE)(val) / (RECORDTYPE)(div); + record[pos] = (RECORDTYPE)(val) / (RECORDTYPE)(div); + } } RECORDTYPE getValue(uint8_t pos) { @@ -119,7 +117,7 @@ class Inverter { void doCalculations(void) { for(uint8_t i = 0; i < listLen; i++) { - if(CMDFF == assign[i].cmdId) { + if(CMD_CALC == assign[i].div) { record[i] = calcFunctions[assign[i].start].func(this, assign[i].num); } } @@ -136,24 +134,19 @@ class Inverter { } void getAssignment(void) { - if(INV_TYPE_HM400 == type) { - listLen = (uint8_t)(HM400_LIST_LEN); - assign = (byteAssign_t*)hm400assignment; + if(INV_TYPE_1CH == type) { + listLen = (uint8_t)(HM1CH_LIST_LEN); + assign = (byteAssign_t*)hm1chAssignment; channels = 1; } - else if(INV_TYPE_HM600 == type) { - listLen = (uint8_t)(HM600_LIST_LEN); - assign = (byteAssign_t*)hm600assignment; - channels = 2; - } - else if(INV_TYPE_HM800 == type) { - listLen = (uint8_t)(HM800_LIST_LEN); - assign = (byteAssign_t*)hm800assignment; + else if(INV_TYPE_2CH == type) { + listLen = (uint8_t)(HM2CH_LIST_LEN); + assign = (byteAssign_t*)hm2chAssignment; channels = 2; } - else if(INV_TYPE_HM1200 == type) { - listLen = (uint8_t)(HM1200_LIST_LEN); - assign = (byteAssign_t*)hm1200assignment; + else if(INV_TYPE_4CH == type) { + listLen = (uint8_t)(HM4CH_LIST_LEN); + assign = (byteAssign_t*)hm4chAssignment; channels = 4; } else { diff --git a/tools/esp8266/hmRadio.h b/tools/esp8266/hmRadio.h index a251b7db..492b93d7 100644 --- a/tools/esp8266/hmRadio.h +++ b/tools/esp8266/hmRadio.h @@ -58,14 +58,14 @@ class HmRadio { mRxChIdx = 0; mRxLoopCnt = RX_LOOP_CNT; - //calcDtuCrc(); - pinCs = CS_PIN; pinCe = CE_PIN; pinIrq = IRQ_PIN; AmplifierPower = 1; mSendCnt = 0; + + mSerialDebug = false; } ~HmRadio() {} @@ -111,7 +111,7 @@ class HmRadio { if(!mBufCtrl->full()) { p = mBufCtrl->getFront(); memset(p->packet, 0xcc, MAX_RF_PAYLOAD_SIZE); - p->rxCh = mRxChIdx; + p->rxCh = mRxChLst[mRxChIdx]; len = mNrf24.getPayloadSize(); if(len > MAX_RF_PAYLOAD_SIZE) len = MAX_RF_PAYLOAD_SIZE; @@ -156,19 +156,19 @@ class HmRadio { 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); mTxBuf[0] = mid; // message id CP_U32_BigEndian(&mTxBuf[1], (invId >> 8)); CP_U32_BigEndian(&mTxBuf[5], (DTU_ID >> 8)); - mTxBuf[9] = cmd; + mTxBuf[9] = pid; if(calcCrc) { mTxBuf[10] = crc8(mTxBuf, 10); 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); if(*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); bool valid = (crc == buf[*len-1]); - if(valid) { - if(mLastCrc == crc) - *rptCnt = (++mRptCnt); - else { - mRptCnt = 0; - *rptCnt = 0; - mLastCrc = crc; - } - mRxStat[(buf[9] & 0x7F)-1]++; - mRxChStat[(buf[9] & 0x7F)-1][rxCh & 0x7]++; - } + //if(valid) { + //mRxStat[(buf[9] & 0x7F)-1]++; + //mRxChStat[(buf[9] & 0x7F)-1][rxCh & 0x7]++; + //} /*else { DPRINT("CRC wrong: "); DHEX(crc); @@ -215,7 +208,8 @@ class HmRadio { } void dumpBuf(const char *info, uint8_t buf[], uint8_t len) { - DPRINT(String(info)); + if(NULL != info) + DPRINT(String(info)); for(uint8_t i = 0; i < len; i++) { DHEX(buf[i]); DPRINT(" "); @@ -234,16 +228,22 @@ class HmRadio { uint8_t AmplifierPower; uint32_t mSendCnt; + bool mSerialDebug; + private: void sendPacket(uint64_t invId, uint8_t buf[], uint8_t len, bool clear=false) { //DPRINTLN("sent packet: #" + String(mSendCnt)); //dumpBuf("SEN ", buf, len); + if(mSerialDebug) { + DPRINT("Transmit " + String(len) + " | "); + dumpBuf(NULL, buf, len); + } DISABLE_IRQ; mNrf24.stopListening(); if(clear) { - uint8_t cnt = 4; + /*uint8_t cnt = 4; for(uint8_t i = 0; i < 4; i ++) { DPRINT(String(mRxStat[i]) + " ("); for(uint8_t j = 0; j < 4; j++) { @@ -258,7 +258,7 @@ class HmRadio { else DPRINTLN(" -> missing: " + String(cnt)); memset(mRxStat, 0, 4); - memset(mRxChStat, 0, 4*8); + memset(mRxChStat, 0, 4*8);*/ mRxLoopCnt = RX_LOOP_CNT; } @@ -295,34 +295,19 @@ class HmRadio { 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 mTxChLst[1]; //uint8_t mTxChIdx; uint8_t mRxChLst[4]; uint8_t mRxChIdx; - uint8_t mRxStat[4]; - uint8_t mRxChStat[4][8]; + //uint8_t mRxStat[4]; + //uint8_t mRxChStat[4][8]; uint16_t mRxLoopCnt; - //uint16_t mDtuIdCrc; - uint16_t mLastCrc; - uint8_t mRptCnt; - RF24 mNrf24; BUFFER *mBufCtrl; uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE]; - }; #endif /*__RADIO_H__*/ diff --git a/tools/esp8266/hmSystem.h b/tools/esp8266/hmSystem.h index c418fb08..3bc202a3 100644 --- a/tools/esp8266/hmSystem.h +++ b/tools/esp8266/hmSystem.h @@ -27,7 +27,7 @@ class HmSystem { 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) { DPRINT("max number of inverters reached!"); return NULL; @@ -35,7 +35,19 @@ class HmSystem { INVERTERTYPE *p = &mInverter[mNumInv]; p->id = mNumInv; 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(); uint8_t len = (uint8_t)strlen(name); strncpy(p->name, name, (len > MAX_NAME_LENGTH) ? MAX_NAME_LENGTH : len);