Reef Central Online Community

Go Back   Reef Central Online Community > General Interest Forums > Do It Yourself > The R3CA Project
Blogs FAQ Calendar Mark Forums Read

Notices

User Tag List

Reply
Thread Tools
Unread 11/07/2013, 02:13 PM   #1
joopie
Registered Member
 
Join Date: Apr 2013
Location: New Hampshire
Posts: 37
Arduino Aquarium Controller

I thought i would share what i have going so far for my aquarium. A few months back i purchased a 90 gallon tank with built in over flow. Since then i have been working on building the stand, canopy, and sump. Most of it is complete, i have been working with arduino and web server to setup the automation and control processes of the tank. Here is what i have so far...

http://www.rareglitch.net/overview.htm

Lets not try to break it or guess the password =)

So currently i have:
-automated control for the heater, with set point of 77.80 decreasing, resets at 78.20.
-auto top off via a solenoid and ultrasonic range finder.
-automated lights that get brighter/dimmer depending on the schedule i have set.
-cooling fans for LEDs will kick on at 85 and off at 80.
-ph probe

i am able to track and trend whatever i want on the web site.i am also able to control every process after inputting a password.
A quick explanation of how it works:

Inputs are provided to the arduino which processes the data and provides any outputs(relays,solenoids). The inputs/outputs are also sent to the web server via HTML get requests. The server process any incoming data with a php script and stores the data in a mysql database. The overview page pulls the data from the database and is displayed in tables and charts(charts from highcarts.com)

If anyone would like any more info or would like to see some code then let me know! i have had blast designing and building everything and cant wait to start filling up the tank/sump.


Attached Images
File Type: jpg IMG_20131027_194616_309.jpg (38.9 KB, 703 views)
File Type: jpg IMG_20131103_191033_573.jpg (43.6 KB, 665 views)
File Type: jpg IMG_20131103_191105_354.jpg (47.3 KB, 645 views)
joopie is offline   Reply With Quote
Unread 11/11/2013, 09:36 AM   #2
adamgoldberg
Registered Member
 
Join Date: Oct 2013
Posts: 43
Oh! Oh! More info, please!!


adamgoldberg is offline   Reply With Quote
Unread 11/15/2013, 10:36 PM   #3
rott
Head zoo keeper
 
Join Date: Nov 2005
Location: Toledo ,Ohio
Posts: 710
wow looks great would you share the code that makes all that happen for the website and the arduino


rott is offline   Reply With Quote
Unread 11/18/2013, 04:14 PM   #4
joopie
Registered Member
 
Join Date: Apr 2013
Location: New Hampshire
Posts: 37
here is the arduino code... i have added a blocked=) to areas that i thought may compromise security of my fish tank. there are still plenty of ideas i'd like to add/fix, but here is what i have so far.


PHP Code:
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Time.h>  
#include <EthernetUdp.h>
#include <NewPing.h>

//PINS
#define PIN_TEMP 3 //Temp Probes 01,02,03+
#define PIN_RY_HEATER 22 //Relay for heater
#define PIN_RY_FAN_LEFT 24 //Relay for left fan
#define PIN_RY_FAN_RIGHT 26 //Relay for right fan
#define PIN_RY_LEVEL 28 //level relay
#define PIN_RY_DRAIN 30 //drain relay
#define PIN_RY_AUX 32 //aux relay
#define PIN_LED_WHITE 9 //LED_WHITE
#define PIN_LED_BLUE 8 //LED_BLUE
#define TRIGGER_PIN  11
#define ECHO_PIN     10
#define MAX_DISTANCE 200
#define amt 30
NewPing sonar(TRIGGER_PINECHO_PINMAX_DISTANCE); 



const 
int chipSelect 4;

byte mac[] = { 
  
0xDA0xAD0xBF0xEF0xFE0xED };
byte ip[] = {
  
192,168,1,120};

OneWire oneWire(PIN_TEMP);
DallasTemperature sensors(&oneWire);

DeviceAddress Probe01 = { 
  
0x280x480xA10x5C0x040x000x000x60 }; 
DeviceAddress Probe02 = { 
  
0x280xB30x6B0x5C0x040x000x000x75 };
DeviceAddress Probe03 = { 
  
0x280xF30x140x980x040x000x000x35 };
DeviceAddress Probe04 = { 
  
0x280x300xE80x1D0x050x000x000x87 };
DeviceAddress Probe05 = { 
  
0x280x8E0xB20xEF0x040x000x000x66  };
DeviceAddress Probe06 = { 
  
0x280xAA0x1D0xEF0x040x000x000x50  };
DeviceAddress Probe07 = { 
  
0x280x6D0x640xEF0x040x000x000xD4  };

//Time
IPAddress timeServer(1321634101); // time-a.timefreq.bldrdoc.gov
const int timeZone = -4;
EthernetUDP Udp;
unsigned int localPort blocked=);
unsigned long CUR_MILLIS;
//String webServer = "blocked=)";
EthernetClient client;


//Alarms
boolean ALARM_LEVEL_HIGH false;
boolean ALARM_LEVEL_LOW false;
boolean ALARM_PH_HIGH false;
boolean ALARM_PH_LOW false;
boolean ALARM_TEMP_AVG_HIGH false;
boolean ALARM_TEMP_AVG_LOW false;

//Input Vars
float IN_TEMP_HEATER;  //probe 1
float IN_TEMP_RETURN;  //probe 2
float IN_TEMP_OVERFLOW//probe 3
float IN_TEMP_ROOM//probe 4
float IN_TEMP_TANK//probe 7

float IN_LED_TEMP_LEFT//probe 5
float IN_LED_TEMP_RIGHT//probe 6

float IN_LED_BLUE 5;
float IN_LED_WHITE 5;

float IN_LEVEL_SUMP//Sump water level
float IN_LEVEL_PH;

float TEMP_AVG;
int IN_HEATER_MODE 2// 0 - OFF, 1 - ON, 2 - AUTO
int IN_LED_FAN_MODE 2// 0 - OFF, 1 - ON, 2 - AUTO
int IN_LED_MODE 2// 0 - OFF, 1 - ON, 2 - AUTO
int IN_LEVEL_MODE 2//0 - OFF, 1 - ON, 2 - AUTO
int IN_AUX_MODE 0//0 - OFF, 1 - ON
int IN_LEVEL_DRAIN_MODE 0//0 - OFF, 1 - ON
int IN_LEVEL_PH_MODE 1//0 - STOP, 1 - CON,2-TEMP, 3 - CAL4, 4 - CAL7, 5 - CAL10, ...
int IN_LEVEL_PH_MODE_L 0;

