Modular Aquarium Controller using Multiple Arduinos

Hey Arduino Community,

This is my first post here so please be kind lol. I am quite a few years removed from circuitry and programming, but not complete green...more turquoise. My experience is more than a decade ago with a (don't laugh) a BASIC stamp (I said don't laugh) and in one of my projects, I used the BASIC stamp to control lights via an X-10 interface...ok now you can laugh. I also have used visual basic programming, mainly access databases.

So my plan is quite ambitious and may take some time, but I am fine with that.

My goal is to build an aquarium controller. I know there are already a few posts on here in regards to various aquarium controllers and a few more complete solutions using the Pi. I think this approach is a little different. What I would like to do is to build smaller modular controllers using Arduino that control specific parts of the aquarium. Then I would build a master controller using Raspberry Pi that would communicate with the individual Arduinos.

Before I can get into specific Arduino controller designs, I need some input on what kind of serial interface would I used between the main controller and the Arduino modular controllers. My initial though was USB, but I'm concerned that would limit the number of modular units I can use. My next through was to use networking where everything connects to a common switch. Any thoughts on this?

The individual Arduino Modules I was thinking of are:

  • RO/DI Controller
  • HO Lighting Controller (0-10vdc outputs)
  • LED Lighting Controller(s) (PWM outputs)
  • Wave Maker (0-10vdc outputs)
  • Sump Water Level Controller
  • Skimmer Controller (0-10vdc outputs)
  • Algae Scrubber Controller
  • Calcium Reactor Controller
  • Water Temperature Controller
  • Cabinet Temperature Controller
  • Return Pump Controller (0-10vdc outputs)
  • Auto Topoff Controller (0-10vdc outputs)
  • Water Change Controller (0-10vdc outputs)
  • Dosing Controller

Each of these modular controls would have their own local inputs, outputs and a basin user interface with about 4-6 buttons and an LCD screen with some indicator LEDs. Exact inputs and outputs would vary by the purpose of each unit. Each unit would be locally configurable and independent as well.

The master unit would be there to centralize status, allow for communication between the units and push out configuration updates from one location. For one example, the main unit would calculate sunrise/sunset and moonrise/moonset times and send this information out to each of the light controllers and the wave controller as opposed to having several controllers calculate this same information. But the local controllers would determine how to respond to this data individually. To further define that scenario, Im envisioning 1 dimmable HO controller (2 channels), 4 LED controllers (6 channels) and one wavemaker controller (4 channels) in the setup. Programming a single device send out incremental updates to 30 channels across six devices would be wiring and programming nightmare. But if each of the six Arduino modules could control their relative parts, then the only communication between the devices is what are the times (from master), what are the manual overrides (from master) and what are the statuses (from modules).

So before I get too far into the weeds on how to design and build each of these units, I need to determine the best approach for communication so I reserve the appropriate channels.

For power, I would prefer to power the Arduinos over the same wire as the communication, so USB or POE for example. I could also use some non-proprietary, such as a 4-pin or 6-pin modular plug. Power for the units being controlled by the aurduino would be provided separately, be it 12vdc, 24vdc, 36vdc, or 48vdc via DC barrel connectors or 120 vac via standard outlets. My goal is to standardize everything to 24vdc, but there will be some exceptions.

My first module to tackle will be an Arduino RO/DI controller, similar to this approach here: RODI Controller - Project Guidance - Arduino Forum

There is a lot of parts and pieces to this one so probably not the easiest one to start with, but its the one part of my system that is currently not already on a controller and one I need help with. But before I can jump in, I think I need to figure out the master communications approach so I dont paint myself into a corner.

Thanks,
Chris

If you want to go the Network route...

then this seems like a nice MQTT project using the Raspberry Pi as the server/broker.

(google what MQTT is if you dont know... quick-n-dirty is called a sub and pub type of approach where your clients (arduinos) subscribe to a 'topic'.. when that topic has any changes (like the state of something).. all subscribed clients get an UPDATE.. and can then do whatever they are programmed with this command/action/change)

IMHO... I would forget about all the modules/modular stuff until you get a decent/stable protocol working.

Once your 'client/modular' Arduino's are getting/parsing the correct incoming data.. then what you connect to them control is another topic/project (dealing with voltages over 5, delivering the current these 'components' need..etc..etc)

What is your 'interface' that you will be using from the 'master controller'...

Alternately..

You could perhaps use an Arduino (mega? seems like you need a lot pins for all these potential 'modular modules')...

and use software-serial lib, so that you can use any pins on the Arduino to send data from......

So your 'MEGA' becomes the 'hub' (so to speak).. and all connected client Arduinos (needs 2 I/O pins each).. and connect to this HUB....

