Micro Metal Gear Motor

Hi ,

I bought couple of micro metal gear motor with shaft encoder. This is the first time I am working with encoders. I have no idea how to get exact rotation through programming.I am not as good enough in programming too. I am using arduino platform. pls help me out to get exact rotation via programming .

Thank you

Hello.

I moved your post to the “Pololu Motor Controller/Drivers and Motors” section of our forum.

This page about using encoders on the Arduino site contains many coding examples and detailed descriptions that you might find helpful.

You should get four ticks from the encoder (a high and a low transition per channel) for each tooth of your encoder wheel per rotation of the gearmotor’s back shaft. In your program you could use an interrupt to measure the ticks of the encoder and then convert it to the counts per revolution of the output shaft of your motor by factoring in the number of teeth on your encoder wheel and the gear ratio of your motor.

- Amanda

Hi,

Thanks for replying .

I copied and pasted the program in arduino and changed pin number with respect to my hardware.When I tried at the first time ,nothing I get in the serial monitor .Then I have copied and placed the " Void Encoder()" function block in the loop function.Though my motors were stationary ,Serial monitor shows some continuous value till 65535. I don’t get it .

I don’t know what code you are using (the page on the Arduino site I linked to has many examples), and I am not sure what the problem with it might be. I recommend testing your encoders to make sure they are working properly. To test your encoders you could supply power to the encoder board and use a multimeter (or oscilloscope) to measure the voltage on the output terminals while turning the encoder wheel. When one of the teeth on the encoder wheel is blocking the sensor you should see a high signal, and when none of the teeth are blocking it you should see a low signal. If your encoder outputs show that the sensors are working, can you post the Arduino code you are using?

- Amanda

  1. Both sensors output showed the voltage between 2.5 to3v. Is it required voltage?

  2. I am using L293D motor driver and below is my code. This is my latest code, here I have faced the problem that one motor works fine but another motor keep on rotating . it seems didn’t exist the condition. what’s wrong with my code? I am not good in programming either.Just learning now.

Program:

int motorRightPositive = 6; 
int motorLeftPositive = 9; 
int motorRightNegative = 5; 
int motorLeftNegative = 10; 
int motorLeftEnable_pin =13;
int motorRightEnable_pin=12;

 int encoder0PinA = 7; //Right motor sensor1 conected to pin 7
 int encoder0PinB = 8; // Right motor sensor2 connected to pin 8
 int encoder0Pos = 0;
 int encoder0PinALast = LOW;
 int n = LOW;
 
 int encoder0PinA1 = 3; //Left motor sensor1 connected to pin 3
 int encoder0PinB1 = 4; // Left motor sensor2 connected to pin 4
 int encoder0Pos1 = 0;
 int encoder0PinALast1 = LOW;
 int n1 = LOW;
 

 void setup() { 
    Serial.begin (9600);
    
   pinMode (encoder0PinA,INPUT);
   pinMode (encoder0PinB,INPUT);
   pinMode (encoder0PinA1,INPUT);
   pinMode (encoder0PinB1,INPUT);
   
   pinMode (motorRightPositive, OUTPUT);  
   pinMode (motorLeftPositive, OUTPUT);
   pinMode (motorRightNegative ,OUTPUT);
   pinMode(motorLeftNegative, OUTPUT);
   pinMode(motorLeftEnable_pin, OUTPUT);
   pinMode(motorRightEnable_pin, OUTPUT);
  
    digitalWrite(motorLeftEnable_pin, HIGH);
    digitalWrite(motorRightEnable_pin, HIGH);
 } 

 void loop() 
 { 
   
 
   n = digitalRead(encoder0PinA);
   if ((encoder0PinALast == LOW) && (n == HIGH))
   {
     if (digitalRead(encoder0PinB) == LOW)
     {
       encoder0Pos--;
     } else
     {
       encoder0Pos++;
     }
     Serial.println (encoder0Pos);
    
   } 
   encoder0PinALast = n;
   
   while(encoder0Pos==290)
   {
 
     digitalWrite(motorRightEnable_pin, LOW);
 
   }
   if(encoder0Pos<=1)
   {
    
     analogWrite (motorRightPositive, 0); 

     analogWrite (motorRightNegative, 100); 
 
   }
   
    n1 = digitalRead(encoder0PinA1);
if ((encoder0PinALast1 == LOW) && (n1 == HIGH)) 

  {
     if (digitalRead(encoder0PinB1) == LOW) 
     {
       encoder0Pos1--;
     } else 
     {
       encoder0Pos1++;
     }
  //  Serial.println (encoder0Pos1);
    
   } 
   encoder0PinALast1 = n1;
   
   while(encoder0Pos1==400)
   {
  digitalWrite(motorLeftEnable_pin, LOW);
 
   }
   if(encoder0Pos1<=1)
   {    
 
 analogWrite (motorLeftPositive, 0); 
 analogWrite (motorLeftNegative, 100);
 }
   
 }

Can anyone pls tell me whats wrong with my program? I couldn’t find it. I can get an output properly when it operates individually but when both motors work together , only one motor executes it command properly and other not? pls some one find the error in my program

I accidentally mixed up the expected signal levels for the encoder’s sensor being blocked or not blocked in my last post. The signal should be low if there is a tooth in front of the sensor and high if there is no tooth in front of the sensor.

