YF-S201 Hall Effect Flow Sensor not returning appropriate readings

I am trying to get a Hall Effect Water Flow Sensor to respond to interrupts. I’ve done quite a bit of searching and have the sensor working successfully on a Raspberry Pi Zero (no external resistors, internal pull down resistor and digital pin with interrupts).

I have an Arduino Nano v4.0 Atmega328p from SunFounder. Sensor is a YF-S201 Sea (generic). I read somewhere that the sensor has an internal 10k resistor but I don’t know how to verify that.

I have tried different resistors (22k, 10k, 4.7k, 1k, 0) without much success, as well as the 3.3v pin, 5v pin and D4 pin setup as OUTPUT and HIGH (which measures about 4.7v).

I have attached a wiring diagram and included the code I’m using (While this code does generate sensor readings when the wheel is spinning, it also generates readings just when I pick up the sensor). This is the closest I’ve gotten to returning sensor readings but they are still really high. No resistor connecting D4 & D2 for this code.

int flowPin = 2; 
int flowPower = 4;
float flowRate;
volatile unsigned long count;

void setup() {
  pinMode(flowPin, INPUT); 
  //pinMode(flowPin, INPUT_PULLUP);
  digitalWrite(flowPin,  HIGH);
  pinMode(flowPower, OUTPUT); 
  digitalWrite(flowPower, HIGH);
  attachInterrupt(digitalPinToInterrupt(flowPin), Flow, FALLING); 
  Serial.begin(9600);  //Start Serial 
}
void loop() {
  
   count = 0;  
  interrupts(); 
  delay (1000); 
  noInterrupts();
  
  //Start the math
  flowRate = (count * 2.25);        // convert count to flow rate
  //flowRate = flowRate * 60;         // seconds to minutes
  //flowRate = flowRate / 1000;       // mL to L
  Serial.println(flowRate);
}

void Flow() {count++; }

You have the sensor connected to GND, D2 and D4 instead of GND, Vcc and a digital pin (D2 is a good one for interrupts indeed). I forgot the colour coding.

You don't need resistors at all (either external or internal) - these hall effect sensors are push/pull. Just connect the sensor properly and start reading.

Code is wrong, too. Disable interrupts ONLY when copying the variable count to another variable, e.g. like this:

noInterrupts();
uint32_t currentCount = count;  // copy the current value of the volatile variable count to another one.
interrupts();
// continue your calculations with currentCount rather than with count.

Resistor removed but I'd like to keep the Vcc wire on D4 (output/high). The change from count to currentCount seemed to bring the high readings under control. Do the interrupts/noInterrupts look correct? When I switch them to noInterrupts then interrupts, the count starts to race through. I only want it reading every few seconds (there are other sensors that are gathering and outputting data).

// Flow Sensor Test

int flowPin = 2;
int flowPower = 4;
float flowRate;
volatile int count;

void setup() {
pinMode(flowPin, INPUT);
digitalWrite(flowPin, HIGH);
pinMode(flowPower, OUTPUT);
digitalWrite(flowPower, HIGH);
attachInterrupt(digitalPinToInterrupt(flowPin), Flow, FALLING);
Serial.begin(9600); //Start Serial
}
void loop() {

count = 0;
interrupts();
delay (1000);
noInterrupts();
uint32_t currentCount = count;

//Start the math
flowRate = (currentCount * 2.25); // convert count to flow rate
flowRate = flowRate * 60; // seconds to minutes
flowRate = flowRate / 1000; // mL to L
Serial.println(flowRate);
}

void Flow() {count++; }

Once you enable the interrupts, the count will increment when the pulse from the meter occurs. The flow sensor is not smart. It does not send the count. It sends pulses for you to count. If you are getting too many pulses, then your connections may be suspect or is not connected as you have drawn.

To the gurus:

what is the result of these two lines of code:

pinMode(flowPin, INPUT);
digitalWrite(flowPin, HIGH);

Set the pin mode to input, then execute a digital write?

vvarrior:
Do the interrupts/noInterrupts look correct?

No, still the same as you used to do it. Follow my example for the correct way. Be aware that various other functions like printing to the Serial console also use interrupts.

adwsystems:
what is the result of these two lines of code:

pinMode(flowPin, INPUT);
digitalWrite(flowPin, HIGH);

Set the pin mode to input, then execute a digital write?

It enables the pull-up resistor, so it's the same as

pinMode(flowPin, INPUT_PULLUP);

I see the reason you changed where the interrupts go. Flow counts the interrupts from the beginning of the loop where count is reset for a second, disables interrupts, copies count, then enables interrupts again. That makes sense and works for counting…

However, the counts are pretty wild. If the sensor is just sitting on the table without moving (or anything going through it), the count remains 0. But if I simply touch it with my finger, the count changes wildly. When I blow through it, the count seems to even out to an expected amount, then drops to zero when set back down on the table.

Sensor Vcc connected to D4
Sensor Data connected to D2
Sensor Grnd connected to GND

I had some difficulty finding the proper pinout schematic for my nano: SunFounder Nano v4.0 Atmega328p. I have attached the one I found. I also tried attaching data wire to D3 with a change to the flowPin to 3 and got the same results

Here is the code I have loaded:

int flowPin = 2; 
int flowPower = 4;
float flowRate;
volatile int count;

void setup() {
  pinMode(flowPin, INPUT_PULLUP); // setup interrupt pin
  pinMode(flowPower, OUTPUT); // turn on flow sensor
  digitalWrite(flowPower, HIGH); // turn up flow sensor
  attachInterrupt(digitalPinToInterrupt(flowPin), Flow, FALLING); 
  Serial.begin(9600);  // Start Serial 
}

void loop() {
  
  count = 0;  
  delay (1000); 
  noInterrupts();
  uint32_t currentCount = count;  
  interrupts();
  flowRate = (currentCount * 2.25);        // convert count to flow rate
  flowRate = flowRate * 60;         // seconds to minutes
  flowRate = flowRate / 1000;       // mL to L
  Serial.println(flowRate);
}

void Flow() {count++; }

vvarrior:
However, the counts are pretty wild. If the sensor is just sitting on the table without moving (or anything going through it), the count remains 0. But if I simply touch it with my finger, the count changes wildly. When I blow through it, the count seems to even out to an expected amount, then drops to zero when set back down on the table.

The count will only change if the interrupt is triggered. The interrupt will only be triggered if it sees a change in the signal. If you touch and the count changes, then the interrupt occurred because the signal changed. So why does the signal change when you touch it? Bad connection? And define "touching it".

Define touching it? Uh, pointer finger on right hand touches the outside of the sensor while it is sitting on the table. Literally physically touching it in the real world, not scripting it. I have attached a picture.

I’ve checked all 3 connections and all appear secure with no fluctuations in signals or resistances with voltmeter. This sensor works on a Rasberry Pi when have it scripted with GPIO.event_detect but it’s using Rising instead of Falling. I’m pretty sure the pin is a 5v pin.

Found the problem... Poor Vcc connection. That's frustrating, but in the process I got to learn all about what a Hall Effect Sensor is, how it works, which led me down the path to determine there was a power problem because of the wild fluctuations when I would touch it with my hand.