From 6b0f8de80a4873dbe234aeb5943338b2ab6c4e94 Mon Sep 17 00:00:00 2001 From: Andrey Klimov Date: Wed, 4 Oct 2017 13:28:30 +0300 Subject: [PATCH] Modbus pooling: optimized sequentional dev reading and some bugs fixed --- item.cpp | 78 +++++++++++++++++++++++++++++++++++++------------------- item.h | 2 ++ 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/item.cpp b/item.cpp index 59a6c20..9d40567 100644 --- a/item.cpp +++ b/item.cpp @@ -26,8 +26,10 @@ e-mail anklimov@gmail.com #include short modbusBusy=0; +extern aJsonObject * modbusitem; -extern int modbusSet(int addr, uint16_t _reg, int _mask, uint16_t value); + +int modbusSet(int addr, uint16_t _reg, int _mask, uint16_t value); extern PubSubClient client; //extern const char* outprefix; const char outprefix[] PROGMEM = "/myhome/s_out/"; @@ -750,41 +752,65 @@ result = node.readHoldingRegisters(20-1, 4); { if (modbusBusy) return -1; modbusBusy=1; + node.begin(9600,SERIAL_8E1,13); - uint8_t result; - int data; - - node.setSlave(getArg()); - result = node.readHoldingRegisters(0, 1); + uint8_t result; - // do something with data if read is successful + uint16_t addr = getArg(0); + uint16_t reg = getArg(1); + short mask = getArg(2); + + int data; + + node.setSlave(addr); + result = node.readHoldingRegisters(reg, 1); + if (result == node.ku8MBSuccess) { - data=node.getResponseBuffer(0); Serial.print(F("Modbus Val: ")); Serial.println(data,HEX); - if (getArg(2)) data>>=8; data&=0xff; - data=map(data,0,0x3f,0,100); - - if (getVal()!=data) - { - SendCmd(0,1,&data); //update OH - - switch (getCmd()) //Save value if not turned off - {case CMD_OFF: - case CMD_HALT: - break; - default: - setVal(data); - } //switch - } //if data changed - - } else {Serial.print(F("Modbus pooling error=")); Serial.println(result,HEX); } + checkModbus(data); + } + else {Serial.print(F("Modbus pooling error=")); Serial.println(result,HEX); } modbusBusy=0; - } +// Looking 1 step ahead for modbus item, which uses same register + Item nextItem(modbusitem->next); + if (modbusitem && nextItem.isValid() && nextItem.itemType==CH_MODBUS && nextItem.getArg(0)==addr && nextItem.getArg(1)==reg) + { + nextItem.checkModbus(data); + modbusitem=modbusitem->next; + if (!modbusitem) modbusitem=items->child; + } + +} + + +int Item::checkModbus(int data) + { + short mask = getArg(2); + int d=data; + if (mask) d>>=8; d&=0xff; + d=map(d,0,0x3f,0,100); + int cmd=getCmd(); + Serial.println(d); + if (getVal()!=d || d && cmd==CMD_OFF || d && cmd==CMD_HALT) //volume changed or turned on manualy + { + if (d) + + { // Actually turned on + SendCmd(0,1,&d); //update OH + setCmd(CMD_ON); + setVal(d); //Storing + } + else { + if (cmd!=CMD_HALT && cmd!=CMD_OFF) {setCmd(CMD_OFF); SendCmd(CMD_OFF); } + } + } //if data changed + } + int Item::Pool() { switch (itemType) diff --git a/item.h b/item.h index 2db8b9a..9124ef7 100644 --- a/item.h +++ b/item.h @@ -93,6 +93,8 @@ class Item int isActive(); void Parse(); int checkModbus(); + int checkModbus(int data); + int checkFM(); };