New! Conversion data array boolean to char. Reading module inputs

Hello! I bring good news.
First I will answer:

  • The idea I have when the bus goes into an error is to detect an error and set a waiting time to re-establish communication and to initialize again. I'm still working on this.
  • I have the second bus already implemented and working. It is a new physical bus with a new USB-RS485 adapter.
    Right now I have a bus that reads the 6 digital input modules at maximum speed and another bus in which I send a query every second. In addition, the second I use to activate relays.

The implementation of the activation of the relays, I'm working on it. What I don't like is that I have 128 relays and I have to attack them all separately. When I get this a bit advanced, I'll post.

[{"id":"209e05d933581382","type":"modbus-flex-getter","z":"3c3fa1ce28c0ce43","name":"Modbus Flex Getter - 1RS485","showStatusActivities":true,"showErrors":true,"logIOActivities":false,"server":"08eb64dc3971b8b1","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":true,"keepMsgProperties":true,"x":390,"y":220,"wires":[["30118cbab3c92f77","bb51eba97298343e","c137dda295101019","e1842eb601f14288","5e5d40d9a78cb6bd","897e047a478e3289","4a34ecc0f0856934","13fb93f070716b95"],[]]},{"id":"39dcb638ca6b4444","type":"inject","z":"3c3fa1ce28c0ce43","name":"begin","props":[{"p":"payload"},{"p":"queueUnitId","v":"0","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"str","x":130,"y":380,"wires":[["0c5c2847fd3d0222"]]},{"id":"30118cbab3c92f77","type":"debug","z":"3c3fa1ce28c0ce43","name":"msg modbus","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":200,"y":120,"wires":[]},{"id":"0c5c2847fd3d0222","type":"function","z":"3c3fa1ce28c0ce43","name":"","func":"if (!(msg.hasOwnProperty('payload'))) {\n    return null;\n}\nvar count;\nif (msg.payload == \"\") {\n    count = msg.queueUnitId + 1;\n} else {\n    if (msg.modbusRequest.unitid < 6) {\n        count = msg.modbusRequest.unitid + 1;\n    }\n    else {\n        count = 1;\n    }\n}\nmsg.payload = {\n    'fc': 2,\n    'unitid': count,\n    'address': 0,\n    'quantity': 16\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":320,"y":380,"wires":[["209e05d933581382","1562a609b2da1bf5"]]},{"id":"1562a609b2da1bf5","type":"debug","z":"3c3fa1ce28c0ce43","name":"msg function","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":500,"y":420,"wires":[]},{"id":"bb51eba97298343e","type":"debug","z":"3c3fa1ce28c0ce43","name":"","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"modbusRequest.unitid","targetType":"msg","statusVal":"","statusType":"auto","x":470,"y":120,"wires":[]},{"id":"c137dda295101019","type":"delay","z":"3c3fa1ce28c0ce43","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":170,"y":320,"wires":[["0c5c2847fd3d0222"]]},{"id":"dc4dba8ce161f3cd","type":"modbus-flex-getter","z":"3c3fa1ce28c0ce43","name":"Modbus Flex Getter - 2RS485","showStatusActivities":true,"showErrors":true,"logIOActivities":false,"server":"1d30ba62236b3eda","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":true,"keepMsgProperties":true,"x":250,"y":700,"wires":[["701f1c6b7856e43a","429761f113c4adb6","b94b862430a7c92e","8c57e745311051c8","6441e4ef2e6ac351","205fa9e97151872c","6e3172a083fca2a5","cdeaf13b136f4ddc","30f6c45f24961eae"],[]]},{"id":"701f1c6b7856e43a","type":"debug","z":"3c3fa1ce28c0ce43","name":"msg modbus","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":540,"y":560,"wires":[]},{"id":"c3607d8d6f797d28","type":"function","z":"3c3fa1ce28c0ce43","name":"","func":"if (isNaN(msg.counter++)){\n    msg.counter = 11;\n}\n\n//Incrementar comptador\nmsg.counter++;\n\n//Comprovació comptador dins de límits i ajustament\nif (msg.counter < 2) {\n    msg.counter = 2;\n}\n\nif ((msg.counter >= 3) && (msg.counter < 11)) {\n    msg.counter = 11;\n}\n\nif (msg.counter >= 16) {\n    msg.counter = 2;\n}\n\n//Lectura inputs WELLPRO WP3082ADAM - Analògics\nif (msg.counter == 2){\n    msg.payload = {\n        'fc': 3,\n        'unitid': msg.counter,\n        'address': 0,\n        'quantity': 8\n    };\n}\n\n//Lectura sensors SHT20 (Temperatura i humitat)\nif ((msg.counter >= 11) && (msg.counter <= 15)) {\n    msg.payload = {\n        'fc': 4,\n        'unitid': msg.counter,\n        'address': 1,\n        'quantity': 2\n    };\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":880,"wires":[["dc4dba8ce161f3cd","5be9684544644059"]]},{"id":"429761f113c4adb6","type":"debug","z":"3c3fa1ce28c0ce43","name":"","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"modbusRequest.unitid","targetType":"msg","statusVal":"","statusType":"auto","x":590,"y":600,"wires":[]},{"id":"30f6c45f24961eae","type":"delay","z":"3c3fa1ce28c0ce43","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":180,"y":820,"wires":[["c3607d8d6f797d28"]]},{"id":"1efd5499a5b7c7ac","type":"comment","z":"3c3fa1ce28c0ce43","name":"Lectura inputs a baixa velocitat (sensors, relés, ...)","info":"","x":230,"y":560,"wires":[]},{"id":"ffdc63fbb4130d4c","type":"comment","z":"3c3fa1ce28c0ce43","name":"Lectura inputs a alta velocitat (pulsadors)","info":"","x":220,"y":40,"wires":[]},{"id":"6150ceeef4ee62b9","type":"inject","z":"3c3fa1ce28c0ce43","name":"begin","props":[{"p":"payload"},{"p":"counter","v":"0","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":90,"y":880,"wires":[["c3607d8d6f797d28"]]},{"id":"70081fa2f327012a","type":"debug","z":"3c3fa1ce28c0ce43","name":"msg1","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":980,"y":560,"wires":[]},{"id":"fc72bb501a3c1949","type":"debug","z":"3c3fa1ce28c0ce43","name":"msg2","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":980,"y":600,"wires":[]},{"id":"b94b862430a7c92e","type":"function","z":"3c3fa1ce28c0ce43","name":"get-Temp-n11","func":"if (msg.modbusRequest.unitid == 11) {\n    var msg1 = {};\n    var msg2 = {};\n    msg1.payload = msg.payload[0];\n    msg2.payload = msg.payload[1];\n    return ([msg1, msg2]);\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":640,"wires":[["70081fa2f327012a"],["fc72bb501a3c1949"]]},{"id":"8c57e745311051c8","type":"function","z":"3c3fa1ce28c0ce43","name":"get-Temp-n12","func":"if (msg.modbusRequest.unitid == 12) {\n    var msg1 = {};\n    var msg2 = {};\n    msg1.payload = msg.payload[0];\n    msg2.payload = msg.payload[1];\n    return ([msg1, msg2]);\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":680,"wires":[["7d3e8ecd36d04889"],["ad41f44073b2a36c"]]},{"id":"6441e4ef2e6ac351","type":"function","z":"3c3fa1ce28c0ce43","name":"get-Temp-n13","func":"if (msg.modbusRequest.unitid == 13) {\n    var msg1 = {};\n    var msg2 = {};\n    msg1.payload = msg.payload[0];\n    msg2.payload = msg.payload[1];\n    return ([msg1, msg2]);\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":720,"wires":[["91eb46501a328c84"],["b77fe990b5e81867"]]},{"id":"205fa9e97151872c","type":"function","z":"3c3fa1ce28c0ce43","name":"get-Temp-n14","func":"if (msg.modbusRequest.unitid == 14) {\n    var msg1 = {};\n    var msg2 = {};\n    msg1.payload = msg.payload[0];\n    msg2.payload = msg.payload[1];\n    return ([msg1, msg2]);\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":760,"wires":[["b88a0aa9a3340e0f"],["278b216f0fa39052"]]},{"id":"6e3172a083fca2a5","type":"function","z":"3c3fa1ce28c0ce43","name":"get-Temp-n15","func":"if (msg.modbusRequest.unitid == 15) {\n    var msg1 = {};\n    var msg2 = {};\n    msg1.payload = msg.payload[0];\n    msg2.payload = msg.payload[1];\n    return ([msg1, msg2]);\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":800,"wires":[["06796e1aa2d5471a"],["b35d2db345465c62"]]},{"id":"7d3e8ecd36d04889","type":"debug","z":"3c3fa1ce28c0ce43","name":"msg1","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":980,"y":640,"wires":[]},{"id":"ad41f44073b2a36c","type":"debug","z":"3c3fa1ce28c0ce43","name":"msg2","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":980,"y":680,"wires":[]},{"id":"91eb46501a328c84","type":"debug","z":"3c3fa1ce28c0ce43","name":"msg1","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":983,"y":719,"wires":[]},{"id":"b77fe990b5e81867","type":"debug","z":"3c3fa1ce28c0ce43","name":"msg2","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":983,"y":759,"wires":[]},{"id":"b88a0aa9a3340e0f","type":"debug","z":"3c3fa1ce28c0ce43","name":"msg1","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":980,"y":800,"wires":[]},{"id":"278b216f0fa39052","type":"debug","z":"3c3fa1ce28c0ce43","name":"msg2","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":980,"y":840,"wires":[]},{"id":"06796e1aa2d5471a","type":"debug","z":"3c3fa1ce28c0ce43","name":"msg1","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":980,"y":880,"wires":[]},{"id":"b35d2db345465c62","type":"debug","z":"3c3fa1ce28c0ce43","name":"msg2","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":980,"y":920,"wires":[]},{"id":"5be9684544644059","type":"debug","z":"3c3fa1ce28c0ce43","name":"","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":530,"y":920,"wires":[]},{"id":"cdeaf13b136f4ddc","type":"function","z":"3c3fa1ce28c0ce43","name":"get-Analog-n2","func":"/*if (msg.modbusRequest.unitid == 2) {\n    var msg1 = {};\n    msg1.payload = msg.payload[0];\n    return (msg1);\n}*/\n\nif (msg.modbusRequest.unitid == 2) {\n    var msg1 = {};\n    var msg2 = {};\n    var msg3 = {};\n    var msg4 = {};\n    var msg5 = {};\n    var msg6 = {};\n    var msg7 = {};\n    var msg8 = {};\n    msg1.payload = msg.payload[1];\n    msg2.payload = msg.payload[2];\n    msg3.payload = msg.payload[3];\n    msg4.payload = msg.payload[4];\n    msg5.payload = msg.payload[5];\n    msg6.payload = msg.payload[6];\n    msg7.payload = msg.payload[7];\n    msg8.payload = msg.payload[8];\n    return ([msg1, msg2, msg3, msg4, msg5, msg6, msg7, msg8]);\n}","outputs":8,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":880,"wires":[[],[],[],[],[],[],[],[]]},{"id":"e1842eb601f14288","type":"function","z":"3c3fa1ce28c0ce43","name":"get-inputs-n1","func":"if (msg.modbusRequest.unitid == 1) {\n    var arr = msg.payload;\n    var byte1 = (arr[0] * 1) + (arr[1] * 2) + (arr[2] * 4) + (arr[3] * 8) + (arr[4] * 16) + (arr[5] * 32) + (arr[6] * 64) + (arr[7] * 128);\n    var byte2 = (arr[8] * 1) + (arr[9] * 2) + (arr[10] * 4) + (arr[11] * 8) + (arr[12] * 16) + (arr[13] * 32) + (arr[14] * 64) + (arr[15] * 128);\n    var msg1 = {};\n    var msg2 = {}; \n    msg1.payload = byte1;\n    msg2.payload = byte2;\n    return ([msg1, msg2]);\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":790,"y":120,"wires":[["a535adb9eb67b31a"],["e4468ea70a523297"]]},{"id":"a535adb9eb67b31a","type":"loxone-control-out","z":"3c3fa1ce28c0ce43","name":"Inputs1.1","miniserver":"c04ca4d6caa1d5c9","control":"19f40e56-0072-ee50-ffff6fc206f2b7bf","x":980,"y":100,"wires":[]},{"id":"e4468ea70a523297","type":"loxone-control-out","z":"3c3fa1ce28c0ce43","name":"Inputs1.2","miniserver":"c04ca4d6caa1d5c9","control":"19f40e7b-0047-1d6c-ffff6fc206f2b7bf","x":980,"y":140,"wires":[]},{"id":"5283b5f6cd6c0016","type":"loxone-control-out","z":"3c3fa1ce28c0ce43","name":"Inputs2.2","miniserver":"c04ca4d6caa1d5c9","control":"19f41951-00b4-8dc5-ffff6fc206f2b7bf","x":980,"y":220,"wires":[]},{"id":"5e5d40d9a78cb6bd","type":"function","z":"3c3fa1ce28c0ce43","name":"get-inputs-n2","func":"if (msg.modbusRequest.unitid == 2) {\n    var arr = msg.payload;\n    var byte1 = (arr[0] * 1) + (arr[1] * 2) + (arr[2] * 4) + (arr[3] * 8) + (arr[4] * 16) + (arr[5] * 32) + (arr[6] * 64) + (arr[7] * 128);\n    var byte2 = (arr[8] * 1) + (arr[9] * 2) + (arr[10] * 4) + (arr[11] * 8) + (arr[12] * 16) + (arr[13] * 32) + (arr[14] * 64) + (arr[15] * 128);\n    var msg1 = {};\n    var msg2 = {}; \n    msg1.payload = byte1;\n    msg2.payload = byte2;\n    return ([msg1, msg2]);\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":790,"y":200,"wires":[["d0f489a34622a3d5"],["5283b5f6cd6c0016"]]},{"id":"d0f489a34622a3d5","type":"loxone-control-out","z":"3c3fa1ce28c0ce43","name":"Inputs2.1","miniserver":"c04ca4d6caa1d5c9","control":"19f41950-001b-8672-ffff6fc206f2b7bf","x":980,"y":180,"wires":[]},{"id":"8d46a9ee02206c0e","type":"loxone-control-out","z":"3c3fa1ce28c0ce43","name":"Inputs3.2","miniserver":"c04ca4d6caa1d5c9","control":"19f41952-023c-9c74-ffff6fc206f2b7bf","x":980,"y":300,"wires":[]},{"id":"897e047a478e3289","type":"function","z":"3c3fa1ce28c0ce43","name":"get-inputs-n3","func":"if (msg.modbusRequest.unitid == 3) {\n    var arr = msg.payload;\n    var byte1 = (arr[0] * 1) + (arr[1] * 2) + (arr[2] * 4) + (arr[3] * 8) + (arr[4] * 16) + (arr[5] * 32) + (arr[6] * 64) + (arr[7] * 128);\n    var byte2 = (arr[8] * 1) + (arr[9] * 2) + (arr[10] * 4) + (arr[11] * 8) + (arr[12] * 16) + (arr[13] * 32) + (arr[14] * 64) + (arr[15] * 128);\n    var msg1 = {};\n    var msg2 = {}; \n    msg1.payload = byte1;\n    msg2.payload = byte2;\n    return ([msg1, msg2]);\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":790,"y":280,"wires":[["29f33b03494ee7da"],["8d46a9ee02206c0e"]]},{"id":"29f33b03494ee7da","type":"loxone-control-out","z":"3c3fa1ce28c0ce43","name":"Inputs3.1","miniserver":"c04ca4d6caa1d5c9","control":"19f41951-02b4-951b-ffff6fc206f2b7bf","x":980,"y":260,"wires":[]},{"id":"611e447cc3908d9a","type":"loxone-control-out","z":"3c3fa1ce28c0ce43","name":"Inputs4.2","miniserver":"c04ca4d6caa1d5c9","control":"19f4197d-0316-0373-ffff6fc206f2b7bf","x":980,"y":380,"wires":[]},{"id":"4a34ecc0f0856934","type":"function","z":"3c3fa1ce28c0ce43","name":"get-inputs-n4","func":"if (msg.modbusRequest.unitid == 4) {\n    var arr = msg.payload;\n    var byte1 = (arr[0] * 1) + (arr[1] * 2) + (arr[2] * 4) + (arr[3] * 8) + (arr[4] * 16) + (arr[5] * 32) + (arr[6] * 64) + (arr[7] * 128);\n    var byte2 = (arr[8] * 1) + (arr[9] * 2) + (arr[10] * 4) + (arr[11] * 8) + (arr[12] * 16) + (arr[13] * 32) + (arr[14] * 64) + (arr[15] * 128);\n    var msg1 = {};\n    var msg2 = {}; \n    msg1.payload = byte1;\n    msg2.payload = byte2;\n    return ([msg1, msg2]);\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":790,"y":360,"wires":[["7835a2118d42ff32"],["611e447cc3908d9a"]]},{"id":"7835a2118d42ff32","type":"loxone-control-out","z":"3c3fa1ce28c0ce43","name":"Inputs4.1","miniserver":"c04ca4d6caa1d5c9","control":"19f41953-0318-a3d0-ffff6fc206f2b7bf","x":980,"y":340,"wires":[]},{"id":"fe6f251a1b85df90","type":"loxone-control-out","z":"3c3fa1ce28c0ce43","name":"Inputs5.2","miniserver":"c04ca4d6caa1d5c9","control":"19f4197e-02b6-123a-ffff6fc206f2b7bf","x":980,"y":460,"wires":[]},{"id":"13fb93f070716b95","type":"function","z":"3c3fa1ce28c0ce43","name":"get-inputs-n5","func":"if (msg.modbusRequest.unitid == 5) {\n    var arr = msg.payload;\n    var byte1 = (arr[0] * 1) + (arr[1] * 2) + (arr[2] * 4) + (arr[3] * 8) + (arr[4] * 16) + (arr[5] * 32) + (arr[6] * 64) + (arr[7] * 128);\n    var byte2 = (arr[8] * 1) + (arr[9] * 2) + (arr[10] * 4) + (arr[11] * 8) + (arr[12] * 16) + (arr[13] * 32) + (arr[14] * 64) + (arr[15] * 128);\n    var msg1 = {};\n    var msg2 = {}; \n    msg1.payload = byte1;\n    msg2.payload = byte2;\n    return ([msg1, msg2]);\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":790,"y":440,"wires":[["d9803f23d95ace50"],["fe6f251a1b85df90"]]},{"id":"d9803f23d95ace50","type":"loxone-control-out","z":"3c3fa1ce28c0ce43","name":"Inputs5.1","miniserver":"c04ca4d6caa1d5c9","control":"19f4197e-0084-0ad5-ffff6fc206f2b7bf","x":980,"y":420,"wires":[]},{"id":"08eb64dc3971b8b1","type":"modbus-client","name":"1RS485","clienttype":"serial","bufferCommands":true,"stateLogEnabled":true,"queueLogEnabled":true,"failureLogEnabled":true,"tcpHost":"127.0.0.1","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB1","serialType":"RTU","serialBaudrate":"38400","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"0x3A","unit_id":"0","commandDelay":"1","clientTimeout":"1000","reconnectOnTimeout":true,"reconnectTimeout":"2000","parallelUnitIdsAllowed":true},{"id":"1d30ba62236b3eda","type":"modbus-client","name":"2RS485","clienttype":"serial","bufferCommands":true,"stateLogEnabled":true,"queueLogEnabled":true,"failureLogEnabled":true,"tcpHost":"127.0.0.1","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB0","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"0x3A","unit_id":"0","commandDelay":"1","clientTimeout":"1000","reconnectOnTimeout":true,"reconnectTimeout":"2000","parallelUnitIdsAllowed":true},{"id":"c04ca4d6caa1d5c9","type":"loxone-miniserver","host":"192.168.2.9","port":"80","enctype":"0","active":true,"keepalive":"30000"}]

I will briefly explain what is done in the scheme:

  • RS485-1:
    Signals from 6 digital input modules are received as fast as possible. The information of each module is divided into 2 bytes and sent to a controller.
    *Here I have a problem. Now a lot of information is constantly being sent to the controller and sometimes it is not needed because there is no state change. That is, I would have to implement a comparator within the functions (where I convert the data) and in case of a change of state send that new information. What happens to me now is that I clutter the controller with a lot of new information.
    How can I save the variables (bytes) and retrieve them in the next function input?

  • RS485-2:
    Every second a new query is made of the status of different sensors.
    Here as a novelty, I have implemented a counter control within the function. The counter number is used to create the modbus message. Inside the function I check that it is not out of range.
    Doing tests with the relays, I think that a read and a write have conflicted.
    I have seen that the counter value was erased and with that information, I have used the "isNaN()" function to invoice and position the value again.
    Finally I send the information to the controller. Same problem as above (controller saturation).

Attached is a screenshot of how I am attacking the resolution to activate relays.

Perhaps the counter is not the best solution. Suggestions welcome and I'm open to making changes.

Sorry if I overdid the explanations.

First of all, the flow looks fabulous! I think you'll find having things chunked off with the minimum amount of "stuff" floating around a lot easier to work with. I'm glad things are working well so far.

Now, on to the questions.

This is actually very simple. Use context.get() and context.set() in your function to hold values between messages. Setup your variable in the startup tab of your function and then refer to it in your actual function to get previous data and save new data. For instance, if you're trying to save an array, your startup tab would have this:

var inputArr = [];
context.set('inputArr', inputArr);

This sets inputArr to be an empty array. The next time you refer to it, it will be an empty array you can either pull from using context.get('inputArr'); ( would give an empty result) or save to with context.set('inputArr', arrayToSaveForLater); Very simple.

Hmmm... I have to wonder about the two functions in your relay control image. Is there a reason you can't combine the two functions together? I wouldn't think there would be any reason you couldn't combine them. The problem you can run into having multiple controlling functions is that you can trigger both at the same time and it would seem that you had some kind of logic error because something didn't appear to activate. If you have a read/write conflict, make one function that is your gatekeeper to both read and write MODBUS nodes. Have two outputs configured to your function and make your function control what message is sent where and when. Remember, a multiple output function is sent an array on your return statement with the position in the array corresponding to the output number. You're going to need a read and write MODBUS node for your relays if you're changing relays and checking the status. I don't see that in your program.

I see the point with using a counter. The TCP/IP protocol uses a very similar setup to validate transmissions. But perhaps you don't need it. You could use your context. functions from above to save a state you're trying to set the relays to, send the relay changes to the controller, get the set response, read the status and see if the status in the response matches the original relay configuration you sent out. That may track stuff better than using numbers, and you're not dependent on something carrying through all the messages (controllers/nodes may scrub out certain information). Again, you know your setup so you know what you have abilities to do.

I'm not sure if there's a way to avoid controller saturation, depending on how you're implementing and using things. Are you setting relays individually or does your controller have a binary equivalent representation? What I mean by that is if I sent out the binary 01110100 (hex 0x74 or dec 116), I would turn on relays 2, 3, 4 and 6 (positions 2, 3, 4 and 6 are 1 or on). If you can send a binary representation of your relay status, that would shrink the necessary traffic on your bus significantly, assuming you're manipulating relays individually. That would be something I could think of to reduce traffic. Check your register list to see if anything equivalent exists.

On the contrary. That's the kind of detail needed to help people solve their problems. Keep it up! The more detail, the better. I think you're on a good path to making this work without issue.

1 Like

Again here!

var inputArr = ;
context.set('inputArr', inputArr);

It works like a charm. I save the data and before sending it I check if there is new information to send. I no longer clutter the controller and have time to do other things.

make one function that is your gatekeeper to both read and write MODBUS nodes

I'm a bit lost with this. I still haven't found where the error is coming from. This error appears sometimes.

Are you setting relays individually or does your controller have a binary equivalent representation? What I mean by that is if I sent out the binary 01110100 (hex 0x74 or dec 116), I would turn on relays 2, 3, 4 and 6 (positions 2, 3, 4 and 6 are 1 or on).

Unfortunately, my relay board does not accept writing to multiple registers. I have to do it relay by relay. That's what I understood from the "manual".

Manual

Right now I have the outputs node as follows:

You can tell perfectly, it doesn't look good.
Also, there are 32 exits here. But I need to do the implementation for 128! Imagine what a mess.
So that I can understand it, the controller http sends me a bit. In the function I look at the status and send the value 256 or 512 to the appropriate address to turn the relay on or off.

I have done a stress test. From the controller I have set the 32 relays to 1 and I have not had any problem. Obviously they don't all turn on at the same time, the modbus node processes one by one (very fast). It has not generated any error.

I'm afraid that the error that sometimes appears is a sensor reading. I have to investigate a bit.

Any suggestions for so many functions? Or if it works is it ok?

Thank you very much.

Good job on making this work so far! Let's see if we can tweak things.

Something that looks like this:
image
Then just use the individual outputs of the function to determine what kind of traffic is going down your bus channels. This way you avoid having read and write commands colliding with each other, which should help any issues related to that.

I checked on that module and I see what you mean by "manual". I wouldn't count on that. There are three ICs on that board. I can't see what they are from the pictures, but you may have better luck looking up those ICs independently. Chances are one of them has built-in MODBUS functionality that they're using to control the board with. If you can find one of those supporting MODBUS and find the manual to it, you may be able to hack the board and get more out of it. I would imagine the IC is converting a MODBUS message into a binary representation on a set of pins, possibly passed to a logic control IC. This would be four or eight pins of the IC (depending on how it's implemented on the IC, could also be a serial command). Chances are you could find out how to send a single command to alter the whole pin array.

That explanation probably didn't make sense. Find out what ICs you have on the board. Research the ICs for their manuals. See if you can send a command not listed in the module's "manual" to do what you're wanting to do.

Yes, a big suggestion. And no, having that many functions doing almost the same thing isn't ok if you can do it all in one. It won't scale well at all.

Without knowing what the functions have inside of them, chances are they're all a copy/paste of each other with one slight modification to make that individual function do the work. I'm guessing the function passes the value for an individual relay on an individual module. Not good. Probably works like this:

  • Read incoming message
  • Check to see if message is my message
  • Figure out if relay needs to be on or off
  • Send command to turn relay on or off

Instead of having a separate function for each, have one function that parses the incoming message and alter its output accordingly. It should look like this:

  • Read incoming command
  • Figure out where the relay is (maybe do some math to figure out what module and relay, something like taking the modulus of the input to figure out relay position and dividing the input by four to figure out it's module)
  • Figure out if the relay needs to turn on or off
  • Send a message that tells module X to make relay Y either on or off.

It shouldn't need to be any more complex than that. Yet. Give it time and you may add extra stuff to do certain things. But for now, that's what I would do. And I would turn that single function into the gatekeeper I showed you above. Have the write node sit on one output and the read node on another. That way traffic can't cross over and everything is handled in one function. Your read can loop back into the function itself so it can verify the status, if that's what's needed. Just do whatever you need to do.

Initially though, do some research on those ICs. That may open up your project significantly.

1 Like

Helo!!!!!

Then just use the individual outputs of the function to determine what kind of traffic is going down your bus channels. This way you avoid having read and write commands colliding with each other, which should help any issues related to that.

It seems somewhat complicated for my level. I'm going to have to investigate and test.

I sent you the manual of a plate that is compatible with mine.
It is exactly the model R4D3C32

Okay, let's get into the 128 functions...

In them I do something very, very simple. I don't check if the relay is at 1 or 0.
I wondered, is it necessary to do 128 queries when I can save the state to the controller?
In my case, it is not necessary. That information is saved when I change the state of the output (in the controller).

Therefore, the function looks like this:

var val;
if (msg.payload == 1) {
    val = 256;
}
if (msg.payload == 0) {
    val = 512;
}
msg.payload = {
    'value': val,
    'fc': 6,
    'unitid': 3,
    'address': 1,
    'quantity': 1,
};
return msg;

The message that comes from the controller is like this:

As you can see, there is nothing that can relate it to the modbus address or the relay number.

I have tried to use the FC16 function but without success. I have not been able to write several records with a single send.

Thank you!

Ok. That is quite a bit more complex then. I see what you mean. It also sounds like that have custom microcontroller firmware that is running that board and doesn't have the ability to manage a FC16 command. Shame. I was hoping they were using an IC that had hardware MODBUS handling built-in. Impressive setup though. I haven't seen that many relays on a board in a long time.

No, it isn't. I was running under the assumption that you were doing a "change and verify" setup. If you want to store the relay states, that would make it significantly easier to implement than having a check state too. Tracking your expected state in Node-Red would be far easier and quicker to work with. If that's all you need, scrap everything I've said about reading relay information and track it in your code.

Very simple and straight forward. It's weird that it's expecting a value of 256 or 512 (binary 0001 0000 0000 and 0010 0000 0000). It makes me wonder what the other set of bits are and what registers they may belong to. Generally if you have an on or off, you're only sending a 1 or 0, maybe true or false. That way you set one register at a time. So that is a very unique implementation. To have it padded by eight bits for no reason makes me think there's more there that could be played with... But that's on your time if you chose to experiment.

That's ok. You can use another object in your query message to pass along as a marker. Use msg.topic, msg.trace, msg.qmod or some unique key that you can assign an address and relay to. The MODBUS node will just pass that value into the message it returns so you have traceability from message to message.

Unfortunately, that's the bane of every electronic designer's life. You have to work with the equipment you have access to and try to make it do what you want. Sometimes you can get a decent amount out of it, sometimes you can't. But if you can get this to work, it sounds like you'll have everything you need as I'm sure you don't need this to be a high-speed switching matrix (i.e. super light show). I think once you start adding tracers to your messages, you'll likely find the cause of your debug error and be able to fix it easier.

Looks like you're well on your way though! Try the tracers in your messages and ignore what I said about setting up a query node if you don't need it. Let me know how it does. I think you're really close though if all you have is an intermittent problem.

1 Like

Hello sir!

Ok. That is quite a bit more complex then. I see what you mean. It also sounds like that have custom microcontroller firmware that is running that board and doesn't have the ability to manage a FC16 command. Shame. I was hoping they were using an IC that had hardware MODBUS handling built-in. Impressive setup though. I haven't seen that many relays on a board in a long time.

It is true that it is a bit of a shame but I had to choose this board because it has 32 relays in a very small space. In total I have 128 relays and I did not want a huge electrical panel to come out.

Very simple and straight forward. It's weird that it's expecting a value of 256 or 512 (binary 0001 0000 0000 and 0010 0000 0000). It makes me wonder what the other set of bits are and what registers they may belong to. Generally if you have an on or off, you're only sending a 1 or 0, maybe true or false. That way you set one register at a time. So that is a very unique implementation. To have it padded by eight bits for no reason makes me think there's more there that could be played with... But that's on your time if you chose to experiment.

This is because one of the features that the board has is delay.
Inside the data the last two bytes are for the delay function.

For that reason, 1 (open) + 2bytes or 2 (closed) + 2bytes

That's ok. You can use another object in your query message to pass along as a marker. Use msg.topic, msg.trace, msg.qmod or some unique key that you can assign an address and relay to. The MODBUS node will just pass that value into the message it returns so you have traceability from message to message.

This would be great but I can't do it.
I unitize a module that takes the information from the controller. Therefore, I can't (or don't know) how to add this type of additional information to it.
image
Thinking, I could add another function after the controller node that would add this information, but in the end, wouldn't it be the same?
You would have:
Controller->address function (individual)->send function (global)->modbus node

As you say, I don't need super fast speed here. The one I have now I think it can work well for me. Where it would be most noticeable is when a scene is activated where different relays are activated and they do not all enter at the same time. It is not worrying. It is true that I am working at 9600 and I want to increase.

thanks for your help!

That almost sounds like a setup for a theater show or something. Regardless of the use, kudos for finding a compact solution.

I feel really stupid now that I completely missed that in the "manual". I was staring at that and it just didn't click. Oops... :man_facepalming:

Yes, it would. And if it solves your problem, it may be your best option. It's too bad that there isn't something that can be passed with it. What node is this you're using? I need to understand this better. It would suck if that was the best answer the node allowed.

If it's working, then at least it's working. As we've discovered, the setup doesn't lend itself to high speed operations so it's probably the best you'll get. At least you know how to work with it so if you do upgrade in the future to some kind of different hardware, you'll have the framework to build on.

But at least it's working, right? So congrats on making it work!

1 Like

Hello!!!

What node is this you're using?

This is the node i am using:

Thanks :slight_smile:

Yep, you're right. Unless the server is sending some kind of identifying information in its payload, there doesn't appear to be anything you can use to identify individual components in the stream. And I don't have a Loxone setup to do any testing with.

But, if all you have to do is add a node to inject an identifier, that's not too bad, though it's going to balloon the number of nodes you have to use to make your setup work. But, it's working apparently, which is good news!

I wish you well in your setup. Enjoy!

1 Like

Hello madhouse!

Thank you very much for your support and your help. It has been a good learning experience. I hope it doesn't end here.
I am very grateful to you. Really, thank you.

1 Like

Hello Madhouse!

A long time without talking! :sweat_smile:

I have been testing and finally found out the problem of some random errors. Well, they are not so random.
They occur when a read command is sent and by chance, someone touches a button and this causes a write command to be sent.
There is a conflict here.
I wonder, is there any parameter where I can check that the node is ready to send?
It should be noted that reading orders are sent periodically and the writings are not stipulated in a specific time.
It should be clarified that these writings are not priority and can wait a few seconds to be sent.
I have tried to add two delays (one in front of each function) with different times but without success.
Do you have any idea for me?

I have tried this but there are too many script functions to implement this.
image

image

thanks for your help!

Ok. You know your setup better than anyone so do what you have to do to make it work. We'll keep trying to find efficiencies so you can manage everything and keep it working.

There's always a way to do that, but I can't think of an effective implementation right now with how you have your flow configured. It would involve a lot of globals and stored variables that are probably more painful than helpful at this point. But...

I just happened to think up a plausible solution for you. Open up your pallette manager, find node-red-contrib-simple-message-queue and install it. It will give you a queue node that looks like this:
image
We can use that to control the traffic flowing to the getter and write nodes. What you'll need to wire up is something that looks like this:


Tada! No more collisions. Here's how it works:

  1. Messages come in on either the Loxone line or the timed flex-getter line.
  2. Each message is sent to the simple message queue node to wait its turn. The queue node is configured to send off the first message and queue the rest.
  3. The message queue sends the message to the traffic splitter function where some kind of tag tells the function to either send it to the getter or the write node.
  4. The triggered MODBUS node finishes its query and sends it to the trigger sending node.
  5. The trigger sending node fires a message off of both ports. One message is to send the {trigger:true} property back to the message queue to send the next message. The other message out of the trigger sending node is the message that gets sent on to the rest of your flow.

Obviously, there will be some logic in the trigger sending node to filter out what doesn't get sent on to the rest of your flow, which should be easy if you work off the flag used to ID whether it's a getter message or a write message. But this will ensure that only one message is being sent at a time to anything on the MODBUS channel, which will eliminate the collisions regardless of where they're coming from. I use this same setup on a SQL node that has no message queueing capabilities and it works like a charm.

Let me know if you have any issues.

1 Like

Hello!
Sorry for taking so long to respond. I've been doing tests.
It is all a mystery the errors that I have.

Let me explain:
I tried what you told me and it worked fine. I started with something simple (screenshot attached), make a single query to a slave every second and send a write command to a different slave. This worked and didn't give any errors.

The next step was to add different functions to make various queries to different slaves:

This is where the problems start. For a while it works fine, but every now and then there is an error. This error is generated without sending any write command (only sending reads). The error is repeated over time. I think the error appears randomly. I do not do anything.I attach a video:

[video-to-gif output image]

I have also tried sending the queries to the queue node at different times. I have not been successful.

Like I told you, it's a bit of a mystery.

What do you have in mind?

Thanks for your help!

[{"id":"9406efe999db21e2","type":"tab","label":"Prova","disabled":false,"info":"","env":[]},{"id":"6be4bcf2eec3ac12","type":"simple-queue","z":"9406efe999db21e2","name":"","firstMessageBypass":true,"bypassInterval":"0","x":500,"y":240,"wires":[["c6003b8143bb3c11","6f53fb8edb2a5311"]]},{"id":"068a655900971466","type":"modbus-flex-getter","z":"9406efe999db21e2","name":"Modbus Flex Getter - 2RS485","showStatusActivities":true,"showErrors":true,"logIOActivities":false,"server":"1d30ba62236b3eda","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":true,"keepMsgProperties":true,"x":390,"y":340,"wires":[["6b0bf016f2fde972","e82bac7da15c9ffd"],[]]},{"id":"d2eed4f12f392279","type":"function","z":"9406efe999db21e2","name":"Getter Function 2","func":"msg.payload = {\n    'fc': 4,\n    'unitid': 14,\n    'address': 1,\n    'quantity': 2\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":100,"wires":[["6be4bcf2eec3ac12"]]},{"id":"d22249c112b7ceac","type":"inject","z":"9406efe999db21e2","name":"Getter Timer","props":[{"p":"payload"},{"p":"counter","v":"0","vt":"num"}],"repeat":"5","crontab":"","once":true,"onceDelay":"15","topic":"","payload":"","payloadType":"date","x":120,"y":20,"wires":[["118a5d2cbc70cef1","d2eed4f12f392279","acafbf340b4a51b1"]]},{"id":"c6003b8143bb3c11","type":"debug","z":"9406efe999db21e2","name":"","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":610,"y":140,"wires":[]},{"id":"b6a89505f154792a","type":"delay","z":"9406efe999db21e2","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":700,"y":400,"wires":[["7b59f646448cd1d0"]]},{"id":"fc25f33a0305042f","type":"modbus-flex-write","z":"9406efe999db21e2","name":"Modbus Flex Write - 2RS485","showStatusActivities":true,"showErrors":true,"server":"1d30ba62236b3eda","emptyMsgOnFail":true,"keepMsgProperties":true,"x":380,"y":400,"wires":[["6b0bf016f2fde972","88af6619816d9d17"],[]]},{"id":"6f53fb8edb2a5311","type":"function","z":"9406efe999db21e2","name":"Traffic Splitter","func":"if ((msg.payload.fc == 4) || (msg.payload.fc == 3)){\n    return ([msg, null]);\n}\nif (msg.payload.fc == 6) {\n    return ([null, msg]);\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":120,"y":380,"wires":[["068a655900971466","7d963bceb75bf2a6"],["fc25f33a0305042f","6474ec65c634250f"]]},{"id":"6b0bf016f2fde972","type":"function","z":"9406efe999db21e2","name":"Trigger Sender","func":"msg.trigger = 1;\nif (msg.payload == \"\"){\n    return ([null, msg]);\n}\nreturn ([msg, null]);","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":340,"wires":[["6be4bcf2eec3ac12","1c1798800365a448"],["b6a89505f154792a"]]},{"id":"c825dd20dc1c3fc2","type":"function","z":"9406efe999db21e2","name":"Sender Function","func":"var val;\nif (msg.payload == 1) {\n    val = 256;\n}\nif (msg.payload == 0) {\n    val = 512;\n}\nmsg.payload = {\n    'value': val,\n    'fc': 6,\n    'unitid': 3,\n    'address': 1,\n    'quantity': 1,\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":240,"wires":[["6be4bcf2eec3ac12"]]},{"id":"e82bac7da15c9ffd","type":"debug","z":"9406efe999db21e2","name":"","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":530,"y":540,"wires":[]},{"id":"7d963bceb75bf2a6","type":"debug","z":"9406efe999db21e2","name":"getter","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":180,"y":500,"wires":[]},{"id":"6474ec65c634250f","type":"debug","z":"9406efe999db21e2","name":"sender","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":160,"y":540,"wires":[]},{"id":"afdf083152b58871","type":"inject","z":"9406efe999db21e2","name":"ON","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"5","topic":"","payload":"true","payloadType":"bool","x":90,"y":220,"wires":[["c825dd20dc1c3fc2"]]},{"id":"71e65d83047dece7","type":"inject","z":"9406efe999db21e2","name":"OFF","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"5","topic":"","payload":"false","payloadType":"bool","x":90,"y":260,"wires":[["c825dd20dc1c3fc2"]]},{"id":"88af6619816d9d17","type":"debug","z":"9406efe999db21e2","name":"","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":510,"y":580,"wires":[]},{"id":"acafbf340b4a51b1","type":"function","z":"9406efe999db21e2","name":"Getter Function 3","func":"msg.payload = {\n    'fc': 3,\n    'unitid': 2,\n    'address': 0,\n    'quantity': 8\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":140,"wires":[["6be4bcf2eec3ac12"]]},{"id":"6159cd88c8a4314c","type":"inject","z":"9406efe999db21e2","name":"Inject","props":[],"repeat":"","crontab":"","once":false,"onceDelay":"5","topic":"","x":150,"y":180,"wires":[[]]},{"id":"1c1798800365a448","type":"debug","z":"9406efe999db21e2","name":"","active":false,"tosidebar":true,"console":true,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":180,"wires":[]},{"id":"118a5d2cbc70cef1","type":"function","z":"9406efe999db21e2","name":"Getter Function 1","func":"msg.payload = {\n    'fc': 4,\n    'unitid': 11,\n    'address': 1,\n    'quantity': 2\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":60,"wires":[["6be4bcf2eec3ac12"]]},{"id":"437a7f840887e34f","type":"inject","z":"9406efe999db21e2","name":"1,3s","props":[{"p":"payload"},{"p":"counter","v":"0","vt":"num"}],"repeat":"1.3","crontab":"","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":150,"y":60,"wires":[[]]},{"id":"77fb04e8b753f2d7","type":"inject","z":"9406efe999db21e2","name":"1,6s","props":[{"p":"payload"},{"p":"counter","v":"0","vt":"num"}],"repeat":"1.9","crontab":"","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":150,"y":100,"wires":[[]]},{"id":"66d5f490e0f9403d","type":"inject","z":"9406efe999db21e2","name":"1,9s","props":[{"p":"payload"},{"p":"counter","v":"0","vt":"num"}],"repeat":"1.9","crontab":"","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":150,"y":140,"wires":[[]]},{"id":"7b59f646448cd1d0","type":"function","z":"9406efe999db21e2","name":"Trigger Sender - Fault","func":"msg.trigger = 1;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":460,"wires":[["6be4bcf2eec3ac12"]]},{"id":"1d30ba62236b3eda","type":"modbus-client","name":"2RS485","clienttype":"serial","bufferCommands":true,"stateLogEnabled":true,"queueLogEnabled":true,"failureLogEnabled":true,"tcpHost":"127.0.0.1","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB1","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"0x3A","unit_id":"0","commandDelay":"300","clientTimeout":"1000","reconnectOnTimeout":true,"reconnectTimeout":"2000","parallelUnitIdsAllowed":false}]

What I'm seeing right off the bat in your video is that your flex-getter and your flex write are both going into query mode at the same time. I don't have any serial connected MODBUS devices, so I don't know if that's normal operation or not. All of mine are TCP connected so the query is over before it can change the state of each node. Your setup should be working just fine as is.

My first question would be, what do you mean by slave devices? Do you mean a different module connected to the same serial converter? Or do you mean a different serial converter altogether? I'm guessing the former, but I'm asking to not assume. The other question is, are you ensuring that your Getter Functions are providing something that can keep all the messages separate? Again, my guess is you are, but I'm not going to assume.

The last thing I could think of is how is your simple queue and flex-getter configured? There's one or two things in those that if you have them configured wrong, they may be causing issues.

On the surface, I can't see anything wrong. But in this case, the problem is going to be in the details and not something on the surface.

Just doing a little research on this node group, it looks like the flex-getter and flex-write nodes use the same queue for each connection. I can't find anything that says this directly, but there's a lot of statements that indicate this. So for one of your serial converters, there's a queue. The other converter gets a different queue. That's what I'm seeing, but I could be wrong.

Another node I'm looking at playing with is the flex-sequencer. I haven't had any experience with it yet, but it might provide a cleaner solution for what you are trying to do and may clean up some of my stuff as well. I haven't read up on it yet because the flex-getter got me everything I wanted.

But if the nodes use the same queue per connection, your flow and mine might be unnecessarily complex.

That still doesn't change how your flow functions now. It shouldn't be having connection issues causing timeouts. Like I say, there's details not on the surface of the flow that would be causing problems. The pattern I'm seeing is getting a return of:

  • array[2]
  • array[2]
  • array[8]

Does it always have a problem on the second array[2] return?

Grrr... I'm blind. Just noticed the flow you posted at the bottom of your message. The video was so hypnotic I just couldn't look away... :slightly_smiling_face:

I'll look through the details and get back...

Hello!

I have reviewed different posts and in other posts the "queue" tag does not appear because they do not have these options enabled:
image

You're right. Use a single rtu bus and there are different devices (slaves) on it. These devices are analog inputs, temperature probes, ...

Checked, I think I found something. Some light?
I have changed the queue time from 300ms to 500ms and it doesn't seem to fail.
This could be? I'm going to leave some time sending messages to test.

I show you a video:
Look at the queues according to the id number (of the slave)

No, it can be anywhere.

Thanks for your help!!!

Interesting... So the read and write do share the same queue. Very interesting... That means you shouldn't need your simple queue node and should be able to inject commands directly into your MODBUS setup and let it queue as normal. No queue, no splitter, no trigger sender. Just injection to MODBUS. That simplifies things a lot.

It could very easily be, though I can't understand why at this point. Maybe there is a slight delay required by your serial converter to reinitialize after a round trip? Though I wouldn't think that would be common, it's not out of the realm of possibility. Do you have any documentation on your converter that might have something like this listed in like a timing chart or something?

You actually took a picture of the option when you grabbed the screenshot for the queue delay. It's the "Queue commands" option just above delay window. That should be the difference between send-when-received and using the built-in queue function.

And thank you as well! I'm learning a lot more about this node than I thought there was to learn. I'm changing some of my own flows based on the stuff you've shown me from your end and stuff I've been reading at the same time. Who knew?

FYI, the flex-sequencer node is really awesome. I just replaced a ton of timed injection nodes and a flex-getter with a single timed injection node and a flex-sequencer. You put all of your queries into it for all your devices on the channel and then just trigger it with the inject node. It manages all the rest. It's so easy that I'm sad I didn't see it's potential before.

There is one small caveat though. It doesn't have the ability to send things like msg.topic or whatever to the output, since there is nothing defined in it. What it does send through though is msg.modbusRequest.name that you can use for an individualized item to reference on the output. I would do something like "dev1-lights" or something like that so you know the device and the parameter queried. You would obviously have to change your output function(s) to read that property instead. But the node itself is soooo easy... I would highly suggest trying it to see what happens. If it starts having problems with the transmission again, you can always revert back to what you have going now.

You would still use the flex-write to send commands out to the devices, so that doesn't change either. But it would simplify your read side drastically.