Suspected issue with Lynxmotion 12 v 90rpm motor encoders

Hi,
I bought 2 x Lynxmotion 12v 90 rpm motors with encoders and Cytron MD10C r3 motor controllers recently. To test them I have written a test harness using Sign-Magnitude PWM but am getting unexpected results for the Encoder B (ENCB) counts:

Motor 1. Clockwise(ENCB) Anti-Clockwise(ENCB)
Run for 18 secs. 874 -4706
“ 963 -4737
“ 894 -4750

Motor 2. 890 0
Run for 18 Secs 905 1
“ 896 0

As the Encoder B counts are not as expected and vary between motors I suspect the motor encoders are faulty. Motor 1 anti-clockwise ENCB counts are not as expected, I would have expected them to be a negative value similar to the clockwise values as the motor run duration was the same for both clockwise and anti-clockwise rotations.

Motor 2 ENCB counts for anti-clockwise rotation with values 0 and 1 are not as expected.

I suspect the encoders are faulty. What’s your view?

Regards,
Graeme

PS
My test harness code is as follows:

//************************************************************************
// Description:
// Test harness
//
// Cyton MD10C r3 Single DC Motor Controller
// Lynxmotion 12V 90 rpm high torque motor with rotary encoder
//
//************************************************************************
#define DEBUG true                    // comment out this line for production

// include libraries
#include <SimplyAtomic.h>             // For the ATOMIC macro

const int CW = 1;             // clockwise
const int CCW = -1;           // anti-clockwise

int speed = 1024;             // motor speed in range 1 .. 1024                  
int motor_run_ms = 18000;     // time for motor to run in on ms
int delay_ms = 1000;

#define ENCA D2               // pin 4 of the Arduino
#define ENCB D1               // pin 5 of the Arduino

#define PWM D4                // pin 2 of the Arduino
#define DIR D3                // pin 0 of the Arduino

volatile int posi = 0;
 
void anticlockwise(void) {
  #if DEBUG
    Serial.println("anticlockwise");
  #endif
  int pos;
  setMotor(CCW, speed);
  delay(motor_run_ms);             // allow motor to run for n us
  ATOMIC() {
     pos = posi;
  }
  posi = 0;
  
  analogWrite(PWM,0);  // force motor to stop
  digitalWrite(DIR,0);
  
  #if DEBUG
    Serial.println(pos); 
  #endif  
}
 
void clockwise(void) {
  #if DEBUG
    Serial.println("clockwise");
  #endif
  
  int pos;

  setMotor(CW, speed);
  delay(motor_run_ms);           // allow motor to run for n us
  ATOMIC() {
     pos = posi;
  }
  
  analogWrite(PWM,0);              // force motor to stop
  digitalWrite(DIR,LOW);

  posi = 0;
  #if DEBUG
    Serial.println(pos);
  #endif
}

 
void setup() {
    Serial.begin(115200);

    pinMode(ENCA,INPUT);
    pinMode(ENCB,INPUT);
    attachInterrupt(digitalPinToInterrupt(ENCA),readEncoderA,RISING);
    pinMode(DIR, OUTPUT); 
    pinMode(PWM, OUTPUT);      
  
    Serial.println("Cytron MD10C / Lynxmotion 12v 90rpm motor w/ encoder test harness");
}

// main loop
void loop() {

    clockwise();

    // wait 
    delay(delay_ms);

    // hide target
    anticlockwise();

    // wait
    delay(delay_ms);

}

void setMotor(int dir, int pwmVal){
  
  if(dir == CW){
    // clockwise
    #if DEBUG
      Serial.println("***clockwise***");
    #endif
    analogWrite(PWM,pwmVal);
    digitalWrite(DIR,HIGH);
  }
  else if(dir == CCW){
    // anti-clockwise
    #if DEBUG
      Serial.println("***anti-clockwise***");
    #endif
    analogWrite(PWM,pwmVal);
    digitalWrite(DIR,LOW);
  }
  else {
    #if DEBUG
      Serial.println("***stop***");
    #endif
    analogWrite(PWM,0);
    digitalWrite(DIR,LOW);
  }
}
 
