diff --git a/lighthub/item.cpp b/lighthub/item.cpp index 152a8f0..adc0318 100644 --- a/lighthub/item.cpp +++ b/lighthub/item.cpp @@ -574,14 +574,16 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send) { case CH_MODBUS: { short numpar=0; if ((itemArg->type == aJson_Array) && ((numpar = aJson.getArraySize(itemArg)) >= 2)) { - int _addr = aJson.getArrayItem(itemArg, 0)->valueint; - int _reg = aJson.getArrayItem(itemArg, 1)->valueint; + int _addr = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_ADDR)->valueint; + int _reg = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_REG)->valueint; int _mask = -1; - if (numpar >= 3) _mask = aJson.getArrayItem(itemArg, 2)->valueint; + if (numpar >= (MODBUS_CMD_ARG_MASK+1)) _mask = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_MASK)->valueint; int _maxval = 0x3f; - if (numpar >=4) _maxval = aJson.getArrayItem(itemArg, 3)->valueint; - if (_maxval) modbusDimmerSet(_addr, _reg, _mask, map(Par[0], 0, 100, 0, _maxval)); - else modbusDimmerSet(_addr, _reg, _mask, Par[0]); + if (numpar >= (MODBUS_CMD_ARG_MAX_SCALE+1)) _maxval = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_MAX_SCALE)->valueint; + int _regType = MODBUS_HOLDING_REG_TYPE; + if (numpar >= (MODBUS_CMD_ARG_REG_TYPE+1)) _regType = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_REG_TYPE)->valueint; + if (_maxval) modbusDimmerSet(_addr, _reg, _regType, _mask, map(Par[0], 0, 100, 0, _maxval)); + else modbusDimmerSet(_addr, _reg, _regType, _mask, Par[0]); } break; } @@ -886,7 +888,11 @@ int Item::VacomSetHeat(int addr, int8_t val, int8_t cmd) { modbusBusy = 0; } -int Item::modbusDimmerSet(int addr, uint16_t _reg, int _mask, uint16_t value) { +int Item::modbusDimmerSet(int addr, uint16_t _reg, int _regType, int _mask, uint16_t value) { + + if (_regType != MODBUS_COIL_REG_TYPE || _regType != MODBUS_HOLDING_REG_TYPE) { + + } if (modbusBusy) { mb_fail(3, addr, value, 0); @@ -895,7 +901,7 @@ int Item::modbusDimmerSet(int addr, uint16_t _reg, int _mask, uint16_t value) { }; modbusBusy = 1; - modbusSerial.begin(9600, dimPar); + modbusSerial.begin(MODBUS_SERIAL_BAUD, dimPar); node.begin(addr, modbusSerial); @@ -912,10 +918,22 @@ int Item::modbusDimmerSet(int addr, uint16_t _reg, int _mask, uint16_t value) { Serial.print(addr); Serial.print(F("=>")); Serial.print(_reg, HEX); - Serial.print(F(":")); + Serial.print(F("(T:")); + Serial.print(_regType); + Serial.print(F("):")); Serial.println(value, HEX); - node.writeSingleRegister(_reg, value); + switch (_regType) { + case MODBUS_HOLDING_REG_TYPE: + node.writeSingleRegister(_reg, value); + break; + case MODBUS_COIL_REG_TYPE: + node.writeSingleCoil(_reg, value); + break; + default: + Serial.println(F("Not supported reg type")); + } + modbusBusy = 0; } @@ -1033,6 +1051,7 @@ boolean Item::checkModbusRetry() { if (cmd & CMD_RETRY) { // if last sending attempt of command was failed int val = getVal(); Serial.println(F("Retrying CMD")); + cmd &= ~CMD_RETRY; // Clean retry flag Ctrl(cmd,1,&val); // Execute command again return true; @@ -1043,23 +1062,53 @@ return false; int Item::checkModbusDimmer() { if (modbusBusy) return -1; if (checkModbusRetry()) return -2; + + short numpar = 0; + if ((itemArg->type != aJson_Array) || ((numpar = aJson.getArraySize(itemArg)) < 2)) { + Serial.println(F("Illegal arguments")); + return -3; + } + modbusBusy = 1; uint8_t result; - uint16_t addr = getArg(0); - uint16_t reg = getArg(1); + uint16_t addr = getArg(MODBUS_CMD_ARG_ADDR); + uint16_t reg = getArg(MODBUS_CMD_ARG_REG); + int _regType = MODBUS_HOLDING_REG_TYPE; + if (numpar >= (MODBUS_CMD_ARG_REG_TYPE+1)) _regType = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_REG_TYPE)->valueint; // short mask = getArg(2); + // Serial.print(F("Modbus polling ")); + // Serial.print(addr); + // Serial.print(F("=>")); + // Serial.print(reg, HEX); + // Serial.print(F("(T:")); + // Serial.print(_regType); + // Serial.println(F(")")); int data; //node.setSlave(addr); - modbusSerial.begin(9600, dimPar); + modbusSerial.begin(MODBUS_SERIAL_BAUD, dimPar); node.begin(addr, modbusSerial); - - result = node.readHoldingRegisters(reg, 1); + switch (_regType) { + case MODBUS_HOLDING_REG_TYPE: + result = node.readHoldingRegisters(reg, 1); + break; + case MODBUS_COIL_REG_TYPE: + result = node.readCoils(reg, 1); + break; + case MODBUS_DISCRETE_REG_TYPE: + result = node.readDiscreteInputs(reg, 1); + break; + case MODBUS_INPUT_REG_TYPE: + result = node.readInputRegisters(reg, 1); + break; + default: + Serial.println(F("Not supported reg type")); + } if (result == node.ku8MBSuccess) { data = node.getResponseBuffer(0); diff --git a/lighthub/item.h b/lighthub/item.h index 7a854dd..75d916f 100644 --- a/lighthub/item.h +++ b/lighthub/item.h @@ -53,6 +53,17 @@ e-mail anklimov@gmail.com #define I_CMD 3 //Latest CMD received #define I_EXT 4 //Chanell-depended extension - array +#define MODBUS_CMD_ARG_ADDR 0 +#define MODBUS_CMD_ARG_REG 1 +#define MODBUS_CMD_ARG_MASK 2 +#define MODBUS_CMD_ARG_MAX_SCALE 3 +#define MODBUS_CMD_ARG_REG_TYPE 4 + +#define MODBUS_COIL_REG_TYPE 0 +#define MODBUS_DISCRETE_REG_TYPE 1 +#define MODBUS_HOLDING_REG_TYPE 2 +#define MODBUS_INPUT_REG_TYPE 3 + #include "aJSON.h" extern aJsonObject *items; @@ -114,7 +125,7 @@ class Item protected: int VacomSetFan (int8_t val, int8_t cmd=0); int VacomSetHeat(int addr, int8_t val, int8_t cmd=0); - int modbusDimmerSet(int addr, uint16_t _reg, int _mask, uint16_t value); + int modbusDimmerSet(int addr, uint16_t _reg, int _regType, int _mask, uint16_t value); void mb_fail(short addr, short op, int val, int cmd); int isActive(); void Parse(); diff --git a/lighthub/options.h b/lighthub/options.h index 31ad60f..87bbde6 100644 --- a/lighthub/options.h +++ b/lighthub/options.h @@ -29,7 +29,9 @@ #define OFFSET_MQTT_PWD OFFSET_CONFIGSERVER+32 #define EEPROM_offset OFFSET_MQTT_PWD+16 +#ifndef INTERVAL_CHECK_INPUT #define INTERVAL_CHECK_INPUT 50 +#endif #define INTERVAL_CHECK_MODBUS 2000 #define INTERVAL_POLLING 100 #define THERMOSTAT_CHECK_PERIOD 5000 @@ -42,7 +44,11 @@ #define MODBUS_SERIAL_BAUD 9600 #endif -#define dimPar SERIAL_8E1 +#ifndef MODBUS_DIMMER_PARAM +#define MODBUS_DIMMER_PARAM SERIAL_8E1 +#endif + +#define dimPar MODBUS_DIMMER_PARAM #define fmPar SERIAL_8N1 #ifndef SERIAL_BAUD