LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Any examples of event driven front panel, paired with real time serial communications going on?

Hello all,

 

I'm starting to get a little desperate as that a deadline is looming.

 

I've been working with a front panel that is driven by events. I have code which receives byte code in real time every 20ms from a serial port...evaluates the state of the front panel, and  based on that, needs to send updated byte code out the serial connection.

 

I found out, that I can't keep event driven code in the same, normally done, 'main' loop as with the serial read/write code that needs to be in real time (due largely to events resetting the timeout timer on every event).

 

I've been trying to read up on suggested producer/consumer type coding...but for the life of me, I can't figure how or what I'd send back and forth over a queue.  In both loops, I'm going to be scanning and updating the front panel components/indicators.....why would I need to send things back and forth? So...I'm just confused as heck.

 

I can't post the whole vi to the list...there's some proprietary stuff there. I've opened a SR with NI....but they're apparently only open Monday-Friday normal 'working hours'...so, I've got no support there over the weekend, and so far, they've not given me a lot of time. They engineer is nice, but I've gotten no hard advice from his analysis of my code yet.

 

So, I'm asking...does anyone have a hard example the could let me see...that combines the things i'm trying to do.....my basics are:

 

1. Receive data over a serial port real time.

 

2. Update event driven front panel

 

3. Scan front panel for settings, and construct next message to send out serial port.

 

The window is event driven...the serial receive and transmit are needing to be real time.

 

I work well from a good solid example...can anyone post something that would be similar in functionality for this?

 

Thank you so much, in advance, for any help...

 

cayenne

0 Kudos
Message 1 of 16
(3,244 Views)

cayenne,

 

I do not have an example now but may be able to point you in the right direction.

 

1. Producer/Consumer is the way to go.

2. Put the serial communications in the Consumer.

3. Have the Event structure and all front panel controls and indicators in the Producer.

4. Have at least two queues*. One will send data (and commands) from Producer to Consumer (messages to be sent out on the serial line). The other* will bring messages received by the serial port back to the Producer.  This is where part of the confusion may be occurring as both loops "produce" and "consume" data.  It may help to think of one loop as being the GUI loop and the other loop as the communications loop.

*User events may be an alternative to the second queue.  I have not worked with them much but I think they could be used to generate an event when the serial port has received data.

 

The communications loop reads the serial port and enqueues the data. It checks for response from the GUI loop and sends it out when it gets one.  It never waits for anything except to receive data from the serial port.  This can run at your 20 ms rate (so long as the data comes in faster than that).

 

The GUI loop has the event structure waiting for user-generated front panel activity. In a timeout case or a User event case it will get the data from the serial port and send the response back. If this takes much time you may need a three loop system so that you can move the slow things out of the event structure.

 

Lynn

Message 2 of 16
(3,239 Views)

cayenne,

 

Attached is an example in LV2010. As shown in the example, I suggest using the following:

 

1) A Timed Loop for your "Consumer" loop. This gives you the best timing accuracy.

 

2) User Event to send serial data to your UI loop - I think this is the fastest way to get data to the UI loop.

 

3) A queue to hold the data to send out the serial port

 

Hopefully this will give you some ideas for your program structure.

 

One issue that you will probably have to deal with is the OS. I'm assuming Windows.

Windows can come along and take 100++ milliseconds whenever it wants.

Consider turning off services and updates to reduce this impact.

 

steve

--------------------------------------------------------------------------------------------------------------------------
Help the forum when you get help. Click the "Solution?" icon on the reply that answers your
question. Give "Kudos" to replies that help.
--------------------------------------------------------------------------------------------------------------------------
Message 3 of 16
(3,225 Views)

@stevem181 wrote:

cayenne,

 

Attached is an example in LV2010. As shown in the example, I suggest using the following:

 

1) A Timed Loop for your "Consumer" loop. This gives you the best timing accuracy.

 

2) User Event to send serial data to your UI loop - I think this is the fastest way to get data to the UI loop.

 

3) A queue to hold the data to send out the serial port

 

Hopefully this will give you some ideas for your program structure.

 

One issue that you will probably have to deal with is the OS. I'm assuming Windows.

Windows can come along and take 100++ milliseconds whenever it wants.

Consider turning off services and updates to reduce this impact.

 

steve


Thank you SOOO much!!  This is very helpful.

 

I'm stuck on one point, and not sure what tools I need to use...to get my data off of the User Event object....

 

I'm sending a 2D array of boolean. I've created my dynamic event node...but how do I get my data off that into my code that I have that works on the 2D array?

 

I have it hooked to the Event Dynamic Registration node...but how do I get my data off that?

 

Screenshot:

data_from_user_event_question.jpg

 

This needs to hook to the dotted line of broken wires on the far left...

 

The data type coming out of the Reg Events object is:

 

user_event_data_types.jpg

 

Again, thank you....I think I understand the coding idea here...just not sure how to get my data off of the User Event wire....

 

 

cayenne

0 Kudos
Message 4 of 16
(3,209 Views)

cayenne,

 

