Pages: [1] 2   Go Down
Author Topic: attachInterrupt debounce or Dirty Power supply?  (Read 1022 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Working on a project to count short random 5 volt pulses generated from a car's onboard computer.  The signal is normally low, but sends out a very short (maybe 5ms) 5 volt pulse whenever certain conditions are met.  The pulses occur randomly and not based on any pattern or timing.  The problem is that the attachInterrupt function seems to be firing more than once for some of the pulses.  Maybe 1 in 10 pulses will get double counted.  See code below.  Thinking it was a dirty power issue, I added .1uf capacitors to the input and output of the 7812 I'm using to power the arduino (MEGA2560) along with a separate 220uf on the output. That did seem to help some, but the double counting still occurs. Circuitwise, I have the pulse going through a voltage follower (CA3240EZ op amp), and am using a pull-down resistor on the interrupt pin (because otherwise I could not get it to trigger on RISING). 

Any thoughts on how to eliminate the double counting?


#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
volatile int allCounts=0;
volatile int wotCounts=0;
int wotPin = 21;
int i;

void setup() {
  pinMode(wotPin, INPUT);
 lcd.begin(16,2);
 
    attachInterrupt(3, iSr, RISING);
 
lcd.begin(16,2);
  lcd.print("All Counts:     ");
  lcd.setCursor (0,1);
  lcd.print("WOT Counts:     ");
  delay (100);
}

void loop() {
 
  lcd.setCursor(11, 0);
  lcd.print(allCounts);
  lcd.setCursor(11,1);
  lcd.print(wotCounts);

}

void iSr()

{
  if (digitalRead(wotPin)== LOW) wotCounts++;
  allCounts++
  ;

}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In the ISR, record when the last pulse occurred. Before incrementing the counters, see if now minus then is greater than some reasonable value.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 222
Posts: 12549
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you have the means to do so, it would be sensible to put a scope on the Arduino input and see whether it is getting the clean signal in that you are intending. If the signal needs cleaning up, it may be easiest to do this externally.

To tackle the problem in software, I'd define a 'pulse' as a rising edge followed by a falling edge after the expected interval. Each time you detect a rising edge record the time, and each time you detect a falling edge calculate the duration of the pulse; only count it if it is within the range of valid pulse lengths.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Peter and Paul, very helpful.  I like the simplicity of just subtracting the now from then approach, but  cant figure a way to make that work for the very first pulse?  Seems like the first pulse will always be counted whether valid or not.  With the rising and falling approach, I assume I'd have to use 2 interrupt pins for the same signal, or can I attach he same pin as both a rising and falling interrupt?
Logged

Poole, Dorset, UK
Offline Offline
Edison Member
*
Karma: 50
Posts: 2202
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void iSr()

{
  if (digitalRead(wotPin)== LOW) wotCounts++;
  allCounts++
  ;

}

To me (at least) this code makes no sense!. You are looking a rising edge on pin 3 but what is wotpin? doing and why should it be low?

Mark
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

wotPin monitors an on/board signal that is normally high but goes low at wide open throttle (WOT).  I wanted to keep a running total of all events, and a separate tally of events that occur when the throttle is fully open.  It's working fine, as is the whole sketch, but for the occasional extra count from the noisy environment.
Logged

Poole, Dorset, UK
Offline Offline
Edison Member
*
Karma: 50
Posts: 2202
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't think checking wot in the same ISR as the other "random" event is the right thing to do. Why not give it its own ISR?

Quote
but for the occasional extra count from the noisy environment.

The above is your unconfirmed assumption!.

Mark
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Seems like the first pulse will always be counted whether valid or not.
How can the first pulse not be valid? It is the second or third pulse immediately following any given pulse (within some timeframe) that might not be valid. The first in a sequence is always valid.
Logged

Offline Offline
God Member
*****
Karma: 27
Posts: 829
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When this happened to me with an optical encoder, I learned that it was because the voltage was not as "5V" as I thought it was.

This might be a dumb question,but do you have your arduino connected to the same ground and the ground used on whatever is sending the pulse? I suspect not, or you probably wouldn't have needed the pulldown.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't think checking wot in the same ISR as the other "random" event is the right thing to do. Why not give it its own ISR?

Hmmm.... hadn't thought of doing that.  Easy enough to give it a try though....

Quote
but for the occasional extra count from the noisy environment.

The above is your unconfirmed assumption!.

Mark

It is my unconfirmed assumption!.  Do you have another theory/explanation?
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When this happened to me with an optical encoder, I learned that it was because the voltage was not as "5V" as I thought it was.

This might be a dumb question,but do you have your arduino connected to the same ground and the ground used on whatever is sending the pulse? I suspect not, or you probably wouldn't have needed the pulldown.

Yes, it all ties back to the car battery...
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Seems like the first pulse will always be counted whether valid or not.
How can the first pulse not be valid? It is the second or third pulse immediately following any given pulse (within some timeframe) that might not be valid. The first in a sequence is always valid.

That might be right.  Let me mull that over with code....   
Logged

Offline Offline
God Member
*****
Karma: 27
Posts: 829
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, well the secret is likely held within the reason why you would need a pulldown. That means that your actual voltage from this 5V pulse was never actually at ground (or below the LOW level the arduino expected) when it was LOW until you put in the pulldown. That is why it never seen a rising edge. So, my guess is that the voltage of this is swinging around and counting extra pulses. Connecting a scope would make this all clear.

5V is only 5V with reference to the same ground. "GND" may be 3V, and 5V may be 8V, but between the two is still 5V.

Perhaps this is an open-drain or open-collector output? In that case, the reference to ground is disconnected.

All we can do is guess without looking at the signal on the scope. Your actual code looks like it should work as long as the signal is actually doing what you think it doing. So likely it isn't doing what you think it is doing.

BTW, what is the value of the pulldown resistor that you are using? According to the ATMEL datasheet for the min voltage for VIH is 3V, and the max voltage for VIL is .3V. And your code could not see a rising edge unless you put in a PULLDOWN. That means your input was somehow floating above 3V so it never saw a rising edge (it always just read HIGH.) You had to pull that signal down to ground for it to ever see a LOW. Perhaps you are dealing with interfacing to ECL logic which is 3.4V for a low, and 4.2V for a high? And also uses GND a bit differently than your arduino does.

Lacking a scope, you may want to just run a simple sketch that reads the state (just using digitalRead) periodically without your pulldown installed. Then try a pulldown, and then try a pullup. If none of these work as expected, try looking at it with an analog pin actually reading the voltage level periodically (basically an o-scope.) Alternatively, you could do something like this: http://www.instructables.com/id/Girino-Fast-Arduino-Oscilloscope/

In the end, if you are dealing with interfacing with a different type of logic family you will need to find the right way to interface it. There are ECL to TTL translator ICs for example. The reason I am pointing you at this is because, as I said, your code should not have a problem. So the problem is in the signal, it may be noise, it may be something else, but the fact that you had to use a pull-down really points at a GND difference to me or a signal with a different different interpretation of what is HIGH and what is LOW than your arduino. There are several logic families out there and they are not all compatible exactly with each other.
« Last Edit: February 08, 2013, 07:14:31 am by Retroplayer » Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Retro, you make a good point.  It may be that I added the pull down before cleaning up the power supply and falsely concluded it was needed.  I will look at the need for the pull down more closely. I have a pc-based scope I will try too.  I have logged the signal before at a relatively low sample rate and it showed ground other than the 5c pulses. 
Logged

Offline Offline
God Member
*****
Karma: 27
Posts: 829
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Retro, you make a good point.  It may be that I added the pull down before cleaning up the power supply and falsely concluded it was needed.  I will look at the need for the pull down more closely. I have a pc-based scope I will try too.  I have logged the signal before at a relatively low sample rate and it showed ground other than the 5c pulses. 

When you do check it again, also do a check using the ground point at the arduino just to be sure it looks the same (it should, of course, but just to be thorough.)
Logged

Pages: [1] 2   Go Up
Jump to: