Water meter with 3 wire reed switch

I want to read pulse from this water meter. It has 3 PINs-blue is Normally Open and Black is normally close).

I can use only normally open pin and use Debounce to count the pulse but it's not accurate when the flow is low because it'll keep connected for a long time which make it difficult to configure the debouncing period.

Is there anyway to use all the 3 wire and signal each other to count the pulse correctly?

Did you read the product specification of the supplier?

It's a reed switch. It's like a relay(NO,NC). But problem for me is to read its digital pulse

you can do this job either by using an interrupt service routine or to dedect a state change methode within the LOOP().

Sounds like you are not handling state change detection and debounce correctly. Show your code and we can correct the problem. Or follow this example:

const byte ButtonPin = 2;
const unsigned long DebounceTime = 10;

boolean ButtonWasPressed = false;
unsigned long ButtonStateChangeTime = 0; // Debounce timer

void checkButton()
  unsigned long currentTime = millis();

  boolean buttonIsPressed = digitalRead(ButtonPin) == LOW;  // Active LOW

  // Check for button state change and do debounce
  if (buttonIsPressed != ButtonWasPressed &&
      currentTime  -  ButtonStateChangeTime > DebounceTime)
    // Button state has changed
    ButtonWasPressed = buttonIsPressed;
    ButtonStateChangeTime = currentTime;

    if (ButtonWasPressed)
      // Button was just pressed
      // Button was just released
1 Like

No debouncing required if you use all 3 wires (Form-C type: NO, NC and COM). Just connect the NO and NC to separate inputs with 10K pullup resistors and connect COM to GND.

Here's example code that detects 5 unique conditions, bounce free.

1 Like

here comes my proposal for water meter counter. I´ve made an object for the water meter. I love objects and structs.

// https://forum.arduino.cc/t/water-meter-with-3-wire-reed-switch/894121
#define ProjectName "Water meter with 3 wire reed switch"
// you may need to change these constants to your hardware
const byte Input_[] {A0};
enum {One};
  byte pin;
  bool state;
  float m3counter;  // cubic meter counter
  float m3pulse;    // cubic meter per pulse
} watermeter {Input_[One], 1, 0.0, 0.01};
void setup() {
  Serial.print(F("File   : ")), Serial.println(__FILE__);
  Serial.print(F("Date   : ")), Serial.println(__DATE__);
  Serial.print(F("Project: ")), Serial.println(ProjectName);
  for (auto Input : Input_) pinMode(Input, INPUT_PULLUP);
void loop () {
  unsigned long currentTime = millis();
  digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
  static unsigned long scanMillis;
  const unsigned long scanDuration{20};
  if (currentTime - scanMillis >= scanDuration) {
    bool stateNew = digitalRead(watermeter.pin);
    if (watermeter.state != stateNew) {
      watermeter.state = stateNew;
      if (!stateNew) {
        watermeter.m3counter += watermeter.m3pulse;
        Serial.print("Watermeter "), Serial.print(watermeter.m3counter), Serial.println(" m³");

Enjoy the day and enjoy coding.

Thanks for all the suggestions. I use Tasmota and set a pin as Counter pin and it works like a charm. I don't set debouncetime. Anyhow, i have to check if it counts correctly if the pressure of water flow change

I think your solution work because it uses all the 3 PIN which will switch the state correctly no matter how fast or slow the water flow.

But I tried Tasmota and it looks like it works correctly based on my initial observation. But this one use only NO and COM

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.