//OUTPUT Vars
boolean OUT_HEATER false;
boolean OUT_LEFT_FAN false;
boolean OUT_RIGHT_FAN false;
boolean OUT_LEVEL false;
//boolean OUT_LEVEL_DRAIN = false;
int OUT_LED_WHITE;
int OUT_LED_BLUE;
float OUT_LEVEL_SUMP;
//Setpoints
float SP_TEMP_RETURN 77.80;
float SPR_TEMP_RETURN 78.20;

float SP_TEMP_LED 85.00;
float SPR_TEMP_LED 80.00;

float SP_LEVEL 11.00;
float SPR_LEVEL 12.00;
//Ranges in minutes
int LED_WHITE_START 720;
int LED_WHITE_END 1200;
int LED_BLUE_START 600;
int LED_BLUE_END 1320;
int LED_MID 960;

//led ranges
int BLUE_UP 150;
int BLUE_LW 19;
int WHITE_UP 200;
int WHITE_LW 19;
//sump ranges
float SUMP_RNG 24;
String readString;
//frame delays
long PREV_MILLIS 0;
long PREV_MILLIS1 0;
long PREV_MILLIS2 0;
long IN_DELAY 1000// 500ms framerate
long XMIT_DELAY 5000// 3s framerate
long REC_DELAY 10000// 10s framerate

boolean keep;
//ph stuff
#define avgSize 20
float phavg[avgSize];
int phRear=0;

float LVLavg[avgSize];
int LVLRear=0;

void QueueEnter(float queue[],float item,int *rear){
  if(*
rear avgSize)
  {
    
queue[*rear]=item;
    *
rear++;
  }else{
    *
rear 0;
  }

}
float getAVG(float queue[]){
  
float avg;
  
int count 0;
  for(
int i 0;avgSize;i++){
    if(
queue[i] != 0){
      
avg += queue[i];
      
count++;
    }
  }
  return 
avg count;
}


void setup()
{
  
Serial.begin(38400);
  
Serial.println("Initializing...");
  
Serial.print("PH Probe... ");
  
Serial.println(startPH());
  
Serial.print("Temperature Sensors... ");
  
Serial.println(startTemp());
  
Serial.print("Ethernet... ");
  
Serial.println(startEthernet());
  
Serial.print("Input/Outputs... ");
  
Serial.println(startPins());
  
Serial.print("Time Server... ");
  
Serial.print(startTime());
  
Serial.print(" ");
  
Serial.println(getTime());
  
Serial.print("Setting up Relays... ");
  
Serial.println(startPins());
  
Config("Password",blocked=));
  
Config("Heater_Mode",IN_HEATER_MODE);
  
Config("LED_Mode",IN_LED_MODE);
  
Config("LED_Fan_Mode",IN_LED_FAN_MODE);
  
Config("Level_Mode",IN_LEVEL_MODE);
  
Config("Level_PH_Mode",IN_LEVEL_PH_MODE);
  
Config("Level_Drain_Mode",IN_LEVEL_DRAIN_MODE);
  
Config("AUX_Mode",IN_AUX_MODE);
}

void loop() 
{
  
CUR_MILLIS millis();
  if (
CUR_MILLIS PREV_MILLIS IN_DELAY){
    
PREV_MILLIS CUR_MILLIS;
    
Inputs();
    
Process();
    
Outputs();
  }
  if (
CUR_MILLIS PREV_MILLIS1 XMIT_DELAY){
    
PREV_MILLIS1 CUR_MILLIS;

    
XMIT();
  }
  if (
CUR_MILLIS PREV_MILLIS2 REC_DELAY){
    
PREV_MILLIS2 CUR_MILLIS;
    
RX();
  }
}

String getTime()
{
  
String theTime;
  
theTime.concat(month());
  
theTime.concat("/");
  
theTime.concat(day());
  
theTime.concat("/");
  
theTime.concat(year());
  
theTime.concat(" ");
  
theTime.concat(hour() - 1);
  
theTime.concat(":");
  
theTime.concat(minute());
  
theTime.concat(":");
  
theTime.concat(second());
  return 
theTime;
}

void XMIT(){
  
Trender("TEMP_RETURN",IN_TEMP_RETURN);
  
Trender("TEMP_HEATER",IN_TEMP_HEATER); 
  
Trender("TEMP_OVERFLOW",IN_TEMP_OVERFLOW); 
  
Trender("TEMP_TANK",IN_TEMP_TANK);
  
Trender("TEMP_ROOM",IN_TEMP_ROOM);
  
Trender("TEMP_AOUT_HEATER",OUT_HEATER?1.0f:0.0f);
  
Trender("LED_ABLUE",map(OUT_LED_BLUE,BLUE_LW,BLUE_UP,0,100)); //grab in var to output in %
  
Trender("LED_AWHITE",map(OUT_LED_WHITE,WHITE_LW,WHITE_UP,0,100)); //grab in var to output in %
  
Trender("LED_XTEMP_LEFT",IN_LED_TEMP_LEFT);
  
Trender("LED_XTEMP_RIGHT",IN_LED_TEMP_RIGHT);
  
Trender("LED_FAN_LEFT",OUT_LEFT_FAN);
  
Trender("LED_FAN_RIGHT",OUT_RIGHT_FAN);
  
Trender("LEVEL_SUMP",IN_LEVEL_SUMP);
  
Trender("LEVEL_FILL",OUT_LEVEL);
  
Trender("LEVEL_XPH",IN_LEVEL_PH);
  
Trender("LEVEL_DRAIN",IN_LEVEL_DRAIN_MODE);
  
//Trender("LEVEL_AUX_MODE",IN_AUX_MODE);
  
Trender("ALARM_LEVEL_HIGH",ALARM_LEVEL_HIGH);
  
Trender("ALARM_LEVEL_LOW",ALARM_LEVEL_LOW);
  
Trender("ALARM_PH_HIGH",ALARM_PH_HIGH);
  
Trender("ALARM_PH_LOW",ALARM_PH_LOW);
  
Trender("ALARM_TEMP_AVG_HIGH",ALARM_TEMP_AVG_HIGH);
  
Trender("ALARM_TEMP_AVG_LOW",ALARM_TEMP_AVG_LOW);
}
void Trender(String table,float value){
  if (
client.connect("blocked=)"blocked=)))
  {
    
client.print("GET /blocked=)");
    
client.print(table);
    
client.print("&value=");
    
client.println(value);

  }
  
client.flush();
  
client.stop();
  
client.flush();
}
void RX(){
  if (
client.connect("blocked=)",blocked=)))
  {
    
client.println("GET /blocked=)");
    
client.println();
  }
  if (
client) {
    while (
client.connected()) {
      if (
client.available()) {
        
char c client.read();
        if (
== '!') {
          
client.stop();
        }
        
readString += c
      }
    }
    
parseString(readString);
    
readString "";
  }
  
