LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

precise height control using motor and a 10turn pot

Hi, In my project, I have to set an object to user set height precise to millimeter. The setup is a vertical guiding shaft on which the object is moved up or down with a steel wire connected to a motor. The height is sensed by a 10 turn pot that gives different voltages for different heights.

 

Basically i'm reading the voltage from pot (Analog input- 1k sampling buffersize-20)

depending on whether object should move up or down turn the motor in required direction

continuously reading height voltage and when desired height is reached, switch off the motor through relay (digital output)

 

this is working except the system is not precise to the millimeter as required..few centimeter off

 

there is some delay I'm unable to understand..- either in acquiring analog voltage or stopping the motor 

 

In the program, i'm averaging height voltage since it was not stable. I tried using some multiplication factor and constants to adjust for the delay...it is not consistent... 

 

suggestions and advices are very appreciated..

Thanks

Thanks...

Pallavi
0 Kudos
Message 1 of 17
(2,772 Views)

Hi Palchan,

 

There are quite a lot of things wrong with your vi. The first thing i noticed was that on each iteration you are inserting an element into an uninitialised array. This is causing the array to get larger and larger, yet you only need the last 10 values. Insert into array causes LabVIEW to constantly re-size the array and as such allocate new memory to store it, this is very time consuming. As the array gets larger and larger it will become slower and slower. As you only need to store ten values then you should implement a circular buffer. I actually have written one of these that will do this job for you and will attach it at the bottom.

 

Secondly, why are you using local variables for everything when you can simply use the terminals? The algorithm you are using to calculate whether to go up/down or stop can also be simlified (i will attach an example of how that incorporates the circular buffer for you to use below).

 

Looking at your DAQ express vi it seems as though you have set it up at a sampling rate of 1Khz and you read 20 samples per iteration but you convert the dynamic data type to read only the last read data, is this your intention. If you set it to convert to a 1D array you will read the last 20 reads instead of just the 1?

 

You are using a sequence structure that is not needed. Just use the error cluster terminals to force order of execution.

 

As you are averaging your readings then you will inherently get a delay depending on how large the data set is your averaging. The bigger the data set the bigger the delay. Obviously the speed of the motor will also effect the error. How noisy is your input? Have you tried using a simpe RC filter? or even a software filter to try and smooth out the noise.

 

Another point. As you are only averaging the last read value instead of all the 20 available, and you are averaging over 10 reads then it will take approx 500ms for you to get your required reading. This is because you are reading 20 samples at 1kHz, which should cause your loop to iterate at about 50ms. Why dont you instead get all the 20 last elements and instantly average these, this should average out the noise in these 20 elements and you may be able to get your reading in 1 iteration.

 

I have attached a simplified version of what you are trying to achieve to better explain. I have attached a circular buffer. I believe you might not actually need this. On the vi i have shown how to use the circular buffer if needed but also how to get the averaged value of the whole 20 elements available every iteration. I havent been able to test this as i dont have any of the hardware so there may be a couple of bugs for you to iron out but it will hopefully point you in the right direction.

 

Rgs,

 

Lucither.

------------------------------------------------------------------------------------------------------
"Everything should be made as simple as possible but no simpler"
Message 2 of 17
(2,756 Views)

Palchen,

 

Have attached another version where you can choose between the circular buffer and the instant average of the last data set.

 

Rgs,

 

Lucither

------------------------------------------------------------------------------------------------------
"Everything should be made as simple as possible but no simpler"
0 Kudos
Message 3 of 17
(2,744 Views)

Hi Pallavi,

 

In addition, I would also like to suggest you to ramp up and ramp down the motor while starting and stoping, to get more accurate result. A small logic needs to be built for that.

 

Regards,

 

Prashant

0 Kudos
Message 4 of 17
(2,740 Views)

That's a good point. Was going to mention that but it looks like his output is just a digital on/off. Do you have any speed control Palchen? Also realised that i made a mistake in my maths earlier. Your iteration loop should be every 20ms not 50ms.

 

On the example i have given you, change the circular buffer from 200 elements to 40. This will be a better test. This is 2 iterations worth. You then have 2 examples the immediate average of 1 iteration of data and then 2 iterations. If either of these don't give the required results you can then up the elements in the buffer. Go up in multiples of 20 (or however many elements you read per iteration if changed).

 

