diff --git a/src/modules/sensors/ModbusRTUasync/ModbusRTU.cpp b/src/modules/sensors/ModbusRTUasync/ModbusRTU.cpp index 5d575416..f6f346b5 100644 --- a/src/modules/sensors/ModbusRTUasync/ModbusRTU.cpp +++ b/src/modules/sensors/ModbusRTUasync/ModbusRTU.cpp @@ -52,6 +52,7 @@ private: uint8_t _countReg = 1; uint32_t _token = 0; bool _isFloat = 0; + CoilData _respCoil; public: ModbusNode(String parameters) : IoTItem(parameters) @@ -127,13 +128,14 @@ public: { if (MB) { - if (_func == 0x02) // coil + if (_func == 0x02 || _func == 0x01) // coil { uint16_t val; - //response.get(3, val); - //regEvent((float)val, "ModbusNode"); + // response.get(3, val); + // regEvent((float)val, "ModbusNode"); CoilData cd(_countReg); cd.set(0, _countReg, (uint8_t *)response.data() + 3); + _respCoil = cd; cd.print("Received : ", Serial); val = cd[0]; regEvent(val, "ModbusNode"); @@ -168,9 +170,33 @@ public: } } + // Комманды из сценария + IoTValue execute(String command, std::vector ¶m) + { + IoTValue val; + // uint8_t result; + // uint32_t reading; + + uint16_t _index = 0; + + if (command == "getBits") + { + if (param.size()) + { + if (_respCoil.size() > _index) + { + _index = param[0].valD; + val.valD = _respCoil[_index]; + return val; + } + } + } + return {}; + } + ~ModbusNode() { - MBNoneMap.erase(_token); + //MBNoneMap.erase(_token); }; }; @@ -283,109 +309,6 @@ public: uint16_t _reg = 0; uint8_t count = 1; - /* - if (command == "readInputRegisters") // vout = mb.readInputRegisters(1, "0х0000", 1, 0) - "Адрес","Регистр","Кличество регистров","1-float, 0-long" - { - if (param.size()) - { - _addr = param[0].valD; - _reg = hexStringToUint16(param[1].valS); - count = (uint8_t)param[2].valD; - count = count > 2 ? 2 : count; - count = count < 1 ? 1 : count; - // val.valD = readFunctionModBus(0x04, _addr, _reg, count, isFloat); - // uint32_t lastMillis = millis(); - Serial.printf("sending request with token %d\n", _token); - Error err; - err = MB->addRequest(_token, _addr, READ_INPUT_REGISTER, _reg, count); - if (err != SUCCESS) - { - ModbusError e(err); - Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e); - } - } - return val; - } - else if (command == "readHoldingRegisters") // vout = mb.readHoldingRegisters(1, "0х0000", 2, 1) - "Адрес","Регистр","Кличество регистров","1-float, 0-long" - { - if (param.size()) - { - _addr = param[0].valD; - _reg = hexStringToUint16(param[1].valS); - count = (uint8_t)param[2].valD; - count = count > 2 ? 2 : count; - count = count < 1 ? 1 : count; - // val.valD = readFunctionModBus(0x03, _addr, _reg, count, isFloat); - - // Create request for - // (Fill in your data here!) - // - server ID = 1 - // - function code = 0x03 (read holding register) - // - start address to read = word 10 - // - number of words to read = 4 - // - token to match the response with the request. We take the current millis() value for it. - // - // If something is missing or wrong with the call parameters, we will immediately get an error code - // and the request will not be issued - - Serial.printf("sending request with token %d\n", _token); - Error err; - err = MB->addRequest(_token, _addr, READ_HOLD_REGISTER, _reg, count); - if (err != SUCCESS) - { - ModbusError e(err); - Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e); - } - } - return val; - } - else if (command == "readCoils") // vout = mb.readCoils(1, \"0х0000\", 1) - "Адрес","Регистр","Кличество бит" - { - if (param.size()) - { - count = (uint8_t)param[2].valD; - count = count > 16 ? 16 : count; - count = count < 1 ? 1 : count; - _addr = param[0].valD; - _reg = hexStringToUint16(param[1].valS); - // node.begin(_addr, (Stream &)*_modbusUART); - // val.valD = readFunctionModBus(0x01, _addr, _reg, count); - - // Read a slice of 12 coils, starting at 13 - Serial.printf("sending request with token %d\n", _token); - Error err; - err = MB->addRequest(_token, _addr, READ_COIL, _reg, count); - if (err != SUCCESS) - { - ModbusError e(err); - Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e); - } - } - return val; - } - else if (command == "readDiscreteInputs") // vout = mb.readDiscreteInputs(1, \"0х0000\", 1) - "Адрес","Регистр","Кличество бит" - { - if (param.size()) - { - count = (uint8_t)param[2].valD; - count = count > 16 ? 16 : count; - count = count < 1 ? 1 : count; - _addr = param[0].valD; - _reg = hexStringToUint16(param[1].valS); - // node.begin(_addr, (Stream &)*_modbusUART); - // val.valD = readFunctionModBus(0x02, _addr, _reg, count); - Serial.printf("sending request with token %d\n", _token); - Error err; - err = MB->addRequest(_token, _addr, READ_DISCR_INPUT, _reg, count); - if (err != SUCCESS) - { - ModbusError e(err); - Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e); - } - } - return val; - } - else */ if (command == "writeSingleRegister") // vout = mb.writeSingleRegister(1,"0x0003", 1) - addr, register, state { if (param.size()) @@ -446,7 +369,7 @@ public: } else { - //msg.setMessage(_addr, WRITE_COIL, _reg, 0x0000); + // msg.setMessage(_addr, WRITE_COIL, _reg, 0x0000); err = MB->addRequest(_token, _addr, WRITE_COIL, _reg, 0); } if (err != SUCCESS) diff --git a/src/modules/sensors/ModbusRTUasync/modinfo.json b/src/modules/sensors/ModbusRTUasync/modinfo.json index ea9d4ef9..88afa653 100644 --- a/src/modules/sensors/ModbusRTUasync/modinfo.json +++ b/src/modules/sensors/ModbusRTUasync/modinfo.json @@ -9,7 +9,7 @@ "id": "mbNode", "widget": "anydataTmp", "page": "Modbus", - "descr": "Данные modbus", + "descr": "Чтение данных modbus", "int": 5, "func": "0x03", "addr": 1, @@ -26,7 +26,7 @@ "id": "mb", "widget": "anydataTmp", "page": "Modbus", - "descr": "Настройки modbus", + "descr": "Настройки и запись modbus", "int": 5, "RX": 18, "TX": 19, @@ -42,7 +42,7 @@ "authorGit": "https://github.com/Mit4el", "specialThanks": "Serghei Crasnicov", "moduleName": "ModbusRTUasync", - "moduleVersion": "1.0", + "moduleVersion": "1.1", "usedRam": { "esp32_4mb": 15, "esp8266_4mb": 15 @@ -51,7 +51,7 @@ "mbClient" ], "title": "ModbusAsync", - "moduleDesc": "Позволяет управлять оборудованием по протоколу modbus. Чтение регситров через Ноды, Запись через функции сценария в ModbusAsunc", + "moduleDesc": "Позволяет управлять оборудованием по протоколу modbus. Модуль ModbusAsync обязательный для настройки. Запись через функции сценария в ModbusAsync. Для чтение регистров добавлять модули ModbusNode.", "propInfo": { "int": "Количество секунд между опросами датчика.", "RX": "Пин RX", @@ -60,33 +60,37 @@ "baud": "скорость Uart", "protocol": "Протокол Uart: SERIAL_8N1 или SERIAL_8N2", "debug": " 1 - включить вывод дебага , 0 - отключить дебаг", - "isFloat": "Тип считываемых данных, если count=2, то данные могут быть long (указать 0) или float (указать 1). Числа Long не рекомендуются (на больших числах не будет точности), так как будет ограничено точность представление в IotManager идет во float", - "func": "Функция modbus", - "addr": "Адрес slav", + "func": "Функция чтения modbus (0x01, 0x02, 0x03, 0x04)", + "addr": "Адрес slave", "reg": "Адрес регистра", - "count": "Количество регистров. В ModbusNode 16-разядные регистры можно считать не более 2 в ноде. Для битовых данных не более 16 бит в ноде. Значение поместится в value Ноды" - + "count": "Количество регистров. В ModbusNode 16-разядные регистры можно считать не более 2 в ноде. Для битовых данных не более 16 бит в ноде. Значение поместится в value Ноды", + "isFloat": "Тип считываемых данных, если count=2, то данные могут быть long (указать 0) или float (указать 1). Числа Long не рекомендуются (на больших числах не будет точности), так как будет ограничено точность представление в IotManager идет во float" }, "funcInfo": [ { "name": "writeSingleCoils", - "descr": "Запись в койл (битовое поле) одного бита. Функция 0х05 протокола. Пример: mb.writeSingleCoils(1, \"0х0000\", 1)", + "descr": "Запись в койл (битовое поле) одного бита, вызывать из ModbusAsunc. Функция 0х05 протокола. Пример: mb.writeSingleCoils(1, \"0х0000\", 1)", "params": ["Адрес","Регистр","Данные"] }, { "name": "writeSingleRegister", - "descr": "Запись данных в один регистр. Функция 0х06 протокола. Пример: mb.writeSingleRegister(1, \"0х0000\", 128)", + "descr": "Запись данных в один регистр, вызывать из ModbusAsunc. Функция 0х06 протокола. Пример: mb.writeSingleRegister(1, \"0х0000\", 128)", "params": ["Адрес","Регистр","Данные"] }, { "name": "writeMultipleCoils", - "descr": "Запись данных в несколько койлов до 16 (число от 0 до 65535). Функция 0x0F протокола. Пример: mb.writeMultipleCoils(1, \"0х0000\", 4, 3) - будут записаны в четыре бита 0011", + "descr": "В разработке! Запись данных в несколько койлов до 16 (число от 0 до 65535), вызывать из ModbusAsunc. Функция 0x0F протокола. Пример: mb.writeMultipleCoils(1, \"0х0000\", 4, 3) - будут записаны в четыре бита 0011", "params": ["Адрес","Регистр","Кличество койлов (бит)","Данные"] }, { "name": "writeMultipleRegisters", - "descr": "Запись данных в несколько регистров. На данный момент записывает 2(два) регистра!!!!! Подходит для записи float?? Функция 0х10 протокола. Пример: mb.writeMultipleRegisters(1, \"0х0000\", 1234.987)", + "descr": "В разработке! Запись данных в несколько регистров, вызывать из ModbusAsunc. Записывает 2(два) регистра!!!!! Подходит для записи float?? Функция 0х10 протокола. Пример: mb.writeMultipleRegisters(1, \"0х0000\", 1234.987)", "params": ["Адрес","Регистр","Данные"] + }, + { + "name": "getBits", + "descr": "Получить из ModbusNode бит по его номеру, если ранее считали из слейва F0x01 или F0x02 более одного бита. Вернёт -1 если данных нет. Пример: mbNode.getCoil(0) получит первый из считанных бит", + "params": ["индекс бита"] } ] },