From e549616abe7556940c224304240ffa3171f61153 Mon Sep 17 00:00:00 2001 From: Andrey Klimov Date: Sun, 29 Oct 2017 14:58:16 +0300 Subject: [PATCH] Vacom 10 Modbus pooling to feedback collection for fan speed and air heating PI regilator are developed Few small changes to conserve RAM usage across code --- item.cpp | 235 ++++++++++++++++++++++++++++++++++----------------- item.h | 2 +- lighthub.ino | 54 +++++------- owSwitch.cpp | 46 +++++----- 4 files changed, 203 insertions(+), 134 deletions(-) diff --git a/item.cpp b/item.cpp index 4844406..a65d053 100644 --- a/item.cpp +++ b/item.cpp @@ -25,6 +25,8 @@ e-mail anklimov@gmail.com #include #include + + short modbusBusy=0; extern aJsonObject * modbusitem; @@ -39,7 +41,7 @@ static aJsonObject * lastobj = NULL; int txt2cmd (char * payload) { - int cmd=0; + int cmd=-1; // Check for command if (strcmp(payload,"ON")==0) cmd=CMD_ON; @@ -47,6 +49,9 @@ int txt2cmd (char * payload) else if (strcmp(payload,"REST")==0) cmd=CMD_RESTORE; else if (strcmp(payload,"TOGGLE")==0) cmd=CMD_TOGGLE; else if (strcmp(payload,"HALT")==0) cmd=CMD_HALT; + else if (*payload=='-' || (*payload>='0' && *payload<='9')) cmd=0; + else if (*payload=='{') cmd=-2; + return cmd; } @@ -73,7 +78,7 @@ void Item::Parse() Serial.print(F(" Item:")); Serial.print(itemArr->name);Serial.print(F(" T:")); - Serial.print(itemType);Serial.print(" =");Serial.println(getArg()); + Serial.print(itemType);Serial.print(F(" ="));Serial.println(getArg()); } } @@ -204,7 +209,7 @@ int Item::Ctrl(short cmd, short n, int * Par, boolean send) cmd=CMD_ON; break; }//switch old cmd - //Serial.print("Tog/oldcmd:");Serial.print(t);Serial.print(" new ");Serial.println(cmd); + //Serial.print("Tog/oldcmd:");Serial.print(t);Serial.print(F(" new "));Serial.println(cmd); break; case CMD_RESTORE: @@ -212,7 +217,7 @@ int Item::Ctrl(short cmd, short n, int * Par, boolean send) switch (t=getCmd()) { case CMD_HALT: //previous command was HALT ? - Serial.print("Restored from:");Serial.println(t); + Serial.print(F("Restored from:"));Serial.println(t); cmd=CMD_ON; //turning on break; default: @@ -294,15 +299,23 @@ int Item::Ctrl(short cmd, short n, int * Par, boolean send) {// Default settings Serial.print(st.aslong); Serial.println(F(": No stored values - default")); + + switch (itemType) + { + case CH_VCTEMP: + Par[0]=20; + break; + default: Par[0]=100; Par[1]=0; Par[2]=100; + } } for (short i=0;iname); +int cmd=getCmd(); +switch (cmd) +{ + case CMD_ON: + //Serial.println(" active"); + return 1; + case CMD_OFF: + case CMD_HALT: + //Serial.println(" inactive"); + return 0; +} + + st.aslong=getVal(); + +switch (itemType) +{ + //case CH_GROUP: + case CH_RGBW: + case CH_RGB: + + val=st.v; + break; + + case CH_DIMMER: //Everywhere, in flat VAL + case CH_MODBUS: + case CH_THERMO: + case CH_VC: + case CH_VCTEMP: + val=st.aslong; +} //switch +Serial.print(F(":="));Serial.println(val); + if (val) return 1; else return 0; +} + /* short thermoSet(char * name, short cmd, short t) @@ -548,9 +605,10 @@ POOL 2101x10 extern ModbusMaster node; -int Item::VacomSetFan (int addr, int8_t val) -{ - Serial.print("VC#");Serial.print(addr);Serial.print("=");Serial.println(val); +int Item::VacomSetFan (int8_t val, int8_t cmd) +{ + int addr=getArg(); + Serial.print(F("VC#"));Serial.print(addr);Serial.print(F("="));Serial.println(val); if (modbusBusy) return -1; @@ -567,24 +625,9 @@ int Item::VacomSetFan (int addr, int8_t val) //node.writeSingleRegister(2001-1,1); } else node.writeSingleRegister(2001-1,0); - delay (500); + delay (50); node.writeSingleRegister(2003-1,val*100); - /* - result = node.readHoldingRegisters(2003, 10); - - // do something with data if read is successful - if (result == node.ku8MBSuccess) - { Serial.print(F(" FM Val :")); - for (j = 0; j < 10; j++) - { - data[j] = node.getResponseBuffer(j); - Serial.print(data[j],HEX);Serial.print("-"); - - } - Serial.println(); - } else {Serial.print(F("Modbus pooling error=")); Serial.println(result,HEX); } - */ modbusBusy=0; @@ -592,11 +635,37 @@ int Item::VacomSetFan (int addr, int8_t val) } -int Item::VacomSetHeat(int addr, int8_t val, int8_t cmd) +#define a 0.1846 +#define b -36.8 + +int Item::VacomSetHeat(int addr,int8_t val, int8_t cmd) { - Serial.print("VC#");Serial.print(addr);Serial.print("=");Serial.print(val);Serial.print(" cmd=");Serial.println(cmd); + Serial.print(F("VC_heat#"));Serial.print(addr);Serial.print(F("="));Serial.print(val);Serial.print(F(" cmd="));Serial.println(cmd); + if (modbusBusy) return -1; + modbusBusy=1; + + node.begin(9600,SERIAL_8N1,13); + node.setSlave(addr); + uint16_t regval; + + switch (cmd) + { + case CMD_OFF: + case CMD_HALT: + regval=0; + break; + + default: + regval=round(((float)val-b)*10/a); + } + + Serial.println(regval); + node.writeSingleRegister(2004-1,regval); + modbusBusy=0; } + + int Item::SendCmd(short cmd,short n, int * Par) { @@ -639,51 +708,12 @@ int Item::SendCmd(short cmd,short n, int * Par) return -1; } - Serial.print(addrstr);Serial.print("->");Serial.println(valstr); + Serial.print(addrstr);Serial.print(F("->"));Serial.println(valstr); client.publish(addrstr, valstr); return 0; } - int Item::isActive() -{ - HSVstore st; - int val=0; - -if (!isValid()) return -1; -//Serial.print(itemArr->name); -int cmd=getCmd(); -switch (cmd) -{ - case CMD_ON: - //Serial.println(" active"); - return 1; - case CMD_OFF: - case CMD_HALT: - //Serial.println(" inactive"); - return 0; -} - - st.aslong=getVal(); -switch (itemType) -{ - //case CH_GROUP: - case CH_RGBW: - case CH_RGB: - - val=st.v; - break; - - case CH_DIMMER: //Everywhere, in flat VAL - case CH_MODBUS: - case CH_THERMO: - case CH_VC: - case CH_VCTEMP: - val=st.aslong; -} //switch -Serial.print(":=");Serial.println(val); - if (val) return 1; else return 0; -} @@ -699,20 +729,35 @@ if (_mask) {value <<= 8; value |= (0xff);} else {value &= 0xff; value |= (0xff00);} - Serial.print(addr);Serial.print("=>");Serial.print(_reg,HEX);Serial.print(":");Serial.println(value,HEX); + Serial.print(addr);Serial.print(F("=>"));Serial.print(_reg,HEX);Serial.print(F(":"));Serial.println(value,HEX); node.writeSingleRegister(_reg,value); modbusBusy=0; } + int Item::checkFM() { if (modbusBusy) return -1; modbusBusy=1; uint8_t j, result; - uint16_t data[1]; + int16_t data; + + + aJsonObject *out =aJson.createObject(); + char * outch; + char addrstr[32]; + + strcpy_P (addrstr,outprefix); + strncat(addrstr,itemArr->name,sizeof(addrstr)-1); + strncat(addrstr,"_stat",sizeof(addrstr)-1); + + // aJson.addStringToObject(out,"type", "rect"); + + + node.begin(9600,SERIAL_8N1,13); node.setSlave(getArg()); @@ -724,13 +769,32 @@ int Item::checkFM() { Serial.print(F(" FM Val :")); for (j = 0; j < 10; j++) { - data[j] = node.getResponseBuffer(j); - Serial.print(data[j],HEX);Serial.print("-"); + data = node.getResponseBuffer(j); + Serial.print(data,HEX);Serial.print(F("-")); } + + // aJson.addNumberToObject(out,"gsw", (int) node.getResponseBuffer(1)); + aJson.addNumberToObject(out,"V", (int) node.getResponseBuffer(2)/100.); + aJson.addNumberToObject(out,"f", (int) node.getResponseBuffer(3)/100.); + aJson.addNumberToObject(out,"RPM", (int) node.getResponseBuffer(4)); + aJson.addNumberToObject(out,"I", (int) node.getResponseBuffer(5)/100.); + // aJson.addNumberToObject(out,"M", (int) node.getResponseBuffer(6)/10.); + // aJson.addNumberToObject(out,"P", (int) node.getResponseBuffer(7)/10.); + // aJson.addNumberToObject(out,"U", (int) node.getResponseBuffer(8)/10.); + // aJson.addNumberToObject(out,"Ui", (int) node.getResponseBuffer(9)); + aJson.addNumberToObject(out,"sw", (int) node.getResponseBuffer(0)); + Serial.println(); } else {Serial.print(F("Modbus pooling error=")); Serial.println(result,HEX); } +if (node.getResponseBuffer(0) & 8) //Active failt + { + result = node.readHoldingRegisters(2111-1, 1); + if (result == node.ku8MBSuccess) aJson.addNumberToObject(out,"flt", (int) node.getResponseBuffer(0)); + } + + result = node.readHoldingRegisters(20-1, 4); // do something with data if read is successful @@ -738,14 +802,27 @@ result = node.readHoldingRegisters(20-1, 4); { Serial.print(F(" PI Val :")); for (j = 0; j < 4; j++) { - data[j] = node.getResponseBuffer(j); - Serial.print(data[j]);Serial.print("-"); + data = node.getResponseBuffer(j); + Serial.print(data);Serial.print(F("-")); } + + int set = node.getResponseBuffer(0); + if (set) aJson.addNumberToObject(out,"set", set*a+b); + aJson.addNumberToObject(out,"t", (int) node.getResponseBuffer(1)*a+b); + // aJson.addNumberToObject(out,"d", (int) node.getResponseBuffer(2)*a+b); + int pwr= node.getResponseBuffer(3); + if (pwr>0) aJson.addNumberToObject(out,"pwr", pwr/10.); else aJson.addNumberToObject(out,"pwr",0); + + Serial.println(); } else {Serial.print(F("Modbus pooling error=")); Serial.println(result,HEX); } + outch=aJson.print(out); + client.publish(addrstr, outch); + free (outch); + aJson.deleteItem(out); modbusBusy=0; } @@ -798,7 +875,7 @@ int Item::checkModbus(int data) if (mask) d>>=8; d&=0xff; d=map(d,0,0x3f,0,100); int cmd=getCmd(); - Serial.println(d); + //Serial.println(d); if (getVal()!=d || d && cmd==CMD_OFF || d && cmd==CMD_HALT) //volume changed or turned on manualy { if (d) diff --git a/item.h b/item.h index 9124ef7..6d258b6 100644 --- a/item.h +++ b/item.h @@ -88,7 +88,7 @@ class Item int SendCmd(short cmd,short n=0, int * Par=NULL); protected: - int VacomSetFan (int addr, int8_t val); + int VacomSetFan (int8_t val, int8_t cmd=0); int VacomSetHeat(int addr, int8_t val, int8_t cmd=0); int isActive(); void Parse(); diff --git a/lighthub.ino b/lighthub.ino index 9a001a0..4343567 100644 --- a/lighthub.ino +++ b/lighthub.ino @@ -70,7 +70,8 @@ dmx relay out #include // Hardcoded definitions -#define GIST 2 +//Thermostate histeresys +#define GIST 2 #define serverip "192.168.88.2" IPAddress server(192, 168, 88, 2); //TODO - configure it //char* inprefix=("/myhome/in/"); @@ -205,19 +206,34 @@ void callback(char* topic, byte* payload, unsigned int length) { Item item (subtopic); if (item.isValid()) { - if (!cmd) + switch (cmd) { + case 0: + { short i=0; - int Par[3]; - + int Par[3]; while (payload && i<3) Par[i++]=getInt((char**)&payload); item.Ctrl(0,i,Par); + } + break; + + case -1: //Not known command + case -2: //JSON input (not implemented yet + break; + + case CMD_ON: + + if (item.getEnableCMD(500)) item.Ctrl(cmd); //Accept ON command not earlier then 500 ms after set settings (Homekit hack) + else Serial.println("on Skipped"); + + break; + default: //some known command + item.Ctrl(cmd); + } //ctrl - else if ((cmd!=CMD_ON) || (item.getEnableCMD(500))) item.Ctrl(cmd); //Accept ON command not earlier then 500 ms after set settings (Homekit hack) - else Serial.println("on Skipped"); } //valid json } //no1wire } @@ -720,7 +736,7 @@ void setup() { //Serial.begin(115200); cmdInit(115200); - Serial.println(F("\nLazyhome.ru LightHub controller v0.9")); + Serial.println(F("\nLazyhome.ru LightHub controller v0.91")); for (short i=0;i<6;i++) mac[i]=EEPROM.read(i); @@ -756,30 +772,6 @@ void setup() { } - -//unsigned long modbus_check=0; - - - -/* -void modbusloop() -{ - - if (millis()>modbus_check) - { - checkDev(0x60); - delay(10); - checkDev(0x61); - delay(10); - checkFMDev(10); - - - modbus_check=millis()+5000; - Serial.println(freeRam()); - } -} -*/ - void loop(){ wdt_reset(); diff --git a/owSwitch.cpp b/owSwitch.cpp index 913e110..40a8cde 100644 --- a/owSwitch.cpp +++ b/owSwitch.cpp @@ -80,10 +80,10 @@ int ow2408out(DeviceAddress addr,uint8_t cur) net->read_bytes(buf+3, 2); //net.reset(); PrintBytes(buf, 5); - Serial.print(" Out: ");Serial.print(buf[1],BIN); - Serial.print(" In: ");Serial.println(buf[4],BIN); + Serial.print(F(" Out: "));Serial.print(buf[1],BIN); + Serial.print(F(" In: "));Serial.println(buf[4],BIN); if (buf[3] != 0xAA) { - Serial.print("Write failure in DS2408 at "); + Serial.print(F("Write failure in DS2408 at ")); PrintBytes(addr, 8, true); return -2; } @@ -97,7 +97,7 @@ if (!net) return -1; if ((devnum=owFind(addr))<0) return -1; buf=regs[devnum]; - Serial.print("Current: ");Serial.println(buf,BIN); + Serial.print(F("Current: "));Serial.println(buf,BIN); mask=0; int r,f; switch (subchan) { @@ -107,7 +107,7 @@ if (!net) return -1; if (wstat[devnum] & (SW_PULSE0|SW_PULSE_P0)) { wstat[devnum]|=SW_CHANGED_P0; - Serial.println("Rollback 0"); + Serial.println(F("Rollback 0")); } else { wstat[devnum]|=SW_PULSE0; @@ -122,7 +122,7 @@ if (!net) return -1; if (wstat[devnum] & (SW_PULSE1|SW_PULSE_P1)) { wstat[devnum]|=SW_CHANGED_P1; - Serial.println("Rollback 1"); + Serial.println(F("Rollback 1")); } else { wstat[devnum]|=SW_PULSE1; @@ -156,7 +156,7 @@ int cntrl2890(uint8_t* addr, int val) { uint8_t buf[13]; if (!net) return -1; // case 0x2C: //Dimmer - Serial.print("Update dimmer ");PrintBytes(addr, 8, true);Serial.print(" = "); + Serial.print(F("Update dimmer "));PrintBytes(addr, 8, true);Serial.print(F(" = ")); Serial.println(val); net->reset(); @@ -270,7 +270,7 @@ int cntrl2413(uint8_t* addr, int subchan, int val) { uint8_t count =10; if (!net) return -1; // case 0x85: //Switch - Serial.print("Update switch ");PrintBytes(addr, 8, false); Serial.print("/");Serial.print(subchan);Serial.print(" = ");Serial.println(val); + Serial.print(F("Update switch "));PrintBytes(addr, 8, false); Serial.print(F("/"));Serial.print(subchan);Serial.print(F(" = "));Serial.println(val); while (count--) { net->reset(); @@ -281,13 +281,13 @@ int cntrl2413(uint8_t* addr, int subchan, int val) { net->write(cmd); results = net->read(); - Serial.print("Got: "); Serial.println(results,BIN); + Serial.print(F("Got: ")); Serial.println(results,BIN); //Serial.println((~results & 0x0F),BIN); Serial.println ((results >> 4),BIN); ok = (~results & 0x0F) == (results >> 4); // Compare nibbles results &= 0x0F; // Clear inverted values - if (ok) {Serial.println("Read ok");break;} else {Serial.println("read Error");delay(1);} + if (ok) {Serial.println(F("Read ok"));break;} else {Serial.println(F("read Error"));delay(1);} } //while if (ok && (val>=0)) @@ -309,7 +309,7 @@ int cntrl2413(uint8_t* addr, int subchan, int val) { if (!val) set|=DS2413_OUT_PinB; else set &= ~DS2413_OUT_PinB; }; set |= 0xFC; - Serial.print("New: ");Serial.println(set,BIN); + Serial.print(F("New: "));Serial.println(set,BIN); cmd = DS2413_ACCESS_WRITE; net->write(cmd); @@ -321,17 +321,17 @@ int cntrl2413(uint8_t* addr, int subchan, int val) { if (ack == DS2413_ACK_SUCCESS) { results=net->read(); - Serial.print("Updated ok: "); Serial.println(results,BIN); + Serial.print(F("Updated ok: ")); Serial.println(results,BIN); ok = (~results & 0x0F) == (results >> 4); // Compare nibbles { if (ok) - {Serial.println("Readback ok"); + {Serial.println(F("Readback ok")); break;} - else {Serial.println("readback Error");delay(1);} + else {Serial.println(F("readback Error"));delay(1);} } results &= 0x0F; // Clear inverted values } - else Serial.println ("Write failed");; + else Serial.println (F("Write failed"));; } //while } //if @@ -352,7 +352,7 @@ int sensors_ext(void) if (wstat[si] & SW_PULSE0) { wstat[si]&=~SW_PULSE0; wstat[si]|=SW_PULSE_P0; - Serial.println("Pulse0 in progress"); + Serial.println(F("Pulse0 in progress")); return 500; } @@ -361,7 +361,7 @@ int sensors_ext(void) wstat[si]&=~SW_PULSE0_R; wstat[si]|=SW_PULSE_P0; regs[si] =(ow2408out(term[si],(regs[si] | SW_MASK) & ~SW_OUT0) & SW_INMASK) ^ SW_STAT0; - Serial.println("Pulse0 in activated"); + Serial.println(F("Pulse0 in activated")); return 500; } @@ -369,7 +369,7 @@ int sensors_ext(void) if (wstat[si] & SW_PULSE1) { wstat[si]&=~SW_PULSE1; wstat[si]|=SW_PULSE_P1; - Serial.println("Pulse1 in progress"); + Serial.println(F("Pulse1 in progress")); return 500; } @@ -378,14 +378,14 @@ int sensors_ext(void) wstat[si]&=~SW_PULSE1_R; wstat[si]|=SW_PULSE_P1; regs[si] =(ow2408out(term[si],(regs[si] | SW_MASK) & ~SW_OUT1) & SW_INMASK) ^ SW_STAT1; - Serial.println("Pulse0 in activated"); + Serial.println(F("Pulse0 in activated")); return 500; } if (wstat[si] & SW_PULSE_P0) { wstat[si]&=~SW_PULSE_P0; - Serial.println("Pulse0 clearing"); + Serial.println(F("Pulse0 clearing")); ow2408out(term[si],regs[si] | SW_MASK | SW_OUT0); if (wstat[si] & SW_CHANGED_P0) { @@ -397,7 +397,7 @@ int sensors_ext(void) if (wstat[si] & SW_PULSE_P1) { wstat[si]&=~SW_PULSE_P1; - Serial.println("Pulse1 clearing"); + Serial.println(F("Pulse1 clearing")); ow2408out(term[si],regs[si] | SW_MASK | SW_OUT1); if (wstat[si] & SW_CHANGED_P1) { @@ -421,7 +421,7 @@ if (wstat[si] & SW_PULSE_P1) { if (!(wstat[si] & SW_DOUBLECHECK)) { wstat[si]|=SW_DOUBLECHECK; //suspected - Serial.println("DOUBLECHECK"); + Serial.println(F("DOUBLECHECK")); return recheck_interval; } @@ -441,7 +441,7 @@ if (wstat[si] & SW_PULSE_P1) { case 0x81: t=wstat[si]; if (t!=regs[si]) - { Serial.println("Changed"); + { Serial.println(F("Changed")); if (owChanged) owChanged(si,term[si],t); regs[si]=t; }