Might be a bit over kill.... if you can configure the Raspberry PI I/O pins.. and send serial data out directly... (but I cant comment on that)..

I -have- made a couple projects that uses the RPi as the display and to host a 'webpage' (GUI/interface)....
with an Arduino connected via USB.....

This connected Arduino does all the serial/action/command sending and parsing... (and in some cases sends real-time data back to the RPi to be displayed on the screen)

I would be more inclined to keep the micro controller count down; maybe a Pi for the GUI and controller and a Mega to manage the hardware, with port extenders if necessary.

Using one controller per function is nice in that it's simple and self contained, but I suspect it may make the overall system harder to debug. Especially if you're looking at Serial debug output from multiple sources.

MQTT sounds good if you do go the multiple unit route; the Pi can log everything so you can debug via telemetry. Communicate to your nodes bu Wifi.

Thanks for the input - its a start.

I will read up on the MQTT and see if that's an option. If I can run it as Cat 3 or Cat 5 and use an extra pair for power, that could be a win/win for this application.

I appreciate the input on not going modular until I get a protocol working first. It is my plan to start with only one and then grow from there. I plan to start with my RO/DI controller. I am currently using an Apex system by Neptune systems for the aquarium, so I will start out with the portions that currently are not controlled, and the RO/DI is an obvious starting point.

For the interface, I am looking at a touch screen option, but if not that, then a small graphics screen with some buttons, like a 6 button or 10 button interface. I will also develop a GUI to run on the Pi that I can log into with my computer or iphone. But really, I want an interface at the tank. There is already a few YouTube channels on how to do that.

My concern with consolidating the controllers comes down to wire management in a saltwater environment. For example, again with the lights. I currently have four LED fixtures, with 6 channels each. Running 24 wires from the lights to a single controller is just sloppy. If I can have a dedicated arduino in each fixture, then I can minimize the wire runs.

There are some cases where a Mega might make more sense though. My only other concern again gets into project box size. What I have seen so far with aquarium DIY controllers is that if the project gets too big, it looks sloppy and it gets difficult to keep things looking sharp.

I do not want any wireless options. My current lights communicate via wireless and its only about 90% reliable.

I kinda like the modular approach..

As the 'modular Arduino' component can be tailored for the use and external hardware it will need to interact with. (mostly with RELAYS I would imagine over all)

One of my projects uses a touch screen..

So that is not an issue.. configuring your RPi to communicate via web browser through comm ports will take some playing around with... but definitely 'doable'..

I have a touch screen one my projects that is an interface for the user.
The scroll through.. find an option and select it.

The page 'submits' (more or less.. its a HTML/CSS/AJAX/PHP/MYSQL application).. and it sends out a 'value' via comm port, and the connected Arduino (via USB), which is listening for incoming serial data, parses my 'packet'.. and decrypts the 'command/action'.. and does whatever it was coded to do for that action/command.

Which can be anything..


Lets start by using your first example.

Dont know what a "RO/DI controller" is...??
What does it do?

Better yet....
What does it need to do in your custom system you are building here?

What does it 'control'?
How is the Arduino going to 'control' the 'RO/DI controller'?

I dont know what these do...(some sort of filter?)... but a quick google/images.. makes it look like it just an 'on/off' type device? (how is it triggered in a normal situation?.. just a timer or something?)

Anyways...

You can then develop a 'client' RO/DI [Arduino] controller.. that has a small Arduino board.. perhaps a relay if needed?..... and some connectors to make every thing 'work'...

Then this 'client' module can be configured to listen for an incoming 'command' to turn the filter on/off (whatever)

Thanks!

In the spirit of cutting back on the modules, I sat down and itemized all of my inputs/outputs in the Go Big or Go Home scenario and I came up with 140....I think I got everything.

As far as types go:

