From b3af9865c7bf6d40e7e1cf483bd4692ac05047bb Mon Sep 17 00:00:00 2001 From: Andrey Klimov Date: Wed, 6 Apr 2022 10:21:39 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1ounter=20mod,=20core=20&=20modbus=20tuned?= =?UTF-8?q?=20for=201/100th=20prec?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lighthub/item.cpp | 42 ++++++++-- lighthub/item.h | 3 +- lighthub/itemCmd.cpp | 103 ++++++++++++++++-------- lighthub/itemCmd.h | 8 +- lighthub/modules/out_counter.cpp | 132 +++++++++++++++++++++++++++++++ lighthub/modules/out_counter.h | 26 ++++++ lighthub/modules/out_modbus.cpp | 83 +++++++++++++------ lighthub/modules/out_modbus.h | 2 +- lighthub/modules/out_pid.cpp | 8 +- lighthub/options.h | 5 ++ lighthub/utils.cpp | 40 +++++++--- 11 files changed, 370 insertions(+), 82 deletions(-) create mode 100644 lighthub/modules/out_counter.cpp create mode 100644 lighthub/modules/out_counter.h diff --git a/lighthub/item.cpp b/lighthub/item.cpp index 4a2f1a4..34947f4 100644 --- a/lighthub/item.cpp +++ b/lighthub/item.cpp @@ -51,6 +51,7 @@ e-mail anklimov@gmail.com #include "modules/out_multivent.h" #include "modules/out_uartbridge.h" #include "modules/out_relay.h" +#include "modules/out_counter.h" #ifdef ELEVATOR_ENABLE #include "modules/out_elevator.h" @@ -205,6 +206,12 @@ void Item::Parse() { driver = new out_elevator (this); // debugSerial<setSubtype(cmd.itemArgType); + //item->setSubtype(cmd.itemArgType); item->setVal(param.asInt32); + item->setSubtype(cmd.itemArgType); } debugSerial<getFloatArg(0); + period = item->getFloatArg(1)*1000.0; +} + +int out_counter::Setup() +{ + abstractOut::Setup(); + driverStatus = CST_INITIALIZED; +return 1; +} + +int out_counter::Stop() +{ +driverStatus = CST_UNKNOWN; +return 1; +} + +int out_counter::Status() +{ +return driverStatus; +} + + +int out_counter::Poll(short cause) +{ + if (!item) return 0; + + +uint32_t timer = item->getExt(); + + if (timer && isTimeOver(timer,millis(),period)) + { + item->setExt(millisNZ()); + itemCmd st; + st.loadItem(item); + float val = st.getFloat(); + //short cmd = st.getCmd(); + val+=period; + st.Float(val); + st.saveItem(item); + } + + return 0; +}; + + +int out_counter::Ctrl(itemCmd cmd, char* subItem, bool toExecute) +{ +debugSerial<getExt()) + { + item->setExt(millisNZ()); + //relay(true); + } + } + else + { + item->setExt(0); + + } + } + return 1; +case S_CMD: + + switch (cmd.getCmd()) + { + case CMD_ON: + case CMD_HEAT: + case CMD_COOL: + case CMD_AUTO: + case CMD_FAN: + case CMD_DRY: + if (!item->getExt()) + { + item->setExt(millisNZ()); + //relay(true); + } + return 1; + + case CMD_OFF: + item->setExt(0); + + return 1; + + default: + debugSerial< +#include + +class out_counter : public abstractOut { +public: + + out_counter(Item * _item):abstractOut(_item){ getConfig();}; + void getConfig(); + int Setup() override; + int Poll(short cause) override; + int Stop() override; + int Status() override; + + int getChanType() override; + int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override; + +protected: + float impulse; + uint32_t period; +}; +#endif diff --git a/lighthub/modules/out_modbus.cpp b/lighthub/modules/out_modbus.cpp index 0034bfa..0dfebd9 100644 --- a/lighthub/modules/out_modbus.cpp +++ b/lighthub/modules/out_modbus.cpp @@ -39,6 +39,7 @@ struct serial_t #define PAR_U8H 7 #define PAR_U8L 8 #define PAR_TENS 9 +#define PAR_100 10 const reg_t regSize_P[] PROGMEM = @@ -51,7 +52,8 @@ const reg_t regSize_P[] PROGMEM = { "i8l", (uint8_t) PAR_I8L }, { "u8h", (uint8_t) PAR_U8H }, { "u8l", (uint8_t) PAR_U8L }, - { "x10", (uint8_t) PAR_TENS } + { "x10", (uint8_t) PAR_TENS }, + { "100", (uint8_t) PAR_100 } } ; #define regSizeNum sizeof(regSize_P)/sizeof(reg_t) @@ -233,7 +235,7 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType) bool is8bit = false; while (paramObj) { - aJsonObject *regObj; + aJsonObject *regObj=NULL; switch (regType) { case MODBUS_HOLDING_REG_TYPE: regObj = aJson.getObjectItem(paramObj, "reg"); break; @@ -257,12 +259,13 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType) case PAR_I16: //isSigned=true; + param=data; mappedParam.Int((int32_t)data); break; case PAR_U16: + param=data; mappedParam.Int((uint32_t)data); - //param=data; break; case PAR_I32: //isSigned=true; @@ -288,7 +291,14 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType) break; case PAR_TENS: + param=data; mappedParam.Tens((int32_t) data); + break; + + case PAR_100: + param=data; + mappedParam.Tens_raw(data * (TENS_BASE/100)); + mappedParam.Float((int32_t) data/100.); } if (mapObj && (mapObj->type==aJson_Array || mapObj->type==aJson_Object)) @@ -306,16 +316,24 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType) aJsonObject *lastMeasured = aJson.getObjectItem(execObj,"@S"); if (lastMeasured) { - if (lastMeasured->valueint == mappedParam.getSingleInt()) + if (lastMeasured->valueint == param) submitParam=false; //supress repeating execution for same val - else lastMeasured->valueint=mappedParam.getSingleInt(); + else lastMeasured->valueint=param; } else //No container to store value yet { debugSerial<name<valueint == param)) + { + debugSerial<getArg(0), modbusSerial); } -int out_Modbus::sendModbus(char * paramName, uint32_t value, uint8_t regType) +int out_Modbus::sendModbus(char * paramName, int32_t value, uint8_t regType) { if (!store) return -1; aJsonObject * templateParamObj = aJson.getObjectItem(store->parameters, paramName); @@ -401,9 +419,12 @@ int out_Modbus::sendModbus(char * paramName, uint32_t value, uint8_t regType) // if (typeObj && typeObj->type == aJson_String) regType=str2regSize(typeObj->valuestring); switch(regType) { - case PAR_I16: case PAR_U16: + //res = node.writeSingleRegister(regObj->valueint,value); + //break; + case PAR_I16: case PAR_TENS: + case PAR_100: res = node.writeSingleRegister(regObj->valueint,value); break; @@ -424,7 +445,7 @@ int out_Modbus::sendModbus(char * paramName, uint32_t value, uint8_t regType) res = node.writeSingleRegister(regObj->valueint,(value & 0xFFFF)>> 8); break; } - debugSerial<valueint<valueint<type ==aJson_Object) break; case 0: //fault execObj->subtype |= MB_SEND_ERROR; + errorSerial<name<name<type ==aJson_Object) { aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,suffixStr); if (execObj && execObj->type == aJson_Object) - { - execObj->subtype |= MB_NEED_SEND; - - aJsonObject *outValue = aJson.getObjectItem(execObj,"@V"); - if (outValue) + { + aJsonObject *polledValue = aJson.getObjectItem(execObj,"@S"); + if (polledValue && (polledValue->valueint == Value)) { - outValue->valueint=Value; - outValue->subtype =regType; + debugSerial<name<subtype =regType; - } + + else + { //Schedule update + execObj->subtype |= MB_NEED_SEND; + + aJsonObject *outValue = aJson.getObjectItem(execObj,"@V"); + if (outValue) + { + outValue->valueint=Value; + outValue->subtype =regType; + polledValue->valueint=Value; //to pevent suppressing to change back to previously polled value if this occurs before next polling + } + else //No container to store value yet + { + debugSerial<name<subtype =regType; + } + } } } diff --git a/lighthub/modules/out_modbus.h b/lighthub/modules/out_modbus.h index 197f5ff..3966ce4 100644 --- a/lighthub/modules/out_modbus.h +++ b/lighthub/modules/out_modbus.h @@ -45,6 +45,6 @@ protected: int findRegister(int registerNum, int posInBuffer, int regType); void pollModbus(aJsonObject * reg, int regType); void initLine(); - int sendModbus(char * paramName, uint32_t value, uint8_t regType); + int sendModbus(char * paramName, int32_t value, uint8_t regType); }; #endif diff --git a/lighthub/modules/out_pid.cpp b/lighthub/modules/out_pid.cpp index 1c3e825..1662ce2 100644 --- a/lighthub/modules/out_pid.cpp +++ b/lighthub/modules/out_pid.cpp @@ -276,8 +276,6 @@ int out_pid::getChanType() int out_pid::Ctrl(itemCmd cmd, char* subItem, bool toExecute) { if (!store || !store->pid || (Status() != CST_INITIALIZED)) return 0; - - int suffixCode = cmd.getSuffix(); if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it @@ -307,6 +305,12 @@ case S_SET: if (!cmd.isValue()) return 0; store->setpoint=cmd.getFloat(); debugSerial<setpoint<itemArg, 2); +if (itemCascadeObj) executeCommand(itemCascadeObj,-1,cmd); +} + //cmd.saveItem(item); //item->SendStatus(SEND_PARAMETERS); return 1; diff --git a/lighthub/options.h b/lighthub/options.h index be2c0f5..e586285 100644 --- a/lighthub/options.h +++ b/lighthub/options.h @@ -1,5 +1,10 @@ #pragma once #include + + +#define TENS_FRACT_LEN 2 +#define TENS_BASE 100 + #define DEFAULT_FILESIZE_LIMIT 65535 #ifndef MAX_JSON_CONF_SIZE diff --git a/lighthub/utils.cpp b/lighthub/utils.cpp index 4285c5d..fab3393 100644 --- a/lighthub/utils.cpp +++ b/lighthub/utils.cpp @@ -116,31 +116,45 @@ int getInt(char **chan) { // Function return first retrived number and move pointer to position next after ',' itemCmd getNumber(char **chan) { itemCmd val(ST_TENS,CMD_VOID); - int fract =0; if (chan && *chan && **chan) { //Skip non-numeric values while (**chan && !(**chan == '-' || (**chan >= '0' && **chan<='9'))) *chan += 1; - int ch = atoi(*chan); - + + long fractnumbers = 0; + short fractlen = 0; + short intlen = 0; + + char * intptr = * chan; + if (*intptr == '-') intptr ++; + while (isDigit(*(intptr+intlen))) intlen++; + char * fractptr = strchr(*chan,'.'); if (fractptr) { - // fract = atoi(fractptr); - // *chan = fractptr; - fractptr += 1; - fract = constrain(*fractptr-'0',0,9); + fractptr ++; + while (isDigit(*(fractptr+fractlen))) fractlen++; + + for (short i=0;i=0)?fractnumbers:-fractnumbers)); + } + else + val.Float(atof(*chan)); + //Move pointer to next element (after ,) *chan = strchr(*chan, ','); if (*chan) *chan += 1; - //debugSerialPort.print(F("Par:")); debugSerialPort.println(ch); - - if (fract) - val.Tens(ch*10+((ch>0)?fract:-fract)); - else - val.Int((int32_t)ch); + } //val.debugOut(); return val;