pearsonben98 Posted July 17, 2019 Share Posted July 17, 2019 Hi, is it possible to write to multiple holding registers at once, kind of in the same way you can read from multiple registers at the same time? for example, device.mydevice.readHolding32(Station, starting address, datapoints) where datapoints decides how many registers you read from. Is it possible to achieve a similar thing with the write function, such as passing an array containing all values to be added to each register? Currently I am having to write "device.mydevice.writeholding32(station, starting address, data) multiple times. Cheers, Ben Quote Link to comment Share on other sites More sharing options...
AzeoTech Posted July 19, 2019 Share Posted July 19, 2019 You can definitely do it through script. Just pass an array for data points. So for example: device.mydevice.setRegisterS32(1, 100, {1,2,3}) which would set register 100/101 to 1, 102/103 to 2, and 104/105 to 3 (register pairs because of the S32 of course). Note that it is "Set" not "Write", and is "Register" not "Holding" because Input Registers can't be set, so there is no reason to differentiate on the output side. Note that with channels, DAQFactory will automatically combine reads of the same type into a minimum number of calls if they are consecutive and the same data type. It will not fill in blanks, though, so sometimes its best to create dummy channels. That said, on the output side you cannot do multiple outputs with one query through channels because there is no way to set multiple channels simultaneously. Quote Link to comment Share on other sites More sharing options...
pearsonben98 Posted July 29, 2019 Author Share Posted July 29, 2019 Hi, thanks for the advice, this works properly now. However, is there a maximum sized array that can be passed to the datapoints field? I currently have a datapoints array with 32 addresses, but i need to write: device.myDevice.setRegisterS16(station, starting_address, data[0,16]) device.myDevice.setRegisterS16(station, starting_address, data[17,31]) I am unable to simply do device.myDevice.setRegisterS16(station, starting_address, data). Cheers, Ben Quote Link to comment Share on other sites More sharing options...
AzeoTech Posted July 29, 2019 Share Posted July 29, 2019 There is a limit defined in the Modbus spec. I don't remember off hand what it is, but I think it is 63 bytes of data for RTU, and each register is 2 bytes. But don't take my word for it on the exact number. The point is that it is a Modbus limit, not DAQFactory, though DAQFactory enforces it. Also note that some devices don't support setting of multiple registers. This is not your case, as it is obviously working with 16 registers. I simply mention it for others that may have issues trying to set more than one at a time. Quote Link to comment Share on other sites More sharing options...
Rodney Posted May 3 Share Posted May 3 I have a similar syntax issue - I am trying to update the clock on a mppt solar controller (ID 5 ) (I can read the data - no issues) I would like to update the 3 registers (hex 9013-9015 = decimal 36883-36885) with the DAQ time values on start up - see the simple clock sequence below The documentation appears fairly simple and comprehensive I was hoping line 8 of the sequence would update the registers - but no luck thanks in advance Rodney Quote Link to comment Share on other sites More sharing options...
AzeoTech Posted May 3 Share Posted May 3 In your case the issue is several fold, and all related to your DAQFactory syntax: 1) you can't put anything but constants inside {}. Your clock variable is not a constant, and in fact is already a properly formatted array, so you don't even need {} 2) you don't need execute() and you are using it wrong anyway. Execute() takes a string and executes the contents of the string as if it was a line of script. You just want to run a line of script so you don't need execute at all. 3) there is no SetRegisterU16, only S16. This is largely because it doesn't matter. DAQFactory isn't going to translate from signed to unsigned for an output nor does it need to. Unless you really want it, I'll save you the long winded explanation why... In the end you just need: Device.myModbusDevice.setRegisterS16(5,36883, clock) Quote Link to comment Share on other sites More sharing options...
Rodney Posted May 3 Share Posted May 3 Thank you that worked its been a few years since I have used DAQ and the execute command was copied from a sequence that used a string to generate the line thanks for the reminder Quote Link to comment Share on other sites More sharing options...
bms Posted July 29 Share Posted July 29 Is there a way to force DF to use Modbus function code 16 for single register writes? I need to write to a ModbusTCP server that doesn't support function code 6 and is timing out on setRegisterS16 requests. SetRegisterS32RWords works fine. Quote Link to comment Share on other sites More sharing options...
AzeoTech Posted July 29 Share Posted July 29 Yes, but you have to use a channel. Under the I/O type options there is Set Register S/U16 (16). The (16) tells DAQFactory to use code 16 instead of 6. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.