Welcome to ScapeCrunch

We are ScapeCrunch, the place where planted aquarium hobbyists come to build relationships and support each other. When you're tired of doom scrolling, you've found your home here.

DIY mega controller (ESP32 project)

Joined
Nov 1, 2022
Messages
282
Reaction score
614
Location
Australia
Been meaning to write this up for a while, so here it is. Over the last few months I've built a full custom controller setup for my 130L planted, CO2 injected tank, running on three ESP32 boards working together. It replaced an ageing Up Aqua CO2/pH controller and turned into a genuinely complete automation system for water changes, dosing, CO2, top-off, and reservoir monitoring. Sharing the overview here in case it's useful or interesting to anyone else down a similar rabbit hole.

The short version​


Three boards, each with its own job:


  • Water change controller — drains, refills, remineralises, and doses the tank automatically, sitting mostly idle between weekly changes.
  • Tank controller — the brains of day-to-day operation, running CO2/pH control, top-off monitoring, the reservoir, and a small front panel with live readouts.
  • Alexa bridge — ties the whole thing into Alexa for voice control and equipment scenes, and handles the feeding routine.

They talk to each other over WiFi and three deliberate hardwired links for the communications that genuinely shouldn't depend on the network as they are safety critical.

Water changes​


Weekly, fully automated. Connect a line from the WaterDrop filter, a drain line that goes outside to the garden or lawn (both with quick connects and manual valves for safety), choose your water change volume in litres, press start and it then:
- runs through safety prompts to ensure everything is connected and safety valves are set correctly.
-prompts to clean prefilters
-prompts to measure remineralisers (calculated on screen, based on your water change volume selection).
-it then drains and refills with RO water. It also turns off/ on smart plugs so skimmers, co2, heaters ect are off for draining then start to turn them on as water fill reaches certain thresholds.
  • during refil it remineralises to target GH and KH from a container with a magnetic stirrer with a perialstatic dosing pump that fires at set percentages of fill.
  • it then connects to my Chihiros dosing pumps and fires the dosing boosts to preload nutrients (again these doses are scaled with selected water change volume)
-all without me touching anything. In fact it now means I can mow the lawn during water changes!
- It doses potassium bicarbonate for KH, calcium and magnesium sulfate for GH, and boosts macros (nitrate, phosphate, potassium, micros), again, all scaled to my actual water change volume.
Everything's logged, every step confirmed before moving to the next, with a wizard-style setup so I can adjust the fill amount, KH target, and anything else on the fly.
I also get phone updates, the fill solenoid is connected with a flow rate sensor, temperature probe and TDS sensor. So every 10L I get an update on the flow rate, tds and temperature of that 10L fill and average so far, so I can spot any issues. It will also abort the water change, stop filter.

CO2 and pH​

This was the original reason the whole project started. My old analogue controller had a pretty coarse hysteresis, and in low KH water even small CO2 swings move pH more than I'd like. The new controller runs a proper pH probe on a scheduled window, targets a specific pH with a tight, tunable hysteresis, and logs everything continuously. It also catches things a dumb timer never could, a sudden pH crash with the solenoid already closed pointed straight at a CO2 regulator dumping its tank, something I'd never have caught otherwise until it was a much bigger problem. The Atlas Ezo ph sensor setup is elite and far more accurate than my previous setup. I can also see live updates, get phone alerts for certain events and have set safety alets and shutoffs for events like rapid changes in ph.
I have also put a weight sensor under my CO2 bottle so it tells me how full/empty my co2 bottle is and predicts refill date based on useage (this is untested as it's still so new, I don't have the data for it to be accurate.)

Dosing​

Being sick of the Chihiros app occasionally being unavailable this year, I have given over control of the scheduling and setup to my controller. I have my own dashboard and phone app that does this now and can send schedules and settings to the Chihiros pumps. It has taken some trial error and bluetooth sniffing apps to work this out but it is rock solid now.
Four channel dosing pump, fully scripted daily doses plus automatic post-water-change boosts, calculated from my actual verified nutrient targets rather than rough guesses. Doses are triggered automatically the moment a water change finishes.

Top-off and reservoir​


