Encoder Counts/time period to PWM value

Hey guys, I have no clue how to do this. How do I convert the number of counts I receive from the encoder over a given time period to a corresponding PWM value?


Well, what does the encoder count tell you? It can tell you how far you’ve gone. So, how do you convert that into a PWM value? Well, if you know that you want to go 3 feet, and your encoders tell you that you’ve only gone 2 feet, then you send your motors a value telling them to go forward. For a specific algorithm, I suggest using PID control. You can search these forums, or the internet in general for an explanation of this.

Is this to calculate the velocity error in PWM units?


Yes, it is. I’d also like to know how many encoder counts/time period for a given PWM value.

You can only do this if the motor is unloaded (and even then it’s shakey, at best). In general you can’t directly correlate a PWM value to a rotational rate. As noted elsewhere, you are better off commanding a velocity and letting a control loop set the PWM value. There are likely to be motor control examples in the white paper and programming areas.


This is why I ask. My PID closed loop control is based on SilverStar’s algorithm. He isn’t accepting private messages or I’d ask him directly. I have a function:

int PID(int request, int actual, int *lastActual, signed int *sum)

In my code, request and actual will be PWM values from 0-255. The request PWM value will come from input from the joystick. The actual PWM value will come from the encoder. My question is, the encoder produces counts/time period. How do you get an actual PWM value from this. Or am I going about it all wrong?

what you could try instead is if you wanted to use PID to make the PWMs function on a more linear scale, measure your top speed (when the PWM is set to 254) and then take any speed, divide it by the top speed, and multiply by 254 - this becomes your “actual” pwm. that way, the PID loop would result in the PWM control being more linear.

I will give this a try. Thanks.

Correct me if I’m wrong (which is entirely possible) but I think this is the idea of the PID loop.

First of all, it is impossible to do a straight conversion between target encoder counts/second to pwm output, since there are always going to be external forces acting on your robot to either speed it up or slow it down.

You need to compare actual encoder counts/sec with a target encoder counts/sec, and use that to adjust your pwm output. Something like this.

pwmOut += (targetEncoderCps - actualEncoderCps) * P_CONSTANT

I would convert your joystick input to a target encoder counts/sec. So if your top speed is 10 rev/sec and you have an encoder with 100 counts/rev (for the sake of simplicity I know encoders don’t come like that) then at top speed you would be getting 1000 counts/sec. So I would do:

targetEncoderCps = (p1_y - 127) / 127 * 1000

First step is to center the joystick at 0, then convert it to the range -1,1], then convert it to the range -1000,1000]. Of course, if you are dealing with integer math (highly recommended), then do this:

targetEncoderCps = ((long)p1_y - 127) * 1000 / 127

The cast is necessary to make p1_y signed and to make sure *1000 does not overflow.

This is the answer I needed. Thanks.

A few points:

If you use the suggested equation(s) in this message, you will only be using the ‘P’ in PID. As in, the pwm01 is being changed only by a proportion of the error. You need to track the integral (sum) of the error, and the derivative (change/time) of the error and consider these in creating a PWM value to be sent to the motors.