04-15-2022 04:26 AM
Hello all,
i need to create timer which will be later used to send CAN frames cyclic (not a NI hardware).
In attached VI, array is created which take reference time, cyclic time, and expected time.
After expected time is reached, values in array are set again.
It use 'Tick count'.
If i use 'wait' function, to slow down the loop, then skip over the expected time.
If i don't use 'wait' function, then loop use 100% of cpu.
Can someone gives idea how to solve this, or eventually what is the good way to implement cyclic messages.
Thanks
Solved! Go to Solution.
04-15-2022 06:37 AM
Have you tried the "Timed Structures" found on the "Structures" Palette (the first Palette)? The Timed Loop, in particular, is designed to "wake up and perform" once every however-much-time you request. You can run this as a "parallel loop" (as you would run an Event Structure, for example), or as an element of a State Machine where you want do "Do this repetitively until I say to stop".
The Help for the Timed Loop is pretty extensive (and bewildering, when first encountered), but there are also some Examples.
Bob Schor
04-15-2022 06:50 AM
If you're looping you will use 100% CPU (one CPU) unless there's some wait in there.
There's just no way around this.
What you made could be a sub VI, used by a higher level VI. However, that higher level VI probably will have a loop, and it should have a wait..
You should probably split up functionality. Make a main VI, make a timer, make something that hold state, make things that communicate with CAN, make something that uses the pieces of the puzzle to do what you want. All this is application 'architecture'. Look into state machines, consumer\producer, message handlers, master\slave, or software architecture in general.
What you have now seems to be going toward 'the VI'. One VI that tries to do everything. This will be very inflexible. As you're probably noticing 😉...
04-15-2022 07:57 AM
Thanks for the fast fedback.
For sure this will not be one VI. This is just VI to see how to get working cycle timer.
Instead of checking if expected time is equal to current time, now i use greater or equal.
So this is some solution in case of skipping the value.
Because i didn't figure out anything better for cyclic can messages...
04-15-2022 08:30 AM - edited 04-15-2022 08:34 AM
So CAN messages themselves are nondeterministic. Meaning you may see messages come in every 10ms, but then that might come in every 12ms and everything needs to work well if it does come in late. CAN messages have a priority and if another message comes in with higher priority, the message you are trying to send, needs to wait, and then retry. This retry is built into the transceiver and you don't need to issue another write. My point is that the precise timing isn't a requirement, and in fact is impossible.
So with that being said I'd say don't worry about sending out single frames with precise timing, because it doesn't matter. Do your best sure, but you don't need to use the high precision timing, or a timed loop.
The way I've done this in the past is just in a loop looking at how much time has passed since the last time each frame went out, and then if enough time has passed, send it again. You can get extra fancy, and instead of tracking the time of the last transmission, track how much time you need to wait until the next transmission. Then you can have your wait function be the minimum value. But honestly throwing in a Wait 1ms or Wait 2ms is fine since you can't be deterministic anyway.
Oh and if you are using XNet you don't need to worry about any of this. XNet hardware has a retransmit feature that is built into the API. You can do the write once, and it will keep sending it out as needed. I cover this in Part 6 of my CAN blog.
Unofficial Forum Rules and Guidelines
Get going with G! - LabVIEW Wiki.
17 Part Blog on Automotive CAN bus. - Hooovahh - LabVIEW Overlord
04-18-2022 04:11 AM
Thanks a lot.
This is helpful.
Very similar like i thought at the first place.