For now, the auto top-off unit itself does the actual work, but the controller now watches the reservoir independently, a proper pressure-based level sensor for the real litre count, plus a simple mechanical float as a dumb, sensor-agnostic backup. If the float ever trips, ATO shuts down immediately and I get a notification, worded differently depending on whether the pressure sensor agrees with the float or not, since a disagreement between the two usually points at the pressure sensor itself needing a look rather than a genuinely empty reservoir. I have some optical sensors on the way, and hopefully by next week the controller is running the ATO independently.

Feeding​


A small but genuinely nice touch. Feeding pauses CO2 injection, filter and skimmer automatically, it's voice activated or you can use a unit mounted button, and the front panel readouts switch to a simple "feeding" display while the filter's off, since the normal sensor numbers would be meaningless with no flow through the lines anyway.

Remote monitoring​


Everything logs to a Grafana dashboard, I have pH, temperature, TDS, reservoir level se sors, it also logs CO2 state, with history of all controller actions that I can actually look back through rather than just a live snapshot. Genuinely useful for spotting slow trends, not just catching sudden problems.

Alexa integration​

Voice control for scenes around water changes, changing settings and feeding, equipment turning off and on automatically at the right points in each process, and a physical feed button that fires the exact same routine as the voice command.

Safety, and why it mattered more than any single feature​


If there's one thing I'd want someone building something similar to take away, it's this. Every automated system that can act on its own needs to fail toward safe, not just work correctly when everything's fine.


A few of the principles that ended up running through the whole build:

  • Solenoids fail closed. Power loss means CO2 and water stay off, never on, by hardware design, not firmware logic that could have a bug in it.
  • A tripped safety condition can't be quietly dismissed. If something raises an alert, like the backup float, you can acknowledge it, but the system won't let you clear it while the actual problem is still physically present. No accidentally waving away a real fault.
  • The one link that has to work regardless of WiFi, does. CO2 and ATO pausing during a water change runs over a direct hardwired connection between boards, not the network. Everything else can be a bit more relaxed about connectivity; that one thing can't be.
  • A backup sensor's only job is to disagree usefully. The float switch isn't there to be a second source of truth, it's there to catch the primary sensor being wrong. When they disagree, the alert tells me which one to actually go check.
  • Never power anything from two sources at once. Learned that one the hard way, destroyed a board's regulator early on doing exactly that. So it now has wifi firmware updates for each board, to save the USB input power when updating by PC

    None of this was designed perfectly the first time either, more caught through actually running it and paying attention than getting it right on paper up front. A few genuine bugs this build taught me: features that were fully coded but sitting behind a switch I'd forgotten to flip on, so they looked complete but never actually ran; a menu screen that could lose progress if you walked away at the wrong moment during a slow calibration step. Both fixed once they showed up in real use, which is really the whole point of building it in stages rather than all at once and hoping. I have spent weeks finding and squashing bugs before I have given over control of the tank to it.

    Next on the list:
    Heater/fan control, full ATO control, uninteruptable power unit uninterruptible that alerts me to power outages and turns on air pumps.

    It is also in a pretty basic case and the cutouts are purposely oversized. I have ordered smoked acrylic to 'wrap' it in so it appears to be black rectangular box, with only the LED parameter readouts (temp, pH, TDS and ATO reservoir litres) visible through the smoke tinted acrylic and the two black control knobs that wake sleeping OLED screens, all other controls will be behind hinged flaps. I want to make sure all the sensors etc are wired correctly though before I wrap and anchor wiring.

    The great thing is, every time I think of something I want to add, it is a coding session with the help of AI and finding the sensors or equipement required. I can wake up with an idea and genuinely have it implemented with an hour or two of soldering and coding. It fits my tank like a glove and is infinitely adaptable. menu setup and setting options all added as I think of them!

    I will add some pictures below of the in progress build! I wanted to share in case anyone is thinking of doing the same, with the prices of ESP32s and the sensors (except for the Atlas Ezo chips! which are expensive but well worth it!) it is definitely a project in reach of anyone with a basic idea of code and soldering.
 
1784275473502.webp
@Art always spoke on his podcast about using cardboard boxes as scaping dojos, so I stole the idea and used it as a coding dojo.
This is the original water change controller setup. It was fully functional and could manage water changes despite looking like I found it in the bin of an electronics supply store!
1784275629456.webp
Beginning to take shape in an actual enclosure.

