So this is my chart below. I need up to 100,000+ counts for both counters. I'm using a Click PLC with two counters in the program, both copying to DD1 and DD2 registers. Any code possible?
Firstly, Modbus returns 16 bit Unsigned Integers. So if your PLC contains -31071
it will give you 34465
Pass the buffer you get out of modbus into a buffer-parser node
Here is an example.
[{"id":"d7de344b8c78bc75","type":"buffer-parser","z":"6f432348c57a2fda","name":"","data":"payload.buffer","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint32be","name":"asUint32","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"int16be","name":"asInt16Array","offset":0,"length":2,"offsetbit":0,"scale":"1","mask":""},{"type":"uint16be","name":"asUInt16Array","offset":0,"length":2,"offsetbit":0,"scale":"1","mask":""},{"type":"buffer","name":"asBuffer","offset":0,"length":-1,"offsetbit":0,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":1370,"y":420,"wires":[["7123d04b8c8db4b1"]]},{"id":"ab925aeaf3a588fb","type":"inject","z":"6f432348c57a2fda","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":1200,"y":360,"wires":[["07302e0635406247"]]},{"id":"07302e0635406247","type":"function","z":"6f432348c57a2fda","name":"example modbus data","func":"msg.payload = { \"data\": [1, 34465],\"buffer\":Buffer.from([0x0,0x1,0x86,0xa1])}\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1400,"y":360,"wires":[["d7de344b8c78bc75"]]},{"id":"7123d04b8c8db4b1","type":"debug","z":"6f432348c57a2fda","name":"debug 42","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1560,"y":420,"wires":[]}]
Apologies, the title is very misleading. Basically these counters will be incrementing above the value of 100,000. These values will never be in the negatives. For example, Say these counts are parts coming out of a stamping press. After a full day the counts would be recorded, the counter would be reset for the next day. In the function node I use 'address': 0 for a starting address which by default is 400001, a 16 bit register. I cannot use this because the counts will stop incrementing at 32,767. I have a 32 bit register with a modbus address of 416385, but 'address': 416385 will not work in a function node. If the value 100,000 is in the PLC, it needs to be 100,000 in the debug node. Is there a node or a function code that can just grab an address, or any type of other work around? Below is another pic
Sorry what you are saying is not clear.
Are you reading values via modbus?
Can you access the registers that your "counters" live at?
If yes, then for each counter you will need to request a length of 2. That will give you data in the format I put in the example function node. You then use the node I linked to (buffer parser) to convert the 2 16 bit registers into a 32 unsigned integer.
In the PLC, "CTD1" the modbus address for the counter itself is 449153, I just use the DD1(416385) to copy the value directly from the counter, which really isn't needed.
Doesn't the modbus protocol (PDU) limit the number of addresses to 65536?
In your reference above are you including the function code (4) or are you trying to extend the protocol?
And just to be clear is your concern not over the size of the value of the counter (which can be more or less anything (2,3,n bytes) but the number of bytes in the address itself?
In which case do you really not have space in the rest of the protocol range for addresses?
Figured it out, 16384 is the pointed register. The rest worked fine.
Didn't know how else to explain it.
It is not clear from your post whether you are now getting values you think are correct or still having issues. I assume the second.
If you are asking flexgetter for a quantity of 4 then that is 4 16 bit integers. So it makes sense that you are getting an array of two values back from the buffer parser node.
From the table you posted above the values in that range are all uint32. And the specific value you want from parts counter 1 is made up from two 16 bit integers (2 words) in consecutive holding registers 16385 and 16386.
So in your request you would specify a quantity of 2, an fc of 3 and an address of 16385.
The table contains no info as to which is the high side and which the low side of the two int16s that will be returned.
I am guessing that you are using a Click PLC and from reading the forums there I think the word order is little word, big word. So to convert to a uin32 you would do hWord << 16 + lWord.
Reverse engineering the results that you posted into a byte stream and then converting back into what I'd expect
- for a stream of uint8 coming from a big endian system (modbus is big endian in its uint16 words);
- to uint32 on a little endian machine
shows that the counter address gives a value of 537648. which correlates with the result that you get for the second pair of words you are retrieving.
a sample flow is here:
[{"id":"d810cec28593e195","type":"inject","z":"6abd5ec3bcaf87f4","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"unitid\":1,\"fc\":3,\"address\":16385,\"quantity\":2,\"value\":{}}","payloadType":"json","x":150,"y":640,"wires":[["3e33906b075edc62"]]},{"id":"3e33906b075edc62","type":"modbus-flex-getter","z":"6abd5ec3bcaf87f4","name":"","showStatusActivities":false,"showErrors":false,"showWarnings":true,"logIOActivities":false,"useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":false,"delayOnStart":false,"startDelayTime":"","x":380,"y":640,"wires":[[],["8cab0c606c6f9398"]]},{"id":"8cab0c606c6f9398","type":"buffer-parser","z":"6abd5ec3bcaf87f4","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint32le","name":"item1","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""}],"swap1":"swap16","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"value","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":650,"y":640,"wires":[["833c4b479eea07bf"]]},{"id":"833c4b479eea07bf","type":"debug","z":"6abd5ec3bcaf87f4","name":"debug 41","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":840,"y":640,"wires":[]}]
if this is not what you are looking for then could you let us have the raw bytes you get from addressing 16385 (payload.buffer from the lower output). and the value that is displayed in the PLC software (or at least the value that you expect).