nd80 water flow with nodemcu/arduino

Hi

i’ve a water flow sensor i want to use nodemcu or arduino to read from the sensor (I mention nodemcu because sometimes i use 3.3v inputs outputs).

is there a specific compotenents i should add and specific programming

you can find the sensor here

TECHNICAL CHARACTERISTICS
Water pressure = 1.75MPa (Max)
Input flow from 20 to 500L / min ± 3%
Working voltage 4.5-15V CD (Red wire)
Maximum current 15mA (5VDC)
Insulation resistance> 100M ohm
Inlet and outlet tube: 3 inches
Material: Aluminum Body; PA66 Nylon turbine; SUS304 steel Axes
Frequency of flow Hz (vertical detection) F = 0.05 * Q Where Q = liters / min
where Q is water flow
Working temperature -20 ° C to + 60 ° C
High pulse output> 4.7V (5V input voltage) (Yellow wire)
Low pulse output <0.5 V (input voltage 5V)
The duty cycle of the output pulses of 50% ± 10%

thanks

Internally it has a magnetic field Hall effect sensor that detects the movement of the blades that is generated with the passage of the liquid. Delivery to the output square pulse signal whose frequency corresponds to the flow of the liquid.

High pulse output> 4.7V (5V input voltage) (Yellow wire)
Low pulse output <0.5 V (input voltage 5V)

Such a square wave should be easy to read and interpret using a nodemcu or arduino but you will need to shift the voltage below 3V3 if using a nodemcu using either a level shifter or resistor divider

when using a similar water flow sensor with a PIC24 I used the External clock from TxCK pin facility to drive a timer which would count pulses - another timer would interrupt at regular intervals to read the water flow timer and count pulses per second, etc
can the NodeMCU timers be driven externally ?

UKHeliBob:
Such a square wave should be easy to read and interpret using a nodemcu or arduino but you will need to shift the voltage below 3V3 if using a nodemcu using either a level shifter or resistor divider

i didn't work with square waves and duty cycles could I've an example (I'm not an expert at all :D)

level shifter is to reduce the 5v to 3.3v for the nodemcu

also will I use the digital pins or analog pins

thanks for your help

I use the sensor directly on the ESP8266 as the pins are 5v tolerant and run the sensor on 5v.

all wifi lines are commented out for testing

// https://www.iotdesignpro.com/projects/iot-based-water-flow-meter

//#include <ThingerESP8266.h>
#include <ESP8266WiFi.h>
/*  I took these out for testing
#define USERNAME "Your Account Username"
#define DEVICE_ID "Device-ID"
#define DEVICE_CREDENTIAL "Your Private Key"
#define SSID "Wi-Fi Name"
#define SSID_PASSWORD "Password"
*/
#define SENSOR  D3
//ThingerESP8266 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);
long currentMillis = 0;
long previousMillis = 0;
int interval = 1000;
//boolean ledState = LOW;
float calibrationFactor = 4.5;
volatile byte pulseCount;
byte pulse1Sec = 0;
float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;

void ICACHE_RAM_ATTR pulseCounter()  // use for ESP8266
// void IRAM_ATTR pulseCounter()  // may be only for ESP32
{
  pulseCount++;
}

void setup()
{
  Serial.begin(115200);
 // thing.add_wifi(SSID, SSID_PASSWORD);  // commented out for testing
  pinMode(SENSOR, INPUT_PULLUP);
  pulseCount = 0;
  flowRate = 0.0;
  flowMilliLitres = 0;
  totalMilliLitres = 0;
  previousMillis = 0;
  attachInterrupt(digitalPinToInterrupt(SENSOR), pulseCounter, FALLING);
}

void loop()
{
  currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    pulse1Sec = pulseCount;
    pulseCount = 0;
    flowRate = ((1000.0 / (millis() - previousMillis)) * pulse1Sec) / calibrationFactor;
    previousMillis = millis();
    flowMilliLitres = (flowRate / 60) * 1000;
    totalMilliLitres += flowMilliLitres;
    // Print the flow rate for this second in litres / minute
    Serial.print("rate: ");
    Serial.print(int(flowRate));  // Print the integer part of the variable
    Serial.print("L/min");
    Serial.print("\t");       // Print tab space
    // Print the cumulative total of litres flowed since starting
    Serial.print("Quantity: ");
    Serial.print(totalMilliLitres);
    Serial.print("mL / ");
    Serial.print(totalMilliLitres / 1000);
    Serial.println("L");
    /*  REM out the internet connection for testing
    thing["data"] >> [](pson& out){
    out["Flow Rate"] = flowRate;
    out["Total"]= totalMilliLitres;
     };
    thing.handle();
    thing.stream(thing["data"]);
    */
  }
}

