Pages: [1]   Go Down
Author Topic: Shaft encoders  (Read 643 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Amateurs train until they get it right, professionals train until they get it wrong... !-)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
i am new to Arduino and i am using it [Arduino ATMega 1280] for my project. i have a problem regarding rotary AB shaft encoding. i am using the below code and i am sure that i am missing some counts from the encoder :L can some one help me to either make this code more efficient or help me in developing other code... the encoding part is done in "void doEncoderA()"... thanks in advance. GXerri.

#define encoderXPinA 19
#define LED 13
int stopm01x = 22,stopm02y = 23,stopm03z = 24,stopm04  = 25,lock = 50;
//outputs
int m1a = 40,m1b = 41,m2a = 42,m2b = 43,m3a = 44,m3b = 45,m4a = 46,m4b = 47,posbx = 30, posby = 31, posbz = 32, posbr = 33;
int m1=40,m2=42,m3=44,m4=46;
int check,check1,message = 0;
unsigned int ZPos = 0, ZPosB = 0, x = 0, y = 0, a=0,b=0;

void setup()
{
  attachInterrupt(0, intt, HIGH); //pin 2
  // encoder pin on interrupt 4 (pin 19)
  attachInterrupt(4, doEncoderA, CHANGE);

  //outputs
  pinMode(m1a, OUTPUT);    //output motor 1 bit A and B
  pinMode(m1b, OUTPUT);    //
  pinMode(m2a, OUTPUT);    //output motor 2 bit A and B
  pinMode(m2b, OUTPUT);    //
  pinMode(m3a, OUTPUT);    //output motor 3 bit A and B
  pinMode(m3b, OUTPUT);    //
  pinMode(m4a, OUTPUT);    //output motor 4 bit A and B
  pinMode(m4b, OUTPUT);    //
  pinMode(lock,OUTPUT);
  //inputs
  pinMode(stopm01x, INPUT);
  pinMode(stopm01x, INPUT);
  pinMode(stopm02y, INPUT);
  pinMode(stopm03z, INPUT);
  pinMode(stopm04,  INPUT);
  pinMode(posby, INPUT);
 
  Serial.begin(9600);
}

void loop()
{
   free(m1),free(m2),free(m3),free(m4);  // free all motors
   do //home motor 3
    {
      digitalWrite(lock, HIGH);
      rev(m3);        //m3 goes reverse
      check=digitalRead(stopm03z);  //check sensor
    }
    while (check == HIGH);       // to be used with present sensor
    digitalWrite(lock, LOW);
      free(m3);        //free
      delay(500);
      ZPos=0;
for (int z=0; z<2; z++)
{
do
{
      digitalWrite(lock, HIGH);
      fwd(m3);       //m3 goes forward
}
while (ZPos != 45);

      digitalWrite(lock, LOW);
      free(m3);//free
      delay(1000);

do
{
      digitalWrite(lock, HIGH);
      rev(m3);
}
while (ZPos != 11);
      digitalWrite(lock, LOW);
      free(m3);    //free
      delay(3000);
 }
}

void doEncoderA()
{
  a++;
  // look for a low-to-high on channel A
  if (a==50)
  {
  if (digitalRead(encoderXPinA) == HIGH)
  {
    // check channel B to see which way encoder is turning
    if (digitalRead(posbz) == LOW)
      {ZPos = ZPos - 1;}         // CCW
    else {ZPos = ZPos + 1;}         // CW
  }
  else   // must be a high-to-low edge on channel A                                       
  {
    // check channel B to see which way encoder is turning 
    if (digitalRead(posbz) == HIGH) {ZPos = ZPos - 1;}          // CCW
    else {ZPos = ZPos + 1;}         // CW
  }
      Serial.print("ZPos= ");
  Serial.println (ZPos, DEC);         
  // use for debugging - remember to comment out
  a=0;
  }
}

void intt()
{
  digitalWrite(lock,LOW);
  brk(m1),brk(m2),brk(m3),brk(m4);  //break all motors
  delay(500);
  free(m1),free(m2),free(m3),free(m4);  // free all motors
  delay(100);
   
   Serial.println("i"); // "i\r" in C#
   delay(100);
  do
  {
    digitalWrite(13,LOW);    //show interrupt on led
    delay(10000);            //
    digitalWrite(13,HIGH);   //
    delay(10000);            //
    check = digitalRead(3);
    check1= digitalRead(2);
  }
  while((check1 == HIGH)||(check == LOW));     //block here
 //   while((check1 == HIGH));
   digitalWrite(13,LOW);
   
   Serial.println("r"); // "r\r" in C#
 // message = 's'; //this iu used to stop homing when the doors are opened
   digitalWrite(lock,HIGH);
   delay(100);
}

void  rev(int M)
{
      digitalWrite(M,HIGH);       //M rev
      digitalWrite(M+1,LOW);        //
}
void  fwd(int M)
{
      digitalWrite(M,LOW);       //M forward
      digitalWrite(M+1,HIGH);        //
}
void  brk(int M)
{
      digitalWrite(M,LOW);       //break
      digitalWrite(M+1,LOW);        //
}
void  free(int M)
{
      digitalWrite(M,HIGH);       //free
      digitalWrite(M+1,HIGH);        //
}

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
Amateurs train until they get it right, professionals train until they get it wrong... !-)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Logged

0
Offline Offline
Shannon Member
****
Karma: 199
Posts: 11649
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

[ don't forget to use the code tags (# button) ]

Your code doesn't make sense - you increment a until it reaches 50 - this deliberately misses transistions.  You have to record the step direction on every transition - the shaft can backstep at any time (even if the motor is turning one way, the encoder can have jitter/noise/vibration, only the combined state of A and B can disambiguate this from real steps)
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 7
Amateurs train until they get it right, professionals train until they get it wrong... !-)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

first of all thanks for your reply smiley-grin
secondly i am incrementing a up to 50 and then resets it back to 0
i am using this sort of dividing [sampling] the number of pulses the encoder is giving me cos it is giving me loads of pulses...
but even without that variable 'a' i am missing counts...

any idea how i can improve my code?? :L

Thanks.
GScerri.
Logged

0
Offline Offline
Shannon Member
****
Karma: 199
Posts: 11649
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah, you have calls to Serial.print in an interrupt handler?  That's definitely not going to help. you might be in the handler for many milliseconds.
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 7
Amateurs train until they get it right, professionals train until they get it wrong... !-)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

yes i am using that Serial.print for debugging (to know the position of the shaft at a moment), and i think it is the problem :L
ill try it without the Serial.print and let you know the outcome...

Thanks:)
Logged

Pages: [1]   Go Up
Jump to: