How to use a Water Flow Meter Sensor (Make Water Meter with Arduino or ESP8266)

In this tutorial, I will examine How to use the Water Flow Meter Sensor YF-S201 with Arduino or ESP-based boards like NodeMCU, How it works, and do a little experiment with the sensor.

How Flow Meter Works

To know how this sensor works, let’s see what’s inside. So inside this sensor, there’s something like a wheel turbine, that will turn if there’s flow through this sensor. The speed of the rotation depends on how fast the flows pass.
The circle on the center of the turbine is a magnet, and on the cover, there is a hall effect sensor.

So while the turbine is turning, the hall effect sensor will give signals or pulse out. If wheel rotation is slow, the pulse out also slow. The faster the flow inside this sensor will make the pulse also faster or higher in frequency.
So we can measure the flow by counting how much the pulse or frequency is given by the sensor.

Flow Meter Wiring Diagram With Arduino

This sensor only has 3 pinouts. Red and Black for the power, which are VCC and GROUND. And the Yellow one is the signal or pulse.

We can just hook up the VCC to 5V, GROUND to GROUND, and the signal to any pins of Arduino. But since we don’t want to pass even a single pulse without counting it. We need to connect the signal or pulse to only interrupt pins. If you are using Arduino Uno or Nano the interrupt pins will only be available on pins 2 or 3. And if you are using the Arduino mega, you will have interrupt pins on 2, 3, and 18,20.

But if you are using the ESP-based board like NodeMCU, almost all pins interrupt support. So you can hook up the signal to any digital pins.

Count The Pulses

First, we need to count the pulses and find the correlation between the number of pulses with volume. So I drain water through the sensor and measure it in a measuring cup.

The Code to Count Pulse

```int sensorPin = 2;
volatile long pulse;

void setup() {
pinMode(sensorPin, INPUT);
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(sensorPin), increase, RISING);
}

void loop() {
Serial.print(pulse);
delay(500);
}
void increase() {
pulse++;
}```

Measuring Volume

After I did comparisons between the number of pulses with volume several times and I got this formula. You can do your own experiment.

Volume = 2.663 x pulse

Code To Measure The Volume

```int sensorPin = 2;
volatile long pulse;
float volume;

void setup() {
pinMode(sensorPin, INPUT);
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(sensorPin), increase, RISING);
}

void loop() {
volume = 2.663 * pulse;
Serial.print(volume);
Serial.println(" mL");
delay(500);
}
void increase() {
pulse++;
}```

The code above will give us the volume that flows through water flow sensor.

Measure Water Flow in mL/s

```int sensorPin = 2;
volatile long pulse;
unsigned long lastTime;

float volume;

void setup() {
pinMode(sensorPin, INPUT);
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(sensorPin), increase, RISING);
}

void loop() {
volume = 2.663 * pulse;
if (millis() - lastTime > 1000) {
pulse = 0;
lastTime = millis();
}
Serial.print(volume);
Serial.println(" mL/s");
}

void increase() {
pulse++;
}```

The code above will give us the Flow rate in mL/s and the refresh time is 1 second.

The Code to get the Flow rate in L/m

```int sensorPin = 2;
volatile long pulse;
unsigned long lastTime;

float volume;

void setup() {
pinMode(sensorPin, INPUT);
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(sensorPin), increase, RISING);
}

void loop() {
volume = 2.663 * pulse / 1000 * 30;
if (millis() - lastTime > 2000) {
pulse = 0;
lastTime = millis();
}
Serial.print(volume);
Serial.println(" L/m");
}

void increase() {
pulse++;
}```

The code above will give us the Flow rate in mL/s and the refresh time is 2 seconds.

Using The Water Flow Sensor with NodeMCU

It is the same way as using it with Arduino but we have to change the code a little bit.

We should change the pin and add syntax in front of the function that called in interrupt.

The Code with ESP8266/NodeMCU

To avoid error on interrupt with ESP8266 we should add ICACHE_RAM_ATTR in front of the function that called on interrupt.

```int sensorPin = D2;
volatile long pulse;
unsigned long lastTime;

float volume;

void setup() {
pinMode(sensorPin, INPUT);
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(sensorPin), increase, RISING);
}

void loop() {
volume = 2.663 * pulse / 1000 * 30;
if (millis() - lastTime > 2000) {
pulse = 0;
lastTime = millis();
}
Serial.print(volume);
Serial.println(" L/m");
}

ICACHE_RAM_ATTR void increase() {
pulse++;
}```

Here’s the complete video on this tutorial.