Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

Changing enumerated constants and state machine which listens for events

Hi,

I have two questions.

Question 1) I am trying to write a vi which is a state machine, which also listens for events.
The program runs through a sequence, listens for events, while reading in data from the serial port in a default state.

What would the best structure be for this?

I have used an event structure which adds items to a queue, with a seperate state structure, which reads items from the queue.
However, my program takes about 2 minutes to respond to events. I have created a cut down program, showing the structure I am using.

Question 2) My test vi, for question 1 is showing problems, where enumerated type constants are changing within the program.
The enumerated constant is a strict type defined control.

This can be seen by running the attatched program "Qn on state with events.vi" with execution highlighting turned on. The program then goes into states that it shouldn't.
Is this a problem with my program? or an incorrect LabVIEW behaviour?
My application works fine, however, the cut down program, showing the structure, doesn't work correctly.

Details on Question 1)
----------------------
The sequence of the VI I'm designing is:
1)Disable front panel buttons which generate events
2)Initialise the serial instrument
3)Program the serial instrument
4)Enable buttons on the front panel which generate events
5)(a)Go into a default state, which is reading data from the serial instrument.
5)(b) at the same time, listen for events from front panel controls, which write commands to the serial instrument.
5)(c) once the event has been carried out, go back into the default state of reading from the serial instrument
6) If the stop button has been pressed, stop the program

The way I have done this, is using queue's and events.
This is the sequence I have followed.

1) Initialise the event structure to have a timeout of -1, never time out
2)Disable front panel buttons which generate events
3)Initialise the serial instrument
4)Program the serial instrument
5)(a)Enable buttons on the front panel which generate events
5)(b)Change the timeout of the event structure to 500ms,Generate a user event at the same time, to update the timeout setting on the event structure.
(This allows the timeout case of the event structure, to read from the serial port on a regular basis)
This allows timeout to be the default case of the event structure.
5)(c) at the same time, listen for events from front panel controls, which write commands to the serial instrument.
5)(d) once the event has been carried out, go back into the default state of reading from the serial instrument
6) If the stop button has been pressed, stop the program

Any advice on this would be greatly appreciated.

Thanks,

Anthony
0 Kudos
Message 1 of 6
(4,122 Views)
Anthony,

could not review your code right now.
What comes into my mind when reading your description, however, is:
* performing serial communication with regular pauses of up to 500ms (which can happen when using the timeout event with 500 ms timeout) is probably not the best idea. Depending on the baud rate and the amount of data your device sends, the serial buffer in your system may overflow. And if not at this situation, there might come anorther one where your code stops working ;-((
* I do not know how to change a strict typedefd enum constant. A constant is a constant! Period.
* I'd suggest changing your setup like this:
- Open and initialise your serial port
- create a named queue 'receive'
- Use a while loop to
+ Check if bytes are at serial port. If so, read them and append them to a shift register (SR).
+ Check, if the SR contains a full respond from your device. If so, remove it from SR and put it into 'receive'
- Use another independent While loop to run your event structure
+ for your FP control events, write your data to your device
+ If a stop button is pressed, perform your cleanup
- Use a third independent While that checks for new queue elements in 'Receive' and processes them.
The 2nd and 3rd whiles can be put together when there's no need for parallel processing your serial data and acting on key-pressed events. But this requires you either to use the timeout event case or to generate a dynamic event with new queue elements. In either case, however, I#d use a timeout value of about some 10 to 100 ms.
Use a local read of the stop button to stop the other independent while loops

Just my € 0,02
Greetings from Germany!
--
Uwe
0 Kudos
Message 2 of 6
(4,116 Views)
Hi Uwe,

Thanks for your suggestions.
I have it working with little or no delay.
The solution was, two while loops, one with an event structure, and one state machine, using queues.
The event structure had an infinite timeout, with each event, it placed an item on the queue.
The state machine, would read each item of the queue. If the queue was empty, it would test the serial port, if there is any bytes at the serial port, then place a read item on the queue.
The read state would read bytes of the serial port, then if there was no data at the serial port, and no items on the queue, continue in the default state, monitoring for bytes on the serial port.

The second problem, with changing enumarated constants, is only with my test code, which was attatched to my previous post.
I agree a constant should never change, but it does.

I'm happy it's solved, however, as it is only with the test code and not the application.

Thanks,

Anthony in Australia.
0 Kudos
Message 3 of 6
(4,105 Views)
Hello lv_datataker, I also observed changing enumerated constants (TypeDef) in my event driven state machine, which consitsts of two loops, too. I have seen the constants changing while running the vi. That caused unwanted event chaos, as in your case. I disconnected all instances from the Type Def, saved the TypeDef under a different name, and replaced the instances with the new TypeDef. That helped to some extend. I havent directly observed changing constants again, but there are many in my vi. Still some unwanted events created, and I do not know whether this is a new problem. Now I can reproducibly create an unwanted event by scrolling with a mouse through a table, and leaving the area of the scroll bar with the mouse pointer. The unwanted (one of the earlier called keyboard events) event is created after a while, even before I release the mouse key. Do you have more wisdom about the enumerated constants in the mean time? Can you post you working vi, or tell us something about the differences, e. g. the timeout settings. Thanks, Kai
0 Kudos
Message 4 of 6
(3,937 Views)
Hi Kai,

I cannot recall the exact steps I did to stop the problem, but I had a seperate VI which didn't show the problem.
As the VI I created was a test VI, and not the end application (the test VI was just testing the structure), I didn't test it that thoroughly.
But as the New VI had a different name, and a different enumerated constant, it wasn't showing the same problem.

The problem I was seeing in the test VI, seems similar to the behaviour you have seen.
I would suggest creating a new VI, with different named enumerated constants, and it may not show the problem.

I am well aware that the VI shouldn't show this behaviour, but it was.
I have managed to find the original problem VI, which I can submit if you wish.

Sorry I can't provide much more information than this.
Thanks, Anthony
0 Kudos
Message 5 of 6
(3,926 Views)
Take a look at this thread on the LAVA (LabVIEW Advanced Virtual Architects) forum.
 
 
It sounds like you are seeing the same issue reported there.
 
Ben
Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 6 of 6
(3,918 Views)