Getting ESP8266 to work with Hall Effect sensor


My home irrigation system consists of a system of 12 water circuits, each of which is controlled by a solenoid operated valve. The valves, in turn are controlled by an electrical controller/timer which is programmed to run the system at night. Most of the water distribution points are drippers.

A problem occurs when occasionally some dirt will lodge in the seat of one of the valves, causing the valve to leak water (under pressure) until detection and correction. It can be several days before the problem can be detected.


My solution was to install a water flow sensor in the main water line and to check the system flow rate each morning when there should be no water flowing through the system. I initially connected the sensor to a small OLED display to ensure its operation. The problem was that the display had to be located in an inaccessible part of my garage. So I modified the system to transmit the data to a web site via my WiFi network. For this I used an ESP8266-01S microprocessor directly rather than my Arduino Uno. Voltage supplied to the ESP8266 is 3.3v. This worked well until I encountered the following problem.


The water flow sensor is a Hall Effect type sensor. When water flows through the pipe a series of electrical pulses in the form of a square wave is transmitted. The frequency of these pulses is a direct function of the flow rate of the water. The operational power to the sensor is 5 volts. When water is flowing, the voltage in the data line is HIGH at 2.5 volts. When no water is flowing the data lead voltage should be zero.

My sketch uses the “pulsein” function to interpret the data. The “pulsein” function waits for the signal to rise to HIGH, then measures the duration of the HIGH portion of the pulse and returns that value. If the signal does not go HIGH after a certain period of time (as in zero flow), “pulsein” returns a value of zero. And all should be cool.


While water is flowing through the sensor, the data line voltage is about 2.5 volts as stated above. But when the water flow ceases, the voltage does not always drop to zero; instead it sometimes goes to a high of 4.9 volts. This apparently posed no problem for the Uno/OLED setup, but the high voltage caused my ESP8266 to “go ape”.


Is there any way by which I can salvage my project by either a circuit modification or a sketch code change, or a combination of both?

I have attached a circuit diagram as well as my sketch code. Please note that I have a 60 minute delay embedded in the void loop.


Measures the flow rate of water flowing through a 3/4-inch PVC pipe using a DIGITEN Hall effect sensor and displaying results on using an ESP8266-01S
Sensor date wire connected to Uno pin D2
The sensor output is in the form of the duration in milliseconds of a square wave pulse and the relationship to the water flowrate is:

F = 4.8 * Q ( in liters per minute)

#include <ESP8266WiFi.h>

// WiFi SSD and Password

char ssid = “tracy”;

char password = “Mange161”;

char server = “”;

//Initialize the client library
WiFiClient client;

#include <SPI.h>

const int sensdatapin = 2;

String apiKey = “0ZUS9CDG08ZU6VJ2”;

unsigned long myChannelNumber = 255517;

void setup() {

unsigned long duration;
float dursec;
float pulsefreq;
float flolit;
float flolitr;
float flogal;
float flocuft;

pinMode(sensdatapin, INPUT);



// init done

WiFi.begin(ssid, password);

Serial.print("Connecting to ");

WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.println(“WiFi connected”);


void loop() {

const unsigned long duration = pulseIn(sensdatapin, HIGH);
//Pulse duration in microseconds

float dursec = duration / 1000000.0;
//Pulse duration in seconds

float pulsefreq = 10.0;

if ( duration != 0 )
pulsefreq = 1.0 / dursec;
pulsefreq = 0.0;

//Pulse frequency in Hz

float flolit = (pulsefreq / 4.8);
float flolitr = 60.0 * flolit;
//Flow rate in Liters/hour

float flogal = flolitr * .26417;
//Flow rate in Gallons/hour
float flocuft = flolitr * .035315;
//Flow rate in cu ft/hour

if (client.connect(server, 80)) { // “” or
String postStr = apiKey;
postStr += “&field1=”;
postStr += String(flogal);
postStr += “\r\n\r\n”;

client.print(“POST /update HTTP/1.1\n”);
client.print(“Connection: close\n”);
client.print("X-THINGSPEAKAPIKEY: " + apiKey + “\n”);
client.print(“Content-Type: application/x-www-form-urlencoded\n”);
client.print(“Content-Length: “);




// Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different
// pieces of information in a channel. Here, we write to field 1.

// 3600000 = 1 hour
// ThingSpeak will only accept updates every 15 seconds.


WiFi-2 Schematic.pdf (112 KB)

Can you post a data sheet for the flow sensor?

When water is flowing, the voltage in the data line is HIGH at 2.5 volts. When no water is flowing the data lead voltage should be zero.

When you measure the voltage of a pulse train with a DMM you will get the average voltage. So for a pulse train of 0 to 5V the average is 2.5V.

instead it sometimes goes to a high of 4.9 volts

If the rotor in the sensor happens to stop over the Hall sensor you could get 5V if the sensor is powered with 5V (depending on how the sensor is made).

Without seeing the flow sensor data sheet, the best that I can suggest that you either power the flow sensor with 3.3V or put a voltage divider on the flow sensor output to drop the 5V output to 3.3V.

Your schematic does not seem to show the flow sensor.
Please use code tags, not quote.

So the voltage I measured was the average, and not the peak voltage. I did not know that. I tried both schemes for reducing the signal voltage, and both worked. So I will change sensor power from 5v to 3.3v since that works. However the problem is not solved. The issue is not about the magnitude of voltage but rather that when the pin is initially HIGH Pulsein waits for it to go LOW and then back to HIGH. In my setup, that could take several hours.

So I tried inserting a "digitalWrite" in the loop to change the pin state to LOW, but that did not work.

Now I'm going to try setting the pinMode to INPUT_PULLUP and changing the pulseIn arguments from (pin, HIGH) to (pin, LOW) to see if that will return a value of "0" for the variable "duration".

The pulseIn() function can take a timeout parameter so that if the transition doesn't happen in time, pulseIn will exit. The syntax is:
pulseIn(pin, state, timeout in microseconds);
PulseIn will return 0 if it times out.

I got the system to operate by doing the following:

  1. Reduced loop delay from 60 minutes to 20 minutes. Will try going to 30 minutes)

  2. Connecting when there is no flow and with the data pin state at LOW. (I had to fiddle with the water controls to get the sensor to this condition)

Would still like to get pulseIn to work when connecting with pin HIGH and not pulsating. (Timeout did not help)

BTW although the sensor specs call for minimum 5v, it works fine at 3.3v.