04-21-2009 01:49 PM
Ok so what I'm trying to do is using LabVIEW 8.0 and a USB 6008 is use a photoresistor to begin rotating a DC motor when it is in the dark and stop motor function once it is exposed to light. Only after the motor has stopped moving do I then want a linear actuator to deploy. Separately all programs work as they should and I have been able to successfully integrate the photoresistor and motor function. What I cannot do is get the actuator to deploy after the motor has reach its designated position.
I was planning on using a stacked sequence structure so that I ensure that the actuator fires only after the motor has finished its task. Since I need to have the photoresistor and motor in a while loop to make sure they are constantly looking for the data telling them what to do, I have them placed in the while loop and the motor portion of the code within a frame of the stacked sequence. Once the motor stops, I then pass the data forward to the next frame which is just a boolean wire which then exits the sequence structure and while loop to give the voltage necessary to control the actuator. This is however not working, the motor continues to ork in synch with the resistor but the actuator won't fire. I'm wondering if there's something wrong with my attempt to pass data out of the while structure. As I read about stacked sequences, it seems that many people don't like to use them because they don't function properly at time so I'm wondering if there's a way to avoid using one but to ensure that the actuator will not fire unless the resistor has guided the motor into position.
I've attached the code to help with an understanding of the program.
I'm using an H-bridge to allow for forward and reverse motion which is why you will see a 3x1 matrix in the case structure.
Thank you!
Solved! Go to Solution.
04-22-2009 12:34 PM - edited 04-22-2009 12:35 PM
Hi leannee,
In this case, the stacked sequence isn't really accomplishing anything--the issue is with how you are passing data out of the while loop. Using a tunnel, the data will not exit the loop until the while loop has finished running. So, the case structure is not executed until the while loop stops, at which point it will use the most recent value of your boolean.
What I would do is move the actuator code inside the main while loop, so you can check if the motor has stopped as the code is running (see below). If you only need to run the actuator code once, you could use the First Call? function in LabVIEW (Data Communication >> Synchronization in the pallette). You would not need to use the sequence structure in this case.
-John
04-22-2009 02:34 PM
Hello John P,
Thank you for your response. I realized that as I was wrapping up last night too, it's good to hear that my thinking was correct. After fixing that however, I realized that I now have another problem. Since the photoresistors are constantly giving the case structure the "go ahead" signal, the actuator is constantly firing unless the motor is functioning, and thereby inhibiting its motion due to the case structure parameters. Since I need the program to be constantly running, I'm not sure that the First Call? function will work. I need to have a user enter a numeric input to activate one sensor which will start the motor rotating until it reaches it's destination. The user's input should come from within the while loop, correct? Or is that not necessary? If the answer is the latter, the first call? function should work, right?
I've also tried investigating another option to eliminate the constant "go" signal passing through the motor and into the actuator programming. Since I'm effectively looking for a negative change in voltage from the photoresistor to indicate that the motor is in position I thought that I could simply take the derivative on the constant voltage reading coming from across the resistor and then using a "less than 0" comparison only allow a negative derivative to pass along to input to the actuator's case structure allowing it to function. However, I'm not seeing a dX/dt other than 0 when I tried this method. I'm wondering if this is because I'm only taking a voltage reading of -0.73 or 0.81, both of which are constants and should have a derivative of zero. I thought that the function would be taking dx(t)/dt and therefore should work, but perhaps I am mistaken. Do I need to somehow start a timing sequence in order to see the change in voltage over time that is needed to trigger the actuator?
Thank you very much for your help
Best,
Leanne
04-22-2009 06:21 PM - edited 04-22-2009 06:22 PM
Hi Leanne,
You could use some digital logic to check for a change in value, as well as the value itself. In the example below, I did this with a Feedback Node which stores the value of the digital line from the previous loop iteration:
Since we are looking at sampled signals, we can approximate the derivative by looking for the difference from one iteration to the next. I think this is what you need to do but let me know if otherwise. Have a great evening!
-John
04-23-2009 12:23 PM
Hi John P,
Your solution worked! I can't thank you enough for your input. I just have one point that needs clarification. In LabVIEW 8.0 the initializer terminal is only in the border of our while loop and we couldn't figure out how to move it into the loops where the feedback node is contained. We needed to modify the signal that goes into the y value of the "and" logic function so that only false data goes into the function (b/c we don't want the actuator firing unless the light signal from the photoresistor is present AND there has been a negative change in voltage. I don't think this was necessary because we didn't use the initializer terminal, but could it have been?
Thanks Again,
Leanne
04-23-2009 01:36 PM
Hi Leanne,
I am not sure if you can move the initialize terminal of the feedback node in LabVIEW 8.0. Regardless, the functionality is the same since this only initializes the feedback node the first time the code is called. If you don't use the intialize, the feedback node will retain whatever value it had from the last time your code was run and will only re-initialize (to False) when you restart LabVIEW.
You probably have a better idea than me of when you want the actuator to fire, and it sounds like everything is working properly so I am not sure if you need to worry too much about the initialize input. I had initialized the feedback node to false to avoid the possibility of the actuator firing when you first start the code and the motor is idle (if the previous value of the feedback node was True).
-John
04-27-2009 02:18 PM
Hello John P,
We have now perfected our code thanks to your help and the program roughly runs how it should, when it should. However, there is a huge time delay between the presentation of the light and the sensor's subsequent stop signal to the motor. We're talking about an almost complete extra rotation by the motor before it comes to a complete stop and the actuator can fire. I'm wondering if the computational load is very heavy now that we have added a feedback node to the code and if the two case structures we have present also are slowing down the program.
Also, what options do we have that can help to increase the speed of program execution? Our device loses all of its use if it cannot react wuick enough in real time.
Thanks Again,
Leanne
04-27-2009 02:41 PM
I just realized that I should probably attach the complete vi.
Thanks!
04-28-2009 10:47 AM
Hi Leanne,
The extra functions added to your code may technically slow down the loop, but I don't think this is the major issue. Your application is performing the following steps:
Of these four steps, only the first is done in hardware. The other three steps (including the USB data transfers) are at the mercy of the operating system and are inherently non-deterministic. Ideally we would want the entire application to be done in hardware.
Unfortunately, the USB-6008 is an introductory board and does not have the capability of outputting a direct signal without going through the OS. Many of our boards (such as the M series) have built-in comparators used for analog triggering and can output a digital signal without going through steps 2-4 above. You could also make this yourself using a comparator (wikipedia link).
Given the restriction of software-timed output, you might want to try using On Demand sampling instead of Continuous (simply remove the DAQmx timing function) for your input as well. You are currently sampling at 1kHz, but are reading 1 sample at a time from the buffered acquisition. You may be lagging behind if the loop is not running at least 1000 times a second. Also, the 6008 will be transferring much more data back to the computer over USB when running at 1kHz which could introduce more latency. It looks like you only need a single sample for what you need to do anyway.
There are also some redundancies in the code (for example, if(bool==true)). I can't imagine that correcting them would offer any noticeable performance increase, but then again I'm more of a hardware guy so it might be worth a shot.
Out of curiosity, how much time does it take between the light source and the motor response?
-John
04-28-2009 12:59 PM
Hello John P,
Thanks for your input! We actually removed one of the redundencies and it helped to speed up the sensor motor integration to a very very noticable extent. Now that we added the actuator back in we're seeing poor performance again and we're pretty sure that it's due to the feedback node. We changed it to a shift register which is supposed to run 3-4x faster and we do see this change for the first time the while loop executes. After that it gets increasingly slower and slower which must be due to the increasing amount of data being stored as the loop executes continuously. Is there a way to purge the memory of the feedback node's iterations after each iteration of the while loop?
Thanks,
Leanne