void readEncoderA() {
  
  int b = digitalRead(ENCB);
  if(b > 0){
    posi++;
  }
  else{
    posi--;
  }
  
}

We see you purchased the following:

Normally if the magnet is in place properly, and nothing appears to be missing or burnt on the rear PCB, the encoder system should work well.

Can you try to use the system without the motor (only connecting the four wires associated with the hall effect sensor) and create code to read the different values if you manually spin the magnet? The values should be simple digital 0 or 1 at 5V from each channel.

1 Like

Hi,

Thanks for the advice. I wrote some code to read the different values and manually spun the magnet slowly as you suggested. The results are as follows:

Motor 1 - Clockwise			Motor 2 - Clockwise	
ENC 
A 	B		                                 A 	B
0	0		                                 0	0
1	0		                                 1	0
1	1		                                 1	1
0	1		                                 0	1
				
0	0		                                 0	0
1	0		                                 1	0
1	1		                                 1	1
0	1		                                 0	1
				
				
Motor 1 - Anti-clockwise	         Motor 2 - Anti-clockwise	
ENC
A 	B		                                  A  B
0	0		                                  0	 0
0	1		                                  0	 1
1	1		                                  1	 1
1	0		                                  1	 0
				
0	0		                                  0	 0
0	1		                                  0	 1
1	1		                                  1	 1
1	0		                                  1	 0

From the results it looks like the hall effect sensors are working when I manually spin the magnet slowly.

Back to the drawing board. My hunch at the moment is that it has to be either my code or magnetic interference affecting the hall effect sensors.

Thanks again for your help.

Regards,
Graeme

Test code is as follows:


//************************************************************************
// Description:
// Test harness to manually check ENC A and ENC B by slowly rotating the
// magnet by hand
//
// Lynxmotion 12V 90 rpm high torque motor with rotary encoder
// Wemos D1 Mini Pro with external antennae
//
//************************************************************************

#define ENCA D2               // pin 4 of the Arduino       Hall Sensor A Vout (Yellow)
#define ENCB D1               // pin 5 of the Arduino       Hall Sensor B Vout (White)

#define PWM D4                // pin 2 of the Arduino       Hall Sensor Vcc 5V (Blue)
#define DIR D3                // pin 0 of the Arduino       Hall Sensor GND (Green)

void setup() {
    Serial.begin(115200);

    pinMode(ENCA,INPUT);
    pinMode(ENCB,INPUT);

    Serial.println("Lynxmotion 12v 90rpm motor w/ encoder test of ENC A and ENC B");
}

// main loop
void loop() {

  int a = digitalRead(ENCA);
  if(a > 0) {
    Serial.print("ENC A = ");
    Serial.println(a);
  } else if (a == 0) {
    Serial.println("ENC A = 0");
  } 

  int b = digitalRead(ENCB);
  if(b > 0){
    Serial.print("ENC B = ");
    Serial.println(b);
  }
  else if (b == 0) {
    Serial.println("ENC B = 0");
  } 

  delay(1000);

}

(Again, not having gone over the code) Consider that unless your code is able to read every single state change in the encoder while it’s running, the data won’t appear as correct. The code needs to be set up in such a way that it detects every digital change in each channel.

1 Like

Hi,

Do you know the Pulses Per Revolution (PPR) for a Lynxmotion 12V 90 rpm 99.11oz-in 1:26.9 Brushed DC Gear Motor w/ Encoder?

The motor uses a MGT010 42 Z encoder but the motors specification does not detail the encoders PPR. I have discovered that this encoder comes in three versions: 12 PPR, 16 PPR and 20 PPR. I know it isn’t the 20 PPR version as that version has an additional Z channel.

I’m still not managing to detect all encoder state changes, currently getting just over 7 PPR using the droneworkshop example code.

Regards,
Graeme

PS
For this test I’ve been using the example Arduino Motor Encoder Sketch which utilizes a Cytron MD10C motor controller, available at Using Rotary Encoders with Arduino | DroneBot Workshop

This motor would be the 16 count version which uses a 36mm diameter magnet. If you factor in an additional low, you’d get 8+8 (per channel) = 16. This is not a “high resolution” quadrature encoder.

1 Like