1784275658636.webp
The screen that walks you through water changes and calculates remineralisers and boost doses.

1784275702291.webp
As it stands today, showing temp, pH and TDS from inline sensors on my filter lines, and how many litres left in my ATO reservoir. Control knob and oled settings screen.

1784275776061.webp
Top of the unit with indicator leds, function buttons, waterproof plugs for sensor banks and the water change controller controls and screen.

It’s still a bit ‘messy’, but after a month of running when I am satisfied it is getting close to bullet proof, I will wrap it nicely in acrylic and add sockets and plugs for all the sensors and control lines.
 
Nicely done! Love seeing automation on FW tanks. Also cool that you were able to hack the dosing pumps by sniffing BT packets. I've also picked up some load cells/HX711 and plan to do the same with the CO2 tank, so curious to see how you find that as most the 'cheap' load cells I've found are more for human weights, so not sure how fine the resolution will be on the low end.

One thing I'd ask, and you might have already mitigated it but not shown in the post, is what happens if the ESP32 hangs while holding the fill line open for either the AWC or ATO? It sounds like you plan to be around during water changes, so it may not be as much of an issue especially with your every 10L updates.

On mine, I am planning for small daily water changes overnight - so it's something that's kept me up at night wondering how to mitigate. In short, I've added a watchdog timer circuit on the RO fill lines so the esp has to kick the solenoid circuit every x seconds to keep it alive, or it shuts off, the fill lines will have a mechanical float switch that will limit overfilling, and the esp boards will have a heartbeat indicator so home assistant can act as a supervisor and shut down master power to either one if they don't report in. This is on top of having float switches for cuts offs, and flow sensors for volumes. I might be on the overly paranoid side, but don't want a cascading failure to cause a flood either!
 
Nicely done! Love seeing automation on FW tanks. Also cool that you were able to hack the dosing pumps by sniffing BT packets. I've also picked up some load cells/HX711 and plan to do the same with the CO2 tank, so curious to see how you find that as most the 'cheap' load cells I've found are more for human weights, so not sure how fine the resolution will be on the low end.

One thing I'd ask, and you might have already mitigated it but not shown in the post, is what happens if the ESP32 hangs while holding the fill line open for either the AWC or ATO? It sounds like you plan to be around during water changes, so it may not be as much of an issue especially with your every 10L updates.

On mine, I am planning for small daily water changes overnight - so it's something that's kept me up at night wondering how to mitigate. In short, I've added a watchdog timer circuit on the RO fill lines so the esp has to kick the solenoid circuit every x seconds to keep it alive, or it shuts off, the fill lines will have a mechanical float switch that will limit overfilling, and the esp boards will have a heartbeat indicator so home assistant can act as a supervisor and shut down master power to either one if they don't report in. This is on top of having float switches for cuts offs, and flow sensors for volumes. I might be on the overly paranoid side, but don't want a cascading failure to cause a flood either!
the load sensor I have is 0-10kg, so my co2 bottle sits beautifully in the middle quadrants. It is a cheapie ($15) so measurements are course, but suits my purpose of giving me a rough idea of bottle usage and time to fill.

For the hanging esp32, I have a few safety factors in place.
The main one is that I’ve used an optocoupler to make the high float (that tells the controller the tank is full) to be not only a signal line, but it also interrupts power to the relay boards that run the ato and water change fill solenoids. So once the mechanical float rises the normally closed solenoids shut regardless of ESP32 status.
I also have a time setup. Flow rate is 2.5lpm, and whatever you set the water change volume at it calculates expected time, and shuts off 5 minutes beyond that. Also shuts off if the flow counter reads 5 litres over expected. Those are iffy on an esp32 hang though.
I also have 3 esp32s in there, one water change controller, one tank controller and a communication board.
The communication board acts like a watchdog for the other two and checks in constantly and notifies me of any non-responsiveness. After 5 minutes of no replies it attempts to aborts all procedures.

I would definitely recommend having a mechanical float as the final safety barrier, so you can have the mechanical interrupt of power to the solenoid.
I am going to use optical sensors for the ato high/low, as the dual optical sensors are so handy and easy to hide, but just above that is a mechanical float switch, that is also the water change refill high sensor.
 
