If you were Registered and logged in, you could reply and use other advanced thread options
|
Posted by BJT on March 14, 2005, 2:09 pm
I am working on a motor control project and i have a simple question.
The QEI i am using is a 16 bit register, and it will increment
everytime the encoder counts. The encoder i am using has a 200 cpr
(counts per revolution). So if the wheel spins 1 revolution, the QEI
register should have a value of 200.
Using this logic,
#revolution = total_counts / cpr
and RPM = #revolution / min
So, RPM = total_counts / cpr / min
However, i have a couple of questions. First, how do i set up the duty
cycle of my PWM signal? For example, If i want a 80 RPM for my moter,
and i am using a PWM period of 2kHz, what would the duty cycle be?
Second, what is prescale for, do i need it?
thanks for the help,
ben
|
|
Posted by mlw on March 14, 2005, 4:15 pm
BJT wrote:
> I am working on a motor control project and i have a simple question.
> The QEI i am using is a 16 bit register, and it will increment
> everytime the encoder counts. The encoder i am using has a 200 cpr
> (counts per revolution). So if the wheel spins 1 revolution, the QEI
> register should have a value of 200.
> Using this logic,
> #revolution = total_counts / cpr
> and RPM = #revolution / min
> So, RPM = total_counts / cpr / min
>
> However, i have a couple of questions. First, how do i set up the duty
> cycle of my PWM signal? For example, If i want a 80 RPM for my moter,
> and i am using a PWM period of 2kHz, what would the duty cycle be?
> Second, what is prescale for, do i need it?
There is *no* standard duty cycle that will ensure the RPM that you want.
If you've read any motor control text, you usually see PID algorithms
referenced. I'm sure you can find a good book in the library, but the short
form (VERY simple velocity control) is:
// Express rotation as counts, its easier
// Assume a fixed interval for each sample 1/10 of a second
// (This saves time calculations)
// Deal with converting rotational counts vs RPM somewhere else.
int target_counts = 20; // Target count 1/10 of a second
int read_counts = counter(); // Read counts
// Calculate error
int error = target_count - read_count;
counter_clear(); // Clear counter for next read
// Calculate power
pwm_output = pwm_output + (error * GAIN);
<<<<<<<<<<<<<<<<<<<<<<<<
Now, if target_counts is greater than read_counts, then the error will be
positive and a wider pulse width will duty cycle will be sent to the wheel
making it go faster. If target_counts is smaller than read_counts, the the
error will be negative and reduce the duty cycle.
As long as you sample fast enough, some good number of times a second, then
the small adjustments of +- a count over time, will pretty much average out
to your RPM target.
This is a very CRUDE algorithm which will accumulate positional error from
sample to sample, but I hope it helps point you in the right direction.
|
|
Posted by BJT on March 14, 2005, 4:54 pm
Thank you for your reply, i was writing some PID code myself for my
control system. I do have one last question. According to your code,
the unit of "error" is counts. And i guess the unit of "pwm_output" is
the duty cycle. "GAIN" is for the P_gain.
But how can you add a duty cycle to counts? (pwm_output = pwm_output +
(error * GAIN)) is that how you do it?
Other question, since the PID control is a continous process, an
interupt will be needed. How often should the interupt occur?
|
|
Posted by Mark Haase on March 14, 2005, 5:09 pm
> Thank you for your reply, i was writing some PID code myself for my
> control system. I do have one last question. According to your code,
> the unit of "error" is counts. And i guess the unit of "pwm_output" is
> the duty cycle. "GAIN" is for the P_gain.
> But how can you add a duty cycle to counts? (pwm_output = pwm_output +
> (error * GAIN)) is that how you do it?
> Other question, since the PID control is a continous process, an
> interupt will be needed. How often should the interupt occur?
You have to think of GAIN as a parameter that converts the error from a
number of counts to a time representing the difference between the
desired positive pulse width and the current positive pulse width. Keep
in mind that you don't really know what the desired positive pulse width
is (if you did this would be a trivial problem), but knowing the error
as a unit of time suffices because you *do* know the current pulse width.
At the same time, however, GAIN also adjusts how strongly the system
reacts to error.
--
|\/| /| |2 |<
mehaase(at)sas(dot)upenn(dot)edu
|
|
Posted by the Artist Formerly Known as K on March 14, 2005, 5:31 pm
BJT wrote:
> Thank you for your reply, i was writing some PID code myself for my
> control system. I do have one last question. According to your code,
> the unit of "error" is counts. And i guess the unit of "pwm_output" is
> the duty cycle. "GAIN" is for the P_gain.
> But how can you add a duty cycle to counts? (pwm_output = pwm_output +
> (error * GAIN)) is that how you do it?
> Other question, since the PID control is a continous process, an
> interupt will be needed. How often should the interupt occur?
>
The code you were given earlier assumes that samples are taken every
1/10 second. You can use whatever interval works best for your
application, however.
Note that there's no requirement that an interrupt occur at all on the
sampling side, provided you know how much time has elapsed since the
last sample. You may then adjust the count based on the actual elapsed
time. Provided you have a reasonable timer interrupt mechanism, however,
you may find it easier just to use an interrupt.
Finally, be aware that the code given earlier is not actually PID --
it's merely 'P' (Proportional), and is often "good enough" for many
applications. I'd recommend trying simple proportional control before
adding integral and derivative components.
--
(Replies: cleanse my address of the Mark of the Beast!)
Teleoperate a roving mobile robot from the web:
http://www.swampgas.com/robotics/rover.html
Coauthor with Dennis Clark of "Building Robot Drive Trains".
Buy several copies today!
|
Related Posts
Latest Posts
|
|
> The QEI i am using is a 16 bit register, and it will increment
> everytime the encoder counts. The encoder i am using has a 200 cpr
> (counts per revolution). So if the wheel spins 1 revolution, the QEI
> register should have a value of 200.
> Using this logic,
> #revolution = total_counts / cpr
> and RPM = #revolution / min
> So, RPM = total_counts / cpr / min
>
> However, i have a couple of questions. First, how do i set up the duty
> cycle of my PWM signal? For example, If i want a 80 RPM for my moter,
> and i am using a PWM period of 2kHz, what would the duty cycle be?
> Second, what is prescale for, do i need it?