Jump to content

Port Output Problems


Recommended Posts

Just hit a new issue that I feared may rear its ugly head!

If you look at Run.vi, you can see that each section in the bottom parallel process (while loop) passes an output value, which is then passed by local variable to the other parallel process (while loop), where it is output to the card.

This output requires an 8-bit unsigned integer (the output port is 8-bit) between 0 and 15 (only the bottom 4 bits of the 8-bits are used, with values 8, 4, 2 & 1). I have identified the necessary binary value for each component (motor, solenoid etc) and this value being passed from each section will fire the necessary component when passed to the other parallel structure.

The issue i'm now encountering, is that the top loop sometimes never gets the output value for the sporadic outputs, as the value I pass for output is part of a sequence diagram within a case structure (in the Assembly area for instance) and the sequence diagram executes so quickly, then the case becomes false and the output value will be set to 0 again for that section, meaning the top loop never received the output value.

Can anyone think of an efficient way to ensure that any output I need definitely reaches the top loop? Bear in mind I need to output differing values constantly - it may just need 2 motors on at some point, then it will need to fire a solenoid, so it will still need to run the motors AND fire the new solenoid, then another solenoid may need activating at a similar time. Basically, a way to ensure that any 4-bit combination I need between 0 and 15 is output when I request it and it doesn't get overlooked.

Cheers guys

Link to comment

Hi Michael:

I must be missing something, but I can't see the reason why you need to use two loops and the local variables?

Can't you just move the contents of the I/0 loop into the main loop and wire the outputs of the sub-vi's directly into the add node? Then once the values for all the sub-vi outputs are updated (once every 100 ms) and ready, they will be posted out by the port output vi.

There is no point in running a separate port output loop more often than the sub-vi's provide new inputs. On the other hand, if you expect the various sub-vi's to provide output too transient to be detected by a 100 ms update, then they too need to be in a loop that is executed more often.

Hope I've helped at least a little,

Best Regards, Louis

Link to comment
Hi Michael:

I must be missing something, but I can't see the reason why you need to use two loops and the local variables? 

Can't you just move the contents of the I/0 loop into the main loop and wire the outputs of the sub-vi's directly into the add node?  Then once the values for all the sub-vi outputs are updated (once every 100 ms) and ready, they will be posted out by the port output vi. 

There is no point in running a separate port output loop more often than the sub-vi's provide new inputs.  On the other hand, if you expect the various sub-vi's to provide output too transient to be detected by a 100 ms update, then they too need to be in a loop that is executed more often.

Hope I've helped at least a little,

Best Regards, Louis

4322[/snapback]

That's actually a very good point Louis! I'm still adjusting to Labview, coming from a C programming background mainly, so the temptation to use local variables is far too great, when in actual fact the wire is labview's version of the local variable if i'm thinking along the right lines?

I'm trying that out now! I can probably get my head round any timing niggles that occur this way!

Fingers crossed - cheers :D

Link to comment

Ah Louis,

what I thought may happen, has happened.

Because i've got so many SubVIs and nested SubVIs (I need them really as i'm using Labview 2 style globals to manage counters and common repeating tasks - i'm assuming that's a good approach?) the performance suffers - now i've moved that into the main loop and removed the other, the output is occuring, but there's a lag and it's sometimes missing its deadlines.

That was why I chose 2 loops - I might try and change the output to a queue maybe, to queue up all output, so nothing is missed - it's all a bit tricky!

Link to comment
Ah Louis,

what I thought may happen, has happened.

Because i've got so many SubVIs and nested SubVIs (I need them really as i'm using Labview 2 style globals to manage counters and common repeating tasks - i'm assuming that's a good approach?) the performance suffers - now i've moved that into the main loop and removed the other, the output is occuring, but there's a lag and it's sometimes missing its deadlines.

That was why I chose 2 loops - I might try and change the output to a queue maybe, to queue up all output, so nothing is missed - it's all a bit tricky!

4325[/snapback]