The Create User Event function requires a named data type. You should be seeing an error for that.

An easy way to do this is to just use an array constant (with a name).

 

Then use "Add Event Case ..." on your Event structure to make the event that will receive the data from your serial loop.

User Events are shown under "Dynamic" in Event Sources.

 

Attached is an example.

 

steve

--------------------------------------------------------------------------------------------------------------------------
Help the forum when you get help. Click the "Solution?" icon on the reply that answers your
question. Give "Kudos" to replies that help.
--------------------------------------------------------------------------------------------------------------------------
Message 5 of 16
(3,197 Views)

@stevem181 wrote:

cayenne,

 

The Create User Event function requires a named data type. You should be seeing an error for that.

An easy way to do this is to just use an array constant (with a name).

 

Then use "Add Event Case ..." on your Event structure to make the event that will receive the data from your serial loop.

User Events are shown under "Dynamic" in Event Sources.

 

Attached is an example.

 

steve


Again, thank you for all the help.

I was researching....and kinda thought that node would show up there. I'd originally had the wrong data type hooked to my create user event. I deleted that, and added in the 2D boolean array. I just now went back and named it.

 

I disconnected it..and reconnected things back...I even edited the event for code to be timeout, then back to the 'serial data' event..just to try to reset things.

 

But that data node in your  example, for some reason isn't showing up for me?

 

data_node_missing.jpg

 

I stretched down the data nodes on the event...and the Serial Data one just doesn't show up....all I get are UsrEvtRef repeated over and over again...

 

I was thinking I need to hit a Refresh button or the equivalent somewhere...?

 

Im close here.....thank you,

 

C

0 Kudos
Message 6 of 16
(3,194 Views)

cayenne,

 

It looks like you just put a label on the Initialize Array function.

This does not put a name on your data which is required by the Create User Event Function.

 

You should be getting the error:

"User event data type is unnamed ..."

Do you have this error?

 

Try using an array constant that is named as shown in my example.

 

steve

--------------------------------------------------------------------------------------------------------------------------
Help the forum when you get help. Click the "Solution?" icon on the reply that answers your
question. Give "Kudos" to replies that help.
--------------------------------------------------------------------------------------------------------------------------
0 Kudos
Message 7 of 16
(3,189 Views)

@stevem181 wrote:

cayenne,

 

It looks like you just put a label on the Initialize Array function.

This does not put a name on your data which is required by the Create User Event Function.

 

You should be getting the error:

"User event data type is unnamed ..."

Do you have this error?

 

Try using an array constant that is named as shown in my example.

 

steve


 

Thank you.

I had JUST figured this out......and was trying to beat you back with the post.

 

I put the array constant in ...with a label. I did have to mess with the event to get it to show...I broke the connection with the dynamic event regsistraion...I then changed the event with code in it..to time out...then changed it back to the Serial Data...and the data node is now showing up there.

 

Thank you!!

 

Ok...whew...moving on how...

 

C

0 Kudos
Message 8 of 16
(3,187 Views)

@stevem181 wrote:

cayenne,

 

Attached is an example in LV2010. As shown in the example, I suggest using the following:

 

1) A Timed Loop for your "Consumer" loop. This gives you the best timing accuracy.

 

2) User Event to send serial data to your UI loop - I think this is the fastest way to get data to the UI loop.

 

3) A queue to hold the data to send out the serial port

 

Hopefully this will give you some ideas for your program structure.

 

One issue that you will probably have to deal with is the OS. I'm assuming Windows.

Windows can come along and take 100++ milliseconds whenever it wants.

Consider turning off services and updates to reduce this impact.

 

steve


Hello,

 

So far, I've had a LOT of luck working from your example. I'd been testing first with just the user event, and that worked fantastically.

 

I've just put in the obtain queue and hooked it up to the enqueue the dequeue....and the release queue...and the stop timed event.

 

I just tried to run, and when I hit the stop button on the front pannel, I got the following error from the dequeue function :

dequeue_error_on_halt.jpg

 

Not sure what I need to look for here to troubleshoot with my first time using queues.  I've also never used the timed event before, and the stop timed element is new to me too, previously before hooking this up, I was using a property node value for my front panel stop button. I removed that and have put in the stopped timed event structure per your example.

timed_stop_release_queue.jpg

 

And here is a shot of the dequeue element hooked to my serial write out in the timed loop structure (which is named Serial).

dequeue_to_serial.jpg

 

Any suggestions on what I might look for that is causing this error?

 

The example is fantastic....and I think I'm close....

 

Regards,

 

cayenne

0 Kudos
Message 9 of 16
(3,144 Views)

You are killing the queue while another loop is currently waiting on it. I would use explicit messages for your queue so you can implement stuff like Stop and Exit messages. Your consumer wold catch these messages and act accordingly. Then release the queue only after all your loops have terminated.

 

If you decide to continue as you are then at a minimum you should wire the error out of your dequeue to a case statement and only process the data when there is no error. Since you do nothing with the error the automatia error handling is kicking in and giving you the error message.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 10 of 16
(3,123 Views)