compteur-impulsions.ino

Arduino Nano (Classic, ATmega328P) · File : compteur-impulsions.ino · Language : Arduino · Use case : Compter des impulsions sans perdre de front

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)"));
  }
}

← Back to the board