client.flush();
  
client.stop();
  
client.flush();
}
void parseString(String str){
  
keep true;
  
int offset 0;
  while(
keep){
    
int start str.indexOf('#',offset) + 1;
    
int mid str.indexOf('@',offset);
    
int finish str.indexOf('$',offset);
    
int endloop str.indexOf('!');
    
offset finish 1;
    
String name str.substring(start,mid);
    
float value strTofloat(str.length(),str.substring(mid 1,finish));
    
setInput(name,value);
    if(
offset == endloop){
      
str "";
      
keep false
    }
  }

}
void setInput(String name,float value){
  if(
name == "Heater_Mode"){
    
IN_HEATER_MODE = (int)(value);
  }
  else if(
name == "LED_Mode"){
    
IN_LED_MODE = (int)(value);
  }
  else if(
name == "LED_Fan_Mode"){
    
IN_LED_FAN_MODE = (int)(value);
  }
  else if(
name == "LED_Blue"){
    
IN_LED_BLUE = (int)(value);
  }
  else if(
name == "LED_White"){
    
IN_LED_WHITE = (int)(value);
  }
  else if(
name == "Password"){

  }
  else if(
name == "Level_Mode"){
    
IN_LEVEL_MODE = (int)(value);
  }
  else if(
name == "Level_PH_Mode"){
    
IN_LEVEL_PH_MODE = (int)(value);
  }
  else if(
name == "Level_Drain_Mode"){
    
IN_LEVEL_DRAIN_MODE = (int)(value);
  }
  else if(
name == "AUX_Mode"){
    
IN_AUX_MODE = (int)(value);
  }
  else{
    
Serial.println("INVALID ARGS PASSED TO SETINPUT");
    
keep false;
  }
}
void Config(String setting,float value){
  if (
client.connect("blocked=)",blocked=)))
  {
    
client.print("GET /blocked=)");
    
client.print(setting);
    
client.print("&value=");
    
client.println(value);

  }
  
client.flush();
  
client.stop();
  
client.flush();
}
boolean startTime()
{
  
Udp.begin(localPort);
  
setSyncProvider(getNtpTime);
  return 
true;
}
boolean startPH(){
  
Serial3.begin(38400);
  
delay(2000);
  return 
true;
}

boolean startPins()
{
  
pinMode(PIN_RY_HEATER,OUTPUT);
  
digitalWrite(PIN_RY_HEATER,HIGH); //off
  
pinMode(PIN_RY_FAN_LEFT,OUTPUT);
  
digitalWrite(PIN_RY_FAN_LEFT,HIGH); //off
  
pinMode(PIN_RY_FAN_RIGHT,OUTPUT);
  
digitalWrite(PIN_RY_FAN_RIGHT,HIGH); //off
  
pinMode(PIN_RY_LEVEL,OUTPUT);
  
digitalWrite(PIN_RY_LEVEL,HIGH); //off
  
pinMode(PIN_LED_WHITE,OUTPUT);
  
pinMode(PIN_LED_BLUE,OUTPUT);
  
pinMode(PIN_RY_DRAIN,OUTPUT);
  
digitalWrite(PIN_RY_DRAIN,HIGH); //off
  
pinMode(PIN_RY_AUX,OUTPUT);
  
digitalWrite(PIN_RY_AUX,HIGH); //off
  
return true;
}
boolean startTemp()
{
  
sensors.begin();
  
  
sensors.setResolution(Probe0112);
  
sensors.setResolution(Probe0212);
  
sensors.setResolution(Probe0312);
  
sensors.setResolution(Probe0412);
  
sensors.setResolution(Probe0512);//left led
  
sensors.setResolution(Probe0612);//right led
  
sensors.setResolution(Probe0712);//tank
  
if (sensors.getDeviceCount() > 0){
    return 
sensors.getDeviceCount();
  }
  else{
    return 
false;
  }
}

boolean startEthernet(){
  
Ethernet.begin(mac,ip);

  
server.begin();
  return 
true;
}
void Alarms(){
  if(
IN_LEVEL_SUMP 15){
    
ALARM_LEVEL_HIGH true;
  }else{
    
ALARM_LEVEL_HIGH false;
  }
  
  if(
IN_LEVEL_SUMP 8){
    
ALARM_LEVEL_LOW true;
  }else{
    
ALARM_LEVEL_LOW false;
  }
  
  if(
IN_LEVEL_PH 9){
    
ALARM_PH_HIGH true;
  }else{
    
ALARM_PH_HIGH false;
  }
  
  if(
IN_LEVEL_PH 7.6){
    
ALARM_PH_LOW true;
  }else{
    
ALARM_PH_LOW false;
  }
  
  if(
TEMP_AVG 82){
    
ALARM_TEMP_AVG_HIGH true;
  }else{
    
ALARM_TEMP_AVG_HIGH false;
  }
  
  if(
TEMP_AVG 76){
    
ALARM_TEMP_AVG_LOW true;
  }else{
    
ALARM_TEMP_AVG_LOW false;
  }
}

void Inputs()
{
  
sensors.requestTemperatures();
  
IN_TEMP_HEATER getTemp(IN_TEMP_HEATER,Probe01);
  
IN_TEMP_RETURN getTemp(IN_TEMP_RETURN,Probe02);
  
IN_TEMP_OVERFLOW getTemp(IN_TEMP_OVERFLOW,Probe03);
  
IN_TEMP_ROOM getTemp(IN_TEMP_ROOM,Probe04);
  
IN_LED_TEMP_LEFT getTemp(IN_LED_TEMP_LEFT,Probe05);
  
IN_LED_TEMP_RIGHT getTemp(IN_LED_TEMP_RIGHT,Probe06);
  
IN_TEMP_TANK getTemp(IN_TEMP_TANK,Probe07);
  
IN_LEVEL_SUMP readLevel();
  
IN_LEVEL_PH PHProcess(IN_LEVEL_PH_MODE);
}

