Conditional exectution of code block.
In one block I am observing a monetary push button switch to toggle an output. I want to switch a valve via modbus whenever there is a change in the output.
This is the block where I observe the switch:
And this is the block that updates the modbus valve terminal:
They are both at level 1 in my system:
My thinking is that the SRTF block will run the modbus once, only when the output value changes. But does not seem to happen. I am probably not understanding how to conditionally run a code block or what the purpose and use of the SRTF block is.
So how does one run the update of the modbus terminal only when there is a change required?
Hi @Gerritjan1 ,
as you mentioned in the e-mail, the correct way to provide connection between various tasks are Inport and Outport blocks. The crucial thing is that corresponding Inport a Outport should have the same Block name (for example PinValve).
The connection between two tasks is shown for example here:
Regarding your question about conditional task running: Is there any special reason to run the task only when the value has changed? Modbus master should write the value only when it differs from previous one. From REXYGEN Modbus documentation, Chapter 4:
write - writes the value to cache (if it differs from the previous value, it is transmitted during the nearest Modbus cycle)
@jan-reitinger The reason I need to read the festo terminal before writing is that the monarco is not the only device using that terminal so I cannot rely on the previous state. And reading the terminal on every cycle will basically block it for other devices.
thanks for the additional information. To temporarily disable reading/writing to Modbus, I would try using the special flags _ReadEnable and _WriteEnable. In your case, the flags would be called MTM__ReadBlock1_ReadEnable and MTM__WriteBlock1_WriteEnable. Setting TRUE to these flags will enable the corresponding operation. You can find the documentation in Chapter3.4. If you have several Master devices on the bus, it is not a completely standard solution.
If I misunderstood your question, please provide more details.
I as understand it, multi master is possible on modbus TCP, that is what I am using. I tried your solution with the enable flags, and it works for a short time :
The main problem now is that the rexygen modbus reads are very unreliable:
When I use the 'SRTF' version i see timeouts in the log, I don't see those when I use the 'enable' version. But still the SRTF version seems to work slighly better.
If I use labview or python I don't have any problems controlling or reading from the same device..
For example if I run the following python script from the command prompt:
import timeit timeit.timeit('client.read_holding_registers(45399).registers', setup='from pymodbus.client import ModbusTcpClient; client=ModbusTcpClient("192.168.169.100")', number=1000)
it returns about 2.4 sec for 1000 runs repeatable and without errors.
If I replace the level 0 task with a basically empty task (just display a constant), it behaver better, I don't see the errors.
My level 0 tick is 0.002 and the level 1 loop time is 0.002 * 50 = 100ms. :
My thinking is the level tasks should have plenty of time to do their job but apparently the leverl0 job seems to ruin things. This task is a PIDE regulation block that has not given me any problems so far.
What is preventing the reading of the modbus registers?
I wanted to inquire if you utilize data from Modbus in the Level0 task. If not, please verify the factor in the Modbus driver block and adjust it based on the fastest task where you read or write Modbus data.
It is worth noting that a task running on a Raspberry Pi with a 2 ms period can be quite demanding. To assess the situation, you can navigate to Target -> Diagnostics -> <your task> and enable Diagnostics in the Task tab. Check the Max/Average time executing values, which are displayed in milliseconds. It is possible that due to the demanding task at level 0, REXYGEN may not have enough time to execute tasks at other levels effectively. Have you considered increasing the tick value? REXYGEN performs various calculations and tasks during execution, making a direct comparison between reading Modbus in REXYGEN and a Python function inaccurate.
Furthermore, you can try enabling more I/O driver messages in Target -> Configure System Log to verify if the desired events occur within individual periods. Specifically, check if the Modbus data is read during the same period when you set the _ReadEnable flag to true.
@jan-reitinger Thanks for the reply,
The level 0 task does not use data from the modbus task. The maximum time value reported for the level0 task is a little less than 0.4 ms with an average of 0.125 ms.
The level 1 tasks have a maximum time of about < .3 ms, except when modbus task is failing, that maxes out at a little less then 5000 ms.
After switching on all messages for IO driver messages I noticed 3 things:
- The MBDRV doesn't seem to respect a low value on the ReadEnable/WriteEnable output, it send and receives all the time, even when there is no change on the toggle value. I would expect this to happen only when the EDGE_1 block detects a change. Even if I set the enable control permanently off, there are still modbus errors.
- On after a timeout message on reading there is also a message 'Client 0 disconnect'
- There are some times messages 'host warning Archive underflow detected' although they don't seem to be correlated to the driver messages. And I am not using any archive blocks in my tasks.
@gerritjan1 I've observed that you are currently using the flags MTM__readBlock_ReadEnable and MT__writeBlock2_WriteEnable. However, in a previous post, you mentioned flags named MTM__readBlock1 and MTM__writeBlock1. It is important to ensure that the flag names correlate properly. Therefore, for MTM__readBlock1, the corresponding enabling flag should be MTM__readBlock1_ReadEnable, and for MTM__writeBlock1, the enabling flag should be MTM__writeBlock1_WriteEnable.
This post is deleted!