View attachment 18580

Seriously, I'm speechless 😮 Beautifully thought out and use case tested 💯💯 the in-progress remineralization is brilliant!

When do you start taking orders? 😁 😁 😁

View attachment 18582
It has taken so much time to find workarounds for things, and it is so setup for my context I would need to move in for a week and teach you how to use it 😂
To communicate outwards to Alexa, I had to hack into a humidity sensor to fake humidity readings and set up routines that trigger at certain humidity ranges. Then to communicate back to the controller I soldered up a set of 5 different voltage splitters to run off a tp link smart usb strip, so I can send different trigger voltages back to the pins. It took a whole day to think about it, set it up, debug and work through it.

It’s been a labor of love, and I’ve genuinely had fun building it and learning all the systems, but the thought of working out how to generalise it for market makes me break out in a sweat!

Would certainly be happy to help anyone interested on doing similar, even on a smaller scale get set up and can share code and wiring setups.

The basic sensor, to esp32, then make it take an action is something I believe anyone can learn! Use a breadboard, DuPont wires and wago wire connectors and you don’t even need to solder anything.
Integrating the systems is where it begins to get time consuming and tricky though!
 
the load sensor I have is 0-10kg, so my co2 bottle sits beautifully in the middle quadrants. It is a cheapie ($15) so measurements are course, but suits my purpose of giving me a rough idea of bottle usage and time to fill.

For the hanging esp32, I have a few safety factors in place.
The main one is that I’ve used an optocoupler to make the high float (that tells the controller the tank is full) to be not only a signal line, but it also interrupts power to the relay boards that run the ato and water change fill solenoids. So once the mechanical float rises the normally closed solenoids shut regardless of ESP32 status.
I also have a time setup. Flow rate is 2.5lpm, and whatever you set the water change volume at it calculates expected time, and shuts off 5 minutes beyond that. Also shuts off if the flow counter reads 5 litres over expected. Those are iffy on an esp32 hang though.
I also have 3 esp32s in there, one water change controller, one tank controller and a communication board.
The communication board acts like a watchdog for the other two and checks in constantly and notifies me of any non-responsiveness. After 5 minutes of no replies it attempts to aborts all procedures.

I would definitely recommend having a mechanical float as the final safety barrier, so you can have the mechanical interrupt of power to the solenoid.
I am going to use optical sensors for the ato high/low, as the dual optical sensors are so handy and easy to hide, but just above that is a mechanical float switch, that is also the water change refill high sensor.
Nice, sounds sensible! I was debating between essentially what you have, and the watchdog circuit for a while, only ended up going watchdog chip as I already feel like I have too many sensors as it is already, and its barely any extra space on the pcb.

Looking forward to your next steps on this project.
 
The beauty of a DIY system is when you have an idea while sitting and watching the fish feed, you can get out the laptop and add a feature.
As the sensors all sit in inline ports on the filter line, the readings drift meaninglessly during feeding, as the filter is off. To hide them, stop them being logged and make me smile at the use of the led segment setup, I added a message and timer to the front panel when the feeding button is pushed:

1784299512630.webp
 
When I was younger, I would be so into this and jumping on the bandwagon with all these cool DIY electronics projects. With age, I've lost a bit of the fire, or may just be too lazy. Perhaps in the near future, when I've gotten a bunch of the higher priority home projects knocked off the list, I'll start tinkering on some of these things as well. Today, I'm painting and reorganizing the garage. :confused:
 
When I was younger, I would be so into this and jumping on the bandwagon with all these cool DIY electronics projects. With age, I've lost a bit of the fire, or may just be too lazy. Perhaps in the near future, when I've gotten a bunch of the higher priority home projects knocked off the list, I'll start tinkering on some of these things as well. Today, I'm painting and reorganizing the garage. :confused:
I would have been the same 10 years ago! My garage is organised and the house is renovated, it’s project time 😂.

Today’s feature add, co2 tuning mode.
Get a phone notification whenever the tank reaches equilibrium (stable pH for 25 minutes), alert status is reset at the controller by either choosing to accept that pH as the controller backstop, or I can open the needle valve and the controller looks for the next equilibrium and alerts me.

1784458552851.webp
 