void Process()
{
  
OUT_HEATER Controller(IN_TEMP_RETURN,SP_TEMP_RETURN,SPR_TEMP_RETURN,true,IN_HEATER_MODE,OUT_HEATER); //Heater controller 
  
OUT_LEFT_FAN Controller(IN_LED_TEMP_LEFT,SP_TEMP_LED,SPR_TEMP_LED,false,IN_LED_FAN_MODE,OUT_LEFT_FAN); //Left LED Fan
  
OUT_RIGHT_FAN Controller(IN_LED_TEMP_RIGHT,SP_TEMP_LED,SPR_TEMP_LED,false,IN_LED_FAN_MODE,OUT_RIGHT_FAN); //Right LED Fan
  
OUT_LED_WHITE LEDController(map(IN_LED_WHITE,0,100,WHITE_LW,WHITE_UP),IN_LED_MODE,"white"); // white led controller
  
OUT_LED_BLUE LEDController(map(IN_LED_BLUE,0,100,BLUE_LW,BLUE_UP),IN_LED_MODE,"blue"); //blue led controller
  
OUT_LEVEL Controller(IN_LEVEL_SUMP,SP_LEVEL,SPR_LEVEL,true,IN_LEVEL_MODE,OUT_LEVEL); //Heater controller 
  
TEMP_AVG = (IN_TEMP_RETURN IN_TEMP_OVERFLOW IN_TEMP_TANK) / 3;
  
Alarms();
}
float PHProcess(int mode){ //0 - STOP, 1 - CON,2-TEMP, 3 - CAL4, 4 - CAL7, 5 - CAL10, 6 - CALD4,7 - CALD7,8 - CALD10
  
if(mode != IN_LEVEL_PH_MODE_L){
    switch(
mode){
    case 
0:
      
Serial3.print("E\r\r");
      
delay(1000);
      break;
    case 
1:
      
Serial3.print("C\r\r");
      
delay(1000);
      break;
    case 
2:
      
Serial3.print(toC(IN_TEMP_RETURN));
      
Serial3.print("\r\r");
      
delay(1000);
      break;
    case 
3:  //ph 4 
      
Serial3.print("F\r\r");
      
Config("LEVEL_PH_MODE",6);
      break;
    case 
4//ph 7
      
Serial3.print("S\r\r");
      
Config("LEVEL_PH_MODE",7);
      break;
    case 
5//ph 10
      
Serial3.print("T\r\r");
      
Config("LEVEL_PH_MODE",8);
      break;
    }
  }
  
IN_LEVEL_PH_MODE_L mode;
  return 
readPH();
}


int LEDController(int IN_LED,int mode,String color){
  if (
mode == 0){  //Off
    
return 0;
  }
  else if(
mode == 1){  //On
    
return IN_LED;
  }
  else{ 
//auto
    
int minNow = ((hour() - 1) * 60) + minute();
    if(
minNow <= LED_BLUE_START){ //0-10
      
return 0
    }
    else if(
minNow >= LED_BLUE_END){//22-24
      
return 0;
    }
    else if(
minNow >= LED_BLUE_START && minNow <= LED_WHITE_START && color == "blue"){ //10-12 blue only
      
return map(minNow,LED_BLUE_START,LED_WHITE_START,BLUE_LW,BLUE_UP);
    }
    else if(
minNow >= LED_BLUE_START && minNow <= LED_WHITE_START && color == "white"){ //10-12 white
      
return 0
    }
    else if(
minNow >= LED_WHITE_START && minNow <= LED_MID && color == "blue"){ //12-16 blue
      
return map(minNow,LED_WHITE_START,LED_MID,BLUE_UP,BLUE_LW);
    }
    else if(
minNow >= LED_WHITE_START && minNow <= LED_MID && color == "white"){ //12-16 white
      
return map(minNow,LED_WHITE_START,LED_MID,WHITE_LW,WHITE_UP);
    }
    else if(
minNow >= LED_MID && minNow <= LED_WHITE_END && color == "blue"){ //16-20 blue
      
return map(minNow,LED_MID,LED_WHITE_END,BLUE_LW,BLUE_UP);
    }
    else if(
minNow >= LED_MID && minNow <= LED_WHITE_END && color == "white"){ //16-29 white
      
return map(minNow,LED_MID,LED_WHITE_END,WHITE_UP,WHITE_LW);
    }
    else if(
minNow >= LED_WHITE_END && minNow <= LED_BLUE_END && color == "blue"){ // 20-22 blue
      
return map(minNow,LED_WHITE_END,LED_BLUE_END,BLUE_UP,BLUE_LW);
    }
    else if(
minNow >= LED_WHITE_END && minNow <= LED_BLUE_END && color == "white"){ // 20-22 blue
      
return 0;
    }
    else{
      return 
0;
    }
  }
}

boolean Controller(float input,float sp,float rst,boolean dec,int mode,boolean output){ 

  if (
mode == 0){  //Off
    
return false;
  }
  else if(
mode == 1){  //On
    
return true;
  }
  else{  
//Auto
    
if(dec){
      if(
input sp){
        return 
true;
      }
      else if(
input rst){
        return 
false;
      }
      else{
        return 
output;
      }

    }
    else{
      if(
input sp){
        return 
true;
      }
      else if(
input rst){
        return 
false;
      }
      else{
        return 
output;
      }
    }

  }
}
void Outputs(){
  
digitalWrite(PIN_RY_HEATER,!OUT_HEATER); //Invert output for relay
  
digitalWrite(PIN_RY_FAN_LEFT,!OUT_LEFT_FAN);
  
digitalWrite(PIN_RY_FAN_RIGHT,!OUT_RIGHT_FAN);
  
digitalWrite(PIN_RY_LEVEL,!OUT_LEVEL);
  
digitalWrite(PIN_RY_DRAIN,!IN_LEVEL_DRAIN_MODE);
  
digitalWrite(PIN_RY_AUX,!IN_AUX_MODE);
  
analogWrite(PIN_LED_WHITE,OUT_LED_WHITE);
  
analogWrite(PIN_LED_BLUE,OUT_LED_BLUE);
}

float getTemp(float last,DeviceAddress deviceAddress)
{
  
float temp sensors.getTempF(deviceAddress);
  if(
temp 0){
    return 
last;
  }
  else{
    return 
temp;
  }
}


float readLevel(){
  
float average;
  
float samples[amt];
  for (
int i=0iamti++) {
    
float uS sonar.ping();
    
float dist uS US_ROUNDTRIP_IN;
    
samples[i] = dist;
    
delay(30);
  }
  
average 0;
  for (
int i=0iamti++) {
    
average += samples[i];
  }
  
  
average /= amt;
  
QueueEnter(LVLavg,SUMP_RNG average,&LVLRear);
  return 
getAVG(LVLavg);
}
float lastPH;
float readPH(){
  
String PHSTR "";
  while(
Serial3.available()){
    
char inchar = (char)Serial3.read();                            
    
PHSTR += inchar;                                         
    if(
inchar == '\r') {
      
float phCheck strTofloat(PHSTR.length(),PHSTR);
      if(
phCheck 14 || phCheck 0){
        return 
lastPH;
      }
      else{
        
float phCorrected;
        if(
phCheck >= 7){
          
phCorrected mapfloat(phCheck,7.00,10.20,7.00,10.00);
        }
        else{
          
phCorrected mapfloat(phCheck,3.70,7.00,4.00,6.99);
        }
        
lastPH phCorrected
        
QueueEnter(phavg,phCorrected,&phRear);
        
Serial.println("");
        
Serial.println(phCorrected);
        
Serial.println(getAVG(phavg));
        return 
getAVG(phavg);
      }
    }       
  }
}
float mapfloat(float xfloat in_minfloat in_maxfloat out_minfloat out_max)
{
  return (
in_min) * (out_max out_min) / (in_max in_min) + out_min;
}
float strTofloat(int chars,String str){
  
char floatbuf[chars];
  
str.toCharArray(floatbuf,sizeof(floatbuf));
  
float value atof(floatbuf);  
}
float toC(float temp){
  return (
temp 32) * (5/9);
}

