The quick answers to your questions:
- No, it can be done with just one groov-io read node!
- No. (I’ll explain below.)
- The best way I’ve found is to use the dynamic settings with a groov-io read node.
Now for the longer answers.
Unfortunately the memory locations of the values are not consecutive in the way that it sounds like you’re expecting. The best way to show this is with the MMP Calculator – you can find this in groov Manage under I/O, select I/O Tools, then click MMP Calculator to see this screen:
Here you can see I’m checking the “Analog Channel Read” area, where the first address holds the analog value that you’re looking for, but then the next consecutive addresses are still associated with this I/O point, but instead hold the minimum and maximum values. Because of this you cannot just read a chunk of memory and have just the values in a nice tidy list, it will have mins and maxes (and a few other things) as well.
Thankfully there’s another approach: dynamic settings!
Here’s a snippet from the help tab for the groov-io read nodes (specifically “read”, not “input”) where it shows that you can inject properties with the module and channel index to grab specific values:
We can use this to our advantage by sending a bunch of messages at this single node, once for each channel, then join all 12 messages together on the other side to give us a nice array of 12 values:
Here’s the simple program I’ve put in the “loop” function node:
module_length = 12;
module_number = 3;
for(var i = 0; i < module_length; i++) {
node.send({ moduleIndex : module_number,
channelIndex : i});
}
I just loop from 0 to 12, and each time I send a new msg object with the properties msg.moduleIndex
and msg.channelIndex
, where the channelIndex i
increments each time. This will get the groov-io node to produce 12 separate msg.payloads
with each value from that one module, where you can either consume them individually or join them into an array of 12 elements.
You can import this flow using the text below and modify it for your own needs, but in my experience this is the best way to read multiple channels without having to drag in a bunch of separate groov-io nodes.
Flow import:
[{"id":"9bcad53e.3d5748","type":"join","z":"6773a439.5cfddc","name":"","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"12","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1250,"y":1560,"wires":[["7e02fe7e.6669b"]]},{"id":"f388653f.829a68","type":"groov-io-read","z":"6773a439.5cfddc","device":"128a79ee.3b01b6","dataType":"channel-analog","moduleIndex":"","channelIndex":"","mmpAddress":"0xF0D81000","mmpType":"int32","mmpLength":"1","mmpEncoding":"ascii","value":"","valueType":"msg.payload","itemName":"","name":"","x":1100,"y":1560,"wires":[["9bcad53e.3d5748"]]},{"id":"7e02fe7e.6669b","type":"debug","z":"6773a439.5cfddc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1390,"y":1560,"wires":[]},{"id":"592b1cca.42bf24","type":"function","z":"6773a439.5cfddc","name":"loop","func":"module_length = 12;\nmodule_number = 3;\n\nfor(var i = 0; i < module_length; i++) {\n node.send({ moduleIndex : module_number,\n channelIndex : i});\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":950,"y":1560,"wires":[["f388653f.829a68"]]},{"id":"b3788d49.ff037","type":"inject","z":"6773a439.5cfddc","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":820,"y":1560,"wires":[["592b1cca.42bf24"]]},{"id":"128a79ee.3b01b6","type":"groov-io-device","address":"localhost","msgQueueFullBehavior":"DROP_OLD"}]