Readout for pulsed water meter

Awesome, thanks @ogiewon . What kind of loop time would you expect for implementing a simple PID controller that measures/sets voltage? I was just thinking to try it to find out, but some googling indicates it may be faster than 1 ms for executing just a few math operations and a read/write.

I'm asking because I haven't quite figured out the difference between Arduino and a NodeMCU, but that is probably something that will become obvious once ebay delivers.

The 'Arduino' type of microcontrollers, do not run an operating system. They are just a CPU running an infinite loop of code. As such, they can scan I/O pins, set I/O pins, perform math, and other logic at amazing speeds (as long as there are no blocking calls in the code!)

These boards can loop() through some simple C/C++ code and read/update GPIO much, much quicker than a board running a full operating system. Dropping the operating system loses a ton of overhead. Of course, the trade-off is that your code has to be well designed and written, you have to manage memory wisely (i.e. no leaks!), and everything is single threaded (so no blocking calls allowed!)

Performing simple PID control is a trivial task for an Arduino board (numerous processor varieties these days), an ESP8266 board, or an ESP32 board.

There are lots of great tutorials online to help familiarize yourself with programming using the Arduino IDE. A NodeMCU ESP8266 board simply needs a standard USB to microUSB cable, and the Arduino IDE downloaded and installed on your computer. You will have to install the board support package for the ESP8266 platform via the Arduino IDE's "Boards Manager" feature.

1 Like


Dan, I'm in the process of setting up a water monitoring and control system for our property, and I'm currently at the point where I have an Arduino Mega set up to calculate a tank's water level through an ultrasonic tranducer (JSN-SR04T), and measure water flow through a common pulsed type of flow meter. I'm currently able to measure and calculate the data that I need within my Arduino sketch (eg. Percentage full of a tank, current flow rate through a pipe, and volume of water that has flowed since start).

My next step will be to get this data into Hubitat (I have an Ethernet shield for connectivity). Now, my question for you is: Does Hubduino have something built-in that would allow me to use it for my purposes (assuming multiple sensors connected to my single Arduino Mega), or am I better off just writing some API calls into my Arduino sketch to send data to an RM endpoint or the Maker API?

HubDuino does have built-in support for attaching multiple sensors to a single Arduino and having each one appear in Hubitat as a unique device. There is already support for the Ultrasonic sensor as well as a pulse counter. So, you should be able to get things up and running relatively easily.

However, every user's needs are somewhat unique. And since your project only has 'sensor' devices which only produce data (i.e. they do not need to receive data like a 'switch' device would), using the Maker API is a very effective solution, especially since you already have your sketch working. If you foresee adding 'actuator' devices to the Arduino, you may want to use HubDuino as it would help simplify the sketch receiving data from the Hub (although the Maker API now supports sending data as well as receiving data... :thinking: )

This is really a case of personal preference, IMHO.

It's good to have options! :wink:


Another idea is to use the baseline SmartThings wifi library, which is the basis of Hubduino, to send data between your board and Hubitat. You don't have to re-work your whole sketch, and make everything fit into the Hubduino example sketch if you don't want. You can just work in the functions from that library that you want to send data to the hub. Just another option if you don't want to re-invent the wheel. Just another great take-away from Hubduino.

It IS great to have options!

1 Like

I neglected to mention that I eventually intend to have some sort of valve actuators or solenoids attached as well, so I think Hubduino is sounding like a good option :wink:

I'm now having a look through the Hubduino repository to try to get a better idea of how it works and what I can do. It certainly looks like an excellent project! A few questions/points:

It seems that I could set up Arduino code for both the flow meter and the distance sensor, which would send the basic measurements to Hubitat (ie. pulse count and distance measured), and then let the Hubitat child device handlers turn those readings into the final readings I'm after. eg. I can see that you have an Ultrasonic child device that can calculate the % full of a tank of given the specified dimensions (very cool!).

I can't quite see something similar for the pulse counter, though. You mentioned above that you implemented something for a user's water flow meter. How exactly is it being handled on the Hubitat side? Is it just being interpreted as a power meter device? I'm guessing that Hubitat doesn't have a "Water Flow" capability or something like that?

And just out of curiosity: I notice that you implemented the ultrasonic distance measuring directly in your code, without the use of a library. I have been using the NewPing library in my sketch so far. It's supposed to be a more robust solution, apparently able to handle various issues that can come up when trying to measure distance with ultrasonic sensors. Did you look into this or other libraries, and are there specific reasons why you chose not to use any?


An easy way to convert pulses per unit of time into water flow (e.g. gallons per hour) is to utilize the Engineering Conversion parameters I built into the PS_PulseCounter class (see below.) This way the data sent to Hubitat will be in the correct Engineering Units, thereby simplifying the Hubitat side of things.

