Go Down

Topic: Interrupt Missing Pulses (Read 1 time) previous topic - next topic

Momonga

My software counts pulses from a wheel encoder but it appears to be missing pulses.
Arduino IME is 1.0.3, board is Duemilanove.

The output form the wheel encoder is wired to DI pin 2 (Interrupt 0).  The same signal is also wired to AI0 to record the wave shape.

I have tried moving the interrupt to DI3 with no change.  I have also tried all interrupt types with no change.

See below code and attached data plot.  Data was recorded with interrupt type "Change".    The pink Pulse line is the Arduino count for interrupts.  As you can see it sometimes misses the rising edge, sometimes the falling edge, and sometimes both.  The waveform looks nice and smooth in both the Arduino collected data and also on an Oscilloscope.  Am I missing something simple?

Code: [Select]
volatile int pulse_count = 0;

void setup() {
  for (int i=2;i<14;i++){
    pinMode(i, INPUT);
  }
  attachInterrupt(0, new_pulse, RISING);
 
  Serial.begin(128000); 
}

void loop() { 
  Serial.print(millis());
  Serial.print(",");
    Serial.print(analogRead(0));
    Serial.print(",");
    Serial.println(pulse_count);
    pulse_count = 0;
}

void new_pulse()
{
  pulse_count = pulse_count + 1;
}




PaulS

Quote
The same signal is also wired to AI0 to record the wave shape.

On or off. What shape, besides a square wave, are you expecting?

What is on the other end of the serial port? Why do you suspect that the problem is with the Arduino?


Momonga

The waveform is what I am expecting, a square wave.
The encoder output is connected to DI2 and AI0.  The Arduino is connected to a laptop which is recording the data via Excel.

The wave shape is as expected and looks clean.  I would expect the Arduino to record a pulse count every time it meets the interrupt criteria, "change" in the case of the data shown.  The Arduino is not showing a count at each state change so could it be that the Arduino is missing the transition?  Could it be something else?  Sure, any ideas?

Grumpy_Mike

That code will only fire the interrupt ona rising edge not a state change.

PaulS

Quote
I would expect the Arduino to record a pulse count every time it meets the interrupt criteria, "change" in the case of the data shown.  The Arduino is not showing a count at each state change so could it be that the Arduino is missing the transition?

The only way that you know this is in the serial data being output. If two encode interrupts occur between serial outputs, how are you dealing with that?

Resetting pulse_count the way that you are could be a problem. Setting an int to a value is a multi-step process, since both the high order byte and the low order byte need to be set. What happens if an encoder interrupt happens in the middle of updating pulse_count?

Momonga

The counter is incremented every time the interrupt routine is called so if two interrupts occur between serial outputs (loops through the code) then the nunber 2 should be sent over the serial link.  I have seen some cases where this has occurred in my data.

Good point on resetting.  I can change the data to Byte or is there a better option?

I will make the change and run it again.

PeterH

I would have thought you should disable interrupts briefly in loop(), just long enough to take a local copy of the pulse count and zero the volatile global copy. If you disable interrupts while doing that then it should be OK using an int counter, but since you seem to be only getting values of 0 or 1, I'd have thought a byte variable made more sense.

Also I'm surprised to see the falling edges triggering interrupts - is that definitely running the same code you posted?
I only provide help via the forum - please do not contact me for private consultancy.

PaulS

Quote
I have seen some cases where this has occurred in my data.

But, is that reflected in the data in the graph?

Momonga

The code posted showed interrupts on Rising, but I took lots of data with Rising, Falling, and Change.  The data shown is "Change".  Sorry for the confusion.

The data showing the counter is not shown in the data I posted.  It was in another file.  If it's helpful I will post it.

PaulS

Quote
The data showing the counter is not shown in the data I posted.  It was in another file.  If it's helpful I will post it.

The question is whether the "missing pulses" are where the next/previous "pulse" was really two pulses.

Momonga

Doubtful, but this is what it looks like.  I think it may just be noise.  It occurred 5 times in 2300 data points.


SurferTim

Just a thought. Maybe the interrupt is happening when you don't expect it.
Code: [Select]
void loop() { 
  Serial.print(millis());
  Serial.print(",");
    Serial.print(analogRead(0));
    Serial.print(",");
    Serial.println(pulse_count);

   // How would this do if the interrupt happens here?
   // Now the pulse_count should be 1, but...
   pulse_count = 0;
}


Momonga

It's possible.  How do I find out?

I would assume this would be the same issue everyone has who uses a wheel encoder and needs an accurate count for navigation.  Anybody have a solution?

SurferTim

I would try this for a while. See if the pulse_count keeps up with the number you expect.
Code: [Select]
void loop() { 
  Serial.print(millis());
  Serial.print(",");
    Serial.print(analogRead(0));
    Serial.print(",");
    Serial.println(pulse_count);

   // pulse_count = 0;
}


Momonga

Thanks,  I'll give it a try and report back.

Go Up