My Neptune Apex web interface compatible DIY reef controller

is that actual salinity reading from your tank?
I'm not sure about conductivity, there is no data in atlas stamp datasheet.The only info I can find is temp affects refractive index (if you are using refractrometer).

for ph, I'm pretty sure it is negligible for reef tank temp range. I did all the calculations a while back when I was building my own circuit.

it should not be too hard to add the T command if you want to use temp compensation.
 
Also found out where I was going wrong with the heater.

I incorrectly thought that I needed to set an on period of 24hrs in the heater outlets setup.

right. for outlet controlled by sensor (instead of time), simply set all 3 time values to 0 in the outlet program.
 
all atlas stamps reading are based on 25C or 77F

for ph, try this
http://www.hamzasreef.com/Contents/Calculators/PhTempCorrection.php

If I enter 25C, corrected reading is exactly the same
If I enter 25.4C, corrected reading is 8.1013

using F, at 77F, corrected reading is same.
at 82F corrected reading is 8.1092

I don't think it is worth the trouble correcting for 0.092, considering we are using DS18B20 temp sensors, which is not exactly a precision instrument.
 
Its looking really cool

Just three last bits frustrating me.

inverting the sate of the back 8 outlets, not using the darlington array so outputs are inverted.

Since enabling all 16 outlets, which do all work I get this error "unable to connect to apex.parsererror".

And the sparkline graphs have disappeared, no changes to .htm file.

Me and programming, its like a teenage boy with a bra strap, a lot of fumbling around.

Any thoughts, greatly appreciated

M
 
Its looking really cool

Just three last bits frustrating me.

inverting the sate of the back 8 outlets, not using the darlington array so outputs are inverted.

Since enabling all 16 outlets, which do all work I get this error "unable to connect to apex.parsererror".

And the sparkline graphs have disappeared, no changes to .htm file.

Me and programming, its like a teenage boy with a bra strap, a lot of fumbling around.

Any thoughts, greatly appreciated

M

from a browser page, enter this url and let me know what you get back

http://your controller ip and port /cgi-bin/status.json

you may need to login on another browser tab or enter your login info in url
 
I'll add a new #define to invert or not outlets 9-16. There seems to be many people not needing the inverted logic.
 
Fair point on the DS's.

I did have a look see at some output data from the water around the great Barrier Reef, I was surprised to note how much change there was in water temp between summer and winter, ~8C. I wondered, if this might be worth replicating to trigger breeding cycles?

Any thoughts?
 
{"pstat":{"hostname":"Mark's 85l Reef","software":"4.20_1B13","hardware":"1.0","serial":"AC4:12345","timezone":"1","d":1410472437,"feed":{"name":0,"active":0},"power":{"failed":1367205445,"restored":1367205445},"probes":[{"did":"base_Temp0","t":"Temp","n":"Water","v":35.0},{"did":"base_Temp1","t":"Temp","n":"Ambient","v":22.0},{"did":"base_pH0","t":"pH","n":"Tank-pH","v": 7.00}],"outlets":[{"n":"Heater","s":"AOF","oid":"0","did":"1_0"},{"n":"Cooler","s":"AON","oid":"1","did":"1_1"},{"n":"Return","s":"AON","oid":"2","did":"1_2"},{"n":"Skimmer","s":"AOF","oid":"3","did":"1_3"},{"n":"LtsMain","s":"AOF","oid":"4","did":"1_4"},{"n":"LtsSump","s":"AOF","oid":"5","did":"1_5"},{"n":"ATO","s":"AON","oid":"6","did":"1_6"},{"n":"Pump","s":"AON","oid":"7","did":"1_7"},{"n":"PwrHd1","s":"AON","oid":"8","did":"1_8"},{"n":"PwrHd2","s":"AON","oid":"9","did":"1_9"},{"n":"Unused11","s":"AON","oid":"10","did":"1_10"},{"n":"Unused12","s":"AOF","oid":"11","did":"1_11"},{"n":"Unused13","s":"AON","oid":"12","did":"1_12"},{"n":"Unused14","s":"AON","oid":"13","did":"1_13"},{"n":"Unused15","s":"AON","oid":"14","did":"1_14"},{"n":"Unused16","s":"AON","oid":"15","did":"1_15"}],"inputs":[{"did":"base_I2","n":"ATO Upper","v":0},{"did":"base_I3","n":"ATO Lower","v":0}],"pwmpumps":[{"wm":"0","sm":"0","l":"115","pw":"0","pa":"1"},{"wm":"0","sm":"1","l":"115","pw":"0","pa":"1"}],"dosers":[{"n":"Colour","dd":"20","dpd":"1","i":"0","st":"0","dv":"0","fv":"1000","s":"off"},{"n":"Growth","dd":"20","dpd":"1","i":"0","st":"10","dv":"0","fv":"1000","s":"off"},{"n":"","dd":"0","dpd":"0","i":"115","st":"0","dv":"500","fv":"10","s":"off"}]}}
 
Oh, thinking about it there is one other change I made, have 3 dosers.

3 dosers appear, last one has no name, and doesn't appear in doser setup.

I'm thinking this may be the cause
 
Last one for me for tonight.

Conductivity wont init

if (data.type==_cond) //set conductivity stamp to return S only, K=10
data.saddr.print("Response,0\rL,1\rC,0\rO,EC,0\rO,TDS,0\rO,SG,0\rO,S,1\rr\r");
else

01:13:53 Conductivity sensor init failed.

lcd says C:getCond

As always help appreciated

M
 
Will this fix the lcd part?

case 2:
#ifdef _COND
lcd << F("C:") << getAtlasAvg(conddata) <<F(" ");
x++;
if (x%2==0) return x>=maxsensors;
#endif
state=3;
case 3:
#ifdef _ORP
lcd << F("O:") << getAtlasAvg(orpdata) <<F(" ");
x++;
if (x%2==0) return x>=maxsensors;
#endif
 
yes. I have to fix that. That string was just a temporary placeholder because the function did not exist yet.

try entering the same init string in atlas sketch. whatever works there should work in the program.
 
Anyway, I found this topic because I was searching for a good way to measure the water level. I had the idea to measure this with by placing a PCB inside the tank to measure the level but I'm not fond of that idea.
Now I see you're using an ultrasonic to do this which is a good idea. But I can't seem to find any waterproof version for this.
Best one I found was this one: http://www.aliexpress.com/item/1PCS...odule-30cm-3-5m-FREE-SHIPPING/1649048115.html but it measures between 30cm and 5m so it is only usable if you can hang it high enough which is not the case for me. Are you still using the HC-SR04 version?

Best waterproof alternative that I've found is by using an IR led for measuring the distance: http://www.sharpsma.com/optoelectronics/sensors/distance-measuring-sensors This one measures distance between 4cm and 15 cm. I may combine this one with a dosing pump to keep the waterlevel stable at a certain level?
 
I'll be working some more to customize the ariadne bootloader. I tried making suggestions to the author to improve the program but he is not open to suggestions at all. The changes I am going to make will simplify the usage and make it work like a bootloader rather than an arduino sketch project.

first, I'll make it work so you can upload sketch to the board via usb serial even if ethernet shield is not connected. Currently, if ethernet shield is not present, the board is just totally frozen. it does not even run the loaded sketch. I have already completed this part of the code.

second, I'll keep the bootloader data to a minimum (20bytes, ip, router, mask, mac, signature), and store it at the very end of the eeprom address space. The current code takes up 64 bytes, and stores non essential, user program related data and stores it at eeprom address 0 :eek1:.

third, currently, you need to convert the generated .hex file to .bin before uploading. This may be good since the upload will be for a much smaller file. But most bootloaders accept the .hex file. So I will try to make it accept .hex file if I have time.

I'm not sure if adding sd card support is worth it, particularly if we are uploading via network, as it just adds another step, might as well burn the sketch while receiving over network. Most existing bootloader that loads from sd card works on fat16 format only anyway. curl has support for tftp protocol, however, I am not able to get it to work. It must not be conforming to standard tftp protocol. The windows tftp client works perfectly fine. I may try to get this to work with http put (using curl).

one important thing I forgot to mention. using this bootloader allows you to add a watchdog timer to the main loop. The standard arduino bootloader will not work as is using watchdog timer to reboot the board (you will end up in an endless reboot cycle). This will cover the last resort case if the main loop hangs, to automatically reboot the controller. (the watchdog timer is the proper way to reboot the controller, as specified in in atmel datasheet, and will be how the controller/mega is rebooted before the new sketch is uploaded to the controller)
 
Last edited:
I got some good progress on the bootloader enhancement.
I am now able to upload using curl.

turns out the command to do tftp upload is simply

curl -T Chauvet16.cpp.bin tftp://192.168.0.120

once I add the http command to reboot the controller, then uploading is simply

curl -0 http://192.168.0.15/reboot (this is password secured)
curl -T Chauvet16.cpp.bin tftp://192.168.0.120

note the controller ip does not have to be the same as the bootloader ip and is configurable. if it is different, and you don't add port forwarding, then it can only be accessed from your local network.

I realize now the reason the .hex file needs to be converted to .bin is because the tftp upload mode is binary and not ascii. I think I'll leave it at that.

I'll fork the bootloader project and upload my changes once I complete more testing and clean up the code.
 
Back
Top