Need Help in Interrupts?

Hi,

I am using optical wheel encoder for measuring the distance travelled and I have connected the signal to (digitalPin2) i.e.interrupt 0, and if I started to count it is giving out random values for 1 count, Ex. 1 count sometime equals 10 counts or sometime equals 50 counts, This has inbuilt schmitt trigger so no issues, Code I use

#define m1 10
#define m2 11
#define m3 12
#define m4 13

const byte left = 0;
const byte right = 1;

volatile int count1;
volatile int count2;


void setup() {
  Serial.begin(250000);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  attachInterrupt(left, incrementer, FALLING);
  // attachInterrupt(right, incrementer1, RISING);

}

void loop() {
  turnright90fn();


}

void turnright90fn()
{
  detachInterrupt(left);
  Serial.print("count1: "); Serial.print(count1); Serial.println("  ");
  attachInterrupt(left, incrementer, FALLING);
  //Serial.print("count2: "); Serial.print(count2); Serial.println("  ");




}


void incrementer()
{
  count1++;
}

void incrementer1()
{
  count2++;
}

And when I do the same using (digitalPin3) i.e. interrupt 1, I am having perfect counts, but I am having two optical encoders and I am using Arduino Uno, which is limited to 2 interrupts, can anyone help me in this.

FYI.

  1. I tried using different Arduino Uno's
  2. Tried using different optical sensors in same pin

Screen Shot of the output which has to show the number "30"(counts/ revolution) is showing somewhere around 150's is attached

Why do you keep attaching and detaching your ISR? Makes no sense to me.

While printing Serial values I dont want interrupt to interfere in printing issues

The preferred way to disable/enable interrupts for reading the values from the isr's is to use noInterrupts() and interrupts(). It has to do with avoiding "race conditions". Arduino Interrupts - #10 by nickgammon - Programming Questions - Arduino Forum

Can you provide some link to the encoders and schmitt triggers. Have you tried configuring the interrupt pins as INPUT_PULLUP

While printing Serial values I dont want interrupt to interfere in printing issues

So, disable interrupts, copy the value, enable interrupts, and print the copy.

That's not the way to count transitions for a quadrature encoder.

You need to use CHANGE, not RISING or FALLING, and you need to run your
ISR on both interrupts - whenever one of the signals changes you have to update the
count for that transition. Unless you sample all the edges you will get miscounting.

There should be one count variable only, incremented or decremented according to which
transition (there are 8 legal transistions, 4 increment and 4 decrement. If both signals
change at once this is an illegal transition and usually means your encoder is running too
fast for the interrupt latency)

I use a changed version of this interrupt driven encoder software.

It works on any pins (with restrictions or bigger changes) using the changeinterrupt capability.

Works like a charm (after changing to use the registers to fit my setup).

will try all those and get back to you guys shortly

thanks

You really need to provide some information about your encoders. Are they quadrature encoders with two channels of output, or are they the more simple optical discs running through a sensor with only one high/low output?

One way would be to attach the outputs of all your encoders to XOR gates, monitor that on a pin looking for CHANGING, and have the interrupt routine inspect the other pins to work out which one has changed.

But unless your encoder wheels are moving really fast, or something inside your sketch delays execution, there's no special need for an interrupt - loop() should execute quickly enough that you can poll the pins and not miss anything.

It is simple optical disc running through a (ir tx and rx) which simply gives out high and low whenever the optical discs passes through it, disc has open and close sections in which disc open section gives out 1 state whereas a disc closed section gives out 0 state.

Disc has 30 open sections for one full revolutions. Let me get you the link of the encoder

But my doubt is I have no problem when I attached to the (digitalPin3), I am getting a perfect 30 counts,but while I attach to (digitalPin2) as my pin , I am getting this problem

I have no problem when I attached to the (digitalPin3), I am getting a perfect 30 counts,but while I attach to (digitalPin2) as my pin , I am getting this problem

In your first posting, the pin 2 (int0) interrupt was RISING, and the pin3 (int1) interrupt was FALLING. When you say that pin 2 does not work properly, but pin3 does, is it with the same encoder disc, sensor and interrupt condition? Does pin 2 work with a FALLING interrupt? Does pin 3 work with a RISING interrupt?

Do you have the external pull up resistor shown in the diagram on this page?

Here is some code to test the functionality of pin 2 interrupt using the tone() function. Jumper pin 11 to pin 2 and run this code. You should see 200 counts per second.

volatile unsigned int count;

void tone_ISR()
{
  count++;
}
void setup() {

  Serial.begin(9600);
  Serial.println("starting interrupt count");
  tone(11, 200);
  attachInterrupt(0, tone_ISR, RISING); // ISR-0 on pin2 (Atmega328)

}

unsigned long lastSecond;
void loop()
{
  if (micros() - lastSecond >= 1000000L)
  {
    lastSecond += 1000000;
    noInterrupts();
    unsigned int copyCount = count;
    count = 0;
    interrupts();
    Serial.println(copyCount);
  }
}

@cattledog,

Tested your code, it shows 200 and 201

Whereas this code is getting me exact 30 counts in digitalPin2

int a;
int b = 0;

unsigned int count  = 0;

void setup() {


  pinMode(2, INPUT);
  Serial.begin(250000);
}

void loop() {

  int a = digitalRead(2);

  if (a == 1 && b==0)
  {
    
    Serial.println(count++);
   
  }
  b = a;
}

Your problem is not with pin 2.

I thought my problem will be in my encoder, so tested with that code, that code being executed perfectly, makes me believe that there is no problem with my encoder or my uno board,

Now I doubt my original code, I am re-writing it again

tried with this code, but even then I am having the same problem

volatile int ticks;



void setup()
{

  Serial.begin(250000);
    attachInterrupt(0, isr, FALLING);

  }

  void loop() {


  Serial.print("counts"); Serial.print(ticks); Serial.println(" ");
}

void isr()
{
  ticks++;
}

@cattledog,

what might be the problem, if the problem is not with pin2

Will there be any problem with attachInterrupt function, but its working like a charm in (Interrupt 1),

Anybody having faced this issue before?

I now tried Arduino 1.0.5(IDE), writing the same code, even now, interrupt 0 is not working but interrupt 1 is working perfect, yet to find a solution, but I am near to it