Inputs (72)
5 Pressure Gages (1/4" lines)
4 TDS Meters (one with temp) (1/4" Lines)
4 Conductivity Sensors
3 Humidity Sensors
4 pH meters
2 ORP Meters
4 Temps Sensors (Air)
5 Temp Senors (Water)
6 Level Sensors
19 Float Switches
5 DC Current Sensors
5 DC Voltage Sensors
5 AC Current Sensors
1 AC Voltage Senors

Outputs (68)
10 0-10vdc Analog Outputs
28 PWM Outputs
6 24vdc Solenoids
3 24vdc Transfer Pumps
2 24vdc Mixing Pumps
2 24vdc Fan Sets
5 24vdc Intermittent Peristaltic Pumps
1 24vdc (variable) Continuous Duty Peristaltic Pump
2 120vac Chillers
6 120vac Heaters
2 120vac HO Ballasts
1 120vac UV Ballast

That's a lot! Far more management when its broken down into logical equipment based modules. I can certainly do this on a single Raspberry Pi, but the coding will be overwhelming to say the least. I was hoping that with task specific Arduinos, I could localize the logic and the Raspberry Pi just plays conductor, centralizes the GUI and coordinates data where needed between modules.

xl97:
I kinda like the modular approach..

Lets start by using your first example.

Dont know what a "RO/DI controller" is...??
What does it do?

Better yet....
What does it need to do in your custom system you are building here?

What does it 'control'?
How is the Arduino going to 'control' the 'RO/DI controller'?

I dont know what these do...(some sort of filter?)... but a quick google/images.. makes it look like it just an 'on/off' type device? (how is it triggered in a normal situation?.. just a timer or something?)

Thanks for taking the time to write this out for me. Lets elaborate on that example. The RODI for what I want to do requires:
3 Pressure Sensors (Mains, RODI, Production)
4 TDS Meters (Mains, RODI, DI, Production)
1 Temp Sensor (Mains)
3 Flow Meters (Mains, Production, Waste)
3 24vdc Solenoids (Mains, Flush, Waste)

If I provide a dedicated 24vdc power supply, then I would want to monitor current and voltage off of this supply as well. If I run a 24vdc from a common power supply, then I may or may not monitor this. Not sure yet.

The logic I have in mind for this is based on what I do every Sunday, just looking to automate it.

  1. Does my RODI Storage Tank Need Water? Yes -> RODI_On
  2. Does my Salt Water Mixing Tank Need Water? Yes -> RODI_On
  3. Else -> RODI_Off

Required Inputs (From Raspberry Pi):

  1. Call_RODI_Storage (Arduino "RODI Storage" Calls for Water)
  2. Call_Salt_Mixing_Tank (Arduino "Salt Mixing Tank" Calls for Water)

Procedure Turn_On:

  1. Open Solenoid_Mains, Solenoid_Flush, Solenoid_Waste
  2. Pause 1 Minute, Close Solenoid_Flush
  3. Wait Until <TDS_DI> is < 95% <TDS_Mains>, Then Close Solenoid_Waste
  4. If Pressure_Production = Pressure_Mains, Then Turn_Off
  5. If Flow_Production = 0, Then Turn_Off

Turn Off Operations:

  1. Close All 24vdc Solenoids

Notifications (Sent to Raspberry Pi):

  1. Pressure_Mains < 55 psi (not enough mains pressure)
  2. Pressure_RODI - Pressure_Mains > 10 psi (sediment filter clogged)
  3. Pressure_Production > 10 psi (while calling for water - means valve is stuck closed)
  4. Volume > 7500 gallons (change carbon blocks, calculated from mains flow rates)
  5. If Flow_Production < Flow_Rated (Flow_rated calculated based on temp and pressure differential)
  6. Flow_Waste > 3 * Flow_Production (flush valve stuck open, flow restrictor compromised, RO membrane fouled, etc)
  7. TDS_RODI > 0.97 TDS_Mains (After Flush Valve Closed)
  8. TDS_DI >= 1.0 (change primary DI cartridges)
  9. TDS_Production >= 0.5 (change primary and secondary DI cartridges)

Interface Connections:

  1. RJ45 with 5v PoE
  2. 24vdc Barrel Jack

Needs a little cleanup but thats a rough idea of the logic. I will have the two tank Arduinos actively call for water and locally control their tank solenoids. The RODI Arduino assume no water calls (passively) and shuts down if there is no active call for water to prevent overflows (and wasted water) should it lose communication with the system.

The physical locations are separate. The RODI system is in the garage on one side of the house and the two tanks are in a shed on the other side of the house. The actual aquarium is in between, closer to the tank storage shed.


At the RODI Controller, I would have a simple 4 line LED Matrix with some scrolling buttons. I should be able to scroll through some basic status pages:

  1. Operating Status (Off, Flush, Waste, Production) and Notifications (See Above)
  2. Valve Status: Open or Closed, Manual or Auto, Each Valve
  3. Sediment Filter: Flowrate, Pre & Post Pressure, Pressure Drop and Volume Water Processed
  4. Carbon Filter: Flowrate Volume Water Processed A and Volume Water Processed B
  5. RO Membranes: Pre & Post Pressure with Pressure Difference, Production & Waste Flowrates and Waste Ration, Pre & Post TDS with removal efficacy, Volume of Water Processed
  6. DI Membranes: Separate Resin Pre & Post TDS, Volume of Water Processed, Mixed Resin Pre & Post TDS & Volume of Water Processed
  7. Reset Filters: (Sediment, Carbon A, Carbon B, RO Membrane A, RO Membrane B, Cation Resin, Anion Resin, Mixed Resin
  8. Manual Valve Operations, each valve {on, off, auto}
  9. Settings: Sediment Filter Drop, Carbon Block Volume, RO Membrane Waste Ration, RO Membrane TDS Rejection Rate, RO Membrane Temp Adjustment, RO Membrane Pressure Adjustment, DI Separate Bed Allowable TDS, DI Mixed Bed Allowable TDS

From the Raspberry Pi, I would send Call signals from Arduino RODI_Storage and/or Arduino Salt_Mix_Tank. I would also be able to request and see the same information from above. I don't necessarily need to be able to force any settings changes or reset filters from the Raspberry Pi as I would only do this while at the RODI unit changing filters.


This is by far the most complicated of the modules. Other modules have far less process interactions to monitor/control

btw, the intent of the detail above is not to design or help me with the RO/DI control module. This just an example of what one module would do. My focus here is still how a Raspberry Pi and Arduino would communicate with each other for the functions listed above.

xl97:
If you want to go the Network route...

then this seems like a nice MQTT project using the Raspberry Pi as the server/broker.

(google what MQTT is if you dont know... quick-n-dirty is called a sub and pub type of approach where your clients (arduinos) subscribe to a 'topic'.. when that topic has any changes (like the state of something).. all subscribed clients get an UPDATE.. and can then do whatever they are programmed with this command/action/change)

I have been looking into the MQTT and this does look like a fairly simple approach. The distance between most modules is pretty close, but some of them are relatively far away....too far for local pin and serial connections, but well within network wiring range.

From what I have seen, it looks like MQTT would work best if I had a dedicated server/broker that was separate from the Raspberry Pi controller. Perhaps a Raspberry Light that everything published to.

So In my example on the RO/DI controller...

  1. Arduino RODI_Storage Publishes the Message "RODI Tank Refill"
  2. Raspberry Pi Controller Reads the Message and Updates the GUI
  3. Arduino RODI_Controller Reads the Message and begins the Turn_On Procedure
  4. Arduino RODI_Storage Publishes the Message "RODI Tank Full"
  5. Raspberry Pi Controller Reads the Message and Updates the GUI
  6. Arduino RODI_Controller Reads the Message and begins the Turn_Off Procedure

What I like about this is should the controller come off-line, the system still functions and thus my controller gets to now just be a GUI host.

What I also like about this is the GUI programming just got easier as its simply just reading and sending messages. For example, From the GUI, I can set out message "SITREP RODI Controller" and the RODI Controller can publish all the current statuses to refresh the GUI.

What I don't like about this is should the Arduino RODI_Storage go offline for any reason, the RODI_Controller will not know to shut water off. Seems to me this could be mitigated by Requesting a "SITREP RODI Storage" at some polling interval and then shutting off if it does not receive a "RODI Tank Refill" message.

Interface will be simple as I can setup a local network via switch located in my tank electrical cabinet. POE injection may be a logistical challenge for this many jacks and will need to be looked at.

Definitely something to play with.

Thanks for your help on both fronts.

wildbill:
I would be more inclined to keep the micro controller count down; maybe a Pi for the GUI and controller and a Mega to manage the hardware, with port extenders if necessary.

Using one controller per function is nice in that it's simple and self contained, but I suspect it may make the overall system harder to debug. Especially if you're looking at Serial debug output from multiple sources.

MQTT sounds good if you do go the multiple unit route; the Pi can log everything so you can debug via telemetry. Communicate to your nodes bu Wifi.

Sorry I did not respond, I had a busy weekend. I do get what you are coming from. There are plenty of online examples for a single unit aquarium controller on both Raspberry Pi and Arduino Mega. I find most of the projects peter out due to the overwhelming number of things to monitor and control on a reef aquarium. Planted tanks are probably better venues for this project.

One of my thoughts on modular is 1) it works for proprietary system on the market now and 2) I can ensure each module is fully functional as a stand alone unit, which cannot be said for proprietary systems on the market today. There are many stories on the various online forums where tanks have crashed due to a controller failure, costing thousands of dollars in livestock. There are many more stories on tanks being destroyed due to basic equipment failure a simple controller would have interrupted. So there is some merit to the project.

So in response to the difficulty of debugging, if my project criteria is that each module must fully function on its own without the input from other modules, then I limit my debugging to the communications protocol and a common GUI.

Which then brings me to MQTT. I had never head of this before but in looking at it, I think this may be perfect for my application. It's not proprietary and does not require a serial interface and will work for both units close by and units remote. It also eliminates a single point of failure that is the current demise of controllers on the market today. I have two fried ones in my garage now and my current one is the last one I plan to have purchased.

The nice thing about this project is my tank is already running on a controller, so I don't have any pressing deadline to get this working. I can take my time, get this working the way I want and change over my equipment just one piece at a time, as opposed to taking over the entire system at once.