Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

PID control of Counters (PWM)

Hello everybody!!

 

I work on a closed loop PID controlled problem (Labview 8.5) and I have a couple of questions in order to make some progress!

Firstly, I have to declare that my loop is composed of 2 AI channels (2 accelerometers), 1 AO channel (excitation channel-shaker), and 2 CO (for pulse creation PWM-controllers). The idea is very simple. When the AI (channel 1) value surpass or underpass a predetermined threshold value, then the appropriate CO should be activated in order to apply the necessary control forces and simultaneously to copy my data values of both AI channels in binary style for CPU velocity reasons! BUT, with the PID controller I want to optimize the Duty Cycle value of the pulses!

My questions are :

 

1) Why when I put Kp=Ti=Td=0 ( = run WITHOUT control) I can copy ALL the AI samples and when I start to activate the PID controller (let’s say for only Kp=0.5) I CAN’T copy ALL the AI samples? Where is my fault?

 

2) About the PID vi which I use, is it correct or I should use the PID vi for ARRAYS?

 

3) And finally, about the Boolean statement just before the Case Structures and the Shift Register, is it ok/necessary?

 

I attach two vis, the ReadBinar .vi is used to read my binary files generated in the end of running of the Control.vi.

 

 

Best regards

 

Grigorio

Download All
0 Kudos
Message 1 of 10
(7,523 Views)

Hi Grigorio,

 

In regards, to your first questions, I'm not too sure what you are referring to.  The data that you are writing to binary file appears to be completely independent from your PID settings which are simply controlling the duty cycle of your counter output.  When you say that you can't copy all the AI samples, how many samples are you copying and how many samples are you expecting?

 

2) Whether you want to use PID for one single sample or for an array of data is up to you, depending on what you require for your set point, but currently you are reading multiple samples each time you call the DAQmx Read VI.  From this array of data, you appear to extract the very first point and are using this to calculate your PID.  So aside from displaying the array of data, and saving it to file, the rest of the data points are not affecting your PID control. 

 

3) Again, this depends on what you are trying to do whether it is necessary or not.  From the looks of it, you are only changing the duty cycle when the PID output falls within the tolerance range that you've specified.  And each tolerance range is set around the previous PID output.  And since this PID output is actually the duty cycle you are saying "I want only want to change the duty cycle if it is close enough to the previously set duty cycle.  If the duty cycle is 0.5, and my tolerance is 0.01, then if the next iteration provides a PID output of 0.6, that's too far from the 0.5 so don't change it. You'll have to decide if this is something you want.

Tejinder Gill
National Instruments
Applications Engineer
Visit ni.com/gettingstarted for step-by-step help in setting up your system.
0 Kudos
Message 2 of 10
(7,501 Views)

Hi Mr. Gill

 

First of all, I want to thank you for your kind interest for my problem! Now, about my first question, I know that the data I am writing to binary file seems to be completely independent from the PID, BUT I have pointed out that when I am running that VI and demending to write 15000 samples with 500 samples/sec, that means 30sec experiment duration, with putting Kp=Ti=Td=0 then it really writes to my binary file 15000 samples and when I put only, let's say Kp=0.5, then in binary files there are about 6500 samples!! A lot of samples are missed!! This is something strange, I think so and I have tried a lot to find it with no good answer up to now! Any idea about this?

 

