I'm looking more into execution timing of projects. I'm not sure what I'm asking matters to much but was wondering if there is a best practice/more sensible way of doing things.
What I've done is put two tasks onto "level 0", but have given them different execution factors. The first task runs with an execution factor of 3, the second a factor of 10 as I need both tasks to run at different times. Is this best practice or should the second task be moved to "level 1" and make it so "level 1" runs at my desired timing factor for that task?
For reference. The first task is writing to a slave device via Modbus as a rate of 0.6sec. The second task is reading from the same device via Modbus every 2sec and logging to a TRND block with the same timing factor.
I hope this makes sense!
great question, makes perfect sense. Can you please provide more details about your project? Namely:
- Do you need the tasks to execute in specific order?
- How long does it take to execute the individual tasks? I don't expect it takes more than a few milliseconds, but please confirm.
- What is the base tick?
- What is the factor of Modbus driver?
- Can you share your project source files? Or at least some minimum example?
so here's your project source files: mike-project-timing.zip
Let's see what you have done...
Here's the same in PDF if you prefer: rexygen-project-timing.pdf
The first thing to understand is the allocation of time slots for individual tasks and drivers:
- Base tick = 20 ms
- RPI - Raspberry Pi driver, factor = 1, i.e. execution period = 20 ms
- MBM - Modbus RTU master, factor = 5, i.e. execution period = 100 ms
- modbus_write_task, start = 0, stop = 1, factor = 3, i.e. execution period = 600 ms
- modbus_read_task, start = 1, stop = 2, factor = 10, i.e. execution period = 2000 ms
The diagram above only illustrates the time slots. It does not show how long each task executes and when exactly it happens.
From what you wrote, I believe it's important to note that it's the yellow Modbus driver where the data is actually sent and received. Therefore all the Modbus registers which you have defined in the Modbus driver configuration for reading, will be read every 100ms. However, your modbus_read_task is scheduled to execute with 2 second period, therefore 9 out of 10 readings will be in fact wasted, creating unnecessary traffic on the serial bus.
Also keep in mind that by default, Modbus write commands are executed only when there is some change to write. The Modbus driver takes care of this for you to preserve bandwidth.
Is this clear to read so far? Learned something new? Willing to continue? Let me know...
I believe you could achieve what you need even with a single task, but I might be misleaded by the project source files reduced to the absolute minimum.
Thank you for the detailed reply. This makes sense to me now. Based on what you have said and how I understand it I have moved everything into one task. I forgot about the Modbus driver execution, I was also trying to reduce traffic but it sounds like that is all done for me
What I have now is one task with the below timings. Which is similar to what I would normally be using. A couple of questions though!
- What is a good execution rate for RPi/Monarco driver?
- What is a good execution rate for the Modbus driver?
Base tick = 20 ms (I have always use 20 ms on RPi and Monarco, I'm not sure if this is good or bad. But I have never had issues)
RPI - Raspberry Pi driver, factor = 1, i.e. execution period = 20 ms
MBM - Modbus RTU master, factor = 5, i.e. execution period = 100 ms
modbus_task, start = 0, stop = 1, factor = 1, i.e. execution period = 200 ms (I use 200 ms most of the time if I have one main task)
The PDF of timing layout makes a lot of sense and I would love to learn more. I am starting to use a lot of process models and think timing could start to be more important for me.
glad I could help.
A "good execution rate" always depends on the project. 20 milliseconds might be too long (controlling RPM of a motor or detecting pushbutton presses or counting pulses from a flowmeter) or way too short (temperature control).
It's the responsibility of the system engineer/designer to find the appropriate timing.
As for Modbus, we typically use twice the rate of the task which is using the data provided by the Modbus driver.