dave-in-nj:
I use the sensor directly on the ESP8266 as the pins are 5v tolerant and run the sensor on 5v.

all wifi lines are commented out for testing

// https://www.iotdesignpro.com/projects/iot-based-water-flow-meter

//#include <ThingerESP8266.h>
#include <ESP8266WiFi.h>
/*  I took these out for testing
#define USERNAME “Your Account Username”
#define DEVICE_ID “Device-ID”
#define DEVICE_CREDENTIAL “Your Private Key”
#define SSID “Wi-Fi Name”
#define SSID_PASSWORD “Password”
*/
#define SENSOR  D3
//ThingerESP8266 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);
long currentMillis = 0;
long previousMillis = 0;
int interval = 1000;
//boolean ledState = LOW;
float calibrationFactor = 4.5;
volatile byte pulseCount;
byte pulse1Sec = 0;
float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;

void ICACHE_RAM_ATTR pulseCounter()  // use for ESP8266
// void IRAM_ATTR pulseCounter()  // may be only for ESP32
{
  pulseCount++;
}

void setup()
{
  Serial.begin(115200);
// thing.add_wifi(SSID, SSID_PASSWORD);  // commented out for testing
  pinMode(SENSOR, INPUT_PULLUP);
  pulseCount = 0;
  flowRate = 0.0;
  flowMilliLitres = 0;
  totalMilliLitres = 0;
  previousMillis = 0;
  attachInterrupt(digitalPinToInterrupt(SENSOR), pulseCounter, FALLING);
}

void loop()
{
  currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    pulse1Sec = pulseCount;
    pulseCount = 0;
    flowRate = ((1000.0 / (millis() - previousMillis)) * pulse1Sec) / calibrationFactor;
    previousMillis = millis();
    flowMilliLitres = (flowRate / 60) * 1000;
    totalMilliLitres += flowMilliLitres;
    // Print the flow rate for this second in litres / minute
    Serial.print(“rate: “);
    Serial.print(int(flowRate));  // Print the integer part of the variable
    Serial.print(“L/min”);
    Serial.print(”\t”);      // Print tab space
    // Print the cumulative total of litres flowed since starting
    Serial.print("Quantity: ");
    Serial.print(totalMilliLitres);
    Serial.print("mL / ");
    Serial.print(totalMilliLitres / 1000);
    Serial.println(“L”);
    /*  REM out the internet connection for testing
    thing[“data”] >> (pson& out){
    out[“Flow Rate”] = flowRate;
    out[“Total”]= totalMilliLitres;
    };
    thing.handle();
    thing.stream(thing[“data”]);
    */
  }
}

Thanks for the example,

was it the same sensor I have?

I have the same sensor working at 3.3V. I haven't seen any issue with it so far.

dave-in-nj:
I use the sensor directly on the ESP8266 as the pins are 5v tolerant and run the sensor on 5v.

all wifi lines are commented out for testing

// https://www.iotdesignpro.com/projects/iot-based-water-flow-meter

//#include <ThingerESP8266.h>
#include <ESP8266WiFi.h>
/*  I took these out for testing
#define USERNAME “Your Account Username”
#define DEVICE_ID “Device-ID”
#define DEVICE_CREDENTIAL “Your Private Key”
#define SSID “Wi-Fi Name”
#define SSID_PASSWORD “Password”
*/
#define SENSOR  D3
//ThingerESP8266 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);
long currentMillis = 0;
long previousMillis = 0;
int interval = 1000;
//boolean ledState = LOW;
float calibrationFactor = 4.5;
volatile byte pulseCount;
byte pulse1Sec = 0;
float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;

