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

Pololu Forum

Encoder Issue - Acceleration

Hello,
I have two 4.4:1 Metal Gearmotor 25Dx63L mm MP 12V with 48 CPR Encoder with a DualMC33926MotorShield and Arduino Uno. One encoder works perfectly fine. The other one was working fine normally (I think) but now has major issues during acceleration of the motor the encoder directions are going back and forth between clockwise (CW) and counterclockwise (CCW). The data sample below is of me rotating and accelerating the motor shaft CCW and you can see the numbers bounce between +1 (CCW - the correct direction) and -1 (CW). I was powering this motor with an 18V power source so maybe that caused some issues? Not sure if that makes sense since the other encoder is working fine and the encoder itself is powered from 5V from the Arduino.

Any advice to change my code or to repair the encoder? My code is below for reference.

19:03:26.309 ->  right_Encoder_Direction_Now: 1
19:03:26.309 ->  right_Encoder_Direction_Now: 1
19:03:26.309 ->  right_Encoder_Direction_Now: 1
19:03:26.309 ->  right_Encoder_Direction_Now: 1
19:03:26.309 ->  right_Encoder_Direction_Now: -1
19:03:26.342 ->  right_Encoder_Direction_Now: 1
19:03:26.342 ->  right_Encoder_Direction_Now: 1
19:03:26.342 ->  right_Encoder_Direction_Now: 1
19:03:26.342 ->  right_Encoder_Direction_Now: 1
19:03:26.342 ->  right_Encoder_Direction_Now: -1
19:03:26.342 ->  right_Encoder_Direction_Now: -1
19:03:26.342 ->  right_Encoder_Direction_Now: 1
19:03:26.376 ->  right_Encoder_Direction_Now: 1
19:03:26.376 ->  right_Encoder_Direction_Now: 1
19:03:26.376 ->  right_Encoder_Direction_Now: 1
19:03:26.376 ->  right_Encoder_Direction_Now: 1
19:03:26.409 ->  right_Encoder_Direction_Now: 1
19:03:26.409 ->  right_Encoder_Direction_Now: 1
19:03:26.409 ->  right_Encoder_Direction_Now: 1
19:03:26.409 ->  right_Encoder_Direction_Now: -1
19:03:26.442 ->  right_Encoder_Direction_Now: 1
19:03:26.442 ->  right_Encoder_Direction_Now: 1
19:03:26.442 ->  right_Encoder_Direction_Now: 1
19:03:26.475 ->  right_Encoder_Direction_Now: 1
19:03:26.475 ->  right_Encoder_Direction_Now: 1
19:03:26.508 ->  right_Encoder_Direction_Now: 1
19:03:26.541 ->  right_Encoder_Direction_Now: 1
19:03:26.541 ->  right_Encoder_Direction_Now: 1
19:03:26.574 ->  right_Encoder_Direction_Now: 1
19:03:26.706 ->  right_Encoder_Direction_Now: -1
19:03:28.296 ->  right_Encoder_Direction_Now: -1

////////////////////////////////////////////////// CODE //////////////////////////////////////////

#include "DualMC33926MotorShield.h"
#include <Wire.h>                               // IMU IC2 Communication

DualMC33926MotorShield md;

#define encoder0PinA  2
#define encoder0PinB  12

volatile unsigned int encoder0Pos = 0;

int right_Encoder_Direction_Now = 1;

void stopIfFault()
{
  if (md.getFault())
  {
    Serial.println("fault");
    while(1);
  }
}

void setup()
{

  pinMode(encoder0PinA, INPUT);
  pinMode(encoder0PinB, INPUT);

  // encoder pin on interrupt 0 (pin 2)
  attachInterrupt(digitalPinToInterrupt(2), doEncoderA, CHANGE);

  Serial.begin(115200);
  Serial.println("Dual MC33926 Motor Shield");
  md.init();

}

void loop()
{
  
}

void doEncoderA() {
  // look for a low-to-high on channel A
  if (digitalRead(encoder0PinA) == HIGH) {

    // check channel B to see which way encoder is turning
    if (digitalRead(encoder0PinB) == LOW) {
      encoder0Pos++;         // CCW
      right_Encoder_Direction_Now = 1;
    }
    else {
      encoder0Pos--;         // CW
      right_Encoder_Direction_Now = -1;
    }
  }

  else   // must be a high-to-low edge on channel A
  {
    // check channel B to see which way encoder is turning
    if (digitalRead(encoder0PinB) == HIGH) {
      encoder0Pos++;          // CCW
      right_Encoder_Direction_Now = 1;
    }
    else {
      encoder0Pos--;          // CW
      right_Encoder_Direction_Now = -1;
    }
  }

  Serial.print(" right_Encoder_Direction_Now: "); 
  Serial.println(right_Encoder_Direction_Now);
  
  //Serial.print(" Encoder A: "); 
  //Serial.print(digitalRead(encoder0PinA));
  //Serial.print(" Encoder B: "); 
  //Serial.println(digitalRead(encoder0PinB));

  // use for debugging - remember to comment out
}