Rgs,

 

Lucither.

------------------------------------------------------------------------------------------------------
"Everything should be made as simple as possible but no simpler"
0 Kudos
Message 5 of 17
(2,728 Views)

Pallavi,

 

In addition to the programming issues discussed by others who have responded, I see several design issues which may be factors.

 

1.  What is the resolution of the pot as a measuring system?  Many 10-turn pots are wire wound construction and have finite resolution.  You did not say how far the total travel is in your system.  While not too likely, it is possible that your potentiometer may not produce a signal resolvable to 1 mm.

 

2. How fast does the system move?  In particular how long does it take to move 1 mm?  This determines how fast the system must respond.

 

3. How long does it take to read data from your sensor?  This has been discussed in some of the responses regarding averaging.  How long does it take to do the calculations (including  filtering and comparing to setpoint)?  How long does it take to write a stop command to the motor?  How much time is allowed for OS latencies?  The OS is involved in this at least twice for each cycle, once to read from the DAQ and once to write.  How long does it take the motor to stop after the command is written to the DAQ?  Is the sum of these times smaller than the time to move 1 mm?

 

I have found (through hard experience) that precise positioning via a desktop OS is better done in hardware.  Use a D/A converter to generate a setpoint voltage.  Use a hardware comparator to compare the voltage from the pot to the setpoint.  Stop the motor when the comparator fires.  Use the A/D inputs to double check after the motor has stopped.  Make small corrections if necessary.

 

Lynn

 

Message 6 of 17
(2,703 Views)

 


@Lucither wrote:

 

Secondly, why are you using local variables for everything when you can simply use the terminals? The algorithm you are using to calculate whether to go up/down or stop can also be simlified (i will attach an example of how that incorporates the circular buffer for you to use below).


In particular there is a serious race condition, because you write to "actual height" at two places in parallel and the outcome will vary depending on which location gets the new value first.

 

Message 7 of 17
(2,686 Views)

It also appears that the loop will execute one time after high limit becomes True or after the height calculation generates a selector value less than 1, but will stop in the current iteration if ABORT is True.  The motor up DAQ VI in the final case structure only executes if ABORT is True.  The other motor up VI may take care of the other cases but it is not clear what happens on that extra iteration.

 

It looks like you need to give some thought to what you are trying to do and make sure that your program actually matches your requirements.

 

Lynn

0 Kudos
Message 8 of 17
(2,665 Views)

Thanks all for your replies..Its very helpful..

 

@ lucither: I now see my error at averaging the data... thanks for explaining..I have been stuck at this averaging for sometime now...

The aim was to do a moving window average and for that purpose as you have mentioned circular buffer seems like a good idea. I had not thought of it before. 

 

(could you please send the vi's in 8.5 version of labview? I could not open both versions you've sent)

But now looking at the error, if I average the 20 points directly out of the 1D array that may suffice.

 

 

@prashanth: I do not have control over motor speed I'm only switching it off and on 

 

@ johnsold: I'm using a 10K 10turn pot, the resolution is somewhere around 0.62v /meter (the max height is about 3meters)- so its about 0.62mv/ mm.

 

I have not recorded the time it takes to move 1mm but its definitely few seconds ( 10-15s) to move 1meter. I'll check the time when i'm in the experiment facility this week. 

 

The other delays you've mentioned- response time of sensors and OS is there a way I can find out these delays?

Actually to counter these delays, a scaling factor was introduced- the idea was to see if the height error is in a linear fashion so then using a linear equation mx+c (m-scaling factor, c-offset for object height itself) it can be counteracted. This helps to reduce the error by 120mm to 20-30mm. but that is it.

 

@altenbach : Is there a way to control which local variable gets updated first?

 

Thanks...

Pallavi
0 Kudos
Message 9 of 17
(2,603 Views)

One more suggestion is required. Currently all the variables (avg, offset, slope etc) are double with 6 precision points.

 

How to round the variable to 2 precision points?

 

tried using fixed point in numeric-conversion palette but unable to change the "range " ( I can only vary word length and integer word length- that doesn't give the exact values I want).  This will help to avoid some unnecessary math (multiplication by 1000 and then dividing by 1000 later) in the program

 

Thanks

 

Thanks...

Pallavi
0 Kudos
Message 10 of 17
(2,596 Views)