That's crazy good. It would have taken a huge amount of time. Once you start going down that rabbit hole..........

Very nice work on the chihiros and alexa integrations too. Easier said than done.
I need to work out how I can do a similar feat for a jebao DC pump that has wifi and BT. There is an actual HA integration created for that exact line of pumps but only for the next model up from mine. I'm sure its possible if I tinker around long enough.

I've not long started and only have the basics so far but even that has taken way too much time between putting the hardware together and then the software side.

Even little things like for the atlas board, switching it from the default uart mode to l2c mode took lots of mucking around. Atleast it did for me.

I'm still undecided whether to use commercial dosing pumps like you have with Chihiros or just grab another esp32 and relay and DIY it. Still pondering.....

Maybe this should be the focus thread for this kind of DIY stuff??

Here is draft 1 of the main page of my dashboard.
The dosing pumps and the leak detection are only placeholders currently. Everything else is functional though.
The more useful charts (using apex charts) are on another view. Was there an advantage in using grafana over something like apex for the charts?

1784535710122.webp
 
Very nice work on the chihiros and alexa integrations too. Easier said than done.
I need to work out how I can do a similar feat for a jebao DC pump that has wifi and BT. There is an actual HA integration created for that exact line of pumps but only for the next model up from mine. I'm sure its possible if I tinker around long enough.

I'm still undecided whether to use commercial dosing pumps like you have with Chihiros or just grab another esp32 and relay and DIY it. Still pondering.....

Here is draft 1 of the main page of my dashboard.

On the jebao pump, I'm planning to use one as well, but still debating between mdp with wifi or dcp model and just using a relay for on/off control. I've seen the same ha integration as you and have had the same thoughts.

If you want to go with diy/stepper driven pumps, you (or anyone else interested) can have my dosing pump circuit board and enclosure design.

Nice dashboard! Is it using mushroom cards and mini graph cards? I haven't gotten that far yet.
 
That's crazy good. It would have taken a huge amount of time. Once you start going down that rabbit hole..........

Very nice work on the chihiros and alexa integrations too. Easier said than done.
I need to work out how I can do a similar feat for a jebao DC pump that has wifi and BT. There is an actual HA integration created for that exact line of pumps but only for the next model up from mine. I'm sure its possible if I tinker around long enough.

I've not long started and only have the basics so far but even that has taken way too much time between putting the hardware together and then the software side.

Even little things like for the atlas board, switching it from the default uart mode to l2c mode took lots of mucking around. Atleast it did for me.

I'm still undecided whether to use commercial dosing pumps like you have with Chihiros or just grab another esp32 and relay and DIY it. Still pondering.....

Maybe this should be the focus thread for this kind of DIY stuff??

Here is draft 1 of the main page of my dashboard.
The dosing pumps and the leak detection are only placeholders currently. Everything else is functional though.
The more useful charts (using apex charts) are on another view. Was there an advantage in using grafana over something like apex for the charts?

View attachment 18644
Very nice! More than likely the handshake the pumps use to receive commands is the same between versions, it is just getting the MAC address and using a bluetooth sniffer on an android device to work out what it is sending. Throw the packets into Claude and it will detangle it for you pretty quickly.
It is one of those things that may take 10 minutes or may take 3 hours, but it will be doable.
For the dosing pumps, I would definitely go the DIY route if I did not already own the Chihiros pumps. They are a very simple device and calibration scripts are very basic and can be tailored better for your context (ie calibration doses being what you actually use, increasing accuracy within the range you want.)

I went Grafana only because I have used it in server project many years ago. It is incredibly good for free, but I can't compare it to anything else as it's all I know.
Today I added a remote connection to be able to change settings from anywhere, as I am back to work after holidays. Again, the beauty of a custom system, it took 10 minutes to add as I had my breakfast and at work I was able to control the box.

A 3/4" flow valve arrived today, my plan is to fit it in the filter outlet line and find the differential between clean pre-filter and dirty pre-filter on the Biomaster. Alerts for filter cleaning time. Necessary? not at all, I will probably still clean it weekly, but why ntot for the cost of a $15 sensor and 30 minutes work.
 
