DQMH Consortium Toolkits Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Helper Loops accessing Hardware

Solved!
Go to solution

Hello everyone,

 

according to Jörg's suggestion (I have an Ö on my keyboard), I implemented helper loops for automating recuring events such as DAQ.

Two issues I have been battling and am looking for input regarding those (see screenshot as well):

  1. The timing is very unstable.
    Since the implementtation utilizes the time-out of the event structure, the duration of the acquisition factors into the timing. (Example: if the time-out is set to 1000 ms, if the process varies in duration between 200 and 250 ms, this results in the iteration taking between 1200 and 1250 ms.) In the case of serial drivers (or something similar) this might simply be the variation on the transmission and therefore irrelevant for th samples, IF I would be able to send the request every 1000 ms (similar to wait until next multiple)...
  2. Serial devices with commands sent from the MHL and acquisition requests sent from the helper loop
    In this case I have the helper loop requesting measurements every 1000 ms (see problem above) and every once in a while the MHL jumps in and requests a change in setting or some other parameter.
    If I don't time those MHL communications precisely, the bytes in the buffer might be assigned to the wrong request (Each request sent to the serial port reads back afterwards a fixed number of bytes).
    It looks like adding one more layer of abstaction (comparable to Fabiola's serial driver example here: https://delacor.com/tips-and-tricks-for-a-successful-dqmh-based-project/, Tip 5: Add Classes to DQMH Modules) might solve this problem...

Any help and comments greatly appreciated !

 

Cheers

Niels Göran

DQMH with Helper LoopDQMH with Helper Loop

 

0 Kudos
Message 1 of 10
(7,245 Views)
Solution
Accepted by Taggart
Hi Niels,
 
You could tackle this in two different ways:
 
1) As per Sam Taggart's recommendations in his blog post here, keep the helper loop reusable. Inside your timeout case of your helper loop, instead of carrying out the action in situ, simply use the MHL queue to inject the action of reading data from the COM port back into the MHL.  So "Read Periodic Data" might be a new case you have in MHL.  The helper loop won't be slowed down by the action, and therefore the timeout of the helper loop event structure will be more accurate. As long as the MHL is not too busy and won't block this action, then this is a simple approach.
 
2) The other approach, is to do something similar to what Fabiola suggests in this video (but implement it in your helper loop) - Tip 4 of https://delacor.com/tips-and-tricks-for-a-successful-dqmh-based-project/.
 - Make the outer while loop of your helper loop a timed structure with loop time of 1 second.
 - Change the event timeout connection of the event structure to be 10ms
 - Inside the event structure timeout case, add a case structure. 
 - Place your existing serial port read code into the case structure.
 - Create your states and pass them around the loop via a shift register
 - Ensure the event structure handles the Stop Module event and any other events such as Start/Stop Acquiring, so that it will terminate when required.
Christopher Farmer

Certified LabVIEW Architect and LabVIEW Champion
DQMH Trusted Advisor
https://wiredinsoftware.com.au

Message 2 of 10
(7,234 Views)

Fabiola's suggestion offers much more robust timing.

 

The reusable helper loop is much better for things that are repetitive but don't have very strict timing requirements.

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
0 Kudos
Message 3 of 10
(7,226 Views)

Re (1), use a calculated, rather than a fixed, timeout.  Take the remainder of the current ms timer MOD your time interval and use that.  So if your loop requires 213 ms, the calculated timeout will be 787.

Message 4 of 10
(7,224 Views)

That will also work.

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
0 Kudos
Message 5 of 10
(7,222 Views)

@drjdpowell wrote:

Re (1), use a calculated, rather than a fixed, timeout.  Take the remainder of the current ms timer MOD your time interval and use that.  So if your loop requires 213 ms, the calculated timeout will be 787.


+1 for James' suggestion. As the timeout value lives on the shift register, this is easy to accomplish. In my blog post about helper loops I wrote: 

 