//  File: PS_PulseCounter.h
//  Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
//  Summary:  PS_PulseCounter is a class which implements the SmartThings "Power Meter"-style device capability.
//			  It inherits from the st::PollingSensor class.  The current version uses a digital input to measure the 
//			  the number of counts between polling intervals.  At the polling interval, the pulse count is converted
//			  to engineering units via a linear conversion (engUnits = slope x counts + offset).
//			  Create an instance of this class in your sketch's global variable section
//			  For Example:  st::PS_PulseCounter sensor3(F("power1"), 60, 5, PIN_PULSE, FALLING, INPUT_PULLUP, 1.0, 0);
//			  st::PS_PulseCounter() constructor requires the following arguments
//				- String &name - REQUIRED - the name of the object - must be in form of "power1", "power2", etc...
//				- int interval - REQUIRED - the polling interval in seconds
//				- int offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
//				- byte pin - REQUIRED - the GPIO Pin to be used as an digital input (Hardware Interrupt)
//				- byte inttype - REQUIRED - which type of Arduino interrupt to trigger the ISR (RISING, FALLING, CHANGE)
//				- byte inputmode - REQUIRED - Mode of the digital input Pin (INPUT, INPUT_PULLUP)
//				- float cnvslope - REQUIRED - Conversion to Engineering Units Slope
//				- float cnvoffset - REQUIRED - Conversion to Engineering Units Offset

The Ultrasonic sensor Arduino code and ST/HE Driver code were actually a ST user contribution to the ST_Anything/HubDuino Project. They are definitely somewhat unique, as almost every other device was implemented much more generically.

Please feel free to 'build a better mousetrap' and share it with the community. I would happily entertain adding your work to ST_Anything/HubDuino assuming it is done in a generic fashion, that others would benefit from as well. I want the community to make additions and enhancements, as long as they follow the architecture and are reusable for other users.

1 Like

I think I'll try the code as-is for now. If I run into any issues, I may implement a NewPing version. But otherwise "If it ain't broke, don't fix it!" hehe

Thanks for your replies! I'm looking forward to getting my first Hubduino project working :slight_smile: (Actually my first Arduino project, really)

1 Like

Understood. But please feel free to customize as you see fit, especially the Ultrasonic Groovy Driver. Your water tank may be a completely different shape and will require an entirely different calculation for tank level/volume.

Have fun and feel free to reach out if you have any issues following the ReadMe to get things up and running.

1 Like

We're down the road a bit on this subject. Just wondering what the prevailing opinion on a pulse counter/communication device is for this application is.

Thanks @ogiewon . Per your post I moved a couple PID controllers I have to ESP8266 and ESP32, I wish I tried Arduino sooner as it is much faster than Labview or using Beaglebones etc.

I got a water meter pulse counter that uploads to io.adafruit working with an ESP8266 and am now trying to get your HubDuino project going as this seems to be the holy grail of customized control with Hubitat. Now that I understand what it is, thanks for pointing me in your direction.

In order to get to counting pulses with your code so my first try is to get a simple relay working with your ST_Anything_Relays_ESP8266. It compiles on my LoLin NodeMCU ESP8266 and the microcontroller boots and is pingable at the hard-coded IP address per your code. However, I can't get your Hubduino Parent Ethernet device to work. After installing all your device drivers and two parent drivers in Hubitat, the HPE device installs successfully. But when I configure it for the IP address of my (pingable) microcontroller with your ST_Anything_Relays_ESP8266.ino code running, HPE gives an exception error:

2021-12-30 02:29:44.024 pm errorjava.lang.NullPointerException: Cannot execute null+900000 on line 414 (method checkHubDuinoPresence)

which corresponds to this line in HPE:
<Line 414> if (now() >= state.parseLastRanAt + (tmr * 1000)) {
which tells me state.parseLastRanAt is null for some reason. I looked around the code but don't see what's wrong. Do you have any suggestions? I just updated my Hubitat from 2.2.X to but that didn't help.

Thanks if any ideas, HubDuino looks really cool to implement if I can get this working.


Also, for the guy above asking about pulse counter code this is what got me going:

1 Like

Did you properly update the sketch with your Hubitat hub’s IP address and port # 39501?

Thanks for the speedy reply, @ogiewon. I had missed that line you mentioned and it all "just works" now, very nice. Your project is the silver bullet for quick-making custom IOT (also props to Hubitat).

If you DM me an email address I'll happily paypal you $30 towards your project pizza fund.

Hey there,

I'm planing for a project, where @ogiewon code would come in really handy. But, a noob as I still am at Arduino, I have a few questions:

  1. Where do I have to implement the code, that @ogiewon posted? Is this for the Arduino, and has to be flashed on it using Arduino IDE?

  2. Can I run automations, based on these values? I'm planing on using this to turn a valve automatically off, after it released a certain volume. Would this be possible?

  3. How would this flow meters need to be wired to the Arduino? Could someone be so nice and give me an example? :smiley:

Thank you all, in advance. :slight_smile:

You'll find this thread helpful in understanding HubDuino/ST_Anything.

I am no expert in hubduino but passing what Ogiewon passed to me. Get a couple LoLin ESP8266 12E from ebay or HiLetGo ESP8266 12E from Amazon. Then figure out how to write to your ESP8266 12E via the Arduino interface. After you get something simple actually written, try to get Ogiewon's ST_Anything_Relays_Butttons_ESP8266.ino working to confirm your Hubitat can talk to it.

As a last step, figure out the pulse counter .ino, which I have not gotten to yet.

1 Like

Ok, sounds a little terrifying, but I'll try my best. :slight_smile:

I didn't want to get lost in the details so I started with this kit (linked below) because it includes a getting started manual that was perfect given I hadn't seen it done before either. The kit uses an esp32 which is just a newer version of esp8266. The getting started guide was worth the time savings alone for stepwise directions for your first try and having all the extra parts that came with it seems like a great value in retrospect.


This is really a good option. I'll order one, too. :slight_smile:

1 Like