Jump to content
inTank Media Baskets

Planning complete DIY monitoring and control


Osric

Recommended Posts

So I am continuing to think about extreme automation for my tank, and trying to work through the details so that I build it once. I'm planning to go DIY as much for the fun of the electronics side of it as for the results with the aquarium, so while I want to do things economically this might not really be the cheapest way to get where I'm going.

 

I decided to think about the project in two phases: monitoring, and control. Initially I think it'll be valuable if all I do is successfully monitor the different parts of the system, with the eventual goal of controlling every part to create the desired effects.

 

I plan to have a total of 5 tanks in the system. They are:

 

  1. The display tank
  2. The salt reservoir
  3. The clear reservoir
  4. The large salt slurry reservoir
  5. The large clear reservoir

 

The large clear reservoir is the simplest part of the system: it gets RO/DI water directly from my filter on the house water; and the filter is connected to a float valve which provides backpressure when the reservoir is full and stops it filling. There is not much protection against overflow here; a the reservoir itself is 27 gallons, and underneath the float valve is a 5 gallon bucket. If the float valve or one of the filter lines fails, it will dump water on the basement floor about 20' from the floor drain and make a mess (after overflowing the 5 gallon bucket under the valve, if that's where it leaks). So at all times the system has 27 gallons of filtered water ready to go.

 

The large salt slurry reservoir is just above that. It too is 27 gallons and all that matters is that its salinity be greater than 35ppt. My intention is to dump tons of salt in it and use a powerhead to keep it circulating. This reservoir is fed by a pump in the large clear reservoir, which will top off the salt slurry by operating once per week for at most 5 minutes or until the float switch indicates it is full, whichever comes first. It is my intention to set the float switch at a position so that if it fails, 5 minutes of refill will not overflow the salt slurry. Again the intent here is to be fail safe: if the float switch fails it should take two consecutive failure weeks to overflow to the floor.

 

The clear reservoir is a 3 gallon tank above the salt slurry reservoir. It is fed from a pump in the large clear reservoir which will top off the clear reservoir by pumping up to the float switch once a week for a maximum of one minute (same system as for the large salt slurry reservoir to avoid overflow in case of failure). If this reservoir overflows, it overflows into the salt slurry reservoir through holes in the plastic shelving.

 

The salt reservoir is another small tank above the salt slurry reservoir (on the same shelf as the clear reservoir). It is fed from a pump in the slurry reservoir as well as from a pump in the large clear reservoir. If it overflows it will overflow into the salt slurry. By pumping alternately from the salt slurry and the large clear reservoir, this reservoir is filled with water that is at exactly 35ppt salinity.

 

The display tank is on the next level of the house in my office. I have drilled holes in the floor, one to accomodate a drain pipe and one to accomodate top-off hoses. It is fed by a pump that is in the clear reservoir by an off-the-shelf ATO system to keep the water level constant. The tank is a 34 gallon solana, and if the entire clear reservoir is pumped into it, it will barely overflow onto my office floor (this could use some adjustment for safety). I need to add a pump to pump salt water from the salt reservoir to this level but the existing pipes should have room for another refill tube.

 