The timeout event of an event structure can be used to repetitively execute code. Timings can be controlled by setting the timeout value of the event structure, or by implementing your own timing code within the timeout case of the event structure.

 

There is also a small mention of the caveats when using the timeout case for critical code.

 

PS: Thanks for the "ö", Niels 😉




DSH Pragmatic Software Development Workshops (Fab, Steve, Brian and me)
Release Automation Tools for LabVIEW (CI/CD integration with LabVIEW)
HSE Discord Server (Discuss our free and commercial tools and services)
DQMH® (The Future of Team-Based LabVIEW Development)


0 Kudos
Message 6 of 10
(7,218 Views)

@joerg.hampel wrote:

There is also a small mention of the caveats when using the timeout case for critical code.

 


In case people don't want to go read the blogpost, the caveat says 

"It is important to state that the timeout event is only triggered if no other events happen during the timespan that was wired to the timeout terminal of the event structure. That’s why it’s called the timeout event after all. So if you’re implementing your event structure to handle all sorts of critical events, your event structure might never actually timeout, and the code inside the timeout event case will never execute.

 

In our case, the timeout event case IS the critical code, and as we only enable/disable the timeout case and register for the Stop Module event, we should be good.

I also brought this up on the NI forums, please read Fabiola’s and Darren’s comments."

 

All great suggestions. Niels, keep us posted on your progress.

 

Regards,

Fab

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
0 Kudos
Message 7 of 10
(7,194 Views)

Oh and this option has worked very well for us when communicating with serial devices

 


@ngblume wrote:

... Fabiola's serial driver example here: https://delacor.com/tips-and-tricks-for-a-successful-dqmh-based-project/, Tip 5: Add Classes to DQMH Modules) might solve this problem...

Regards,

Fab

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
0 Kudos
Message 8 of 10
(7,193 Views)

Hey everyone,

 

thank you for your replies !!

I really like Christopher's suggestions of feeding it back to the MHL (especially since the workload there is small). Furthermore, I make reuse of the same case in MHL that might also be triggered from the outside (i.e. if timed helper loop is inactive).

Extending Tip 5 of Fabiola (separate abstraction layer for serial devices) into a separate module also sounds quite reusable, since it can be kept "dumb" and unaware of the commands and handling of replies and only perform VISA write and read.


@Christopher: For the second suggestion (Tip 4 of Fabiola), I'm not sure, if I understand fully the advantages of adding a State Machine, given that I don't have an order of steps to perform, but rather just one repetitive and some event-driven ones. Wouldn't the 1s timing of the while loop "overwrite" the 10 ms time-out of the event structure (resulting in 1 s timing)?

 

@James: I never thought about using the run duration to calculation the remaining wait period. Simple fix !

 

Thanks for all the ideas!

Will keep you posted, what implementation works best for me in this case!

 

Cheers

Niels Göran

 

0 Kudos
Message 9 of 10
(7,157 Views)

 @Christopher: For the second suggestion (Tip 4 of Fabiola), I'm not sure, if I understand fully the advantages of adding a State Machine, given that I don't have an order of steps to perform, but rather just one repetitive and some event-driven ones. Wouldn't the 1s timing of the while loop "overwrite" the 10 ms time-out of the event structure (resulting in 1 s timing)?

Actually, you're right - you don't need the state enum passing around if there is only one state so this simplifies it a little! The 10ms is necessary so that the event structure will actually timeout, and you can perform your repetitive action.  You could make this 1ms, or 100ms...it probably wouldn't matter because the loop structure with 1s timing will keep things in check. The event structure is there to also handle the Stop Module event, or any other events such as Start Acquiring or Stop Acquiring if you were to need those.

Christopher Farmer

Certified LabVIEW Architect and LabVIEW Champion
DQMH Trusted Advisor
https://wiredinsoftware.com.au

0 Kudos
Message 10 of 10
(7,054 Views)