/*-------- NTP code ----------*/

const int NTP_PACKET_SIZE 48// NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets

time_t getNtpTime()
{
  while (
Udp.parsePacket() > 0) ; // discard any previously received packets
  // Serial.println("Transmit NTP Request");
  
sendNTPpacket(timeServer);
  
uint32_t beginWait millis();
  while (
millis() - beginWait 1500) {
    
int size Udp.parsePacket();
    if (
size >= NTP_PACKET_SIZE) {
      
// Serial.println("Receive NTP Response");
      
Udp.read(packetBufferNTP_PACKET_SIZE);  // read packet into the buffer
      
unsigned long secsSince1900;
      
// convert four bytes starting at location 40 to a long integer
      
secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      
secsSince1900 |= (unsigned long)packetBuffer[43];
      return 
secsSince1900 2208988800UL timeZone SECS_PER_HOUR;
    }
  }
  
Serial.println("No NTP Response :-(");
  return 
0// return 0 if unable to get the time
}

// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
  
// set all bytes in the buffer to 0
  
memset(packetBuffer0NTP_PACKET_SIZE);
  
// Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  
packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  
packetBuffer[1] = 0;     // Stratum, or type of clock
  
packetBuffer[2] = 6;     // Polling Interval
  
packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  
packetBuffer[12]  = 49;
  
packetBuffer[13]  = 0x4E;
  
packetBuffer[14]  = 49;
  
packetBuffer[15]  = 52;
  
// all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:                 
  
Udp.beginPacket(address123); //NTP requests are to port 123
  
Udp.write(packetBufferNTP_PACKET_SIZE);
  
Udp.endPacket();




joopie is offline   Reply With Quote
Unread 11/19/2013, 08:58 PM   #5
rott
Head zoo keeper
 
Join Date: Nov 2005
Location: Toledo ,Ohio
Posts: 710
would you please share the html files?? or email them to me I would like to start using this very soon


rott is offline   Reply With Quote
Unread 11/19/2013, 09:01 PM   #6
rott
Head zoo keeper
 
Join Date: Nov 2005
Location: Toledo ,Ohio
Posts: 710
you replaced your local ip and password with blocked=) did you also replace a FQDN also with blocked=)


rott is offline   Reply With Quote
Unread 11/19/2013, 09:54 PM   #7
joopie
Registered Member
 
Join Date: Apr 2013
Location: New Hampshire
Posts: 37
i don't believe i replaced a FQDN with blocked... I block out some URLs for the get requests. Showing the way i have the get request set up for the trender function would allow anyone to insert data into my data tables. I'm sure what i have going is not very secure but seems to be ok so far... I am going to add interlocks so that if someone was able to gain access they wouldn't be able to do much. I just hard code it so that the sump level will never drain below x inches, or fill over x inches. same with heater, and lighting. So the main page is generated from a couple of php files and javascript for the charts.AJAX makes server calls to update the server without refreshing. here are some example links of how i get the tables:

http://www.rareglitch.net/getTables.php?tables=TEMP_%
http://www.rareglitch.net/getTables.php?tables=LED_%
http://www.rareglitch.net/getTables.php?tables=LEVEL_%

if you guys know of,or find any vulnerabilities id hope you would let me know =). i hope my code will help, and i will try to answer any questions. I am no web developer, i just took the time to learn and understand what to do and piece it all together. as far as charting please see http://www.highcharts.com/. i used the highstock for plotting my points. It needs a json output to load the points. here is the json output of the temp_return table: http://www.rareglitch.net/get_json.p...le=TEMP_RETURN



php file to generate the tables and format the table names and data to be more appealing:

PHP Code:
<?php
include_once('connect.php');
$tables $_GET['tables'];
$query "SHOW TABLES LIKE '".$tables."'";
$result mysql_query($query,$connect);
$out "<table border='.5'>";
$out .= "<tr bgcolor='#9ACDFD'>";
$out .= "<td>Last Update:</td>";
$first mysql_fetch_row($result);
$result mysql_query($query,$connect);
while(
$row mysql_fetch_row($result)){
    
$out .= "<td bgcolor='".getColor($row[0])."'>".getName($row[0])."</td>";
}
$out .= "</tr>";
$out .= "<tr>";
$dateQRY "SELECT Date FROM ".$first[0]." ORDER BY Date DESC LIMIT 1";
$dateResult mysql_query($dateQRY,$connect);
$out .= "<td>" .mysql_fetch_array($dateResult)[0] . "</td>";

$query "SHOW TABLES LIKE '".$tables."'";
$result mysql_query($query,$connect);
while(
$row mysql_fetch_row($result)){
    
$iquery "SELECT Value FROM ".$row[0]." ORDER BY Date DESC LIMIT 1";
    
$iresult mysql_query($iquery,$connect);
    
$out .= "<td>" formatData($row[0],mysql_fetch_array($iresult)[0]) . "</td>";
}
$out .= "</tr>";
$out .= "</table>";
echo 
$out;