1784550404626.webp
Tank hub - live stats, controller settings, log of tracked stats as well as where I can put in test results from manual testing. Has all the test calculators (Thanks Rocco, your NO3 Hanna checker calculator is built in here) for NO3, dKH , dGH, CO2 and Ca test kits, put the raw values in and it uploads the calculated values to a Google Sheets. The data is then viewable in historical charts.
1784550603071.webp
1784550647812.webp

Also my feeding schedule, brine shrimp hatching instructions (I always forget as I make big batches and freeze them and it's so long between hatches!) and dosing calculations, recipes and notes.
Frustrated with there being no decent aquarium logging apps, I am pretty happy with my DIY (nearly all AI tbh) setup.
 
Awesome project 💪, I'm deep in that ESP32 rabbit hole as well. Haven't read the posts in detail , but here some ideas for you you might like I've implemented so far:
  • apart from pH monitoring CO2 in a gas pocket, so you can derive CO2 and calculate KH.
  • use a stepper motor to adjust a needle valve.
  • monitor light intensity, air pressure, pwm fan speed, and oxygen in a gas pocket.

Last December I bought myself a 3D printer, which made the interior of the rabbit hole so much nicer.

Good luck with the project, it's on my watch list now 👊
 
On the jebao pump, I'm planning to use one as well, but still debating between mdp with wifi or dcp model and just using a relay for on/off control. I've seen the same ha integration as you and have had the same thoughts.

If you want to go with diy/stepper driven pumps, you (or anyone else interested) can have my dosing pump circuit board and enclosure design.

Nice dashboard! Is it using mushroom cards and mini graph cards? I haven't gotten that far yet.
I have the Jebao MDP-6500, the one in github is MDP-10000. Basically the same pump though.
DIY pumps seems like the way to go then. I'll use a separate esp32 board for that though. Only because the existing one is in a final enclosure ( a small ABS box and no room for more internal wiring, connections etc). Happy to look at your design thanks. I don't have a 3d printer (yet lol) so will have to figure out another way to mount them. Maybe some kind of DIN rails?

Thanks. Yes spot on. Mushroom cards and mini-graph cards. I just used the mini-graph cards on the main screen to keep it clean and minimal.

Very nice! More than likely the handshake the pumps use to receive commands is the same between versions, it is just getting the MAC address and using a bluetooth sniffer on an android device to work out what it is sending. Throw the packets into Claude and it will detangle it for you pretty quickly.
It is one of those things that may take 10 minutes or may take 3 hours, but it will be doable.
For the dosing pumps, I would definitely go the DIY route if I did not already own the Chihiros pumps. They are a very simple device and calibration scripts are very basic and can be tailored better for your context (ie calibration doses being what you actually use, increasing accuracy within the range you want.)

I went Grafana only because I have used it in server project many years ago. It is incredibly good for free, but I can't compare it to anything else as it's all I know.
Today I added a remote connection to be able to change settings from anywhere, as I am back to work after holidays. Again, the beauty of a custom system, it took 10 minutes to add as I had my breakfast and at work I was able to control the box.

A 3/4" flow valve arrived today, my plan is to fit it in the filter outlet line and find the differential between clean pre-filter and dirty pre-filter on the Biomaster. Alerts for filter cleaning time. Necessary? not at all, I will probably still clean it weekly, but why ntot for the cost of a $15 sensor and 30 minutes work.
I'll start having a good play around to work out the Jebao pump. My home assistant is running on a proxmox VM, so I have linux at my disposal for packet sniffing etc which is what it's very good at.

Great, DIY pumps it is. I'll look forward to putting that together. That is one thing I have stabilised is the fert dosing. Just currently done manually. I wonder for the macro solution, is a magnetic stirrer warranted? Mine mixes up pretty good so probably don't need it.

If my current charts don't do what I want, I'll look into grafana then. Did you use the HA remote connection (which you pay for) or something like tailscale - that's what I intend to use.

The flow valve idea I actually have on my list lol for the exact reason you do. I figure once you have the settings for a clean filter and tubing etc, then for example once the flow is reduced to like 85% it triggers a phone notification. I think that would be a nice addition.

The beauty of a DIY system like this, you can continually amend, add ideas, bolt on new hardware etc. Its basically only limited by your imagination.

Oh very cool and functional dashboards btw.
 
Last edited:

Top 10 Trending Threads

Back
Top