Pololu Robotics & Electronics
Menu
My account Comments or questions? About Pololu Contact Ordering information Distributors

Pololu Forum

Magnetic Encoder Pair Kit RPM Problem

I have two of these 12 CPR magnetic encoders , mounted on the 50:1 extended shaft motors on the balancing robot chassis. I am using this encoder arduino library on an A-Star 32u4 Micro.

The problem I am having is that the code appears to work perfectly up to around 50% motor speed, or analogWrite(130). As the speed increases, the encoder counts slow down, stop incrementing, and then begin dropping. As the speed increases further, the count slows down, stops decrementing, and then begins increasing again.

I had a few thoughts on what could be causing this. Is this normal function, and the encoders only work at low rpms? Is this an issue with the Serial.print statements causing the code to run too slow? I have tried different Serial.begin rates, but didn’t really notice a difference. I had also thought of proximity of the encoders, as they only had about a 1/4 inch gap between them, but the problem persisted when I removed one of the motors from the chassis. Do I need pull up resistors? According to the library, the code enables internal pullup resistors, but it does mention adding extra resistors.

Any help would be appreciated. This is my code:

#include <Encoder.h>
int phasePin = 11;
int phasePinB = 12;
int motorPin = 9;
int motorPinB = 10;
Encoder myEnc(14, 15);
Encoder myEncB(8, 7);
 
void setup() 
{ 

  pinMode(motorPin, OUTPUT);
  pinMode(phasePin, OUTPUT);
  pinMode(motorPinB, OUTPUT);
  pinMode(phasePinB, OUTPUT);
  
  digitalWrite(phasePin, HIGH);
  digitalWrite(phasePinB, HIGH);
  Serial.begin(38400);
  while (! Serial);
  Serial.println("Speed 0 to 255");

} 

 
void loop() { 

  if (Serial.available())
  {

    int speed = Serial.parseInt();
    if (speed >= 0 && speed <= 255)
    {

      Serial.println(speed);
      analogWrite(motorPin, speed);
      analogWrite(motorPinB, speed);
    }

  }

    long newPosition = myEnc.read();


     long newBPosition = myEncB.read();
     
     Serial.print(newPosition);
     Serial.print(" ");
     Serial.print(newBPosition);
     Serial.println(" ");

  
}

Hello.

I suspect you’re code is missing counts because you are not using interrupt pins for your encoders. The encoder.h library documentation recommends using a pin capable of interrupts for the first pin of the constructor. If both pins have interrupt capability it will use will them for best performance. Currently, since none of the pins you are using have interrupts, the library is working in low performance polling mode, which will miss counts, especially at higher speeds. The A-Star 32U4 Micro uses the same microcontroller as the Arduino Leonardo, so the interrupt pins available for use with that library are pins 0, 1, 2, 3.

Brandon

That would definitely make sense. I had been going off of this image on the 32u4 User’s guide, which says that pins 0, 1, 2, 3, 7, 8, 9, 10, 11, 14, 15, and 16 are interrupts. Based off of this website, it looks like the issue is that 0-3 are standard external interrupts, 7 has some special conditions, and 8-11 and 14-16 are pin change interrupts.

I am currently using pins 0-3 for an IMU and a bluetooth module, so I will attempt to follow this forum post to use pin change interrupt pins for my encoders.

Thanks for you help!

Adam