function 
getColor($tablename){

    switch(
$tablename){
    case 
"TEMP_AOUT_HEATER":
        return 
"red";
        break;
    case 
"TEMP_HEATER":
        return 
"royalblue";
        break;
    case 
"TEMP_OVERFLOW":
        return 
"green";
        break;
    case 
"TEMP_RETURN":
        return 
"yellow";
        break;
    case 
"TEMP_ROOM":
        return 
"cyan";
        break;
    case 
"LED_ABLUE":
        return 
"royalblue";
        break;
    case 
"LED_XTEMP_LEFT":
        return 
"lightgray";
        break;
    case 
"LED_XTEMP_RIGHT":
        return 
"lightgray";
        break;
    case 
"TEMP_TANK":
        return 
"pink";
        break;

    default:
        return 
"white";
        break;
    }
}
function 
getName($tablename){

    switch(
$tablename){
    case 
"TEMP_AOUT_HEATER":
        return 
"Heater Status";
        break;
    case 
"TEMP_HEATER":
        return 
"Heater Temp";
        break;
    case 
"TEMP_OVERFLOW":
        return 
"Overflow Temp";
        break;
    case 
"TEMP_RETURN":
        return 
"Return Temp";
        break;
    case 
"TEMP_ROOM":
        return 
"Room Temp";
        break;
    case 
"LED_ABLUE":
        return 
"Blue LEDs";
        break;
    case 
"LED_AWHITE":
        return 
"White LEDs";
        break;
    case 
"LED_XTEMP_LEFT":
        return 
"Left LEDs";
        break;
    case 
"LED_XTEMP_RIGHT":
        return 
"Right LEDs";
        break;
    case 
"TEMP_TANK":
        return 
"Tank Temp";
        break;
    case 
"LED_FAN_LEFT":
        return 
"Left Fan";
        break;
    case 
"LED_FAN_RIGHT":
        return 
"Right Fan";
        break;
    case 
"LEVEL_FILL":
        return 
"Fill Status";
        break;
    case 
"LEVEL_SUMP":
        return 
"Sump Level";
        break;
    case 
"LEVEL_XPH":
        return 
"PH Level";
        break;
    case 
"LEVEL_DRAIN":
        return 
"Drain Status";
        break;
    case 
"ALARM_LEVEL_HIGH":
        return 
"Level High Alarm";
        break;
    case 
"ALARM_LEVEL_LOW":
        return 
"Level Low Alarm";
        break;
    case 
"ALARM_PH_HIGH":
        return 
"PH High";
        break;
    case 
"ALARM_PH_LOW":
        return 
"PH Low";
        break;
    case 
"ALARM_TEMP_AVG_HIGH":
        return 
"AVG Temp High";
        break;
    case 
"ALARM_TEMP_AVG_LOW":
        return 
"AVG Temp Low";
        break;
    default:
        return 
$tablename;
        break;
    }
}
function 
formatData($table,$data){
    switch(
$table){
    case 
"LED_FAN_RIGHT":
    case 
"LED_FAN_LEFT":
    case 
"LEVEL_FILL":
    case 
"TEMP_AOUT_HEATER":
    case 
"LEVEL_DRAIN":
        switch(
$data){
        case 
1:
            return 
"On";
            break;
        case 
0:
            return 
"Off";
            break;
        default:
            return 
$data;
            break;
        }
        break;
    case 
"LED_AWHITE":
    case 
"LED_ABLUE":
        if(
$data <= 0){
            return 
"Off";
            break;
        }else{
            return 
$data "%";
            break;
        }
    case 
"ALARM_LEVEL_HIGH":
    case 
"ALARM_LEVEL_LOW":
    case 
"ALARM_PH_HIGH":
    case 
"ALARM_PH_LOW":
    case 
"ALARM_TEMP_AVG_HIGH":
    case 
"ALARM_TEMP_AVG_LOW":
        switch(
$data){
        case 
1:
            return 
"<center>ALARM</center>";
            break;
        case 
0:
            return 
"<center>GOOD</center>";
            break;
        default:
            return 
$data;
            break;
        }
    default:
        return 
$data;
        break;
    }
}
connect.php
PHP Code:
<?php
//CONNECT.PHP

$hostname "blocked";
$database "blocked";
$username "blocked";
$password "blocked";

if(!
$connect mysql_connect($hostname,$username,$password,$database)){
    die(
'FAILED TO CONNECT' mysql_error());
}
$bool mysql_select_db($database,$connect);
if(!
$bool){
 die(
'FAILED DB SELECT' mysql_error());
}
?>
json file to convert mysql table into json for charting:
PHP Code:
<?php
include_once('connect.php');
$table $_GET['table'];

if(
$table == "blocked"){
    
$qry "SELECT * FROM ".$table;
    
$result mysql_query($qry,$connect);
    while(
$row mysql_fetch_array($result)){
        if(
$row['Setting'] == "blocked"){

        }else{

        
        echo 
"#" $row['Setting'];
        echo  
"@" $row['Value'] . "$";
    }
    }
    echo 
"!";

}else{
    
$shorten false;
    
$count 3;
    
$start 0;
    
$qry "SELECT * FROM ".$table." ORDER BY Date ASC";
    
$result mysql_query($qry,$connect);
    if(
mysql_num_rows($result) > 100000 mysql_num_rows($result) < 200000){
        
$shorten true;
        
$count 5;
    }elseif(
mysql_num_rows($result) > 200000){
        
$shorten true;
        
$count 10;
    }else{
        
$shorten false;
    }
    while(
$row mysql_fetch_array($result)){
        
$dates strtotime($row['Date']) * 1000;
        switch(
$table){
            case 
"TEMP_AOUT_HEATER":
                
$values = ((float)$row['Value'] * 5) + 85.00;
                break;
            case 
"LED_FAN_LEFT":
            case 
"LED_FAN_RIGHT":
                
$values = ((float)$row['Value'] * 5) + 80.00;
                break;
            case 
"LEVEL_FILL":
                
$values = ((float)$row['Value'] * 5) + 5.00;
                break;
            case 
"LED_ABlUE":
            case 
"LED_AWHITE":
                
$values = ((float)$row['Value'] * .1) + 0.00;
            default:
                
$values = (float)$row['Value'];
                break;
        }
        if(
$shorten){
            if(
$start == $count){
                
$array[] = array($dates,$values);
                
$start 0;
            }else{
                
$start++;
            }
        }else{
            
$array[] = array($dates,$values);
        }
    }
    echo 
json_encode($array);
}
?>
overview site:
PHP Code:
<!DOCTYPE HTML>
<
html>
    <
head>
        <
meta ***********="Content-Type" content="text/html; charset=utf-8">
        <
link rel="icon" type="icon" href="1_fish.ico"/>
        <
link rel="shortcut icon" type="icon" href="1_fish.ico"/>
        <
title>Fish Tank</title>
        
        
    </
head>
    <
body bgcolor="grey">

