compteur-impulsions.ino
Short pulses get lost when polling a pin: attachInterrupt on INT0 (Nano pin 2) captures every falling edge. With software debounce and atomic copying, the water or energy meter becomes pulse-accurate.
Hardware
An Arduino Nano classic (ATmega328P at 16 MHz, 30-pin DIL breadboard footprint, mini-B USB, 5 V logic, RESET pin at the lower-left corner). Arduino Nano, dry contact or open-collector sensor on pin 2, optional test button.
Wiring
Contact between D2 and GND (internal INPUT_PULLUP); for pulse sensors, respect the output voltage rating.
How it works
The pin-2 (INT0) interrupt service routine increments a volatile counter; the 25 ms window crushes mechanical bounce. noInterrupts brackets the copy of the 32-bit counter.
Running it
In the Arduino IDE, select the Arduino Nano board and ATmega328P processor, pick the serial port, then upload. The board's 5 V rail suits 5 V sensors; otherwise use 3.3 V on compatible pins.
Variants
Count two channels (INT0 + INT1 pin 3) for a differential meter, or add the total into EEPROM at power-down.
compteur-impulsions.ino
// Compteur d'impulsions sur interruption externe (INT0 = broche 2).
// Ideal compteur d'eau/energie a contact sec, avec anti-rebond materiel.
volatile unsigned long impulsions = 0;
volatile unsigned long dernierFront = 0;
const int BROCHE = 2; // INT0 obligatoire pour attache materielle
const unsigned long REBOND = 25; // ms
void comptage() {
unsigned long maintenant = millis();
if (maintenant - dernierFront >= REBOND) {
impulsions++;
dernierFront = maintenant;
}
}
void setup() {
pinMode(BROCHE, INPUT_PULLUP); // contact vers GND
attachInterrupt(digitalPinToInterrupt(BROCHE), comptage, FALLING);
Serial.begin(9600);
}
void loop() {
static unsigned long derniereAffichage = 0;
if (millis() - derniereAffichage >= 1000) {
derniereAffichage = millis();
noInterrupts();
unsigned long copie = impulsions; // lecture atomique
interrupts();
Serial.print(F("impulsions : "));
Serial.print(copie);
Serial.print(F(" (debit ~ "));
Serial.print((copie - (copie)) * 60); // a vous de differencer
Serial.println(F("/min)"));
}
}