This is my first time posting on this forum. I have tried to format this question properly, but let me know if I need to correct anything. I searched to see if someone else had a similar problem, but let me know if someone has already answered this question.

Overview: I am sending pulses to my Arduino, but sometimes one single pulse is interpreted as anywhere from 2 to 30 pulses. But after looking at the pulse on an oscilloscope (see Fig. 1) I am not sure why. When I use a really long wire the ratio of false pulses to legit pulses is about 1 to 1. I shortened the length of the wire and improved the situation, so that only 1 in about every 2,000 pulses is registered as a false pulse.

For one test, I added a capacitor to the short wire situation, but that increased the rise time and made the problem worse. I am currently using attachinterrupt and have tested the situation with using both a rising and falling edge. Right now, I mainly want to understand how interrupts work on the Arduino in light of my current problem, although I welcome general advice.

  1. When I set the interrupt to the falling edge, why does the Arduino still sometimes count 1 pulse as several? The falling edge in the photo, which is for the really long wire case, lasts about 40 microseconds and appears to have a clean break. The pulse remains low for about 80 milliseconds. Could the falling interrupt trigger during the rise time based off the oscillatory behavior shown in Fig. 1? I smoothed out the signal by adding in a 1 nF capacitor, but the Arduino still counted false pulses. So could the rise time period have anything to do with it? I also have a 10k Ohm pullup resistor connected to the Arduino's 5 V for the pulse path.

I have the relevant code attached below. I have much more code as well, but it deals with saving pulseCounts to the SD Card and uploading electricity consumption files through the cell network.

Cheers.

//Global Variables
unsigned long pulse_time = 0;
unsigned long last_pulse_time = 0;
byte code = 1; //code let's me see if a false pulse was reported for each 
//SD file

void setup() {
  attachInterrupt(digitalPinToInterrupt(3), onPulse, RISING);
}

void onPulse() {
  pulse_time = millis();
  if ((pulse_time - last_pulse_time) > 50 ) {
    Serial.println("Good Pulse");
    pulseCount++;
    last_pulse_time = pulse_time;
  } else {
    Serial.println("Bad Pulse");
    pulseCount++;
    code = 2;
  }
}

Fig. 1: Pulse With Really Long Wire (Counted as multiple pulses)

  • 1
    That is not a nice pulse. You can fix it with a rc filter and a transistor. The transistor can be triggered at a lower voltage. Looking at the scope picture, about 1.5 to 2V would be a good trigger voltage (because the 0V is much stronger than the 5V level). You may not use the Serial.println in a interrupt function because they use interrupts themself. Because of the Serial.println, you can not make any conclusions with this sketch. – Jot Apr 9 at 11:13
  • Thanks, I ran the test again leaving out the Serial.println statements and instead printed the statements in loop(), but I still get false pulses. I believe I have tried a RC filter. I always have a 10 kOhm resistor tied to the 5 V line, but then I added a 1 nF capacitor between the pulse line and ground. The signal from that is much smoother, but it increases the rise time, so I still have false pulses. I could add a transistor, but before adding hardware I am more curious about why it is counting multiple pulses. Is there a way to determine if it is rise time or the oscillations? – Bryan Kinzer Apr 9 at 14:01
  • 1
    How is the signal generated? Is it just pulled low by the external source? I'd try a lower value pull-up resistor? Also, a Schmitt trigger could help to prevent the effect of a (very) slow rise. – Gerben Apr 9 at 15:03
  • I have a pulse meter that generates a pulse for every unit of electricity consumed. Yes, the pulse line is default high (5 V) and is then pulled low for the duration of the pulse to 0 V before returning high. I have done a test with a 1 kOhm resistor, and it decreased the rise time to about 4 milliseconds as compared to about 25 milliseconds in the short wire case. The signal looks smooth, but I have been warned that there may be unintended consequences for making a pull up resistor below 10 kOhms. Is there a reason I should be hesitant about lowering the pull-up resistor value? – Bryan Kinzer Apr 10 at 6:59

Firstly, unless the processor pin is a Schmitt trigger, increasing capacitance will only make the problem worse by allowing any noise to be interpreted as multiple high-low transitions. For a CMOS logic input the area around the transition point of 1/2 VDD typical is actually an area of linear operation, not digital.

A Schmitt trigger introduces hysteresis such that when the signal is interpreted as a high level, it must go low by more than the hysteresis to be interpreted as a low level again. This is accomplished with a bit of positive feedback added to a buffer where the output transition from low to high then pulls the input that much higher or a transition from high to low pulls the input that much lower:

enter image description here

The red line represents the typical CMOS threshold and the green lines represent the thresholds defined by the hysteresis of the Schmitt trigger. The hysteresis defines the noise immunity of the input. Most processors have pins that are equipped with a Schmitt trigger or and external device like a 74HC14 can be used.

Another way to deal with this type of noise is to lock out any transitions within the expected pulse-to-pulse transitions: Once triggered, no more transitions are allowed until the lock out time expires.

  • 1
    ATmega inputs are Schmitt triggers. – Chris Stratton Apr 10 at 20:03
  • Okay, from this article link it mentions that for a 5 V arduino, VIH = 3.0 V. Does that mean that if I set the Interrupt to RISING, that it should only trigger when the pin voltage starts below VIH and then becomes higher than VIH? Is VIH the correct term for a CMOS threshold and does VIH = 3.0 V on my ATMEGA328 chip? The oscillatory behavior on the oscilloscope seems to occur when the voltage is more than 4 V. – Bryan Kinzer Apr 13 at 10:04
  • For that part at 5V the maximum low voltage (VIL) is 1V and the minimum high voltage (VIH) is 3V. When an interrupt is set to trigger on a rising edge, then that means the input must go from low to high to generate an interrupt but even a short noise pulse of a few micro seconds from high to low to high again can generate a new interrupt. I see from your scope capture that there is a lot of ripple on the input which means that there is probably a lot of ripple on your 5V... if your 5V goes higher while your input stays the same, this looks to the processor like the input is going lower. – John Taylor Apr 18 at 16:25

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.