My Neptune Apex web interface compatible DIY reef controller

thanks for confirmation.

as to atlas stamp support. I think there was a request to support 2 ph, salinity/conductivity and orp but only pick 3 since there are only 3 serial ports. I think I'll do it this way, since I don't think there is any more work to add the orp support.

the way I'm doing temp now is user can specify maxtemp in config.h (really choice is 1 or 2), and the code will auto detect. The only problem is, for 2 temp sensors, I have not figured a good way to determine which one is the first Temp and which one is the second one. Say for me, I will use the second one as "ambient" temp (the sensor is not in tank water) and is just for information only and will not be used to control anything. But since depending on the DS18B20 address, one will come first before the other during the OneWire search function, I might end up requiring hard coding of the address in config.h to simplify things. The OneWire sample sketch that comes with arduino will print out the address of the DS18B20.
 
d0ughb0y -

I actually like the idea of hard coding the temp sensors. Should in theory help with speed up the query on the temp sensor.
 
I think as all people who will try to construct this controller could aslo run
one_wire_address_finder.ino, copy addresses of sensors and paste their addresses into config.h

In this way no problem to add two or more temp sensors.
And later maybe some more sofisticated code could be done..
 
Seem to be running A.OK now on the desk. I have a seperate sketch running which uses a DHT22 Sensor and 3 DS18b20's I have used this library before and it really works well with multiple DS18b20 sensors reporting the address and temperature for each. Also allows you to change precision. Each sensor is returned in a single array and always in the same order. It's perfect for this controller I think.
I was going to have a look at this today and see how it would plug in to the current code.

Here's a direct link to the example code in the library for multiple sensors.

https://github.com/milesburton/Ardu...ry/blob/master/examples/Multiple/Multiple.pde

This is the DHT library I am using atm, would like dewpoint etc in there.
https://github.com/adafruit/DHT-sensor-library
And here's the output.
Code:
Dallas Temperature IC Control Library Demo
Locating devices...Found 3 devices.
Parasite power is: OFF
Device 0 Address: 28FF9CAF141400EE
Device 1 Address: 28FFD566151400F5
Device 2 Address: 28FF7F3E151400BF
Device 0 Resolution: 9
Device 1 Resolution: 9
Device 2 Resolution: 9
Requesting temperatures...DONE
Device Address: 28FF9CAF141400EE Temp C: 21.50 Temp F: 70.70
Device Address: 28FFD566151400F5 Temp C: 21.00 Temp F: 69.80
Device Address: 28FF7F3E151400BF Temp C: 22.00 Temp F: 71.60
Humidity: 54.70 %	Temperature: 21.90 *C 71.42 *F	Heat index: 76.57 *F

For the Atlas sensors I think creating a plugin type container may be a good way. Sort of
Code:
callback sensor:{name:temp,EC,PH,ORP,...},{nickname},{sensor#},{Type:DS18b20,Serial,I2c,Onewire,bluetooth,ethernet,...},{pin/port},{baud},{address},{poll},{avg},{power before read}, etc, etc;
Code:
#define sensor(temp,'inside',1,DS18b20,48,,28FF9CAF141400EE,20,3,0,);
#define sensor(temp,'outside',2,DS18b20,48,,28FFD566151400F5 ,20,3,0,);
#define sensor(temp,'tank',3,DS18b20,48,,28FF7F3E151400BF,20,3,0,);
The workings behind are where I fall down!
Going this way, any new sensors just need a new variable adding, sparkys sensors for example have slightly different calls. A lot of the drone type code uses these definitions due to the wide range of sensors.
If you want to add for example DHT then just add the library and enable the option and insert the relevant sensor read and return code to a chunk and it propagates throughout all areas of code.
The plugin container handles the interrupts and timings as your code is doing now for sensors. Just makes it more of a flexible system due to the range in sensors, i2c addresses, baud rates etc.

Adding a new variable also adds all the required points of code, adding a supported sensor could then be done through a line in config.h

Here is the hacked together from the examples code I am running to read the three temp sensors and the DHT for humidity :bum:

PHP:
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 9
#include "DHT.h"

#define DHTPIN 2     // what pin we're connected to

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11 
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// arrays to hold device addresses
DeviceAddress insideThermometer, outsideThermometer, tankThermometer;

void setup(void)
{
  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");

  // Start up the library
  sensors.begin();
dht.begin();
  // locate devices on the bus
  Serial.print("Locating devices...");
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");

  // report parasite power requirements
  Serial.print("Parasite power is: "); 
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");

  // assign address manually.  the addresses below will beed to be changed
  // to valid device addresses on your bus.  device address can be retrieved
  // by using either oneWire.search(deviceAddress) or individually via
  // sensors.getAddress(deviceAddress, index)
  //insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
  //outsideThermometer   = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 };

  // search for devices on the bus and assign based on an index.  ideally,
  // you would do this to initially discover addresses on the bus and then 
  // use those addresses and manually assign them (see above) once you know 
  // the devices on your bus (and assuming they don't change).
  // 
  // method 1: by index
  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 
  if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); 
if (!sensors.getAddress(tankThermometer, 2)) Serial.println("Unable to find address for Device 2"); 

  // method 2: search()
  // search() looks for the next device. Returns 1 if a new address has been
  // returned. A zero might mean that the bus is shorted, there are no devices, 
  // or you have already retrieved all of them.  It might be a good idea to 
  // check the CRC to make sure you didn't get garbage.  The order is 
  // deterministic. You will always get the same devices in the same order
  //
  // Must be called before search()
  //oneWire.reset_search();
  // assigns the first address found to insideThermometer
  //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
  // assigns the seconds address found to outsideThermometer
  //if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer");

  // show the addresses we found on the bus
  Serial.print("Device 0 Address: ");
  printAddress(insideThermometer);
  Serial.println();

  Serial.print("Device 1 Address: ");
  printAddress(outsideThermometer);
  Serial.println();

 Serial.print("Device 2 Address: ");
  printAddress(tankThermometer);
  Serial.println();
  // set the resolution to 9 bit
  sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION);