The code you submitted does not have many nested sub-vi's. I've developed applications with thousands of VI's and they run very quickly, efficiently and everything is synchronized. Your code is very lightweight so the lag you are seeing must be comming from somewhere else. The solution to your problem is to simply to create subvi to handle the port writing and place that wherever you need it. I built a quick VI to do this for you and I modified your original code to include this VI. Basically just place the VI down wherever you need to modify one item. The VI remembers the previous states of all the items so you don't need to worry about synchronization.

One thing I noticed is the multitude of File IO. Is this really necessary? File IO is a big bottleneck.

post-2-1111825777.gif?width=400

Download File:post-2-1111825775.llb

Link to comment

well, top bloke!

going to test drive that after the weekend but thank you very much for your help!

RE the File I/O, it was still slightly iffy before I added that - I need to log everything that happens, in the order it does - I suppose a queue could do that, passing the queue to one subVI handling file I/O? Hmmmmm, that could work!

I did wonder about the number of SubVIs - it seemed like it should be ok!

thanks man :)

Link to comment
well, top bloke!

going to test drive that after the weekend but thank you very much for your help!

RE the File I/O, it was still slightly iffy before I added that - I need to log everything that happens, in the order it does - I suppose a queue could do that, passing the queue to one subVI handling file I/O? Hmmmmm, that could work!

I did wonder about the number of SubVIs - it seemed like it should be ok!

thanks man :)

4349[/snapback]

seems to be running pretty smoothly cheers Michael :)

I've got a niggle with some Boolean Logic

This attached VI basically picks up if a passing object is metal or plastic (assuming nothing of any other type has been placed on the conveyor) - I can do the metal identification easy, but for the plastic one I have a niggle - it works most of the time - but when the conveyor is moving quickly, it picks up the metal objects as both 'reject' (or plastic) and 'metal'

So my code must nearly by right, just a slight issue in it - not really sure how to do a latch :(

Boolean logic isn't my strong point - it's really bugging me!

Link to comment
seems to be running pretty smoothly cheers Michael :)

I've got a niggle with some Boolean Logic

This attached VI basically picks up if a passing object is metal or plastic (assuming nothing of any other type has been placed on the conveyor) - I can do the metal identification easy, but for the plastic one I have a niggle - it works most of the time - but when the conveyor is moving quickly, it picks up the metal objects as both 'reject' (or plastic) and 'metal'