For water changes, my plan is to add a pump to the display tank held at the desired water level mid-change. By turning off the system pumps it should be possible to pump out the exact amount of water in a fail-safe way (note that if this pump were to fall to the bottom of the tank, a siphon effect would drain the whole tank and that'd be disasterous).

 

Whew, this is a long post already just describing the plumbing, without even getting into monitoring or control. I'll stop here and see if there's interest in picking apart possible failures or improvements to this setup before we go about monitoring and automating it.

 

thanks

Osric

Link to comment

So today I finished the first 1/12th of the first stage of this project - a 12 socket power bar with every socket under arduino control.

 

I used Sharp S102S11 solid state relays for the switching, protecting each with a 220R resistor, and wiring and indicator resistor in parallel which is drilled through the face of the socket so that you can tell if the socket is on. For wiring to the Arduino, I cut an old VGA cable in half - they contain 14 wires, almost exactly what's needed here - and wired the pins of the VGA cable to the SSR's inputs and the parallel LEDs.

 

The power bar itself consisted of four blocks of four sockets each of molded plastic with backs encased in a square box of solid metal; my plan was to use the back of this power bar as a heatsink for the SSRs.

 

The problem is that attaching the relays to the back of the power bar looks pretty difficult; my wires are all pretty short and the back slides off one end rather than snapping in and out. I have wired up just one socket for starters and it works; the SSR doesn't get even the teeniest bit warm after running a 100W lightbulb for a few minutes. I'm wondering if I need the heatsink at all ... the SSRs are rated for 8A (i.e 880W) and the some of the biggest pumps Tunze makes draw as much as maybe 40W. So I'm interested in opinions to confirm mine: seems like at these loads I hardly have to worry about heat, so why bother with heatsinks?

 

thanks

Osric

Link to comment
  • 1 month later...

I have finished my 12-socket power bar that will serve as the power center of my setup. First I cut up the strip that runs down the hot side of the power bar and attached wires to each section. Sadly I got the color coding wrong and used white for hot (black is hot in household wiring in north america).

 

IMG_20120903_153546.jpg

 

Then I drilled out each socket so that I could insert an indicator LED, and inserted all the parts back into the housing:

 

Screen%20shot%202012-09-22%20at%204.22.36%20PM.png

 

I drilled an entry hole for an old VGA cable (which has 14 wires in it - plenty for my 12 socket setup) and wired each one to the SSR.

 

Screen%20shot%202012-09-22%20at%204.24.33%20PM.png

 

Now to actually program the finished product!

 

Osric

Link to comment

Aside from the power center, the other thing I'm working on is the overflows. I like BeanAnimal's writeup about it, and am going to do something similar to what he suggests: two overflows to the sump, one siphon and one open, and one emergency siphon to the drain to guard against overflow.

 

In my first pass, I tried to be a bit too clever and made the overflow too short. In my case, I want a hang-on-back PVC overflow, whose pipes will run into my basement. Here's PVC Overflow Mark I:

 

Screen%20shot%202012-09-22%20at%204.46.14%20PM.png

 

The problem is that though this works fine, if the tank drains beyond its input the rushing water sucks in so much air that it completely loses its siphon and can't recover. So I'm thinking I'll have to extend it down so that the bottom elbows basically touch the bottom of the tank and then see if it can hold siphon across a complete tank drain, which it still might not since I'm dumping water to the basement sump. So if that still doesn't work, I will have to add an aqualifter to keep the siphon primed, and I'll just leave that running all the time with its output back into the tank.

 

[EDIT: upon further exploration it's only if I run it with the standpipe clogged that it loses siphon. If I give it an upturned intake via a couple of elbows, and let it run open it functions perfectly well as a loud overflow. So I think all I will do is put an end cap on the standpipe, and loop an airline into the tank at the water level. The airline will then enable the siphon to the basement to break before the siphon in the overflow breaks, and it will resume siphon when the water level rises again.]

 

Osric

Link to comment

Good stuff. I've done a few microcontroller weather stations and was getting ready to do basically the same thing as you.

 

I stumbled on the Jarduino project and it is pretty much amazing, and I canned my ideas of building my own and was just going to order the stuff to build one of those instead. Then I bought a reef angel today... Got a good deal on a lightly used one. Still arduino based but a little less hardware foolery.

 

The jarduino site doesn't look like much but if you download and look through the manual it's really thorough. Also, there are some youube videos that really illustrate the interface and features.

 

 

Anyway. Some sites I was using for ideas:

http://www.openreefs.com/

http://code.google.com/p/jarduino-aquarium-controller/

http://code.google.com/p/stilo/

 

 

Good luck.

Link to comment
Good stuff. I've done a few microcontroller weather stations and was getting ready to do basically the same thing as you.

 

For sure the practical approach would be to use one of the existing systems - I am doing it this way as much for the fun of both hobbies as to get the end result. I also want some things that seem uncommon - most notably automated water changes - and I'm looking forward to getting it all pieced together personally.

 

Osric

Link to comment
see my sig for pvc overflow ideas and issues

 

Thanks! I had already read your thread in fact before embarking on my overflow. You might be interested in my latest change: a bump before output to completely silence the overflow and improve throughput. Here's a picture:

 

IMG_20120923_191147.jpg

 

The way this works is super simple and I don't know why more people don't show this as an example. Basically to get down the drain the water level has to rise in the standpipe to several inches above the T because of the additional bump in the piping. If there is enough water flow this creates a second full siphon that sucks the water through the whole system dramatically faster than having the standpipe sucking in air and is, additionally, completely silent and bubble free.

 

So I plan to use this design to build BeanAnimal's three pipe overflow, with two to the sump and one to the drain in case of disasterous overflow. My sump is still in shipping so I probably won't get to actually set this up until next weekend but I'm very much looking forward to seeing if this works as I expect it to. Testing with a 5 gallon bucket on the tank itself for half a day proved very satisfactory noise wise, and the flow will be much stronger once the siphon outlet is in the basement.

 

Osric

Link to comment

The pH circuit is reasonably easy to use, but it looks like for top accuracy you need to recalibrate it after getting everything into the final position. As I only plan to use it to build my own circuit for pH this isn't a concern for me, but if it was I'd probably write a simple Arduino sketch to allow it to be recalibrated while being part of the system.

 

Pics of first readings.

 

Osric

 

IMG_20120927_003808.jpg

IMG_20120927_003817.jpg

IMG_20120927_003831.jpg

Link to comment

Why not just go with Reef Angel? You could still program your own codes etc., but most of the hardware would already be in place. It probably also offer a lot more features than totally starting from scratch, and it would likely be a lot cheaper. You could probably use whatever you already build on the controller as well considering that Reef Angel is arduino based.

Link to comment
Why not just go with Reef Angel? You could still program your own codes etc., but most of the hardware would already be in place. It probably also offer a lot more features than totally starting from scratch, and it would likely be a lot cheaper. You could probably use whatever you already build on the controller as well considering that Reef Angel is arduino based.

 

Well I'm doing it as much for the fun of enjoying both hobbies as anything, and getting my 11 year old to program the controller as a way of teaching him more about programming. So that's one reason not to use the off-the-shelf solutions.

 

On RA specificially they only support two float switches - obviously with ATO in mind - I want to have automatic water changes and control of all the various reservoirs in my setup. To truly get this set up the way I want I think I'll need at least 8 float switches in the system. 'course it's entirely possible that I have too many reservoirs, but as nobody has provided any alternatives this is the only setup I can come up with that seems entirely fail-safe to me.

 

Osric

Link to comment
  • 4 weeks later...
So I plan to use this design to build BeanAnimal's three pipe overflow, with two to the sump and one to the drain in case of disasterous overflow. My sump is still in shipping so I probably won't get to actually set this up until next weekend but I'm very much looking forward to seeing if this works as I expect it to. Testing with a 5 gallon bucket on the tank itself for half a day proved very satisfactory noise wise, and the flow will be much stronger once the siphon outlet is in the basement.

 

So I do now have this working. It was a fair bit fiddlier than I expected, due to the extreme suction created by the drop to my basement. I have three pipes into the basement; one goes to the sewer system and two go to the sump.

 

The main drain is 0.5" PVC with the extra bump as described in my prior post. I found that making the extra bump tall makes it hold its prime better as well as keeps the water level well above the intake so that the intake is completely submerged. This overflow follows the shape indicated by the parts as shown here:

 

IMG_20120924_195228.jpg

 

Note that although the parts shown to give you a clear idea of the shape are 3/4", that proved to be overkill for the primary drain in my case because the drop is about 70-80" and under full siphon this draws a lot of water (see Bean Animal's calculator). The 0.5" drain, when fully open, can handle the entire flow of the return pump.

 

But as per Bean Animal's silent overflow design, the idea is to have a trickle of water going through another overflow. If you put all the flow through this first overflow, it sucks air through the standpipe and is very noisy. I use a valve in the basement to restrict the flow so that the pipe is solid water to the basement and completely silent; both the intake and all the piping are completely full of water (the intake is in fact submerged; the water level being controlled by the second siphon bump).

 

The second overflow is a standard design. Originally I used another siphon bump but I found that in failure cases this would wind up sometimes sucking enough air to break the secondary siphon and cause overflow; the basic design is safer and since it's only carrying a trickle of water it is very quiet. I do find it a bit finicky to adjust the primary flow to make the secondary truly silent; I recommend a gate valve if you can get it (I have ball valves and they are a pain to fine tune). However the setting can be found, and the secondary carries water down its walls to the basement and the whole setup is quieter than the water coming into the back of the solana through the overflow grate. I silenced that too by putting the solana sponge behind the overflow grille.

 

A third overflow leads directly into the sewer system. It will not carry water under normal circumstances but will be used to drain water during water changes in order to avoid losing its siphon due to evaporation.

 

I am still fine tuning this but confident now that a completely silent PVC overflow is, indeed, possible.

 

Osric

Link to comment
  • 1 month later...

Screen%20Shot%202012-12-03%20at%201.30.29%20AM.png

 

Finally got around to putting the Arduino in place - with just the temperature sensor so far. It's gathering 6 data points per minute, logged on the computer side over USB and plotted once per minute to my monitoring website.

 

[edit] After gathering a few hours of data, the raw data look a little messy:

 

Screen%20shot%202012-12-03%20at%207.22.17%20AM.png

 

so applying 'smooth bezier' to gnuplot's input file was the answer:

 

Screen%20shot%202012-12-03%20at%207.22.48%20AM.png

Osric

Link to comment
Screen%20Shot%202012-12-03%20at%201.30.29%20AM.png

 

Finally got around to putting the Arduino in place - with just the temperature sensor so far. It's gathering 6 data points per minute, logged on the computer side over USB and plotted once per minute to my monitoring website.

 

Hey man!

Good to see you post some Arduino stuff. Please put your temp sensor code up when you get the chance. I'm surprised you are having noise issues if you are only sampling every six minutes. Maybe you need to do some smoothing at the Arduino level?

Link to comment
Hey man!

Good to see you post some Arduino stuff. Please put your temp sensor code up when you get the chance. I'm surprised you are having noise issues if you are only sampling every six minutes. Maybe you need to do some smoothing at the Arduino level?

 

Well it's not really noise, it's really hitting the resolution limit of the ADC. Since the ADC is converting 0-5v to 10 bits, the temperatures available around those in the graph are:

 

73.38

73.83

74.28

74.73

75.18

75.63

76.08

76.53

76.98

 

So it's really a resolution problem, with the ADC jumping between two of these values, creating the jitter that represents a value somewhere in the middle. We could fix this in software but we have no real need of the temperature sensors full range, so probably the right solution is to learn enough about op amps to map this voltage range to 0-5v (e.g. map 790mv -> 0, and 1190mv -> 5v, would give us temperatures between 68f and 105f, with a resolution of 0.03f between steps instead of 0.48f, for much more accurate readings.

 

The circuit to accompish this is simple if I understood op amps fully; as it is I'll have to use some examples to fix it in fact. It'll probably wait until after I have a bit more automation in place; the accuracy is good enough for my purposes at the moment...

 

Osric

 

P.S. Will post code later but the arduino code for this essentially consists of the sample code wired up so that it prints a data point to the serial port every 10s, so it's not much different than the code as provided by atlas. Also I grabbed the actual values coming out of my sensor in practice, they are slightly different than the values I calculated above:

 

74.7075.1575.5976.0376.4776.9277.3677.8078.2478.6879.1379.5780.01

 

P.P.P.S. FWIW, here is the code listing for grabbing the temperature data. I'm using a Mega which is why there are so many pins, and the RGB Shield from adafruit for the display.

 

#include <Wire.h>#include <Adafruit_MCP23017.h>#include <Adafruit_RGBLCDShield.h>// The shield uses the I2C SCL and SDA pins. On classic Arduinos// this is Analog 4 and 5 so you can't use those for analogRead() anymore// However, you can connect other I2C sensors to the I2C bus and share// the I2C bus.Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();// These #defines make it easy to set the backlight color#define RED 0x1#define YELLOW 0x3#define GREEN 0x2#define TEAL 0x6#define BLUE 0x4#define VIOLET 0x5#define WHITE 0x7static const char *version = "Aquarius v0.1";#define BOOT_LIMIT 100000long basetime = 0;boolean upOK = 0;void read_basetime() {  char byte = 0;  int counter = 0;  while (byte != '*') {	while (!Serial.available()) {	  counter++;	  if (counter > BOOT_LIMIT) { return;	  }	  if (counter % 100 == 0) { Serial.write("awaiting basetime\r\n");	  }	}	byte = Serial.read();	if (byte >= '0' && byte <= '9') {	  basetime *= 10;	  basetime += (byte - '0');	}  }  upOK = true;}void setup() {  // set up the LCD's number of columns and rows:   lcd.begin(16, 2);  lcd.setBacklight(YELLOW);  lcd.setCursor(0, 0);  lcd.print(version);  delay(2000);  lcd.setBacklight(GREEN);  clearstatus();  showstatus("Booting...");  delay(2000);  pinMode(52, OUTPUT);  showstatus("52 output mode");  delay(500);  // Debugging output  Serial.begin(9600);  showstatus("Serial Console");  Serial.write(version);  read_basetime();  if (upOK) {	Serial.write("\r\nStartup successful.\r\n");  } else {	Serial.write("\r\nInvalid basetime.\r\n");  }  delay(500);  clearstatus();}long showtime(long millis) {  long seconds = millis/1000;  // set the cursor to column 0, line 1  // (note: line 1 is the second row, since counting begins with 0):  lcd.setCursor(0, 1);  // print the number of seconds since reset:  lcd.print(seconds);  lcd.print("	   ");  return seconds;}void showstatus(char *message) {  // set the cursor to column 0, line 0  lcd.setCursor(0,0);  lcd.print(message);}void clearstatus() {  showstatus("				");}float read_temp(void) {		float v_out;		float temp;		digitalWrite(A15, LOW);		digitalWrite(52, HIGH);		delay(2);		v_out = analogRead(15);		digitalWrite(52, LOW);		v_out*=.0048;		v_out*=1000;		 		temp= 0.0512 * v_out -20.5128;		return   temp;} uint8_t i=0;long lastTime = 0;long t = 0;void log_temp(float celsius) {  Serial.print("T|");  Serial.print(t + basetime);  Serial.print("|");  Serial.print(celsius);  Serial.print("|");  Serial.print(c2f(celsius));  Serial.write("\r\n");}float c2f(float celsius) {  return 9*celsius/5+32;}void loop() {  t = showtime(millis());  showstatus("Temp: ");  float temp = read_temp();  lcd.print(c2f(temp));  if (t % 10 == 0 && t > lastTime) {	log_temp(temp);	lastTime = t;  }}

 

The python that's needed on the other end of this:

 

#!/usr/local/bin/pythonimport serialimport timeser = serial.Serial('/dev/cu.usbmodem1b11', 9600)degf = open('degf.dat', 'w')degc = open('degc.dat', 'w')version = 'error'while not 'Aquarius' in version:  version = ser.readline();  print(version)version = version[version.find('Aquarius'):]print('Arduino Aquarius version string: ');print(version);ser.write(str(int(time.time())))ser.write('*')while 1:  raw = ser.readline().strip()  if raw.startswith('T'):	f = raw.split('|')	print(f)	print(time.asctime(time.localtime(int(f[1]))))	degf.write(f[1])	degc.write(f[1])	degf.write(' ')	degc.write(' ')	degf.write(f[3])	degc.write(f[2])	degf.write('\n')	degc.write('\n')	degf.flush()	degc.flush()  else:	print(raw)

Link to comment
  • 2 months later...

Well, a cautionary tale. I had my overflow set up as of the end of October, and in the first week of February I had an overflow.

 

Why? Because I'd never gotten around to fine tuning my emergency drain overflow and as days turned into weeks and everything ran perfectly I frankly forgot to get back to it. So I was running with just the two overflows - the primary and the trickle - and no emergency drain setup. When my trickle overflow stopped carrying its load for some unknown reason, I wound up with a fairly big overflow in my office.

 

So I have set up the emergency overflow, and it works great. I know this because I went away on vacation just after that and the problem with the trickle overflow struck again in my absence, but the water all went down the drain this time, no overflow on the floor. Re-priming the trickle (which I hadn't done last time but did this time) seems to have properly fixed the problem, though I am unclear on how it lost its prime in the first place.

 

Osric

Link to comment

Archived

This topic is now archived and is closed to further replies.

  • Recommended Discussions

×
×
  • Create New...