Pulse interface on power meter - is debouncing needed?

Hi, I have a power meter with SO Pulse interface which generates 2000 pulses / 1kWh (http://www.eltako.com/fileadmin/downloads/en/_flyer/electronic_single-phase_energy_Meter_with_display_WSZ12DE_gb.pdf). Pulse lentgh is 50ms. I would like to count pulses with arduino and send the counted values in certain time intervals to my mysql server via ethernet. I did initial testing - connected +5V from arduino uno to SO+ pin on the power meter, and D2 to SO- pin. I also connected 10k pulldown resistor between D2 and GND. Basically it works, but when I counted the pulses and compared with the kWh value measured on the power meter's display, the result is my arduino measured more kWh than the power meter (difference in my tests was 0.02 - 0.08 kWh and it looks this difference increases with the longer measured time intervals).

What I am interested in is whether I need some kind of debouncing for the input. As there is not mechanical switching inside of the powermeter I assume the debouncing should not be needed. Or am I wrong?

The other thing - I used 10 meter wire (0.5mm2 / 20 AWG). Can this be an issue?

This was my code:

volatile int IRQcount;
int pin = 2;
int pin_irq = 0; //IRQ that matches to pin 2

void setup() {
  // put your setup code here, to run once:
  Serial.begin (9600);
  Serial.println("starting");
  attachInterrupt(pin_irq, IRQcounter, RISING);
  
}

void IRQcounter() {
  IRQcount++;
}

void loop() {
  // put your main code here, to run repeatedly:

  cli();//disable interrupts
  IRQcount = 0;
  sei();//enable interrupts

  delay(60000);

  cli();//disable interrupts
  int result = IRQcount;
  sei();//enable interrupts

  Serial.print(F("Counted = "));
  Serial.println(result);
}

--> this gave me results like ~30-35 pulses per 1 minute

Then I tried to alternate the code and enter some debouncing:

volatile int IRQcount;
int pin = 2;
int pin_irq = 0; //IRQ that matches to pin 2

void setup() {
  // put your setup code here, to run once:
  Serial.begin (9600);
  Serial.println("starting");
  attachInterrupt(pin_irq, IRQcounter, RISING);
  
}

void IRQcounter() {
 static unsigned long last_interrupt_time = 0;
 unsigned long interrupt_time = millis();
 // If interrupts come faster than 30ms, assume it's a bounce and ignore
 if (interrupt_time - last_interrupt_time > 30)
 {
   IRQcount++;
 }
 last_interrupt_time = interrupt_time;
}

void loop() {
  // put your main code here, to run repeatedly:

  cli();//disable interrupts
  IRQcount = 0;
  sei();//enable interrupts

  delay(60000);

  cli();//disable interrupts
  int result = IRQcount;
  sei();//enable interrupts

  Serial.print(F("Counted = "));
  Serial.println(result);
}

--> this seemed to give me slightly less pulses per minute, ~5 pulses per minute less than the original code, but in 6 minutes I measured difference of 0.02kWh between arduino and the power meter

Any ideas or hints for this project?

The 10K pulldown resistor is rather weak ... the signal will have a slow fall time that might be a bit noisy. I would use a 1K resistor to strengthen the signal. Note that the SO output can handle up to 20mA - the 1K will draw about 5mA (for 50ms). The capacitor should eliminate any spikes that might be picked up due to the longer cable run.

The 100nF capacitor risks creating multiple transitions by glacially slow transitions. Use 1nF or so perhaps. There is no harm in debouncing the signal as you know its 50ms wide.

The last_interrupt_time variable should also be volatile.

Unless you run the two versions side-by-side on the same signal on two Arduinos, or use some independent method of pulse counting I don't see whether you can confirm or refute which versions of the code work reliably. In the long term you can compare the count against the meter's kWh display.

My plan is to place the arduino near to the power meter - so the cable length will be 5-10 cm. Should I also use the capacitor, even if the cable is short?

Regarding the code comparison - I can upload both versions to 2 arduinos and compare - good idea. Then I will see whether the debouncing will do any difference or not.

And I also found an article with sample code on openenergymonitor site and they do not use debouncing there, but they use FALLING interrupt mode instead of RISING. I do not know whether this makes any difference, but I think it does not matter whether I use FALLING or RISING. Or am I wrong? Here is the article: http://openenergymonitor.org/emon/buildingblocks/introduction-to-pulse-counting And here is the code: http://openenergymonitor.org/emon/node/123

That short a distance it will probably be fine, but keep the signal cable away from the mains cables of course.

To do proper debouncing you need to respond to both edges, otherwise you cannot tell how long a signal has been high for - you are currently unable to distinquish a 1us noise pulse from a 50ms pulse, for instance.

Also I wouldn't bother with the interrupt routine at all, loop() should be able to poll many times during the 50ms pulse duration.

fanofard: My plan is to place the arduino near to the power meter - so the cable length will be 5-10 cm. Should I also use the capacitor, even if the cable is short?

The short cable should make a good improvement - capacitor not needed

fanofard: And I also found an article with sample code on openenergymonitor site and they do not use debouncing there, but they use FALLING interrupt mode instead of RISING. I do not know whether this makes any difference, but I think it does not matter whether I use FALLING or RISING. Or am I wrong?

The turn off time of most opto-isolators are sometimes an order of magnitude (or more!) slower than the turn on time.

The way you have it wired, when the transistor (SO+ and SO-) switches on, the signal goes high faster than when it falls, so here I would use RISING interrupt mode.

If it were wired with a pullup and the transistor switched the signal to GND, then the signal would fall faster than when it rises, so here I would use FALLING interrupt mode.

So I tried both versions at the same time - using 2 arduinos. The result is the same - it counted exactly the same value. So it looks debouncing is not needed in this case.