Controlling motor speed (in RPM) using an encoder

Because of these interrupts:

Encoders spec the Pulses Per Revolution of a signal line, but the code triggers off of the rising and falling edges (CHANGE) of both of the signal lines, so it counts 4 times per pulse.

In the original code they just did theta = EncoderCount/PPR

But you did theta = EncoderCount / (PPR * CountPerPulse);

Is their a mistake? Which one is right? Why did you multiple PPR by CountPerPulse and why didn't the original author do that?

EDIT: You mentioned this in a previous reply

I googled and it said counts per revolution should be the encoders PPR multiplied by 4. So the variable should be set to CountsPerRevolution = PPR*4 not just 4 right?

I found what I will assume is the same motor on another website (not amazon) and they listed the PPM as 7. Here are the specs (they even multiplied PPM by 4 to get the CountsPerRevolution):

Encoder Specifications:

  • Encoder Type: Quad
  • PPR: 7
  • CPR: 7 x 4 = 28
  • CPR at output shaft: 840

I'm not sure if the fact that my motor is 6v and there's is 12v would affect the specs. I got the specs from this website: GA12-N20-12v 1000 RPM ALL Metal Gear Micro DC Encoder Motor with Precious Metal Brush GA12-N20-12v 1000 RPM ALL Metal Gear Micro DC Encoder Motor with Precious Metal Brush [RMCS-2536] - ₹380.00 : Robokits India, Easy to use, Versatile Robotics & DIY kits

My motor is from amazon: uxcell GA12-N20 6V 1000RPM DC Gear Motor with Encoder Speed Velocity Measurement for Mini Car Balance Motor Encoder DIY : Amazon.ca: Toys & Games

I think I am right because:

The manufacturers spec the PPR of the signal line because it is the resolution of the lines/holes/magnets on the encoder's physical wheel. If you place multiple sensors to detect the lines/holes/magnets at different phases, you can synthesize higher resolution, but you are still bound by the physical properties of the sensor wheel.

Yes, with the way the code is counting all 4 edges of the two signals. It would be possible to count 1,2,3, or 4 of those 4 edges by fiddling with these lines:

You could do one Count Per Pulse with:

  attachInterrupt(digitalPinToInterrupt(interruptPinA), ISR_EncoderA, FALLING); // Attach interrupt to encoder pin A
//  attachInterrupt(digitalPinToInterrupt(interruptPinB), ISR_EncoderB, CHANGE); // Attach interrupt to encoder pin B

You could do two Counts Per Pulse with:

  attachInterrupt(digitalPinToInterrupt(interruptPinA), ISR_EncoderA, CHANGE); // Attach interrupt to encoder pin A
//  attachInterrupt(digitalPinToInterrupt(interruptPinB), ISR_EncoderB, CHANGE); // Attach interrupt to encoder pin B

You could do three Counts Per Pulse (which would be weird) with:

  attachInterrupt(digitalPinToInterrupt(interruptPinA), ISR_EncoderA, CHANGE); // Attach interrupt to encoder pin A
  attachInterrupt(digitalPinToInterrupt(interruptPinB), ISR_EncoderB, FALLING); // Attach interrupt to encoder pin B

The tradeoff is between resolution and speed. If the processor can only handle up to 100RPM while reading 4 edges, it might be able to handle 400RPM (or more) when counting on one edge.

A very basic and fast way to use an encoder is to use one of the signals as a clock signal, trigger on one of it's edges, and then count based on the value of the other signal. Since if it was triggering off of the falling edge of signal A, it could assume that A is already LOW, and the increment/decrement is solely dependent on B:

attachInterrupt(digitalPinToInterrupt(EncoderPinA), ISR_encoderSimple, FALLING);
...
ISR_encoderSimple(void){
   // assume pinA is low
   if(digitalReadFast(EncoderPinB)==HIGH){
     ++encoderCount;
   } else {
     --encoderCount;
  }
}

7 PPR seems so low compared to the 900 in the original code

7 is the number of magnets on the encoder wheel. It gets multiplied by the gear reduction number because with a 30:1 reduction, the motor has to turn 30 times to turn the output shaft once. 7*30 = 210 pulses per (output shaft) revolution.

The code author's 900PPR would match the 900PPR listed on his link to the Amazon motor with the 80RPM option.

I was googling and chatgpting haha and they said this is how they got the PPR:

CPR=PPR×4=7×4=28
CPR at output shaft=CPR×Gear Ratio=28×30=840

so it should be 840?

EDIT: CPR and PPR are different. PPR is not multiplied by 4...

PPR=7 (at the motor shaft, where a cheap 7-bump encoder is easy to fit)

CPP=4 (at the motor shaft or at the output shaft -- it's done by the code using the input pulses on A & B)

CPR=PPRxCPP=7x4=28 (at the motor shaft)

PPR at output shaft = PPRxGear Ratio=7x30=210

CPR at output shaft = CPRxGear Ratio=28x30=840

CPR at output shaft = PPRx4xGear Ratio=7x4x30=840

I'd be a little concerned that some of the versions of the motor have 7PPR at the motor and some have 12PPR, and think that you ought to test your actual motor.

which version has 12 ppr? The one is listed from amazon doesn't even mention the specs? The one from the original author is a completely different motor.

The only difference between the motor I have and the one from the website is the voltage. Mine runs on 6V and theirs on 12V. Im assuming this has to do with a difference in gear ratios. So this will definitely affect the PPR.

I'm comparing these two:

My Motor
Similar motor where I got the specs. However this one has a different voltage. Its 12v instead of 6v

This one:

That's 12PPR at the motor, 900PPR at the output after a 75:1 gear reduction.

The original author's math is wrong. The only 900PPR-at-the-output-motor on the amazon page he links to is the 80RPM motor, and his youtube graphs show it running at up to 240 RPM.

When he's showing 100RPM operation on his graph, it takes more than a second to make a single turn.

He's got his numbers wrong.

It's just units conversion that kids learn in elementary school. But you have to be careful with the names or you blow it by huge factors.

CPR_output != CPR_motor != PPR_motor != PPR_output

Thanks, yes.

But i'm wondering if there will be a difference in PPR with regards to the 2 motors i am comparing that I linked. They have difference voltages. Im not sure if this affects gear ratios and hence the PPR

I LINKED THE WRONG MOTOR WAIT

And why do you think changing voltage might change the gear ratio?

AFK.

Just thought different gear ratios would require more or less voltage.

I honestly have no clue.

They look the same, I'm just not sure if that means they will have the same PPR. I don't know if its safe to assume they do. The motor I have didn't have the specs mentioned. So i'm just using the other motors specs.

They don't. Gears are like levers, also something taught in elementary school.

From:

specs on different gear ratios:

I meant the motor that I am using

This one: My motor

Does not have the specs I need like PPR.

So I found a similar motor this one that does have specs.

Curious, does the second motor require more voltage then the second? (dumb question i know). They have the same max speed...

Sure. Amke your best guess.

If I had a motor like this and didn't know what it did...

.... and then measure the counts/rev by setting it to a low speed and timing the actual revolutions in an interval of time and then do the elementary school ratio math on counts and revolutions.

The second motor has the same voltage as the second motor.

I meant first motor vs. second motor haha

Maybe you could post some pictures of your motor from various angles.

1 Like

Do I need to change the Kp, Ki and Kd values from the original code? Like how do you guess the values? Or do I keep them as is?

I would try them as is and see how it behaves.