Go Down

Topic: Micro Metal gear motor with shaft encoder (Read 5475 times) previous topic - next topic

Kannan

Jul 17, 2014, 08:50 am Last Edit: Jul 30, 2014, 05:50 am by Kannan Reason: 1
Hi ,

I am new here. I am working on micro metal gear with shaft encoder.I am trying to get exact 90 degree rotation in the wheel. But I couldn't get the exact turning , each time it slips the angle. please find my program below and give some solution.

1. Micro Metal gear - http://www.pololu.com/product/2218

2. Encoder - http://www.pololu.com/product/2590

3. Program:-
-------------
Code: [Select]

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

int encodervariable=0;
int encoder0PinA = 3;
int encoder0PinB = 4;
int 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 (motorRightPositive, 100);
    analogWrite (motorRightNegative, 0);
    analogWrite (motorLeftPositive, 0);
    analogWrite (motorLeftNegative, 100);
 
}

void loop() {
  n = digitalRead(encoder0PinA);
  n1 = digitalRead(encoder0PinA1);
 
 
    if(encoder0Pos!=-453 )
  {
  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(encoder0Pos1!=-420 )
  {
if ((encoder0PinALast1 == LOW) && (n1 == HIGH)  ) {
    if (digitalRead(encoder0PinB1) == LOW) {
      encoder0Pos1--;
    } else {
      encoder0Pos1++;
    }
   Serial.print (encoder0Pos1);
    Serial.print("Right");
    Serial.print ("/");
  }
  }
  encoder0PinALast1 = n1;
 
 
 
   if(encoder0Pos1==420 || encoder0Pos1==-420)
  {
   
       encoder1();
  }
 
  if(encodervariable==-453 )
  {
   
encoder();
  }
 
 
}

void encoder1()
{
  analogWrite (motorRightPositive, 0);
    analogWrite (motorRightNegative, 0);
}

void encoder()
{
 analogWrite (motorLeftPositive, 0);
    analogWrite (motorLeftNegative, 0);
}


MarkT

Serial.print @ 9600 baud will take a long long time compared to the spacing of
encoder pulses, so you will be losing pulses.

Typically people do their encoder processing in an interrupt routine to avoid
such issues, there are numerous examples in these forums so have a search?

As a stop-gap change the baud rate to 115200 ??
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

raschemmel

You didn't specify which type of encoder you got. (3.3V or 5V).
Also, where did you get the code ? Did you write this program yourself ? If so , is this your first attempt at writing code for rotary encoders ?
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

MarkT

Also those gear ratios are not exact ratios, you need to know the exact
ratio (as a ratio) to do encoder pulse counting accurately.  Counting the
teeth on the gears is one way to find this out :)
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Kannan


Serial.print @ 9600 baud will take a long long time compared to the spacing of
encoder pulses, so you will be losing pulses.

Typically people do their encoder processing in an interrupt routine to avoid
such issues, there are numerous examples in these forums so have a search?

As a stop-gap change the baud rate to 115200 ??



Thank you , I set with 115200 baud,it didn't miss the signal.

Kannan


You didn't specify which type of encoder you got. (3.3V or 5V).
Also, where did you get the code ? Did you write this program yourself ? If so , is this your first attempt at writing code for rotary encoders ?


I am using 5v encoder. yes, this is the first time using the encoder and I did write program by myself. pls help me . how to achieve the angle properly?

Kannan

Hi everyone,

Now, I can get a proper rotation but dono is it right or wrong form? still I get the rotation and another problem facing here is wheel slips after some rotation. how to solve this?

raschemmel

Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

Kannan

#8
Jul 26, 2014, 11:59 am Last Edit: Jul 30, 2014, 05:51 am by Kannan Reason: 1
Yes , I tried it but nothing helps. But I came up with modified code but here I am facing problem that when one motor completes it rotation , it affects the other motor and couldn't get exact same position. Pls tell what wrong with my program.

Code:-
Code: [Select]

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

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

int encodervariable1=0;
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 (115200);
 
  pinMode (motorRightPositive, OUTPUT);  
  pinMode (motorLeftPositive, OUTPUT);
  pinMode (motorRightNegative ,OUTPUT);
  pinMode(motorLeftNegative, OUTPUT);
  pinMode(motorLeftEnable_pin, OUTPUT);
  pinMode(motorRightEnable_pin, OUTPUT);
   

   
 
}