sensors.setResolution(tankThermometer, TEMPERATURE_PRECISION);

  Serial.print("Device 0 Resolution: ");
  Serial.print(sensors.getResolution(insideThermometer), DEC); 
  Serial.println();

  Serial.print("Device 1 Resolution: ");
  Serial.print(sensors.getResolution(outsideThermometer), DEC); 
  Serial.println();
  
    Serial.print("Device 2 Resolution: ");
  Serial.print(sensors.getResolution(tankThermometer), DEC); 
  Serial.println();
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.print(DallasTemperature::toFahrenheit(tempC));
}

// function to print a device's resolution
void printResolution(DeviceAddress deviceAddress)
{
  Serial.print("Resolution: ");
  Serial.print(sensors.getResolution(deviceAddress));
  Serial.println();    
}

// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(" ");
  printTemperature(deviceAddress);
  Serial.println();
}

void loop(void)
{ 
  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");

  // print the device information
  printData(insideThermometer);
  printData(outsideThermometer);
  printData(tankThermometer);
  
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit
  float f = dht.readTemperature(true);
  
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index
  // Must send in temp in Fahrenheit!
  float hi = dht.computeHeatIndex(f, h);

  Serial.print("Humidity: "); 
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: "); 
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\t");
  Serial.print("Heat index: ");
  Serial.print(hi);
  Serial.println(" *F");
  delay(10000);
}
just my 0.02c
 
Last edited:
I have question regarding naming of outlets?

- How long could be that name ?
- Which chars could be used ?
- Are chars as space, _ , Å¡, Å , č, Č alowed or not?
 
Ok, I am now having a major problem with the controller. I decided to hook it up to the tank, even though I still dont have my jebs. Problem I am now facing is that it is cutting off on me, and stalling out on the code. Was not doing this before, but I also did not have all this equipment attached to it. But even if I just have the heater plugged into it it does this. Any ideas what is going on so I can fix this?
 
Ok, I am now having a major problem with the controller. I decided to hook it up to the tank, even though I still dont have my jebs. Problem I am now facing is that it is cutting off on me, and stalling out on the code. Was not doing this before, but I also did not have all this equipment attached to it. But even if I just have the heater plugged into it it does this. Any ideas what is going on so I can fix this?

How do you have your arduino powered? are you using a power adapter into the jack? I have found switching AC voltage can take more power than a USB port can provide.
 
How do you have your arduino powered? are you using a power adapter into the jack? I have found switching AC voltage can take more power than a USB port can provide.

Im using a 12 v plug, into a 12 v jack which is wired to the ground and 12 v inputs on the arduino.
 
NVM, finally got it working properly, in a way. I think somewhere in the code it is getting hanged up, with syncing with the RTC, emailing me, and turning things on is just to much. If I slowly turn everything on after it has booted up for a bit, seems to be running fine. Have not done the new update yet, so maybe that will fix it. Have to go back in the unit anyway, seems I forgot to hook up the pins for the PH stamp.

On a side note, for some reason I cant set up my fuge light to come on at a certain time and off at a certain time. I wanted to have it off at 10 am and back on at 6pm. So I put in:
off: 10:00:00
on: 18:00:00
off: 10:00:00

It seems to go great, but instead of it going on and off at those times It creates a strobe light effect on my fuge.
 
Last edited:
NVM, finally got it working properly, in a way. I think somewhere in the code it is getting hanged up, with syncing with the RTC, emailing me, and turning things on is just to much. If I slowly turn everything on after it has booted up for a bit, seems to be running fine. Have not done the new update yet, so maybe that will fix it. Have to go back in the unit anyway, seems I forgot to hook up the pins for the PH stamp.

On a side note, for some reason I cant set up my fuge light to come on at a certain time and off at a certain time. I wanted to have it off at 10 am and back on at 6pm. So I put in:


It seems to go great, but instead of it going on and off at those times It creates a strobe light effect on my fuge.



