My Neptune Apex web interface compatible DIY reef controller

I have his code running on a UNO with the ph module attached. Still waiting on my probe to arrive. Just reads 0v. I did read on his blog the calibration is a manual thing in his code. Have to record the readings in a serial monitor and re-compile code with the values for 4 and 7.

right, it does not store the calibration values internally, but is part of the program.

I did not get a response to my questions yet. I asked if i2c address is hard coded, if i2c lines have pullups and if i2c will work at 400khz. I think if he answers the questions, it will permanently show on his listings and may affect his sales (depending on the answers), which now seems to be doing pretty well.
 
My Neptune Apex web interface compatible DIY reef controller

I am done with doser code. I will update the files in github soon. I still need to update the circuit diagram a bit for the new feeder.

This is how the browser pages look. It shows the remaining volume in the bar graph.
fejGJhg.png

tap on a pump, and you get to manually dose or reset dosed volume (0 if you refilled the container)
bAHgW3O.png


doser setup page
G9KF4Et.png
3m8r9OH.png


you specify doser name, daily total dose volume in ml, number of doser per day, interval in minutes between doses, dosing start time, and the container volume when it is full.

The start time is so you stagger dosing between the two pumps so you don't pump the two liquids at the same time.

If the interval is set to 0, it will automatically spread the number doses per day evenly.

Say if doses per day is 24, interval 0 will make it dose every hour.
In the above example, interval is 30 minutes. With start time of 12pm, it will does at 12pm, 12:30pm, 1pm,etc until 24 doses are made, which is 12am. This is for if you want to dose something at night only.

This is the calibration page
YB1CinS.png

specify your calibration volume (usually 1ml or 5ml). Set a value for ON time units. The default 980 will run the pump for 1 second. This part is trial and error. You want to get the number of time units needed to get the target calibration volume. Tap the Start button when ready.
Then tap the +Dose button to start dosing into your measuring container. Adjust the ON time value and tap +Doser until you reach your target volume. The total time units is displayed. Once you reach your target, tap Save. Then empty the liquid from your measuring container and tap Test to test dose the same volume. Repeat by tapping the Start button until you get the correct time units to get the target volume.

The dosed volume is stored in eeprom so the value is remembered across reboot. An alarm will sound if the remaining volume is less than one day's dosing volume. And dosing will completely stop if remaining volume is 0. Doser on and off timestamp are logged in outlet log file.

That's it.
 
Last edited:
I updated the feeder to use two wires only and hookup is direct to the manual feed switch. This simplified the program and the circuit.

The feed switch is an active high switch. Meaning, if you press the button, it sends +V signal to the feeder cpu. To control the feeder from say an arduino, you need to make two connections, one is the Ground (I used the battery negative terminal) and the second is the terminal on the push button that is not +V (this is the pin further from the lower edge). To activate the feeder (Y\you need batteries in the feeder of course), simply send a high pulse of 100ms duration. It's a little bit more elaborate that this. Since you retain the ability to manually feed by pressing the manual feed button, the arduino pin will be subjected to the feeder's +V whenever you press the manual feed button on the feeder. As such I programmed the arduino pin to be in "tri-state" (high impedance) mode so it does not affect the controller circuit.

If you are already using the original feeder circuit/setup, you should make sure #define _FEEDER is present. Otherwise, use #define _FEEDER_V2 to use the code for version 2 of the feeder.

gTyFk85.jpg

The signal connection. You don't need to completely remove the lcd/electronics panel. Just solder a wire to the pin on the switch.

hN0IGVR.jpg

I soldered the second (ground) wire to the battery negative terminal.

If you want to completely dismantle the pieces, there are 4 screws holding the top part (where the lcd is attached) to the lower part.
 
Last edited:
I just uploaded the files to github.
https://github.com/d0ughb0y/Chauvet16

I created a release (tag) to files before the upload, just in case someone may be interested in getting the files before this major update.
I deleted the temperature branch, as I don't think it is needed anymore.

Remember, this new version sends the gzipped index.htm to the browser, so if you make any changes to index.htm, you must gzip it to file named index.gz and upload it to the SD card (upload both files).
 
Excellent d0ughb0y!

This dosing part is really good add-on of functionality of controller.

