Table of Contents

About

The following section is an introduction to liquid debit meters or sensors that can measure the flow of liquids through a tube or pipe and how they can be used together with Arduino for various automation projects.

Debit Meter / Sensor

The YF-S401 is a cheap and small debit meter that is typical of most debit level meters in that it does not output an analog value but rather emits pulses that can be correlated to the flow of liquid through the sensor. In some ways the architecture is similar to a dynamo where a propeller on the inside of the sensor is moved by the flow of liquid through the debit meter that generates some electricity and, in this case, a pulse that can be measured in order to determine the rate of flow.

The technical specifications state that the flow rate can be determined by knowing that the sensor emits 98 pulses per second for each litre of liquid passing through the meter. Or, in other words, the debit $Q$ in liters per minute corresponds to a frequency of $\frac{1}{98}Hz$.

Something that must be watched out for is that the debit meter only works in one direction and the correct flow direction is marked on the plastic housing.

Sensor Code

Using the formula above, the following code should provide the bare minimum for measuring the debit of liquids passing through the debit meter:

// the calibration factor is the number of pulses per second for a litre
// for the YF-S401 that would be 98 pulses per second for one litre (as read from the datasheet)
#define CALIBRATION_FACTOR 98
 
// the digital pin used to measure the debit rate
#define SENSOR_SIGNAL_PIN_DIGITAL 12
 
unsigned long markTime;
 
// in C++ this value will wrap around
volatile byte pulse;
 
byte meterInterrupt;
 
// this function executes when the sensor interrupts and emits a falling pulse
void pulseInterrupt() {
  // increment the pulse counter (note that this value will wrap around)
  pulse++;
}
 
setup() {
    // start serial port for data output
    Serial.begin(115200);
 
    // convert the digital pin number to an interrupt number
    meterInterrupt = digitalPinToInterrupt(SENSOR_SIGNAL_PIN_DIGITAL);
 
    // attach a falling interrupt to the pulse pin that will call the function pulseInterrupt()
    attachInterrupt(meterInterrupt, pulseInterrupt, FALLING);
}
 
loop() {
    // measure the debit every second
    float elapsedTime = millis() - markTime;
    if(elapsedTime > 1000) {
        // halt interrupts during calculations
        detachInterrupt(meterInterrupt);
 
        // mark this time frame as a starting reference for the next time frame
        markTime = millis();
 
        // the flow rate is the number of pulses divided by the elapsed time in milliseconds 
        // divided by the calibration factor representing the pulses per second corresponding to a litre
        //
        // note that the nominator is multiplied by 1000.0 in order to convert the milliseconds to seconds
        // due to the calibration factor being the number of pulses per second, not milliseconds
        //
        // the rate is in liters per minute but it can be converted to milliseconds conveniently
        // using the formula: 1000* rate / 60
        float flowRate =  (1000.0 * pulse / elapsedTime) / CALIBRATION_FACTOR;
        Serial.printf("%.1f", flowRate);
 
        attachInterrupt(meterInterrupt, pulseInterrupt, FALLING);
    }
}

The code is actually very simple and the sensor is nice to work with, especially compatible with asynchronous semantics due to using interrupts and callbacks, which is more elegant than using sequential programming. The code outputs the flow rate to the serial port but obviously the code can be altered in order to push the data to MQTT or otherwise.

The Arduino GPIO tool developed by Wizardry and Steamworks has support for installing and uninstalling interrupts built-in but the actual counting of the signals will have to be performed by something that is listening to the MQTT bus because the tool just pushes data onto the MQTT broker and does not compute any debits because it is an universal template.

Usage Scenarios

In terms of usage, the debit meter is mostly inaccurate with an advertised error rate of $\pm 10\%$ but there are situations when redundancies are needed. For example, the debit meter has been used with the hydroponics bay as a feedback element in order to determine whether the automatic irrigation is running. The bay is meant for in-door usage, such that water spills are unacceptable and even though relying on GPIO states, whilst measuring pin levels is sufficient, having an additional flow meter emit signals whenever the water is flowing is a great way to ensure that the water is stopped in time or to panic and fail gracefully in case the water cannot be stopped (ie: reboot the ESP in case the pump-relay system becomes unresponsive in order to stop the water from overflowing and causing a flood).

Index