First off, I'd like to apologize - I am very, very new to LabVIEW, and about as new to software development for hardware control in general. I did try to find an answer to this issue already, but I'm not entirely sure what I'm searching for.
I currently have a working LabVIEW program which operates an electron gun by way of a NI USB-6501 card. Because of the nature of having a machine that shoots out a powerful electron beam, we want to make sure that if the controlling computer stalls or fails for any reason, we have a failsafe that can shut off the gun. Our current idea is to hook up an Arduino Uno to a pin on the USB-6501, and have LabVIEW generate a timed signal that the Arduino can read. If this signal fails (indicating the controlling computer has stalled or shut off), the Arduino triggers a power relay which is independent of the controlling computer, and shuts off the gun.
I understand that the USB-6501 operates on TTL signals, so the signal I want should be something along the lines of "output TTL high, wait 1 second, output TTL low, wait one second, repeat", but I have no idea how to go about programming that in LabVIEW. My first thought was to have it output a square wave using the "simulate signal" function, or to have it generate an iterative boolean signal using the "DAQmx write" function, but I don't really understand how to implement either idea, or if either idea would even work.
Any advice would be greatly appreciated.
Solved! Go to Solution.
I believe I found a similar example from about a year ago on the forums. Following that example, I implemented the attached code in the main body of my program. However, when I probed the chosen pin with a voltmeter, I did not see the ttl high / low sequence I expected to see - I didn't see anything at all, to be honest. And worse, the addition of this bit of code slowed down the main program to the point of being essentially useless.
Did I do something wrong here? Again, any advice is appreciated.
If it slowed down your main program, I guess you placed this code into your main loop (extra 1 s delay). Put it into separate independent VI for test, in LabVIEW everything is parallel
I do not know how the input task is configured in MAX (Refnum in). It might be correct, it might be not.
Check Help -> Find Examples -> Search -> Digital output -> Write Dig Channel.vi
The input task is just configured as writing a digital value to a single line (my chosen pin).
I put this code in my main loop, and also tried it in subloops within the main program, and no matter what it just adds on that one second time delay to my entire program.
Okay, I modified the example code and put it in its own VI as a test as per your suggestion. The attached modification DOES produce the TTL high/low loop that I want.
But now if I input it anywhere in my main code body, everything goes to hell. It completely stalls out the main program, and nothing works. I've attached that too so you can see the general structure (where loops are, etc), though I know it's probably going to be fairly unreadable. The four sets of things inside the case structure are subVI's composed themselves of a case structure with two other nested case structures - I have not tried inputting this code into those, only into the main body and the main case structure of the code.
Once you do THINK DATAFLOW everything falls into places! 😄
- You need to put that DO pulse VI in it's own loop parallel to your main VI!
- When you put that DO pulse generation in its loop ("arduino TTL low-high") you should put the CreateTask and StopTask outside of the loop: no need to create/stop the task in each iteration!!!
- Why are there coercion dots at the wait functions?
- Why are there bended wires? Do you know Ctrl-U?
- LabVIEW comes with a huge library of example VIs: did you examine all those DAQmx examples?
- Suggestion: Learn about "producer-consumer structures"!
First off, I just want to say that no, I had no idea about ctrl-U, and that it is the most beautiful frigging thing I have ever seen in my programming life. You have earned "hero" status for teaching me about this, haha.
I have no reason why the start-stop was within the loop, other than I was blindly following another forum post. Taking a step back, I realize this doesn't make any sense - I've changed it so the start/stop are outside the loop, and it works equally well, so thank you for the suggestion.
I have no idea why the wait functions have coercion dots. I looked it up and I understand now that those dots appear when there are issues with data types that don't match up? But all I've done is wire a numeric constant to the timer, and it does work, so I'm not entirely sure what that means, or if it affects my program in any meaningful way.
I put the loop parallel to my main loop and everything works smoothly now. I guess I don't really understand the data flow concepts in LabVIEW as well as I should - I will read up on them!
Thank you so, SO much for your help!!!
But all I've done is wire a numeric constant to the timer, and it does work
Yes, it works - in this case as intended…
Coercion dots mark places, where LabVIEW needs to convert datatypes. This conversion might work like you intended the VI to work - but it might not work as you think in other places.
How did you create the numeric constant? Do you know the easiest way to do this? Just right-click the input of the Wait function and select create->constant! This works with any input/output of any function/subVI - and this way you will always create a constant with the needed datatype…
I created the constant by going into the Functions palette --> Programming --> Numeric --> Numeric constant. I didn't know you could right click to create the constant of the correct type (I'm learning as I go, sort of a need-to-know basis rather than any formal training) - thank you for the tip!