******** 
type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
******** type="text/javascript">
<!-- 
//Browser Support Code
if(screen.width <=699){
   document.location = "http://www.rareglitch.net/lite.htm";
}
function ajaxAlarm(){
   var ajaxRequest;  // The variable that makes Ajax possible!
   
   try{
      // Opera 8.0+, Firefox, Safari
      ajaxRequest = new XMLHttpRequest();
   } catch (e){
      // Internet Explorer Browsers
      try{
         ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {
         try{
            ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
         } catch (e){
            // Something went wrong
            alert("Your browser broke!");
            return false;
         }
      }
   }
   // Create a function that will receive data sent from the server
   ajaxRequest.onreadystatechange = function(){
      if(ajaxRequest.readyState == 4){
         var ajaxDisplay = document.getElementById('ajaxAlarm');
         ajaxDisplay.innerHTML = ajaxRequest.responseText;
      }
   }
   ajaxRequest.open("GET", "getTables.php?&tables=ALARM_%", true);
   ajaxRequest.send(null); 
}
function ajaxLED(){
    var ajaxRequest;  // The variable that makes Ajax possible!
    
    try{
        // Opera 8.0+, Firefox, Safari
        ajaxRequest = new XMLHttpRequest();
    } catch (e){
        // Internet Explorer Browsers
        try{
            ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try{
                ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e){
                // Something went wrong
                alert("Your browser broke!");
                return false;
            }
        }
    }
    // Create a function that will receive data sent from the server
    ajaxRequest.onreadystatechange = function(){
        if(ajaxRequest.readyState == 4){
            var ajaxDisplay = document.getElementById('ajaxLED');
            ajaxDisplay.innerHTML = ajaxRequest.responseText;
        }
    }
    ajaxRequest.open("GET", "getTables.php?tables=LED_%", true);
    ajaxRequest.send(null); 
}
function ajaxTemp(){
    var ajaxRequest;  // The variable that makes Ajax possible!
    
    try{
        // Opera 8.0+, Firefox, Safari
        ajaxRequest = new XMLHttpRequest();
    } catch (e){
        // Internet Explorer Browsers
        try{
            ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try{
                ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e){
                // Something went wrong
                alert("Your browser broke!");
                return false;
            }
        }
    }
    // Create a function that will receive data sent from the server
    ajaxRequest.onreadystatechange = function(){
        if(ajaxRequest.readyState == 4){
            var ajaxDisplay = document.getElementById('ajaxTemp');
            ajaxDisplay.innerHTML = ajaxRequest.responseText;
        }
    }
    ajaxRequest.open("GET", "getTables.php?tables=TEMP_%", true);
    ajaxRequest.send(null); 
}
function ajaxLevel(){
   var ajaxRequest;  // The variable that makes Ajax possible!
   
   try{
      // Opera 8.0+, Firefox, Safari
      ajaxRequest = new XMLHttpRequest();
   } catch (e){
      // Internet Explorer Browsers
      try{
         ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {
         try{
            ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
         } catch (e){
            // Something went wrong
            alert("Your browser broke!");
            return false;
         }
      }
   }
   // Create a function that will receive data sent from the server
   ajaxRequest.onreadystatechange = function(){
      if(ajaxRequest.readyState == 4){
         var ajaxDisplay = document.getElementById('ajaxLevel');
         ajaxDisplay.innerHTML = ajaxRequest.responseText;
      }
   }
   ajaxRequest.open("GET", "getTables.php?tables=LEVEL_%", true);
   ajaxRequest.send(null); 
}
function ajaxCFG(password){
    var ajaxRequest;  // The variable that makes Ajax possible!
    
    try{
        // Opera 8.0+, Firefox, Safari
        ajaxRequest = new XMLHttpRequest();
    } catch (e){
        // Internet Explorer Browsers
        try{
            ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try{
                ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e){
                // Something went wrong
                alert("Your browser broke!");
                return false;
            }
        }
    }
    // Create a function that will receive data sent from the server
    ajaxRequest.onreadystatechange = function(){
        if(ajaxRequest.readyState == 4){
            var ajaxDisplay = document.getElementById('ajaxCFG');
            ajaxDisplay.innerHTML = ajaxRequest.responseText;
            
        }
    }
    //var pass = document.getElementById("pass").value;
    ajaxRequest.open("GET", "blocked, true);
    ajaxRequest.send(); 


}
function updateConfig(name,value){
    var ajaxRequest;  // The variable that makes Ajax possible!
    
    try{
        // Opera 8.0+, Firefox, Safari
        ajaxRequest = new XMLHttpRequest();
    } catch (e){
        // Internet Explorer Browsers
        try{
            ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try{
                ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e){
                // Something went wrong
                alert("Your browser broke!");
                return false;
            }
        }
    }
    // Create a function that will receive data sent from the server
    //ajaxRequest.onreadystatechange = function(){
    //    if(ajaxRequest.readyState == 4){
    //        var ajaxDisplay = document.getElementById('ajaxCFG');
    //        ajaxDisplay.innerHTML = ajaxRequest.responseText;
    //    }
    //}
    ajaxRequest.open("GET","blocked, true);
    ajaxRequest.send(null); 
}
ajaxAlarm();
ajaxLevel();
ajaxTemp();
ajaxLED();

ajaxCFG(document.getElementById("pass"));

//window.setInterval("loadChart()",3000);
window.setInterval("ajaxTemp()",5000);
window.setInterval("ajaxLED()",5000);
window.setInterval("ajaxLevel()",5000);
window.setInterval("ajaxAlarm()",5000);
window.setInterval("ajaxCFG(document.getElementById('pass').value)",5000);
</script>
<table border="0" width="100%">
<tr align="center"><td><div id ='ajaxAlarm'></div></td></tr>
</table>
<table border="0" width="100%">

<tr align="center"><td><div id ='ajaxTemp'></div></td><td><div id ='ajaxLED'></div></td></tr>
<tr align="center"><td><iframe src="chart_Temp.htm" frameborder="0" width="100%" height="320"></iframe></td><td><iframe src="chart_LED.htm" frameborder="0" width="100%" height="320"></iframe></td></tr>
<tr align="center"><td valign="bottom"><form>Password:<input type="password" id="pass"></form></td><td><div id ='ajaxLevel'></div></td></tr>
<tr align="center"><td valign="top"><div id ='ajaxCFG'></div></td><td><iframe src="chart_Level.htm" frameborder="0" width="100%" height="320"></iframe></td></tr></table>



</div>    </body>
</html> 



joopie is offline   Reply With Quote
Unread 11/20/2013, 06:04 PM   #8
rott
Head zoo keeper
 
Join Date: Nov 2005
Location: Toledo ,Ohio
Posts: 710
I all ready have a machine setup with wamp for internal use so that should work


rott is offline   Reply With Quote
Unread 11/22/2013, 03:10 PM   #9
rott
Head zoo keeper
 
Join Date: Nov 2005
Location: Toledo ,Ohio
Posts: 710
Anytime your ready I can be


rott is offline   Reply With Quote
Unread 12/03/2013, 03:22 PM   #10
MLS
Registered Member
 
MLS's Avatar
 
Join Date: Nov 2011
Posts: 67
Joopie, thanks for sharing your code and actual internet view of your program! It has given me a lot of ideas for my new project!


__________________
Mike

40L Reef Tank, 10 Gallon Nano, 5 Gallon Pico
MLS is offline   Reply With Quote
Unread 12/06/2013, 02:06 PM   #11
gernby
Registered Member
 
Join Date: May 2004
Posts: 70
Wow, this is awesome! Thanks for sharing!

Glancing at your code, it seems that you are using an analog output instead of PWM. Is that correct? If so, what is the max output voltage, and what drivers are you using with it? Also, which Arduino board are you using?


gernby is offline   Reply With Quote
Unread 12/06/2013, 05:50 PM   #12
joopie
Registered Member
 
Join Date: Apr 2013
Location: New Hampshire
Posts: 37
I'm using an arduino mega. The analogwrite is outputing a 0-5v pwm, see http://arduino.cc/en/Reference/analogWrite

im using a transistor and seperate 10v power source to up it to 0-10v pwm.
here is a good example:http://arduino-for-beginners.blogspo...-with-pwm.html

the led drivers i have are the Mean Well ELN-60-48P dimmable driver:
http://www.rapidled.com/mean-well-el...mmable-driver/

they are nice but they cut out at ~15%, so i recommend going with the Mean Well ELN-60-48D dimmable driver that cut out around 5%.


joopie is offline   Reply With Quote
Unread 12/06/2013, 08:24 PM   #13
gernby
Registered Member
 
Join Date: May 2004
Posts: 70
Good to know. I'm planning to use the LDD-L drivers, which allow a 0~2.5V analog input for dimming OR a 0~2.6+V PWM input. When using the analog dimming mode, the LED's dim range is something like 20%-100%, so thinking about using PWM for the high power LED strings, and analog for the low power LED strings.


gernby is offline   Reply With Quote
Unread 12/14/2013, 01:33 AM   #14
joopie
Registered Member
 
Join Date: Apr 2013
Location: New Hampshire
Posts: 37
Updated site so that each column header is a link to that data points chart.Charts with a lot of data points may take a awhile to load.
http://www.rareglitch.net/overview.htm
Also check out my "mobile" version of the site(no charts).
http://www.rareglitch.net/lite.htm


joopie is offline   Reply With Quote
Unread 12/18/2013, 01:35 PM   #15
rott
Head zoo keeper
 
Join Date: Nov 2005
Location: Toledo ,Ohio
Posts: 710
wow that is very nice took a few minutes to load but I did like it


rott is offline   Reply With Quote
Unread 12/18/2013, 04:43 PM   #16
gernby
Registered Member
 
Join Date: May 2004
Posts: 70
Quote:
Originally Posted by rott View Post
wow that is very nice took a few minutes to load but I did like it
:iagree: I kept getting popups about slow script performance. Is there a way to pre-process the data so that it loads quicker?


gernby is offline   Reply With Quote
Unread 12/18/2013, 08:30 PM   #17
joopie
Registered Member
 
Join Date: Apr 2013
Location: New Hampshire
Posts: 37
I'm sure there is a better way but this works well for me since i'm usually loading the site off the lan.


joopie is offline   Reply With Quote
Unread 12/25/2013, 10:37 PM   #18
rott
Head zoo keeper
 
Join Date: Nov 2005
Location: Toledo ,Ohio
Posts: 710
joopie merry christmas


rott is offline   Reply With Quote
Unread 12/31/2013, 09:17 PM   #19
joopie
Registered Member
 
Join Date: Apr 2013
Location: New Hampshire
Posts: 37
So i got a new toy for Christmas, you can see it in action at http://www.rareglitch.net/overview.htm or http://www.rareglitch.net/fishcam.htm

May not work for older IE browsers. recommend chrome or firefox.


joopie is offline   Reply With Quote
Unread 12/31/2013, 10:13 PM   #20
dre7606
Registered Member
 
dre7606's Avatar
 
Join Date: Oct 2006
Location: Fort Worth, TX
Posts: 43
joopie can you provide a parts list? This I love the added video feed!


dre7606 is offline   Reply With Quote
Unread 01/01/2014, 07:45 AM   #21
reefwiser
Registered Member
 
reefwiser's Avatar
 
Join Date: Nov 2013
Location: Louisville,Kentucky
Posts: 1,208
Looks like your fish cam is knocked out of view. I have to straight web cams at work all the time for monitoring production in a factory.


reefwiser is offline   Reply With Quote
Unread 01/01/2014, 10:04 AM   #22
joopie
Registered Member
 
Join Date: Apr 2013
Location: New Hampshire
Posts: 37
yeah seems to reset after awhile. i think i fixed it, now it should look at the tank when it boots up.


joopie is offline   Reply With Quote
Unread 01/01/2014, 01:09 PM   #23
reefwiser
Registered Member
 
reefwiser's Avatar
 
Join Date: Nov 2013
Location: Louisville,Kentucky
Posts: 1,208
Love the wrasse swimming up down the one side.


reefwiser is offline   Reply With Quote
Unread 01/05/2014, 01:49 PM   #24
joopie
Registered Member
 
Join Date: Apr 2013
Location: New Hampshire
Posts: 37
So the camera thing is cool but the wife doesn't like random people looking into our fish tank, and possibly whatever is reflected off the glass lol. so that wont be on there anymore.


joopie is offline   Reply With Quote
Unread 01/05/2014, 02:06 PM   #25
joopie
Registered Member
 
Join Date: Apr 2013
Location: New Hampshire
Posts: 37
Quote:
Originally Posted by dre7606 View Post
joopie can you provide a parts list? This I love the added video feed!
Arduino Mega:
https://www.sparkfun.com/products/11061

Ethernet Shield to talk with database and time keeping:
http://yourduino.com/sunshop2/index....t_detail&p=291

Temperature Sensors DS18b20(7 in use):
http://www.amazon.com/DS18b20-Waterp...erature+sensor

LED 90g Dimmable Solderless Kit:
http://www.rapidled.com/standard-sol...-dimmable-kit/

Opto-Isolated 2 Channel Relays for fans,heater and water change pump:
http://yourduino.com/sunshop2/index....t_detail&p=218

Power strip with above relays mounted inside to control outlets:
http://www.amazon.com/Technical-Pro-...dj+power+strip

Solenoids for auto top off, draining, water changes:
http://www.adafruit.com/products/996

I do have some flow meters installed but not in use:
http://www.adafruit.com/products/828

Ultrasonic range finder for sump level:
http://yourduino.com/sunshop2/index....t_detail&p=115

A PC for web server running Ubuntu and LAMPP. I also use this computers power supply to power the relays and solenoids.

I think that pretty much covers the arduino electronics.


joopie is offline   Reply With Quote
Reply

Tags
aquarium, arduino, automation, control

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On



All times are GMT -6. The time now is 02:39 PM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Powered by Searchlight © 2024 Axivo Inc.
Use of this web site is subject to the terms and conditions described in the user agreement.
Reef CentralTM Reef Central, LLC. Copyright ©1999-2022
User Alert System provided by Advanced User Tagging v3.3.0 (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.