Pages: [1]   Go Down
Author Topic: Interrupt Overhead  (Read 924 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey,

I have been trying to calculate the velocity for two motors, using encoder interrupts, which later would be used to apply PID control. Velocity Calculation code gives out correct velocity till a certain rpm (goes up as input voltage goes up), but then starts giving negative velocity (goes down as voltage goes up). Following is the code:

Code:

#define DirectionPin 3    // direction pin

int encoder0Pos = 0,oldPos = 0;  // encoder position
int dir = 0;
unsigned long oldTime, newTime, dt;
float vel;


void setup() {
  Serial.begin(9600);            // set up Serial library at 9600 bps
  pinMode(DirectionPin, INPUT);

// encoder pin on interrupt 0 (pin 2)
  attachInterrupt(5, doEncoder, RISING);
  oldTime = millis();
}

void loop() {
  newTime = millis();              // read the current time stamp
  dt = newTime - oldTime;           // compute delta time
  oldTime = newTime;
 
  vel = (float) ((encoder0Pos - oldPos) * 4.25) / (dt);  // velocity estimate in ms 
  int temp = encoder0Pos - oldPos;
  oldPos = encoder0Pos;
 
  Serial.println(vel);
}

// Interrupt routine
void doEncoder()
{
  dir = digitalRead(DirectionPin);     // read the direction of motor
  if (dir == HIGH) {encoder0Pos = encoder0Pos - 1;}
  else {encoder0Pos = encoder0Pos + 1;}
 
}


I need to connect three of these motors later in near future, but this code seems to have lot of interrupt overhead. Interrupt frequency is around 8000 ticks per second per motor.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26332
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You could get rid of the digitalRead in the ISR, and use the fast version instead.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

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

I did the same. Following is the code.

Code:

#define DirectionPin 3    // direction pin

int encoder0Pos = 0,oldPos = 0;  // encoder position
int dir = 0;
unsigned long oldTime, newTime, dt;
float vel;


void setup() {
  Serial.begin(9600);            // set up Serial library at 9600 bps
  pinMode(DirectionPin, INPUT);

// encoder pin on interrupt 0 (pin 2)
  attachInterrupt(5, doEncoder, RISING);
  oldTime = millis();
}

void loop() {
  newTime = millis();              // read the current time stamp
  dt = newTime - oldTime;           // compute delta time
  oldTime = newTime;
 
  vel = (float) ((encoder0Pos - oldPos) * 4.25) / (dt);  // velocity estimate in ms 
  int temp = encoder0Pos - oldPos;
  oldPos = encoder0Pos;
 
  Serial.println(vel);
}

// Interrupt routine
void doEncoder()
{
  dir = (PINE & 0b00100000) >> 5;
  if (dir == HIGH) {encoder0Pos = encoder0Pos - 1;}
  else {encoder0Pos = encoder0Pos + 1;}
}


I could notice some improvement but, I finally need to implement this with three motors in parallel. Connecting two of them, I faced the same problem again. Any solutions?
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26332
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That wasn't quite what I meant.
I see no reason here that "dir" should be global.
Either:
Code:
  if (digitalReadFast(DirectionPin) {encoder0Pos = encoder0Pos - 1;}
  else {encoder0Pos = encoder0Pos + 1;}
or
Code:
  if ((PINE & 0b00100000) >> 5) {encoder0Pos = encoder0Pos - 1;}
  else {encoder0Pos = encoder0Pos + 1;}
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

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

Cool ! Thanks a lot for your reply.

I will try that soon and post my results here !
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26332
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I forgot: encoder0Pos should be declared "volatile"
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

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

Hey,

May I know the reason for declaring it 'volatile'?

By the way, forgot to mention, Interrupt frequency is around 12646 counts per sec per motor.
(1024 Counts per Rotation and 741 Rotations per Minute (RPM))

I tested my motor with your suggestions incorporated. It (two motors together) still gives erroneous velocity values.

Would you suggest me to consider following options?

  • Analog PID Controller (using resistors, Op-Amp and Capacitors)
  • Use of Motion Control Chip (PID Controller - LM629)

Thanks in advance !
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26332
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
May I know the reason for declaring it 'volatile'?
Sometimes, the reference material is a little deficient.
Not in this case, however:
http://arduino.cc/en/Reference/Volatile
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Grand Blanc, MI, USA
Offline Offline
Faraday Member
**
Karma: 95
Posts: 4084
CODE is a mass noun and should not be used in the plural or with an indefinite article.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I forgot: encoder0Pos should be declared "volatile"

And should be accessed atomically in loop() ?
Logged

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26332
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good point.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Pages: [1]   Go Up
Jump to: