Pages: [1]   Go Down
Author Topic: Arduino board - Interrupt Pin rate?  (Read 453 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I'm using Arduino UNO and trying to do position control of geared DC motor with encoder.
The following is code to check if the encoder counting is working. (well it's not..)

Code:
#define encA 2 // encoder channel A
#define encB 3 // encoder channel B

volatile int enc0 = 0; // initial encoder count #
int en1 = 5; // motor1 enable
int dir1 = 4; // motor1 direction
int pwm1 = 6; // motor1 pwm

void setup() {
  pinMode(en1, OUTPUT);
  pinMode(dir1, OUTPUT);
  pinMode(encA, INPUT);
  attachInterrupt(0, doEncoder_Expanded, CHANGE); // do counting if encA CHANGE
  pinMode(encB, INPUT);


  Serial.begin(9600);
  Serial.println("start");
 
}

void loop(){

  Serial.println(enc0);
  analogWrite(pwm1, 150);
  digitalWrite(en1, HIGH);
  digitalWrite(dir1, HIGH);
 
  if (enc0>100){
  analogWrite(pwm1, 0);
  delay(1000);
  enc0 = 0; 
}
}

void doEncoder_Expanded() {
  if (digitalRead(encA) == HIGH) {
    if (digitalRead(encB) == LOW) {
      enc0 = enc0 + 1;
    }
    else {enc0 = enc0 - 1;}
  }
  else {
    if (digitalRead(encB) == LOW) {
      enc0 = enc0 - 1;
    }
    else {enc0 = enc0 + 1;}
  }
}

encoder channel A and B are attached to interrupt pins and enc0 is supposed to increase/decrease as motor rotates. But the motor keeps rotating and en0(counting #) is printed as 0 all the time.
Maybe because the resolution of the encoder is 1024 and the geared ratio is 16:1, the Arduino interrupt pins cannot read the signal. (Because of so many countings..)
Is it really the problem of slow interrupt pin rate?
I'm not sure what is the critical problem.. THX
Logged

0
Offline Offline
Shannon Member
****
Karma: 220
Posts: 12700
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Use direct port manipulation for reading the encoder pins, much faster than digitalRead(), and you should get
quite a speed-up.

You can check pin2 (on an Uno) like this
Code:
  if (PIND & 4)
and pin3
Code:
  if (PIND & 8)
So something like this will run faster:
Code:
void doEncoder_Expanded()
{
  byte b = PIND ;
  if (b & 4)
  {
    if (b & 8)
      enc0 -- ;
    else
      enc0 ++ ;
  }
  else
  {
    if (b & 8)
      enc0 ++ ;
    else
      enc0 -- ;
  }
}
Note the copying of PIND into b - this means that we read the state of pin2 and 3 simultaneously and just once - this
prevents any race conditions.
Logged

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

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thx for your help.

How can I define PIND then? It seems like the state of encoder pin, but you meant both of the pins, A and B.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34724
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thx for your help.

How can I define PIND then? It seems like the state of encoder pin, but you meant both of the pins, A and B.

You don't define it,it's already predefined just like HIGH and LOW
Logged

0
Offline Offline
Shannon Member
****
Karma: 220
Posts: 12700
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

google knows about direct port manipulation, thats why I mentioned the phrase.

  http://www.arduino.cc/en/Reference/PortManipulation
Logged

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

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

THX both of you.
Now I can expect better accuracy. I'll try!
Logged

Pages: [1]   Go Up
Jump to: