LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Controlling Motor RPM with PID control

Solved!
Go to solution

Hi everyone,

 

I am trying to operate a BLDC motor (1960KV) at a desired RPM. The actual motor RPM is measured using an optical quadrature encoder (720 CPR). The encoder comes with four wires: 5VDC, DGND, Channel A and Channel B. I am using NI USB-6218, 2022 Q3 labVIEW with Win 11 Home. 

 

1. When set to run at a particular RPM (say 4000), the motor initially gets to the setpoint, but the measured RPM fluctuates between 3700-4400 (shown in image-1). Is there a way to reduce these fluctuations?

2. While operating at the same set point of 4000 RPM, the motor randomly jumps between the range of 4000-14000 (image-2 and 3). This is probably in response to the noise in the input signal. Is there a way to smoothen the response of the motor so that it gets to the setpoint value without abrupt movements, and then stays there (no follow up jitters)?

3. Do I need to apply some sort of filter to the measured data from the encoder before it is provided as process variable to the PID controller?

 

Please let me know if you need any additional info.

 

Thanks.

lza

0 Kudos
Message 1 of 13
(1,266 Views)

Hi Iza,

 


@laz_2331 wrote:

I am trying to operate a BLDC motor (1960KV) at a desired RPM. The actual motor RPM is measured using an optical quadrature encoder (720 CPR). The encoder comes with four wires: 5VDC, DGND, Channel A and Channel B. I am using NI USB-6218, 2022 Q3 labVIEW with Win 11 Home. 


Would you mind to downconvert your VI to LV2021 or LV2019? (File->Save for previous)

 

How do you read the encoder data?

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 2 of 13
(1,252 Views)

Hello GerdW,

 

Thank you for your response. 

 

I have attached the VI. I hope it works.

 

I am counting the rising edges for the encoder.

 

Thanks,

lza

 

 

0 Kudos
Message 3 of 13
(1,227 Views)

Hi Iza,

 


@laz_2331 wrote:

1. When set to run at a particular RPM (say 4000), the motor initially gets to the setpoint, but the measured RPM fluctuates between 3700-4400 (shown in image-1). Is there a way to reduce these fluctuations?

2. While operating at the same set point of 4000 RPM, the motor randomly jumps between the range of 4000-14000 (image-2 and 3). This is probably in response to the noise in the input signal. Is there a way to smoothen the response of the motor so that it gets to the setpoint value without abrupt movements, and then stays there (no follow up jitters)?

3. Do I need to apply some sort of filter to the measured data from the encoder before it is provided as process variable to the PID controller?


  • The shift registers aren't initialized and can introduce problems when starting the VI a 2nd time…
  • What's the point of building an array from exactly one sample and then calculating the Mean from that value? (You may try PtByPt-Mean instead…)
  • Do you really run the loop at 20ms iteration time? I guess there will be some jitter as you also call DAQmx two times in the loop with your USB-connected device…

Applying a filter (most often low-pass) on the pv will introduce an additional lag that you need to handle with the PID, too. From my experience: this quickly gets tricky! (I sometimes used a median filter with 5 samples when sampling at 100 Hz…)

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 4 of 13
(1,214 Views)

GerdW,

 

I have added shift registers and PtByPt-Mean to the VI. 

 

About the 20ms iteration time: I am not entirely sure what is a good value here. I have seen significant changes in the encoder output when I scan the range of 'milliseconds to wait' from 10ms upto 1000ms. The encoder output sees lesser jitters as the wait time increases, also the amplitude of fluctuations reduce (image attached). At this point, I would just go with a higher wait time. But, is that technically the right thing to do? I would appreciate it if you could point me towards understanding that part better.

 

Thanks,

lza

 

0 Kudos
Message 5 of 13
(1,180 Views)
Solution
Accepted by topic author laz_2331

Hi Iza,

 


@laz_2331 wrote:

I have seen significant changes in the encoder output when I scan the range of 'milliseconds to wait' from 10ms upto 1000ms. The encoder output sees lesser jitters as the wait time increases, also the amplitude of fluctuations reduce (image attached).


An encoder gives you discrete signals, it only can output full pulses.

When you use a smaller delay a small difference in counts has greater impact than for a longer delay.

Example: Let's say there is one count per millisecond. So you will get 20 counts in 20ms and 1000 counts in 1000ms. A small variation of ±2 counts relates to ±10% difference at 20ms and only ±0.2% for 1000ms… (*)

 

So general rule: measuring for longer delays will improve the frequency measurement. (In the end longer delays will act similar as a lowpass filter.)

 

BUT: longer delays will also influence your PID control as the PID cannot react as soon/as often to pv changes. It's a huge difference if the PID can react each 50ms on a new pv value - or only each 1000ms!

 

Suggestion: you need to find a good compromise between encounter measurement and PID control behaviour. What about 250ms iteration time? This will give you 4 encoder readings per second…

 

(*) more exact calculation:

4000 rpm * 720 ppr * 1min/60s = 48´000 pulses per second = 48 kHz

48kHz * 20ms = 960 pulses, 48kHz * 250ms = 12000 pulses.

A variation of ±10 pulses will result in ±1% difference for 20ms and ±0.08% for 250ms…

 

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
Message 6 of 13
(1,167 Views)

GerdW,

 

Thank you for the explanation. I have some follow-up questions:

 

1. There will be some variation of the counts from the encoder (I am assuming this is more mechanical than an acquisition problem), so it is ok for the RPM output to fluctuate a bit?

2. At 4000rpm and with a specification of 720 CPR, the encoder pulse frequency is 48kHz? Is it the same as the sampling frequency? I am confused what the 4 RPM readings per second (4Hz) is then? I can see that I get four values of RPM per second based off of the 250ms wait time. 

3. How do I ensure that when the RPM is set to 4000, the process variable should not exceed ±1% (other than using longer wait times)? Can I apply a Band Pass Filter to the RPM values before they are fed to the PID controller? The filter asks for sampling frequency, and low/high cutoff frequency which I am still not clear about.

 

I have attached two images, one where the PID output stays within the ±1% (without using any filter), but exceeds this limit a few seconds later. These are at 250ms wait time as you had suggested.

 

Thanks again,

lza

 

Download All
0 Kudos
Message 7 of 13
(1,155 Views)

Hi Iza,

 


@laz_2331 wrote:

1. There will be some variation of the counts from the encoder (I am assuming this is more mechanical than an acquisition problem), so it is ok for the RPM output to fluctuate a bit?

2. At 4000rpm and with a specification of 720 CPR, the encoder pulse frequency is 48kHz? Is it the same as the sampling frequency? I am confused what the 4 RPM readings per second (4Hz) is then? I can see that I get four values of RPM per second based off of the 250ms wait time. 

3. How do I ensure that when the RPM is set to 4000, the process variable should not exceed ±1% (other than using longer wait times)? Can I apply a Band Pass Filter to the RPM values before they are fed to the PID controller? The filter asks for sampling frequency, and low/high cutoff frequency which I am still not clear about.


  1. After all its a noisy measurement so you cannot avoid fluctuations! (The motor will not rotate at an exact speed, the iteration times of your loop will vary, and so on…)
  2. The pulse frequency is ~48kHz at 4000rpm. The counter itself can count much faster pulse trains (typically at 10MHz for NI USB boards). The 4Hz samplerate only defines how often you read the current counter value…
  3. You cannot "ensure" a fixed pv value - that is a measurement value! You only can improve the control behaviour to achieve a rather stable pv value.
    And no, I would NOT apply a bandpass filter on a pv value! I would only recommend either median filters (to remove short spikes) or lowpass filter (to damp high-frequency noise)…

@laz_2331 wrote:

Can I apply a Band Pass Filter to the RPM values before they are fed to the PID controller? The filter asks for sampling frequency, and low/high cutoff frequency which I am still not clear about.


When you don't know how a bandpass filter works then you should not use them…

 

On your VI:

  • Why do you divide the PID output by 2000? Why is the PID output range set to 940…2000 when you need duty values of 0.47…1.0?
    You should set the correct output range and simply change the P gain to produce the correct output values! (When you use P=0.02 to output values in 940…2000 range then a P=1e-5=0.02/2000 will fit for the 0.47…1 range!) You can implement any scaling from pv units to output units with the correct P gain…
  • Why is "Encoder RPM" still an array indicator? It (still) doesn't make sense to build an array of exactly one element…
  • The shift register to hold the millisecond timer value is initialized incorrectly! The first iteration of your loop will give a huge "delta t" value: use TickCount to initialize the shift register!
Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 8 of 13
(1,136 Views)

Make yourself a mental note to come back to this later.

 

A counter can also be used to measure encoder frequency *directly* in hardware with < 1 msec measurement time and < 0.1% error.  But there are some caveats, and the associated work-arounds aren't trivial if you're somewhat newish to LabVIEW, DAQmx in general, and Counter/Timers in particular.

    For now, work on squeezing out the best performance you can with your current software-timed loop and GerdW's excellent help.  It may be good enough that you don't need to optimize further.  (Besides, some of the workarounds could include a fallback plan similar to your current approach, so you'd want to make it as good as possible anyway.)

 

When the time comes, this old post of mine can be a template for a more robust task config.  Even though it illustrates an AI task, most of it will apply similarly to a CTR Freq task. 

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 9 of 13
(1,120 Views)

Thank you GerdW. 

 

Here are the corrections I made:

Used 250ms wait time, 

Initialized shift register using tick count,

Adjusted the PID output limits

Applied a median filter to PV.

 

Sample output attached.

 

Thank you Kevin. This will take a bit of understanding, but I will look into it once I get there.

 

lza

0 Kudos
Message 10 of 13
(1,089 Views)