0
Offline
Newbie
Karma: 0
Posts: 13
Arduino rocks
|
 |
« on: February 04, 2013, 09:10:31 am » |
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? 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; }
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #1 on: February 04, 2013, 09:35:06 am » |
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?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 13
Arduino rocks
|
 |
« Reply #2 on: February 04, 2013, 10:24:14 am » |
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?
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 269
Posts: 25381
Solder is electric glue
|
 |
« Reply #3 on: February 04, 2013, 10:29:08 am » |
That code will only fire the interrupt ona rising edge not a state change.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #4 on: February 04, 2013, 10:30:31 am » |
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?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 13
Arduino rocks
|
 |
« Reply #5 on: February 04, 2013, 11:03:53 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Milton Keynes UK
Offline
Tesla Member
Karma: 88
Posts: 6277
-
|
 |
« Reply #6 on: February 04, 2013, 11:10:10 am » |
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?
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #7 on: February 04, 2013, 11:10:11 am » |
I have seen some cases where this has occurred in my data. But, is that reflected in the data in the graph?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 13
Arduino rocks
|
 |
« Reply #8 on: February 04, 2013, 11:17:56 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #9 on: February 04, 2013, 11:22:06 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 13
Arduino rocks
|
 |
« Reply #10 on: February 04, 2013, 11:29:28 am » |
Doubtful, but this is what it looks like. I think it may just be noise. It occurred 5 times in 2300 data points.
|
|
|
|
|
Logged
|
|
|
|
|
Miramar Beach, Florida
Offline
Faraday Member
Karma: 49
Posts: 3441
|
 |
« Reply #11 on: February 04, 2013, 11:43:37 am » |
Just a thought. Maybe the interrupt is happening when you don't expect it. 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; }
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 13
Arduino rocks
|
 |
« Reply #12 on: February 04, 2013, 12:10:39 pm » |
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?
|
|
|
|
|
Logged
|
|
|
|
|
Miramar Beach, Florida
Offline
Faraday Member
Karma: 49
Posts: 3441
|
 |
« Reply #13 on: February 04, 2013, 12:14:26 pm » |
I would try this for a while. See if the pulse_count keeps up with the number you expect. void loop() { Serial.print(millis()); Serial.print(","); Serial.print(analogRead(0)); Serial.print(","); Serial.println(pulse_count);
// pulse_count = 0; }
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 13
Arduino rocks
|
 |
« Reply #14 on: February 04, 2013, 12:16:48 pm » |
Thanks, I'll give it a try and report back.
|
|
|
|
|
Logged
|
|
|
|
|
|