The voltage readings you got from the encoders seem like they might be reasonable, and since the encoders seem to be working for you when used individually, they are probably fine. It is not apparent to me what is wrong with your code, especially since you stated that both motors work when tested individually. What does the “non-working” motor do when you test both motors together (e.g. it does not spin at all or it spins in the opposite direction of what you expect)? What is the code that you use when testing the encoders separately?

- Amanda

Thanks for your reply,

  1. As your replied I checked the sensor , I get value “0” when the shaft hub blocks the sensor and gives value"1" when it out the sensor. So, my sensor working properly. As per that program when I rotate the wheel I get proper value of rotation.

  2. Now, my scenario is to stop the two motors individually when it exceeds the condition .
    a)When I use “If” condition , both motors stops separately but each time the value exceeds the condition.So, I cant make it 90 degree exactly at each time.
    b) When I use “While” statement , one motor execute the condition and other it not execute the condition,so it keep on rotating .
    what should I do to make these two motor works individually ? please give some idea , here is my code below.

Program:-

int motorRightPositive = 6; 
int motorLeftPositive = 9; 
int motorRightNegative = 5; 
int motorLeftNegative = 10; 


int encodervariable=0;
int encodervariable1=0;

 int encoder0PinA = 3;
 int encoder0PinB = 4;
 float encoder0Pos = 0;
 int encoder0PinALast = LOW;
 int n = LOW;


 int encoder0PinA1 = 7;
  int encoder0PinB1 = 8;
  int encoder0Pos1 = 0;
 int encoder0PinALast1 = LOW;
 int n1 = LOW;
 
 
 void setup() { 
   pinMode (encoder0PinA,INPUT);
   pinMode (encoder0PinB,INPUT);
   pinMode (encoder0PinA1,INPUT);
   pinMode (encoder0PinB1,INPUT);
   Serial.begin (9600);
   
   pinMode (motorRightPositive, OUTPUT);  
   pinMode (motorLeftPositive, OUTPUT);
   pinMode (motorRightNegative ,OUTPUT);
   pinMode(motorLeftNegative, OUTPUT);

    
   analogWrite (motorLeftPositive, 100);
     analogWrite (motorLeftNegative, 0);
     
   analogWrite (motorRightPositive, 0);
     analogWrite (motorRightNegative, 100); 
 } 

 void loop() { 
   n = digitalRead(encoder0PinA);
   n1 = digitalRead(encoder0PinA1);
   
   if ((encoder0PinALast == LOW) && (n == HIGH)) {
     if (digitalRead(encoder0PinB) == LOW) {
       encoder0Pos--;
     } else {
       encoder0Pos++;
     }
     encodervariable = encoder0Pos;
    Serial.print (encodervariable);
     Serial.print("Left");
    // Serial.print ("//");
   }
      
   encoder0PinALast = n;
   
   if ((encoder0PinALast1 == LOW) && (n1 == HIGH)) {
     if (digitalRead(encoder0PinB1) == LOW) {
       encoder0Pos1--;
     } else {
       encoder0Pos1++;
     }
     encodervariable1 = encoder0Pos1;
     Serial.print (encodervariable1);
     Serial.print("Right");
   //  Serial.print("/");
   } 
  
     
   encoder0PinALast1 = n1;
   
    if(encodervariable1==50 || encodervariable1==-50) 
   {
     
        analogWrite (motorRightPositive, 0);
     analogWrite (motorRightNegative, 0); 
     
   }
   
   if(encodervariable==-60 )
   {
     
     analogWrite (motorLeftPositive, 0);
     analogWrite (motorLeftNegative, 0);
   }
   
  
 }

I am not entirely sure what you mean when you say:

It sounds like you are trying to use your encoders to tell when your motor or system has reached 90 degrees, but it does not always stop at 90 degrees. If that is the case, it might be because your program is missing encoder counts and causing the motor or system to turn further than expected. To prevent missing counts, you could try using interrupts in your sketch. The Arduino web page I linked to earlier has example sketches for using those, so you might refer to them to get started. It also has libraries with functions that take care of handling the interrupts for you.

If that is not the case, can you be more specific about what you expect to happen and what is actually happening (e.g. I expect my motor to turn 90 degrees, but instead it only turns 80 degrees)?

- Amanda

Hi,

yes , I am trying to get exact 90 degree in wheel rotation but each time it slips the angle. what should I do to get 90 degree exact turning?

I don’t think encoder miss the values, when motor start rotates , I can get an output properly. And I am using the same code which is in previous message.

The issue might be due to inertia and not your code. You could try lowering the motor speed to test if the wheels do skid or slip. If the wheels give an exact 90 degree rotation at a slower speed, then you will need to do some calibrations with the values in your code until the behavior meets your expectations at higher speeds. Another issue might be that you are setting your motor driver to coast rather than brake. You might try looking for an input functions table in your driver’s datasheet to see if it is possible to operate in drive/brake mode.

- Amanda

Hi,

Which motor driver is best to do braking? I am using L298N motor driver.

Many motor drivers can be operated in a drive-brake mode, including the motor driver that you have. (It looks like the L298N datasheet calls it “Fast Motor Stop”.) I am not sure what your motor supply voltage is, but you might be interested in using the Dual MC33926 Motor Driver Shield for Arduino since you are using an Arduino. You can refer to “Truth Table” in the “Logic Commands and Registers” section of the MC33926’s datasheet (located under the “Resources” tab on the product’s page) for how to run your motors in drive-brake mode.

By the way, if you have not done so yet, you might want to do a test, like the one I mentioned in my last post, to figure out if your issue was caused by inertia or improper motor control settings before changing out your hardware.

- Amanda