Are you using the MC33926 shield as a shield (i.e. mounted directly on the Arduino)? I noticed you are using pin 12 for one of your encoder signals, and pin 12 is connected to the status flag indicator pins on the drivers. It’s possible that this is causing interference. Could you try moving it to another pin that the shield does not use (such as pin 11) and see if you get the same results? You can reference the “Shield Connections: Signals, Power, and Motors” section of the Dual MC33926 Motor Driver Shield user’s guide for more information about the default Arduino pin mappings.

If you do get the same results, can you probe the encoder outputs with an oscilloscope and post captures of them? Also, could you post some pictures of your setup that show all of your connections?

Brandon

Thanks Brandon,
I am using it as a shield on the Arduino. Just tried moving pin 12 to 11 (and also 5) but no change in results. Still random spikes of direction change during acceleration. I don’t have access to an oscilloscope unfortunately but here is a photo of my setup testing the encoder. Thank you for your help with this.

It’s probably not great to be calling the Serial.print() commands inside of your doEncoderA() function that runs when the interrupt triggers since it can be relatively slow, but if it works for your other motor and encoder it might not be a problem. Do you still see the problem if you slow the motor down to around half of the speed? If you try swapping the other motor and encoder to use the same pins (2 and 11), does the problem follow the motor and encoder or the pins?

Brandon

The code I’m using is a simplified version of my encoder function and am using the Serial.Print() in the interrupt to help debug the issue. I don’t print the direction in my larger program but I’m getting the same results essentially. I just replaced the same setup with the other encoder on pins 2 and 11 and it works exactly as expected with the output below (accelerating the motor).

On the malfunctioning encoder the direction stays as expected when keeping a constant velocity but the direction starts rapidly erratically changing when I accelerate the motor. I’m thinking I need to replace that motor/encoder.

18:48:09.653 ->  right_Encoder_Direction_Now: 1
18:48:09.653 ->  right_Encoder_Direction_Now: 1
18:48:09.653 ->  right_Encoder_Direction_Now: 1
18:48:09.653 ->  right_Encoder_Direction_Now: 1
18:48:09.653 ->  right_Encoder_Direction_Now: 1
18:48:09.686 ->  right_Encoder_Direction_Now: 1
18:48:09.686 ->  right_Encoder_Direction_Now: 1
18:48:09.686 ->  right_Encoder_Direction_Now: 1
18:48:09.686 ->  right_Encoder_Direction_Now: 1
18:48:09.686 ->  right_Encoder_Direction_Now: 1
18:48:09.686 ->  right_Encoder_Direction_Now: 1
18:48:09.686 ->  right_Encoder_Direction_Now: 1
18:48:09.686 ->  right_Encoder_Direction_Now: 1
18:48:09.719 ->  right_Encoder_Direction_Now: 1
18:48:09.719 ->  right_Encoder_Direction_Now: 1
18:48:09.719 ->  right_Encoder_Direction_Now: 1
18:48:09.719 ->  right_Encoder_Direction_Now: 1
18:48:09.719 ->  right_Encoder_Direction_Now: 1
18:48:09.719 ->  right_Encoder_Direction_Now: 1
18:48:09.719 ->  right_Encoder_Direction_Now: 1
18:48:09.719 ->  right_Encoder_Direction_Now: 1
18:48:09.752 ->  right_Encoder_Direction_Now: 1
18:48:09.752 ->  right_Encoder_Direction_Now: 1
18:48:09.752 ->  right_Encoder_Direction_Now: 1

Thank you for the additional information.

Could you post some pictures of the encoder part of the gearmotor? A side-on view (with the wires facing downward) would probably be the most helpful. If you have the newer version of the 4.4:1 Metal Gearmotor 25Dx63L mm MP 12V with 48 CPR Encoder that has an end cap, could you remove that first? It has 3 clips holding it on, and a small flat-head screwdriver might help to get under them.

Brandon

Tried my best to take good photos but its difficult to get a good close shot in focus. The encoder with an issue is the one on the left. If you are wondering what this is, I’m trying to use the two reaction wheels attached to this inverted pendulum with the goal to balance on their own. I need to use the encoder/wheel speeds as one of feedback parameters into this control system.

Thank you for posting those pictures. I was hoping to get a good look at both the magnetic disc and the hall effect sensor to see if either of them might be bent or somehow not aligned properly, but it is hard to tell from the pictures. Could you try getting a better look at them in person (in particular the hall effect sensor) to see if it looks bent at all? You might try applying some light pressure to it so it sits slightly closer to the disc to see if that helps at all.

Brandon

I just checked the sensor and it looks normal and the same as the other working encoder. I tried pressuring it closer to the disc but it didn’t change the results.

Thanks for checking that. Since you have one unit working and I do not see any obvious problems, I do not think it is worthwhile to continue trying to troubleshoot this. Please email us at support@pololu.com with your order information and a reference to this thread so we can look into getting you a replacement.

Brandon