06-05-2024 11:52 AM - last edited on 06-05-2024 12:59 PM by altenbach
Hi guys,
I wrote here a week or two ago about using a button to turn a light off, with that light having been switched on due to a magnetic field strength limit being exceeded.
When the level is within limits, the green light turns on (with DAQ analog output and solid state relay circuit). When the level is out of limits, the red light turns on with second DAQ output.
I managed to get the button to work in a test VI and have since put it into our main VI, which logs the data of all four magnetometers to a csv file, and only turns on during the day time (weekdays)
However, I need to also add a timer to it, so that when the level is exceeded, the red light turns on, and instead of it staying red until a user presses a button, it will ALSO turn from red to green if 30 seconds has passed.
I have tried to use several methods but I just cant figure it out. For example, I thought that when the level is exceeded, it will enter into a case structure, where 'True' gets the current time, and then wire this to a shift register, to be compared in the next loop iteration with the current time, and if the difference is greater than 30, it would turn the light off.
However, what happens instead is in the next while loop iteration, it just goes back into that case structure and updates the time again, so there is no difference obviously.
If this was Python, I could write
timer_started = False
start_time = None
while True:
if level_exceeded() and not timer_started:
start_time = time.time()
timer_started = True
if level_exceeded() and (time.time() - start_time >= 30😞
turnLightOff()
timer_started = False
This code would work, because it has a second variable called 'timer_started', which is initialised when you first start the clock, and it then restarted when you stop the clock. In my LabVIEW code, there is only one variable: level_exceeded. And I cant figure out a way to do a second 'variable' in labview.
I have attached my VI, the important code is on the far right, where you can see a 'get time' function being added on to 30.
Solved! Go to Solution.
06-05-2024 12:02 PM
We can't help if you post a password protected VI.
06-05-2024 12:17 PM
Sorry about that. This should be unlocked. Thank you for your help in advance. I know the VI is probably very badly written also.
06-05-2024 12:20 PM
@altenbach wrote:
We can't help if you post a password protected VI.
Another thing you should not do (unless you intend to propagate a "LabVIEW Virus" that does bad things to anyone who opens it) is to post a VI set to "Run when Opened" (as you did). Please don't do that!
Bob Schor
06-05-2024 12:21 PM - edited 06-05-2024 12:22 PM
Sorry Bob. I probably should have modified that before uploading to a forum. We do sort of require it to do that, it solved a problem for us in that windows update would force an automatic restart and data logging would stop. So we put the VI into windows startup folder and enabled that option.
06-05-2024 12:45 PM - edited 06-05-2024 12:51 PM
Sorry, This will have to wait until later, because my laptop screen is not big enough to efficiently look at it. I also don't have any DAQ installed, thus I cannot see how your assistants are configured.
Does the code even work? I see that you are opening a file, then use "ref to path" to write to a spreadsheet file, but that tool actually tries to open it's own reference to the same file, but since the file is already open I am not sure how well that will end. Why not use lowlevel IO instead? Your sequence structure s not really needed if you strategically place some wired dependencies. Why do you think you need to get the time twice in parallel in the first frame, once is probably enough (...you are allowed to branch the wire!) You can eliminate the "NOT" by swapping the cases of the outer case structure. I think everything would be much easier if you would replace all these inner loops with a simple state machine architecture having only an outer while loop. It is also somewhat dangerous having to abort the VI to end it, because that could leave the instrument in an undefined state. Some of your logic is a bit mind boggling, for example the following:
Once this is a clean state machine, implementing your led timeout requirements would be significantly simpler. Right now, nothing could ever happen on weekends. What if the LED goes on 25seconds before the weekend? Too many cats to herd!
06-05-2024 12:48 PM - edited 06-05-2024 12:49 PM
@Bob_Schor wrote:
Another thing you should not do (unless you intend to propagate a "LabVIEW Virus" that does bad things to anyone who opens it) is to post a VI set to "Run when Opened" (as you did). Please don't do that!
I did not notice! Thankfully mine opened broken because I don't have any DAQ, but that is definitely a bad habit 😞
06-05-2024 01:01 PM - edited 06-05-2024 01:06 PM
I will explain the logic behind the snippet of code you posted (boolean array to number, equal to zero, and NOT)
Inside the inner for loop (there are 2), there is a InRangeAndCoerce with a NOT after it. This returns true if the value of the magnetometer is outside of +-250.
However, the inner for loop is analyzing all 4 magnetometers at once, so it gives a 1D Boolean array of four boolean values. If all four are above 250, it would be T-T-T-T. If the first is but the latter 3 are not, it would be T-F-F-F. In both these cases, the 'boolean array to number' would not be equal to zero, only F-F-F-F would be (all 4 magnetometers in limit). So if any of the magnetometers are out of range, 'equal to zero' will be false, and then the NOT makes it true.
So if any of the four magnetometers on the inner for loop are out of range, the end result of the two for loops is true. Yes I know thats terribly written. But the for loops are used to write data to the file, and then this causes a boolean array, which I cant use in the code because I need a single boolean value.
Regarding your question of whether it works, yes it actually does. It logs all 4 magnetometers to a csv file. It also works turning the lights green or red. And it also works that if the level is exceeded, the light will latch onto red, and will stay red until you press a button.
Yes you are right, if the light goes red 25 seconds before the weekend, it will be on until monday morning 7am. Honestly I would probably just take that if it meant it would work now (30 second timer still doesnt work), I dont know how hard implementing a state machine will be but I will try.
06-05-2024 01:11 PM - edited 06-05-2024 01:12 PM
@lorc34 wrote:
So if any of the magnetometers are out of range, 'equal to zero' will be false, and then the NOT makes it true.
So basically the entire thing is just an "OR array elements", right?
(Also, your innermost case structure seems to only differ by two constants, so the DAQ should be after the case structure.)
06-05-2024 01:14 PM
Yes that is true I didnt know about that , it is exactly that