About the second question, when you say 'From this array of data, you appear to extract the very first point...' do you mean that in real time I check EVERY single point whether surpasses or underpasses a predetermined threshold? That is what I really want, in real time I want to check every acquired point of acceleration in order to adjust the duty cycle as soon as possible! I don't want to collect some points (i.e. as in an array of points) and after a while to check all these points one by one, then I don't make control in real time, I think so. So, some points affect the PID and the duty cycle, the other ones (which don't surpass or underpass a predetermined threshold) just simply are saved to the binary file in order to complete the time history! I have to mention that I have 2 PID vis, because I have two controllers for my experiment, one for surpass a threshold and the other for underpass another threshold! Is that a problem? Two PID vis simoultaneously?

 

About the third question, I think that I do the inverse from what you say, because I make the boolean condition just before the case structure in order to change the duty cycle value when the previous one DOESN'T fall within tolerance range that I have specified (FALSE statement in Case Structure loop)!! And if the previous duty cycle value falls within a tolerance value then (TRUE statement in Case Structure loop) it is kept for the present loop the previous duty cycle value. So, is that statement useful/correct OR it is better to always change the duty cycle value for every loop (CPU velocity, control reliability ?)

 

Closing, what I only want is to check EVERY point acquired from one AI channel, and if it is surpassed or underpassed a predetermined value, THEN PID control (via PWM control forces) make some progress in order to bound the acceleration value (AI channel) acquired!! If it is necessary, please make any correction you think for improving my vi and send it back to me.

 

Thank you for your time!!

 

 Best regards!!!!

 

 Grigorio

0 Kudos
Message 3 of 10
(7,485 Views)

The only reason I could see how your file can be writing less points is if it takes more time to run through your while loop with gain settings of 0.5.  If you execution takes longer then less points get written before your loop stops (which is currently stopping based on the user pressing the stop button or when the Analog output task is done, whichever comes first)

Does this occur consistently at any PID setting that isn't zero?

 

If you want to ensure that you get 15000 samples everytime, you may want to set that up as your stop condition instead. 

 

You are not checking EVERY sample point.  Everytime you call the DAQmx read VI, you are pulling all the samples in the buffer and only checking the first point in that group of samples.  This could very well be suitable for you, but if you really want to check every single data point, you may want to consider only pulling a single sample each time DAQmx read is called.  Keep in mind that this may result in buffer overflow errors  so you may need to change your timing.

 

For your third question, you are certainly ensuring that you are only executing code when you need to.  of course you are also constantly polling to see what that Boolean value is equal to.  Again, speed is always subjective, but I certainly don't think it's hurting your application.  If you really wanted to get efficient, you could explore a master/slave design pattern.  That would involve moving your counter output tasks to 2 "slave" loops which only execute when triggered by the "master" loop.  That would as you could imagine involve some substantial rewriting.  So if your program is running fairly well, you should decide if it's in fact worth it.

 

Hope this helps!

Tejinder Gill
National Instruments
Applications Engineer
Visit ni.com/gettingstarted for step-by-step help in setting up your system.
0 Kudos
Message 4 of 10
(7,457 Views)

Dear Mr. Gill

 

Thank you for one more time for your valuable help on my problem!

 

For the first problem, I have pointed out that as the Kc, Ti and Td values grows up, the written samples are downsized! But, with only Kc=Ti=Td=0, I finally get the desired number of samples! One more fact is that when Kc, Ti or Td ≠ 0 then the number of loop iterations are LESS than the one when Kc=Ti=Td=0 ! What happens? I work on a 18-bit M-Series PCI card (PCI-6289, really fast).

 

About the second problem about the checked points, I have tried all the DAQmx Read.vi the selections DAQmx Read Analog 1D DBL NChan 1Samp, DAQmx Read Analog 2D DBL NChan NSamp, DAQmx Read Analog 1D WFM NChan 1Samp and DAQmx Read Analog 1D WFM NChan NSamp selections in order to achieve point by point check! I have also downsized the proffered number of samples from 15000 to 6000 and sampling rate from 500 to 200 samples per second for speed reasons with no such progress! What do you propose me now? I have two AI Channels and in one of them I want to check EVERY point if it is up or down of a threshold! In which ‘selsection’ of DAQmx read I must target on?

 

And about the third problem for the case structure, shift register and tolerance (comparing the present duty cycle value with the previous one) I have tried to get totally rid of case structure and shift register by constantly changing the duty cycle value with no comparison Booleans with the previous duty cycle value with no progress! Iget errors about the duty cycle value that cannot applied to the system but in the meanwhile I have previously limited that value in the output range of the PID.vi terminals! (0.05 to 0.95)!

 

Thank you for your time!

 

Best regards

 

Grigorio

0 Kudos
Message 5 of 10
(7,420 Views)

Hello,

 

Have you been checking your loop iterations to make sure that the behavior you are seeing is not expected based on your code? It looks like you are using the DAQmx Is task Done VI to stop the loop. Can you verify whether this is what is causing your iterations to be lower than expected? With your DAQmx settings, you have setup a Continuous Acquisition which means you will always have to read back more than one point. If you are wanting to process point-by-point, you need to setup a Hardware Timed Single Point Acquisition for your analog input as well. Once you do that, you can read back a single analog value. In terms of your comparison, I'm not entirely clear on what you are having trouble with. Can you be a little more specific?

 

-Zach

0 Kudos
Message 6 of 10
(7,396 Views)

Hello Zach!

 

First of all, I want to thank you for your kind interest on my problem!!

 

I must describe you the desired process with the Control.vi. There are two AI channels writing down the acceleration of a structure in two different points (for velocity reasons I use Binary Type storage for my data). One AO channel for structure sinusoid excitation (shaker) and two CO channels for controlling two solenoid valves with which I want to control my structure acceleration (minimize it as well and fast as possible)!!

 

In order to help the description, let’s ‘cut’ the block diagram of Control.vi into three pieces (Before While LoopInside While LoopAfter While Loop).

 

In Before While Loop section, the main question is about simultaneousness. The DAQmx Start inside the Flat Sequence Structure, do you think that is necessary, ok? I want to run my experiment for 30s and to collect 6000 samples with 200 samples/s. In addition, in the CO DAQmx timing, I have set 200 samples/channel in order to be able to change the duty cycle value because of the conditions inside the While Loop. Do you think that everything in this section works well? 

 

Inside the While Loop, firstly in the DAQmx Read, I have set 200 samples per Input Channel, which is also equal to the AI and AO Sampling rate! Before some days I have put there -1 and unfortunately the total written samples were less than 6000!! My main problem is how I can check all the read data without losing run velocity and simultaneous if one sample is >0 then it goes further to the first PID.vi (left solenoid valve) or if that sample is <0 then it goes further to the second PID.vi (right solenoid valve)!! When a sample has gone to a PID.vi, then I want to tune the duty cycle of the controller (PWM control) as well as possible in order to achieve the Setpoint value for the second AI channel. Are all these possible? If not, what do you suggest me?

In addition I compare the present duty cycle value with the previous one in order to be inside a tolerance value (let’s say 0.1). Moreover, is it correct the Case Structures where I want to share the positive and negative AI samples before going to the respective PID ?

 

Finally, After the While Loop, I believe that everything is OK. I just finish all the tasks.

 

I have to mention that I work on a PCI-6289 and Labview 8.5.

 

With best regards!

 

 Grigorio

Download All
0 Kudos
Message 7 of 10
(7,370 Views)

Hello,

 

In your code, the sequence structure doesn't actually do anything for you because of data flow. You have already connected the error wires so the sequence structure becomes redundant. I'm not sure why you changed your countout output from hardware timed single point to continuous. If you put a -1 in your DAQmx read, it will only read the samples currently available so your number will change every time - this is expected behavior. Do you want your loop to be doing things point by point or in chunks of data?

 

-Zach

0 Kudos
Message 8 of 10
(7,344 Views)

Hello Zach!

 

The truth is that I can't really understand your first two sentences of your reply (i.e. In your code, the sequence structure doesn't actually do anything for you because of data flow. You have already connected the error wires so the sequence structure becomes redundant.) Please, can you eplain a bit more?

 I have changed the countout output  from hardware timed single point to continuous in order to be able to change continuously the duty cycle value! With hardware timed single point, the vi resulted in error and after changing that it was corrected. I would like to read as many points as possible in order to the information resulted will be adequate to extract correct decision about the control (i.e duty cycle of PWM) (Nyquist sampling theory). Don't forget that my structure is sinusoidally excited with frequencies from 1.5 to 3 Hz so the number of samples / second controlled is crucial. So taking into consideration, CPU velocity, PCI  capabilities and of course signal resolution, what do you think about that? Point by point or small chunks of data?

 

With best regards

 

Gregorio

0 Kudos
Message 9 of 10
(7,330 Views)

Hello,

 

Data flow means that a function cannot proceed to the next one until all inputs and outputs are satisfied. Since you have your error wires connected, those are inputs that must be satisfied before a function can run - which results in a serially defined execution. Sequence structures do the same thing when error wires or other inputs are not available for a particular function. If you are truly wanting to process your signal in real time as it comes in, point by point is the preferred method when possible. If you cannot achieve fast enough data rates or losing data points is acceptatble, then continuous will work.

 

-Zach

0 Kudos
Message 10 of 10
(7,292 Views)