void ICACHE_RAM_ATTR pulseCounter()  // use for ESP8266
// void IRAM_ATTR pulseCounter()  // may be only for ESP32
{
  pulseCount++;
}

void setup()
{
  Serial.begin(115200);
// thing.add_wifi(SSID, SSID_PASSWORD);  // commented out for testing
  pinMode(SENSOR, INPUT_PULLUP);
  pulseCount = 0;
  flowRate = 0.0;
  flowMilliLitres = 0;
  totalMilliLitres = 0;
  previousMillis = 0;
  attachInterrupt(digitalPinToInterrupt(SENSOR), pulseCounter, FALLING);
}

void loop()
{
  currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    pulse1Sec = pulseCount;
    pulseCount = 0;
    flowRate = ((1000.0 / (millis() - previousMillis)) * pulse1Sec) / calibrationFactor;
    previousMillis = millis();
    flowMilliLitres = (flowRate / 60) * 1000;
    totalMilliLitres += flowMilliLitres;
    // Print the flow rate for this second in litres / minute
    Serial.print(“rate: “);
    Serial.print(int(flowRate));  // Print the integer part of the variable
    Serial.print(“L/min”);
    Serial.print(”\t”);      // Print tab space
    // Print the cumulative total of litres flowed since starting
    Serial.print("Quantity: ");
    Serial.print(totalMilliLitres);
    Serial.print("mL / ");
    Serial.print(totalMilliLitres / 1000);
    Serial.println(“L”);
    /*  REM out the internet connection for testing
    thing[“data”] >> (pson& out){
    out[“Flow Rate”] = flowRate;
    out[“Total”]= totalMilliLitres;
    };
    thing.handle();
    thing.stream(thing[“data”]);
    */
  }
}

what should I change as the sensor I have is different in size and Frequency of flow Hz

connect a hose, a valve and a container.
use a timer , maybe the Arduino itself
and run the water for some exact time.
them measure the volume of water

based on the volume and the time, the flow can be determined.
based on the flow measured and flow reported,
change the flow calibration factor.

dave-in-nj:
connect a hose, a valve and a container.
use a timer , maybe the Arduino itself
and run the water for some exact time.
them measure the volume of water

based on the volume and the time, the flow can be determined.
based on the flow measured and flow reported,
change the flow calibration factor.

So the thing I need to update is "4.5" factor based on my testing

the only issue that the sensor diameter is 3 inches and it should be vertically with the water comes up to the sensor.

it makes it to hard for testing in my room

KareemWaheed:
So the thing I need to update is "4.5" factor based on my testing

the only issue that the sensor diameter is 3 inches and it should be vertically with the water comes up to the sensor.

it makes it to hard for testing in my room

UP

If you are going to count pulses / time, use LPM = pulses per second * 20.
If time / pulses, LPM = 20000 / millis().
For example: 10 pulses in 1 second = 200 LPM, 100 millis() per pulse = 200 LPM.
In @dave-in-nj’s program, calibration factor would be 0.05.

I would agree that lab calibrating a sensor will be difficult, but you also miss the criteria for calibration.

straight runs of pipe, both before and after, to eliminate turbulence.
enough pipe to establish the Reynolds Number accurately and repeatedly

The field mounted unit would then also be required to have the same straight run of pipe.

probably a flow straightener would be needed to pre-condition the incoming flow.

I would totally dismiss any idea of accuracy. You cannot supply a low cost device to replace an actual instrument and expect similar accuracy.

The best you could hope for is to install and then run the test of volume over time and adjust the unit for field calibration.
Do that over at least 4 points, 1/4, 1/2, 3/4 full flow and create a curve.
If things are exactly where you expect, you can extrapolate the other points.
If they do not fit as expected, then more points in between would be needed.

From part to part, you might find 20% variation in readings.
The reason an actual instrument cost so much is that dimensions are exact and machined, not cast surfaces
Bearings and seals are high quality, Moving parts are balanced and weighed and polished, etc
Even then, individual instruments are supplied with calibration tables to account for differences in manufacturing.

a ‘custody transfer’ rated turbine flow meter will cost more than a new car. But it is also a precision instrument.

by all means, use the device, but do not put high expectations on long term accuracy or accuracy over a range of flows and flow conditions.