So my code must nearly by right, just a slight issue in it - not really sure how to do a latch :(

Boolean logic isn't my strong point - it's really bugging me!

4372[/snapback]

ah one more niggle i've seen

when I profile the system using Michael's output method, it runs brilliantly - nice and quickly, lots of iterations and reacts more than quick enough to input

in the assembly area though, I have to delay it somehow - basically when the sort area fires a plastic ring down the chute, if there's no already a plastic ring in the assembly hopper, open a solenoid to let this newly fired ring into the hopper - so firstly, I have to add a delay in the assembly area of about 300ms to let the ring slide down the chute before it opens - and I also have to add a delay of about 450ms before it shuts the solenoid so the ring drops down properly. this makes assembly perfect BUT completely slows down the program and reaction to input becomes slow generally - I can see from the profiling tool that the subsections iterate about 1/3 as quickly with these delays in - using the 'wait (ms)' node.

hmmmmmmmm!

if there a way to put a delay in without making the rest of the program suffer as a result? :(

cheers :)

Link to comment
if there a way to put a delay in without making the rest of the program suffer as a result? :(

cheers :)

4373[/snapback]

Yes. All you need to do is separate the VI's into separate parallel loops. This will allow the "slow" VI's to run at any speed they wish and the other VI's won't be affected. It should be straight forward but if you need any help let me know and I can post the modified code.

Link to comment
Yes. All you need to do is separate the VI's into separate parallel loops. This will allow the "slow" VI's to run at any speed they wish and the other VI's won't be affected. It should be straight forward but if you need any help let me know and I can post the modified code.

4390[/snapback]

At present I've been using 4 queues to pass data around - 1 for identifying the peg number, 1 for the ring number, 1 for the first inspection area and 1 for the final inspection area.

Is it still possible to use just 4 queues?

If I obtain a queue outside of the parallel loops, then feed this into the six seperate loops, will the queues be passed around ok? I've got a feeling the queues won't run properly as one of the loops will effectively trap it until it finishes executing, which is when the program terminates?

I've had trouble in the past with queues and multiple loops so not overly sure - going to back-up my work now and have a hack at it, but got a feeling it'll go pear shaped lol! :(

Link to comment
At present I've been using 4 queues to pass data around - 1 for identifying the peg number, 1 for the ring number, 1 for the first inspection area and 1 for the final inspection area.

Is it still possible to use just 4 queues?

If I obtain a queue outside of the parallel loops, then feed this into the six seperate loops, will the queues be passed around ok? I've got a feeling the queues won't run properly as one of the loops will effectively trap it until it finishes executing, which is when the program terminates?

I've had trouble in the past with queues and multiple loops so not overly sure - going to back-up my work now and have a hack at it, but got a feeling it'll go pear shaped lol! :(

4398[/snapback]

I'm assuming you mean along these sort of lines Michael?

Only issue now is for some reason the output has stopped working in certain areas - if I do highlight execution things appear to happen - will my input VI cause issues do you think? The Chain Conveyor works, but the Sort Area is not firing the Solenoid - neither does the Assembly Area, but the Conveyor Area starts up the conveyor belt when it thinks there's both a peg and ring in the system (so this proves the Sort Area is correctly identifying them, just not firing the solenoid to sort the rings) and the Reject Area solenoid is firing too - so just seems to be the sort and assembly are playing up - odd - going to keep trying to work this out, but can you see anything that i've done in my labview naivety?

My Logfile is all as it should be - so the SubVIs at least think they're doing what they should be - just the issue with the output - probably a schoolboy error on my part!!!! I've not changed the way that output writer works - odd!

Can see a difference though - I've added a delay where I need it and the reject area solenoid still fires immediately when a reject object is in front of it - I'm just not too sure if my queues are working properly or not

Any ideas dude? Cheers :)

*EDIT*

I seem to have sorted the problem by putting the index array functions for the input outside the while loop - that was the only difference between them and the reject area - thought I'd give it a shot - worked! When the index array was inside it seemed to look like it was iterating twice on the loop, so the outwriter value to fire the solenoid of '1' would be moved to the edge of the while loop, then it would iterate again, now the firing case was false, so a value of '0' overwrote the '1' waiting and then the loop seemed to release the new value of '0' to the outwriter, thus cancelling the original request to fire the solenoid! Weird!

The only issue now is that sometimes if I halt the program with my Stop button I get an error from the 'pegqueue' or 'ringqueue' LV2 global I made saying there is a missing parameter - I think this is only when the queue is empty.

*EDIT*

Seem to have fixed the queue problem by turning off automatic error handling - although it's not ideal, handling errors is not really critical here - the hardware i'm working with has limited facilities in that respect

*EDIT*

put clusters in now to neaten it up slightly!

Does my approach RE the queues look ok to you? You evidently know your stuff :D

*EDIT*

test tomorrow and I may well be done, give or take some frilly HCI extras :D

long post anyone? :D

Link to comment
Well, all looks good as far as I can see. Now that all processes are in parallel, the queue messaging architecture makes more sense. This way, if one process is waiting for a message, it doesn't hold up the others. Good job!  :thumbup:

4417[/snapback]

cheers dide :)

only thing that i've noticed now is when I hit the stop button there's quite often a lag of about 4-5 seconds.

Ideally it's meant to be an emergency stop - it halts all the parallel processes then the next part of the sequence writes zeros to all the ports to halt all activity.

It was quick a while back, but now it's got a lag in it - down to those 'wait' functions you reckon?

Link to comment
cheers dide :)

only thing that i've noticed now is when I hit the stop button there's quite often a lag of about 4-5 seconds.

Ideally it's meant to be an emergency stop - it halts all the parallel processes then the next part of the sequence writes zeros to all the ports to halt all activity.

It was quick a while back, but now it's got a lag in it - down to those 'wait' functions you reckon?

4420[/snapback]

Well, one quick thing I can come up with is the following (see image). This will speed up your longest loop. to detect the button press faster. You can do this to the other loops as well but you should use the tic count timer instead of the seconds since function. This will give you finer resolution. There is probably a slicker approach but this is the best I can do quickly.

post-2-1112629316.gif?width=400

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.