void loop() {
  digitalWrite(motorLeftEnable_pin, HIGH);
   digitalWrite(motorRightEnable_pin, HIGH);
  analogWrite (motorRightPositive, 50);
    analogWrite (motorRightNegative, 0);
    analogWrite (motorLeftPositive, 50);
    analogWrite (motorLeftNegative, 0);
 
  n = digitalRead(encoder0PinA);
  n1 = digitalRead(encoder0PinA1);
 
   
 
    if(encodervariable!=500 )
  {
  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( encodervariable1!=-864 )
  {
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==-864)
  {
   
       encoder1();
       
  }
 
  if(encodervariable==500 )
  {
   
encoder();
  }

}

void encoder1()
{
  digitalWrite(motorRightEnable_pin, LOW);
  analogWrite (motorRightPositive, 50);
  analogWrite (motorRightNegative, 50);

  delay(1000);
  encodervariable1=0;
  encoder0Pos1 =0 ;
 
}

void encoder()
{
  digitalWrite(motorLeftEnable_pin, LOW);
  analogWrite (motorLeftPositive, 50);
  analogWrite (motorLeftNegative, 50);
   
  delay(1000);
  encodervariable=0;
  encoder0Pos=0;
}


Kariky

First get rid of delay commands as they are not meant to be used on real working program. If i understand correctly they pause the whole program for 1 sec. when first motor is stopped ?
My software has no bugs, only random features.

Kannan


First get rid of delay commands as they are not meant to be used on real working program. If i understand correctly they pause the whole program for 1 sec. when first motor is stopped ?


But without using delay,How could I stop the motor for certain time?

MarkT

Study the BlinkWithoutDelay example...  Rather than stopping and waiting
you regularly check.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

raschemmel

Edit your post and use the CODE TAGS toolbutton "#"

Can you post a photo of a hand-drawn schematic ?
What are you using for a driver ?
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

Kannan


Study the BlinkWithoutDelay example...  Rather than stopping and waiting
you regularly check.


Thanks Mark ,I will look that .

Kannan

#14
Jul 29, 2014, 06:18 am Last Edit: Jul 30, 2014, 05:52 am by Kannan Reason: 1

Edit your post and use the CODE TAGS toolbutton "#"

Can you post a photo of a hand-drawn schematic ?
What are you using for a driver ?


Here with the code tags

Code: [Select]

/* Right motor and left motor terminals and enable pin */

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

/* Left encoder connect with pin 3 and 4 */

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

/*Right encoder connect with pin 7 and 8 */

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 (115200);
 
  pinMode (motorRightPositive, OUTPUT);  
  pinMode (motorLeftPositive, OUTPUT);
  pinMode (motorRightNegative ,OUTPUT);
  pinMode(motorLeftNegative, OUTPUT);
  pinMode(motorLeftEnable_pin, OUTPUT);
  pinMode(motorRightEnable_pin, OUTPUT);
   

   
 
}

void loop() {
 
  n = digitalRead(encoder0PinA);
  n1 = digitalRead(encoder0PinA1);



    if(encoder0Pos!=850 )
  {
  if ((encoder0PinALast == LOW) && (n == HIGH))
  {
    if (digitalRead(encoder0PinB) == LOW)
    {
      encoder0Pos--;
    } else
    {
      encoder0Pos++;
    }
   
    Serial.println (encoder0Pos);
    Serial.print("Left");
 
  }
  motorleftrun();
}

 if(encoder0Pos==850 )
  {
      encoder();
  }

  encoder0PinALast = n;
   
  if( encoder0Pos1!=850 )
  {
if ((encoder0PinALast1 == LOW) && (n1 == HIGH)  ) {
    if (digitalRead(encoder0PinB1) == LOW) {
      encoder0Pos1--;
    } else {
      encoder0Pos1++;
    }
     
   
  Serial.println (encoder0Pos1);
    Serial.print("Right");
   
  }
  motorrightrun();
  }
  encoder0PinALast1 = n1;
 
   if( encoder0Pos1==850)
  {
       encoder1();
  }

}


void encoder1()
{
  /* I am trying to make "When right motor statisfies the above condition ,function calls
  here and stop motor for 1 second and reset the encoder value" but I couldn't get the result*/
  digitalWrite(motorRightEnable_pin, LOW);
  analogWrite (motorRightPositive, 50);
  analogWrite (motorRightNegative, 50);
   delay(1000);
  encoder0Pos1 =0 ;  
}


void encoder()
{
  /* the same above scenerio here*/
  digitalWrite(motorLeftEnable_pin, LOW);
  analogWrite (motorLeftPositive, 50);
  analogWrite (motorLeftNegative, 50);
    delay(1000);
   encoder0Pos=0;
}


void  motorleftrun()
{
  digitalWrite(motorLeftEnable_pin, HIGH);
    analogWrite (motorLeftPositive, 50);
    analogWrite (motorLeftNegative, 0);
}

void motorrightrun()
{
  digitalWrite(motorRightEnable_pin, HIGH);
  analogWrite (motorRightPositive, 0);
    analogWrite (motorRightNegative, 50);  
}


***** I will update schematic soon and by the way I am using L298N motor driver *****

Pls reply and help me

Go Up