Still I have one comment or suggestion.. for future improvements.
For us marine aquarist dosing of ALK and CA solution should not be at the same time. If this is dosing at same time then we didn't do nothing as we got lot of lime in sump or on place where we dosing both solution.
I used to add both solution before return pump so then this solution is fast and good mixed with return pump.
If I dose both solution at the same time soon my return pump is full of lime and need to be cleaned in acid :(

Dosing of other types of solutions is not a problem as in KH/CA dosing case so it could be done anytime.

So it is important to dose KH (which I think is more frequently (than dosing CA if we use max saturated CaCl solution) and in delays between dosing KH after a short delay also CA solution should be added.
In this way dosage of KH will mix better with aquarium water and when we dose CA solution also this will mix better with aquarium water.

In this way KH dosing should be master and for CA dosing (as inverse) in sw should be calculated dosing in delay of KH dosing.

As dosing of saturated CaCl solution is much less and much less frequently as dosing KH solution this can't be problem proceed in delays of dosing KH.
 
d0ughb0y in Sensors section line 140 (if (ds.reset2()) { //500us) should the 2 be in the ds.reset, I'm getting a complie error "class OneWire' has no member named 'reset2'
 
I forgot to add, I modified OneWire library.

In OneWire.h, add this line after reset(void)

Code:
uint8_t reset2(void);
Then in OneWire.cpp

change reset(void) to reset2(void) and add this code above the reset2(void) function.

Code:
uint8_t OneWire::reset(void) {
    uint8_t r = reset2();
    delayMicroseconds(420);
    return r;    
}
This change is part of the Temp sensor optiomiization.

I basically split out that last long 420 us delay to another call from the main loop.
If you use the normal OneWire code to get the temp reading, it can easily take 12ms or more for one request. With the optimized code, it is split into multiple calls from the main loop, and each call takes 500us or less.

I will update the readme in github with this info later.
 
Last edited:
Excellent d0ughb0y!

This dosing part is really good add-on of functionality of controller.

Still I have one comment or suggestion.. for future improvements.
For us marine aquarist dosing of ALK and CA solution should not be at the same time. If this is dosing at same time then we didn't do nothing as we got lot of lime in sump or on place where we dosing both solution.
I used to add both solution before return pump so then this solution is fast and good mixed with return pump.
If I dose both solution at the same time soon my return pump is full of lime and need to be cleaned in acid :(

Dosing of other types of solutions is not a problem as in KH/CA dosing case so it could be done anytime.

So it is important to dose KH (which I think is more frequently (than dosing CA if we use max saturated CaCl solution) and in delays between dosing KH after a short delay also CA solution should be added.
In this way dosage of KH will mix better with aquarium water and when we dose CA solution also this will mix better with aquarium water.

In this way KH dosing should be master and for CA dosing (as inverse) in sw should be calculated dosing in delay of KH dosing.

As dosing of saturated CaCl solution is much less and much less frequently as dosing KH solution this can't be problem proceed in delays of dosing KH.

you can specify a different start time for each doser pump.

Code:
#define DOSERDEFAULT {"Cal",300,24,0,0,0,3800},{"Alk", 300,24,0,10,0,3800}

The starttime is the fifth value, and is minutes since midnight.
for Cal, it starts at midnight, and Alk at 10 minutes past midnight.
 
BTW, the webserver code improvement fixes some browser connection problem you may be experiencing with the previous code.

I tried to find the cause of that problem, and initially I thought it was the controller's arduino running out of sram, because whenever the problem occurs, the http request data returned is usually > 1.5k. That's why I made the SRAM memory optimization to free up more memory. But that did not seem to fix it. And the problem seems to be with smartphone browser only, as I never see that problem with firefox on my laptop.
(and the Ethernet W5100 chip actually has its own buffer memory so it is not using the arduino memory).

Then after modifying the TinyWebserver code, I do not see that problem anymore on the smartphone, and the http response time now seems faster.
 
I forgot to add, I modified OneWire library.

In OneWire.h, add this line after reset(void)

Code:
uint8_t reset2(void);
Then in OneWire.cpp

change reset(void) to reset2(void) and add this code above the reset2(void) function.

Code:
uint8_t OneWire::reset(void) {
    uint8_t r = reset2();
    delayMicroseconds(420);
    return r;    
}
This change is part of the Temp sensor optiomiization.

I basically split out that last long 420 us delay to another call from the main loop.
If you use the normal OneWire code to get the temp reading, it can easily take 12ms or more for one request. With the optimized code, it is split into multiple calls from the main loop, and each call takes 500us or less.

I will update the readme in github with this info later.

I forgot again, you need to comment out the delayMicroseconds(420) at the end of the original reset(void) function.

I have updated the readme on github with this instructions.
 
I just uploaded a fix to doser calibration code. You will need to upload both index.htm and index.gz to the SD card. I setup my dosers for cal and alk. For my pumps, I get 1ml per 1000 time units. Calibrate using your dosing volume. I set mine up to dose 2ml each time so I calibrated the pumps using 2ml.

I will start working on the atlas sensors code probably by this weekend. To keep things simple for now, I will just code for the serial interface used by atlas stamps only. I will try to make the code modular so it will be easy to add code to work with other types of sensor circuits. I won't be able to test this code since I only own one atlas ph stamp and do not plan on adding any more atlas sensors.
 
I will start working on the atlas sensors code probably by this weekend. To keep things simple for now, I will just code for the serial interface used by atlas stamps only. I will try to make the code modular so it will be easy to add code to work with other types of sensor circuits. I won't be able to test this code since I only own one atlas ph stamp and do not plan on adding any more atlas sensors.

I can test the ORP circuit and one other pH circuit
 
Few question regarding dosers part.

in Calibration window
what means: Current Total Time Units:?
and in what time units is that value as now there is 0 by default.

If we change daily dose or we change anything in dosers setup this became effective on next start of dosers event for this channel?

When we choose "Volume to dose" is that volume recorded as Dosed volume and substracted from already dosed volume?

Colored bar represent how much volume is still in liquid reservoair which is stored in "Full Volume (ml):"?

As I try to manually start dosing and after a hour when those small volume had to be already added on main page nothing has changed?

Still when I enter some value in "Dosed Volume in ml:" then this is shown in colored bar.
 
For dosers, the colored part of the bar is the remaining volume. The full and dosed volume numbers are shown below the bar.
Remaining = full - dosed

If nothing is changing, that means your doser is not calibrated. If it is not calibrated, the program cannot determine the volume dosed. If it is calibrated, you need to tap on the refresh button (upper right corner) to get the new status data to reflect the updated value. The manual dose will send the command to the controller, but it may take the controller several seconds to complete the dose, so you may not see the new values when you go back to the main page right away.

The total time units is the accumulated time units you tapped +Dosed button.

So let's use my pumps as example. I know now it takes 1000 time units to get 1ml. If I did not know that, I will put my measuring container to catch doser output, set time units to say 250, and tap +Dose until I get 1 ml, which will be 4 times.

First tap, total time=250, second tap, total=500, third tap, total=750, fourth tap, total=1000 and the measuring container now has 1 ml. I then make sure volume is set to 1 ml then tap save. If the last +Dose went over 1ml, then I have to start over, but remembering the last total time units so I know not to exceed that. Total time units is read only and gives you a running total how much time the pump being calibrated has been ON. 1 time unit is 1.02ms, and it takes about 100 time units to move the pump motor for my pump and it produces 1 drop and is approximately 0.1 ml.
 
Last edited:
My Neptune Apex web interface compatible DIY reef controller

I'll add a warning to calibrate first before dosing.

If an actual pump is connected, it will not turn ON if not calibrated. The ON time is calculated as

ON time = volume to dose x rate

Where rate is in time units/ml and is 0 if not calibrated.

The controller log has the message to calibrate first before using and likewise on the LCD.
 
ok, I just updated github with the doser code fix so it displays an error if you try to manually dose and the doser is not calibrated. In the process I found a bug in all my http error display so I fixed that as well.

index.htm and index.gz changed, so you must upload both files to SD card after uploading the arduino code.

Since the arduino code is getting large (almost 90k), you can save time by unchecking "verify code after upload" in Arduino preferences.
 
Doughboy, this is an awesome project you have going. I have been looking at getting an apex and came across this thread. I have always wanted to learn arduino so this projects is very tempting. I'm just concerned I will buy the parts, fail to get it going and end up with an unfinished know of wires. Lol. Seeing how your control app is web based I assume it works with both android and iOS? I will have to read the whole thread a bit later because I am currently trying to entertain a demanding and impatient 2 year old. Thanks.
 
Back
Top