The new updates causes my controller to go off with its alarms, even though nothing is on for any kind of alerts, it will still sound alarms, and cant get them to stop.
 
On a side note, for some reason I cant set up my fuge light to come on at a certain time and off at a certain time. I wanted to have it off at 10 am and back on at 6pm. So I put in:


It seems to go great, but instead of it going on and off at those times It creates a strobe light effect on my fuge.

you program by the minutes in a cycle, not by absolute time of day.

if your cycle is 24 hours, and you want it to come on only from 6pm to 10pm, then the cycle starts (cycle always starts at midnight) in off state for 18 hours, on for 4 hours then off again for 2 hours.

so specify
off 18:00, on 4:00, off 2:00
 
The new updates causes my controller to go off with its alarms, even though nothing is on for any kind of alerts, it will still sound alarms, and cant get them to stop.

whenever you do an update, make sure not tot update config.h from the github file, since you probably edited the values in config.h. compare the files for any changes and apply the changes to your config.h file.

as to alarm, compare the alarm values you are getting, and then change the alarm values in controller setup.
 
I have question regarding naming of outlets?

- How long could be that name ?
- Which chars could be used ?
- Are chars as space, _ , Å¡, Å , č, Č alowed or not?

only standard ascii. that is what is supported by arduino.

outlet name is declared as char name[14]
so you can have up to 13 characters.
 
The workings behind are where I fall down!
Going this way, any new sensors just need a new variable adding, sparkys sensors for example have slightly different calls. A lot of the drone type code uses these definitions due to the wide range of sensors.
If you want to add for example DHT then just add the library and enable the option and insert the relevant sensor read and return code to a chunk and it propagates throughout all areas of code.
The plugin container handles the interrupts and timings as your code is doing now for sensors. Just makes it more of a flexible system due to the range in sensors, i2c addresses, baud rates etc.

Adding a new variable also adds all the required points of code, adding a supported sensor could then be done through a line in config.h

<onewire.h><dallastemperature.h>

I coded this originally for my own use, and did not take into consideration to make the program more generic. I am revising the code to make it generic, without over complicating it. Its not quite as simple as defining an interface and user can plug in implementation, because for each additional sensor, the file logging code, the web interface, etc are affected. drone codes don't have that. I used to contribute to multiwii quadcopter project, so I'm familiar with the program structure of drone code and use some of the ideas from there (like use of config.h) where possible.

my temp sensor code works slightly different, such that I break down your equivalent of readTemperature into at least 3 program loop cycles. OneWire is extremely slow, since I want to keep the total execution time for each loop to about 1ms, I have to split the call to get temperature into 3 parts (or more). The standard OneWire sketch for ds18b20 takes several milliseconds to get the temp value.
</dallastemperature.h></onewire.h>
 
whenever you do an update, make sure not tot update config.h from the github file, since you probably edited the values in config.h. compare the files for any changes and apply the changes to your config.h file.

as to alarm, compare the alarm values you are getting, and then change the alarm values in controller setup.

Didnt make any changes within the config.h files. Only changed Chauvet16.ino, Network.ino, and Outlets.ino. As for the alarm, I changed them to where I should not be getting any alarms, no emails, no sound, or even the sonar.

The alarm started sounding after a reboot of the controller and once I turn on an outlet, does not matter which outlet I turn on.
 
I took the controller apart, re did all the pins, left it open, and plugged it in. Only the 12v power supply going to the arduino. I left it on for quite some time, no alarm being sounded. As soon as I turn on an outlet, boom, alarm sounds. I am thinking either my relay has gone bad, or I have the relay wired wrong, just dont know where. I have 5 volts coming from the arduino pinned into the relay board via vcc near pin IN0. I also have and additional 5 v from a gutted usb plug feeding into jd-vcc as well as the ground going to GND pin near the jd-vcc pin.

I just did an additional test, unplugged all the pins going to the relay board, same thing, alarms sounds when I go to turn an outlet on. Maybe something wrong with the outlets.ino?
 
***Erasing this comment**** I am more than sure now my relay board is out, power is not getting through when things are turned on now.
 
Last edited:
Arduino WiFi shield

Arduino WiFi shield

I am going to look into incorporating a Wifi Shield into the controller as the TP-link wifi client I am using is to slow and it is not practical to run an ethernet cable to my aquarium. this will take me some time as I am not a Arduino native. I noticed there are quite a few diferent WiFi shields available on eBay and thought it may be a good idea if we decide as a group the one we want to support.

Thanks
Bill
 
I am going to look into incorporating a Wifi Shield into the controller as the TP-link wifi client I am using is to slow and it is not practical to run an ethernet cable to my aquarium. this will take me some time as I am not a Arduino native. I noticed there are quite a few diferent WiFi shields available on eBay and thought it may be a good idea if we decide as a group the one we want to support.

Thanks
Bill

if you are using the official arduino wifi shield, then it should almost be a direct replacement, only changing the initialization. other than cost ($85 vs I think I got my ethernet shield for like $10), I think this is a good option to use.
 
Back
Top