# simple RPM question

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
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
BJT wrote:

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.
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
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?
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>

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
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
BJT wrote:

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:
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
BJT wrote:

I think you took my code sample too litteral. Motors, encoders, and amplifiers vary so widely, there is no way you can speak in anything but generalities.
This line is key:
pwm_output = pwm_output + (error * GAIN);
The pwm_output is some arbitrary number that represents the duty cycle, how about if we write it this way:
pwm_output = pwm_outpt + count2pwm(error);
The point is that if the expected position is less than where it should be, you increase the duty cycle, if the expected position is more, then you reduce the duty cycle. The idea is that your system reaches equilibrium.
Now this is (obviously) not PID, it is a velocity control algorithm. PID is more geared towards velocity and position.