Improved Arduino LED lighting code - Page 11
Planted Tank Forums
Your Tanks Image Hosting *Tank Tracker * Plant Profiles Fish Profiles Planted Tank Guide Photo Gallery Articles

Go Back   The Planted Tank Forum > Specific Aspects of a Planted Tank > DIY


Reply
 
Thread Tools Display Modes
Old 04-10-2013, 12:07 AM   #151
sink
Algae Grower
 
PTrader: (2/100%)
Join Date: Jun 2011
Location: Boston, MA
Posts: 148
Default

Quote:
Originally Posted by shrimper23 View Post
Any idea on the I2C capability guys? Also, Sink, a quick question on your code, I see you name the channels with a "k". Such as kChan0Pin, is there a reason for this? Just wondering as I haven't seen this before.
It is a convention in C to name constants starting with a lowercase k. It helps distinguish later on things that should be constant from things that can be safely reassigned. It is not a requirement though, merely a suggested style.

I would think you will have no issues with multiple devices on I2C.

Cheers.
sink is offline   Reply With Quote
Sponsored Links
Advertisement
 
Old 09-21-2013, 01:00 AM   #152
willflyfood
Newbie
 
PTrader: (0/0%)
Join Date: Sep 2013
Location: Fort Worth TX
Posts: 2
Default

Sink I am driving my self nuts here.... what pins did you use for the RTC?
willflyfood is offline   Reply With Quote
Old 09-21-2013, 04:20 AM   #153
willflyfood
Newbie
 
PTrader: (0/0%)
Join Date: Sep 2013
Location: Fort Worth TX
Posts: 2
Default Pins

I am using pin 4 and 5 but when I run the serial monitor I see nothing...
willflyfood is offline   Reply With Quote
Old 10-05-2013, 10:04 PM   #154
sink
Algae Grower
 
PTrader: (2/100%)
Join Date: Jun 2011
Location: Boston, MA
Posts: 148
Default

Quote:
Originally Posted by willflyfood View Post
Sink I am driving my self nuts here.... what pins did you use for the RTC?
Sorry for the delay in replying!

The RTC communicates over I2C, so you just use whatever pins those are on your board. On the Duemilanove that I have those are A4 and A5. It might be different on the Uno. There isn't anything special about my code in this respect, you hook up I2C the same way you would for any Arduino device. For just one I2C device (the RTC) you'd connect the SDA on the RTC to the SDA on the Arduino, and same for the SCL ports.
sink is offline   Reply With Quote
Old 10-05-2013, 10:13 PM   #155
sink
Algae Grower
 
PTrader: (2/100%)
Join Date: Jun 2011
Location: Boston, MA
Posts: 148
Default

Quote:
Originally Posted by willflyfood View Post
I am using pin 4 and 5 but when I run the serial monitor I see nothing...
The serial doesn't really send anything unless you "talk" to it with the client.py script I supplied in the code.

If you run the client.py script and enter "time" at the prompt, you get no response? Is there an error?
sink is offline   Reply With Quote
Old 10-06-2013, 05:15 AM   #156
HunterX
Planted Tank Obsessed
 
HunterX's Avatar
 
PTrader: (22/100%)
Join Date: May 2012
Location: Springfield MO
Posts: 361
Default

Hello everyone. I want to thank you all for taking the time to put this information on the forum. I do have a question. Has anyone used the arduino to control LED fixtures made by build my led.com? From what I understand, they are built with LED Drivers built into the fixture. Further more, they can ship with a prefab APEX dimming cable. It appears to be a standard RJ45 connection on the end that would plug into the controller. Would it be possible do use the Arduino with that setup to control the LEDs? if so what would I need?

Thank you in advance for your response.
HunterX is offline   Reply With Quote
Old 10-06-2013, 10:28 PM   #157
O2surplus
Planted Tank Enthusiast
 
O2surplus's Avatar
 
PTrader: (4/100%)
Join Date: Jan 2010
Location: yorba linda, ca.
Posts: 591
Default

Quote:
Originally Posted by HunterX View Post
Hello everyone. I want to thank you all for taking the time to put this information on the forum. I do have a question. Has anyone used the arduino to control LED fixtures made by build my led.com? From what I understand, they are built with LED Drivers built into the fixture. Further more, they can ship with a prefab APEX dimming cable. It appears to be a standard RJ45 connection on the end that would plug into the controller. Would it be possible do use the Arduino with that setup to control the LEDs? if so what would I need?

Thank you in advance for your response.

The Apex controller outputs a 0-10V analog signal to dim the leds. So chances are good that the dimmable drivers in the BuildMyLed fixture are designed to accept that type of dimming control signal. The Arduino outputs a 5V PWM signal, so it won't be directly compatible with the drivers in the BML fixture.
If you have your heart set on using the arduino as your controller, just purchase LED drivers that accept a 5V PWM signal directly, and you'll be set.Checkout the Meanwell LDD-L & LDD-H series of drivers. They will work well for your application, and they're cheap too. Here's a link-LDD-1000H | Mean-Well LDD-1000H | USA Warehouse
__________________
225 Gal, Glass "Reef Ready" w/ twin Iwaki Pumps & 2 Ocean Clear inline filters. Custom 320 watt LED Lighting system utilizing a 6' Maker's Heat Sink, 12 BridgeLux Vero 18's,3 purpose built 5 channel A6211 Led driver/Controllers, and a 20lb CO2 system w/ Milwaukee Ph Controller.
O2surplus is offline   Reply With Quote
Old 10-07-2013, 03:50 PM   #158
HunterX
Planted Tank Obsessed
 
HunterX's Avatar
 
PTrader: (22/100%)
Join Date: May 2012
Location: Springfield MO
Posts: 361
Default

Quote:
Originally Posted by O2surplus View Post
The Apex controller outputs a 0-10V analog signal to dim the leds. So chances are good that the dimmable drivers in the BuildMyLed fixture are designed to accept that type of dimming control signal. The Arduino outputs a 5V PWM signal, so it won't be directly compatible with the drivers in the BML fixture.
If you have your heart set on using the arduino as your controller, just purchase LED drivers that accept a 5V PWM signal directly, and you'll be set.Checkout the Meanwell LDD-L & LDD-H series of drivers. They will work well for your application, and they're cheap too. Here's a link-LDD-1000H | Mean-Well LDD-1000H | USA Warehouse
Thanks for your reply. I'm sending you a PM.
HunterX is offline   Reply With Quote
Old 10-08-2013, 05:46 PM   #159
estill
Algae Grower
 
PTrader: (3/100%)
Join Date: Jan 2007
Location: Tacoma, Washington
Posts: 25
Default

To address the 0-10V "signal", could you use the Arduino PWM output to control a transistor or MOSFET? I know you can do this to drive a DC motor, and it will fool most multimeters into seeing a lower voltage.
estill is offline   Reply With Quote
Old 12-01-2013, 03:07 PM   #160
Gisimo
Algae Grower
 
PTrader: (0/0%)
Join Date: Apr 2012
Location: Denmark
Posts: 17
Default

Hello everyone i am considering to make a new light for at nano tank and i was wondering if i could use a Arduino Micro or mini instead of an uno ??

Last edited by Gisimo; 12-01-2013 at 03:33 PM.. Reason: Mistake
Gisimo is offline   Reply With Quote
Old 12-01-2013, 05:05 PM   #161
shrimper23
Algae Grower
 
PTrader: (0/0%)
Join Date: Oct 2011
Location: Franktown,CO
Posts: 5
Default I2C freezing

Hey Sink, wanted to see if you might be able to advise me on my project here. I have your code working beautifully with the Adafruit 16-channel 12-bit pwm driver. However, after integrating it into my full control code i'm having an issue. The code will perform as expected right up to the dimming stage, when it hits my LCD goes blank, LED's flash, and the whole I2C bus stops dead. It seems to me I may have to much going on with the I2C. I'm using an UNO R3 with a DS1307, the Adafruit PWM controller, and their I2C 16x2 LCD on the bus. Please let me know if you have any idea how I might fix this issue. Thank you.


#include <Wire.h>
#include "RTClib.h"
#include <SoftwareSerial.h>
#include <OneWire.h>
#include <Adafruit_PWMServoDriver.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>

#define OFF 0x0
#define WHITE 0x7
#define rxpin 3
#define txpin 2

RTC_DS1307 RTC;
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

const long kTurnOn = 39000; // 37800time dawn begins - 0900hrs
const long kTurnOff = 59000; // 70200 time sunset begins - 2100hrs
const int kDayState[] = { 3000, 4000, 4000, 4000, 0, 0, 2000, 3000 }; // daytime LED state
const int kNightState[] = { 0, 4, 45, 4, 2000, 0, 0, 4 }; // nighttime LED stat
const long kFadeDuration = 0;
long ctr;
int state_chan1, state_chan2, state_chan3, state_chan4, state_chan5, state_chan6, state_chan7, state_chan8;

Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
SoftwareSerial myserial(rxpin, txpin);
int DS18S20_Pin = 4;
OneWire ds(DS18S20_Pin);

int floatstate = 0;

long phReadInterval = 10000;
long previousMillisPH = 0;
int PHState = HIGH;
float PH_Val;

void fader(long start_time, const int start_state[], const int end_state[], int out[2]) {

float per_second_delta_0 = (float) (end_state[0]-start_state[0])/kFadeDuration;
float per_second_delta_1 = (float) (end_state[1]-start_state[1])/kFadeDuration;
float per_second_delta_2 = (float) (end_state[2]-start_state[2])/kFadeDuration;
float per_second_delta_3 = (float) (end_state[3]-start_state[3])/kFadeDuration;
float per_second_delta_4 = (float) (end_state[4]-start_state[4])/kFadeDuration;
float per_second_delta_5 = (float) (end_state[5]-start_state[5])/kFadeDuration;
float per_second_delta_6 = (float) (end_state[6]-start_state[6])/kFadeDuration;
float per_second_delta_7 = (float) (end_state[7]-start_state[7])/kFadeDuration;

long elapsed = ctr-start_time;

out[0] = start_state[0] + per_second_delta_0 * elapsed;
out[1] = start_state[1] + per_second_delta_1 * elapsed;
out[2] = start_state[2] + per_second_delta_2 * elapsed;
out[3] = start_state[3] + per_second_delta_3 * elapsed;
out[4] = start_state[4] + per_second_delta_4 * elapsed;
out[5] = start_state[5] + per_second_delta_5 * elapsed;
out[6] = start_state[6] + per_second_delta_6 * elapsed;
out[7] = start_state[7] + per_second_delta_7 * elapsed;
}

long seconds_since_midnight() {
DateTime now = RTC.now();
long hr = now.hour();
long min = now.minute();
long sec = now.second();
long total = hr * 3600 + min * 60 + sec;
return total;
}

void set_state(const int state[]) {
if (state[0] >= 0 && state[0] <= 4096) {
pwm.setPWM(0, 0, state[0]);
state_chan1 = state[0]; }
if (state[1] >= 0 && state[1] <= 4096) {
pwm.setPWM(1, 0, state[1]);
state_chan2 = state[1]; }
if (state[2] >= 0 && state[2] <= 4096) {
pwm.setPWM(2, 0, state[2]);
state_chan3 = state[2]; }
if (state[3] >= 0 && state[3] <= 4096) {
pwm.setPWM(3, 0, state[3]);
state_chan4 = state[3]; }
if (state[4] >= 0 && state[4] <= 4096) {
pwm.setPWM(4, 0, state[4]);
state_chan5 = state[4]; }
if (state[5] >= 0 && state[5] <= 4096) {
pwm.setPWM(5, 0, state[5]);
state_chan6 = state[5]; }
if (state[6] >= 0 && state[6] <= 4096) {
pwm.setPWM(6, 0, state[6]);
state_chan7 = state[6]; }
if (state[7] >= 0 && state[7] <= 4096) {
pwm.setPWM(7, 0, state[7]);
state_chan8 = state[7]; }
}

void determine_state() {
if ( ctr >= 0 && ctr < kTurnOn ) { // night
set_state(kNightState);
} else if ( ctr >= kTurnOn && ctr <= (kTurnOn+kFadeDuration) ) { // sunrise
int foo[2];
fader(kTurnOn, kNightState, kDayState, foo);
set_state(foo);
} else if ( ctr > (kTurnOn+kFadeDuration) && ctr < kTurnOff ) { // day
set_state(kDayState);
} else if ( ctr >= kTurnOff && ctr <= (kTurnOff+kFadeDuration) ) { // sunset
int foo[2];
fader(kTurnOff, kDayState, kNightState, foo);
set_state(foo);
} else if ( ctr > (kTurnOff+kFadeDuration) && ctr < 86400 ) { // night
set_state(kNightState);
}
}

float getTemp(){
//returns the temperature from one DS18S20 in DEG Celsius

byte data[12];
byte addr[8];

if ( !ds.search(addr)) {
//no more sensors on chain, reset search
ds.reset_search();
return -1000;
}

if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return -1000;
}

if ( addr[0] != 0x10 && addr[0] != 0x28) {
Serial.print("Device is not recognized");
return -1000;
}

ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end

byte present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad


for (int i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}

ds.reset_search();

byte MSB = data[1];
byte LSB = data[0];

float tempRead = ((MSB << 8) | LSB); //using two's compliment
float TemperatureSum = tempRead / 16;

return TemperatureSum;

}

void getPHvalue(){
unsigned long currentMillisPH = millis();

if(currentMillisPH - previousMillisPH > phReadInterval){
previousMillisPH = currentMillisPH;
if(PHState == HIGH){
PHState = LOW;
}
else {
PHState = HIGH;
myserial.print("r\r");
while(myserial.available() > 0){
PH_Val = myserial.parseFloat();
if(myserial.read() == '\r');
}
}
}
}

void setup() {
myserial.begin(38400);
RTC.begin();
lcd.begin(16,2);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, INPUT);
pwm.begin();
pwm.setPWMFreq(800);
ctr = seconds_since_midnight();
Serial.print(ctr);
}

void loop(){
ctr = seconds_since_midnight();
determine_state();
floatstate = digitalRead(7);
if (floatstate == HIGH) {
digitalWrite(6, HIGH);
delay(10000);
digitalWrite(6, LOW);
}
else {
digitalWrite(6, LOW);
}

if ( ctr >= 0 && ctr < 26000 ) {
lcd.setBacklight(OFF);
} if ( ctr >= 0 && ctr < kTurnOn ) {
digitalWrite(5, LOW);
} else if ( ctr > (kTurnOff+kFadeDuration) && ctr < 86400 ){
lcd.setBacklight(OFF);
digitalWrite(5, LOW);
}
else {
lcd.setBacklight(WHITE);
digitalWrite(5, HIGH);
}


DateTime now = RTC.now();
lcd.setCursor(0, 1);
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);

getPHvalue();
lcd.setCursor(0,0);
lcd.print("PH:");
lcd.print(PH_Val);

float temperature = getTemp();
lcd.setCursor(8,0);
lcd.print(temperature);
lcd.print("C");

delay(5000); //just here to slow down the output so it is easier to read

}

My apologies for the post length.
shrimper23 is offline   Reply With Quote
Old 12-01-2013, 09:23 PM   #162
Pady
Newbie
 
PTrader: (0/0%)
Join Date: Dec 2013
Location: Sweden
Posts: 2
Default

Hello all of you
First of all I would like to say big thanks to Sink and O2surplus and all you other guys :-)
You all helped me getting started with my LED controller Arduino.
I'll have to read it all again to understand how it really works...
I need to fix up 4 channels with different 100% brightness and sunrise/down and moon light. Also putting in and reading everything to my laptop.
Pady is offline   Reply With Quote
Old 12-03-2013, 06:17 PM   #163
TomLS
Newbie
 
PTrader: (0/0%)
Join Date: Dec 2013
Location: Portsmouth, UK
Posts: 2
Default

Oh, and its probably worth noting that I'm using the Nano V3 ATMega328 board, but from what I can tell it's functionally identical to the uno...

This is related to a post which is still apparently being moderated!...

Last edited by TomLS; 12-03-2013 at 07:37 PM.. Reason: related post in moderation
TomLS is offline   Reply With Quote
Old 12-07-2013, 09:59 AM   #164
TomLS
Newbie
 
PTrader: (0/0%)
Join Date: Dec 2013
Location: Portsmouth, UK
Posts: 2
Default

Okay, I have tried to make a long post on here twice now, regarding questions about the code, but apparently it still remains in moderation. How long does this usually take?!

In the meantime I have made some achievements based on this code, which I would like to give back to the community.
1) modified the libraries to make it fully compatible with IDE 1.0,
2) added temperature probe support,
3) added i2c LCD support,
4) split out the code to allow for different start times and durations for the fade of each channel.

I will attempt to post this up here in the next couple of days!
TomLS is offline   Reply With Quote
Old 04-09-2014, 02:01 PM   #165
O2surplus
Planted Tank Enthusiast
 
O2surplus's Avatar
 
PTrader: (4/100%)
Join Date: Jan 2010
Location: yorba linda, ca.
Posts: 591
Default

Hey everyone-

I'm no coding genius like "Sink" but I did manage to make his code compatible with Arduino 1.05 and add some new features. I've been using this version of the code to control the lighting on my tank fo a little over a week and it works great.

Note: If you already have the original Arduino 23 version of this code and want to upgrade to this one you'll need to update your libraries first and compile the code using Arduino 1.0. Updating the libraries is easy. Open each Library header file (.h) and add the following line of code to the beginning of the "define section".

Code:
#if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h"#endif
Here's what I added-

1.) I2C LCD supported. Time/Date/Temp/Dimming mode & fan control status are all displayed on the LCD.
2.) Dallas Temp support- Dallas OneWire DS18B20 Temp sensors are auto detected and the temperature is displayed to the LCD.
3.)Cooling fan control logic added in- Digital Pin#8 Turns on/off in accordance with the Led state.

Here's a photo of the Lcd -


Here's the modified code-
Code:
/*
 * Name:    tank-control.pde
 * Author:    User "sink" at plantedtank.net forums
 * URL:        http://bitbucket.org/akl/tank-control
 *
 * This is control code for an aquarium lighting system.  It is intended to be
 * run on an Arduino microcontroller board.  It allows independant
 * high-resolution control of two PWM outputs (normally connected to LED
 * drivers) and complete flexibility with respect to intensity, timing
 * schedules, and sunrise/sunset.
 *
 * This code requires the following libraries: Wire, TimerOne, Time, DS1307RTC
 *
 * The latest version of this code can always be found at above url.
 */

/*
 * Copyright (c) 2011, User "sink" at plantedtank.net forums
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.

 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.  
 */
/* NOTICE: 4/2/2014- Addtional support for I2C LCD & Dallas OneWire Temperature readout added by O2Surplus.
              The original Libraries used in this version of the code were updated for use with Arduino 1.5-r2.
              Please make sure to use the proper version of said libraries. */
              
#include <TimerOne.h>
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <OneWire.h> // added to original code by O2Surplus 4/2/2014
#include <LiquidCrystal_I2C.h>// added to original code by O2Surplus 4/2/2014

//LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

//Temperature chip i/o
int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2

OneWire ds(DS18S20_Pin);  // on digital pin 2

int fanEnable = 8;// assigns cooling fan ON/OFF control to digital pin 8.

/*
 * IMPORTANT:  These *must* be the pins corresponding to the Timer1 timer on
 * the ATmega168/328.  These are digital pins 9 and 10 on the Uno/Duemilanove.
 */
const int kChan0Pin = 9; // Channel 0 Pin
const int kChan1Pin = 10; // Channel 1 Pin

// All times are in seconds since midnight (valid 0 - 86399)
const long kTurnOn = 32400; // time dawn begins - 0900hrs
const long kTurnOff = 75600; // time sunset begins - 2100hrs

/*
 * Light "state" represents the PWM duty cycle for each channel This normally
 * dictates light intensity. It is an array { duty_chan_1, duty_chan_2 }.
 * Possible values for duty cycle are 0 - 1023.
 */
const int kDayState[] = { 1023,1023 }; // daytime LED state
const int kNightState[] = { 0, 0 }; // nighttime LED state

// duration (in seconds) of sunrise/sunset fade
const long kFadeDuration = 3600; // 60 minutes

long ctr;

/*
 * fader -- Determine output state for a given time to provide smooth fade from
 * one state to another.
 *     Args:
 *     start_time  -- time (in seconds) of start of fade
 *     start_state -- beginning state
 *     end_state   -- ending state
 *     out         -- array to update with state
 */
void fader(long start_time, const int start_state[], const int end_state[], int out[2]) {

  float per_second_delta_0 = (float) (end_state[0]-start_state[0])/kFadeDuration;
  float per_second_delta_1 = (float) (end_state[1]-start_state[1])/kFadeDuration;

  long elapsed = ctr-start_time;

  out[0] = start_state[0] + per_second_delta_0 * elapsed;
  out[1] = start_state[1] + per_second_delta_1 * elapsed;
}

// return seconds elapsed since midnight
long seconds_since_midnight() {
  time_t t = now();
  long hr = hour(t);
  long min = minute(t);
  long sec = second(t);
  long total = hr * 3600 + min * 60 + sec;
  return total;
}

// set output state
void set_state(const int state[]) {
  if (state[0] >= 0 && state[0] <= 1023) Timer1.setPwmDuty(kChan0Pin, state[0]);
  if (state[1] >= 0 && state[1] <= 1023) Timer1.setPwmDuty(kChan1Pin, state[1]);
}

/*
 * determine_state -- This is where the actual timing logic resides.  We
 * examine ctr (seconds since midnight) and then set output state accordingly.
 * Variable ctr rolls back to 0 at midnight so stages that cross midnight (ie:
 * nighttime) are broken up into two stages.
 */
void determine_state() {
  if ( ctr >= 0 && ctr < kTurnOn ) { // night
      set_state(kNightState);
      
      lcd.setCursor(0,2);
      //lcd.print("                   ");
      lcd.setCursor(5,2);
      lcd.print("NIGHT/MODE");         // LCD coding added by O2Surplus 4/2/2014
      digitalWrite(fanEnable,LOW);
      lcd.setCursor(6,3);
      lcd.print("FANS-OFF");
      
  } else if ( ctr >= kTurnOn && ctr <= (kTurnOn+kFadeDuration) ) { // sunrise
    int foo[2];
    fader(kTurnOn, kNightState, kDayState, foo);
    set_state(foo);
      
      lcd.setCursor(0,2);
      //lcd.print("                   ");
      lcd.setCursor(3,2);
      lcd.print("SUNRISE/MODE");              // LCD coding added by O2Surplus 4/2/2014
      digitalWrite(fanEnable, HIGH);
      lcd.setCursor(7,3);
      lcd.print("FAN-ON");
  } else if ( ctr > (kTurnOn+kFadeDuration) && ctr < kTurnOff ) { // day
    set_state(kDayState);
      
      lcd.setCursor(0,2);
      //lcd.print("                   ");
      lcd.setCursor(5,2);             
      lcd.print("DAY/MODE");              // LCD coding added by O2Surplus 4/2/2014
      digitalWrite(fanEnable, HIGH);
      lcd.setCursor(7,3);
      lcd.print("FAN-ON");
  } else if ( ctr >= kTurnOff && ctr <= (kTurnOff+kFadeDuration) ) { // sunset
    int foo[2];
    fader(kTurnOff, kDayState, kNightState, foo);
    set_state(foo);
      lcd.setCursor(0,2);
      //lcd.print("                   ");
      lcd.setCursor(5,2);
      lcd.print("SUNSET/MODE");              // LCD coding added by O2Surplus 4/2/2014
      //lcd.setCursor(11,2);
      //lcd.print("  ");
      digitalWrite(fanEnable, HIGH);
      lcd.setCursor(7,3);
      lcd.print("FAN-ON");
  } else if ( ctr > (kTurnOff+kFadeDuration) && ctr < 86400 ) { // night
    set_state(kNightState);
      lcd.setCursor(0,2);
      //lcd.print("                   ");
      lcd.setCursor(5,2);
      lcd.print("NIGHT/MODE");          // LCD coding added by O2Surplus 4/2/2014
      digitalWrite(fanEnable,LOW);
      lcd.setCursor(6,3);
      lcd.print("FANS-OFF");
  }
}

/*
 * Utility function for pretty digital clock time output
 * From example code in Time library -- author unknown
 */
void printDigits(int digits) {
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
 
}
void displayDigits(int digits) {
  lcd.print(":");
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits);
  
}

/*
 * Display time
 * Adapted from example code in Time library -- author unknown
 */
void digitalClockDisplay() {
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(month());
  Serial.print("/");
  Serial.print(day());
  Serial.print("/");
  Serial.print(year()); 
  Serial.println(); 
}
void lcdClockDisplay() {
  lcd.setCursor(0,0);
  lcd.print(hour());
  displayDigits(minute());
  displayDigits(second());
  lcd.print("  ");
  lcd.print(month());
  lcd.print("/");
  lcd.print(day());
  lcd.print("/");
  lcd.print(year()); 
   
}
void setup() {
  Serial.begin(115200); // Max for Arduino Uno
  setSyncProvider(RTC.get);
  setSyncInterval(120);
  Wire.begin();
  lcd.begin(20,4);         // initialize the lcd for 20 chars 4 lines and turn on backlight
  Timer1.initialize(6666); // 150Hz PWM
  pinMode(kChan0Pin, OUTPUT);     
  Timer1.pwm(kChan0Pin, 0);
  pinMode(kChan1Pin, OUTPUT);     
  Timer1.pwm(kChan1Pin, 0);
  pinMode(fanEnable,OUTPUT);   // Fan control coding added by O2Surplus 4/2/2014
}

void loop () {
  float temperature = getTemp();// Temperature serial display coding addded by O2Suplus 4/2/2014
  Serial.println(temperature);
  ctr = seconds_since_midnight();// Original code
 
  lcd.setCursor(0,1);          // Temperature to I2C LCD added by O2Surplus 4/2/2014
  lcd.print("Temp C = ");
  lcd.print(temperature);
 
  determine_state();// Original code
  Serial.print("ctr: ");
  Serial.print(ctr); // display counter
  Serial.println();
  digitalClockDisplay(); //display time
  Serial.println();
  lcd.setCursor(0,0); //Time/Date to I2C display added 4/2/2014 by O2Surplus
  lcd.println();
  lcdClockDisplay();
 
   

  
  delay(1000); // no need to do anything until next second
}// Original Code ends here.


float getTemp(){
  //returns the temperature from one DS18S20 in DEG Celsius // Added by O2Suplus 4/2/2014

  byte data[12];
  byte addr[8];

  if ( !ds.search(addr)) {
      //no more sensors on chain, reset search
      ds.reset_search();
      return -1000;
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return -1000;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28) {
      Serial.print("Device is not recognized");
      return -1000;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end

  byte present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE); // Read Scratchpad

  
  for (int i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
  }
  
  ds.reset_search();
  
  byte MSB = data[1];
  byte LSB = data[0];

  float tempRead = ((MSB << 8) | LSB); //using two's compliment
  float TemperatureSum = tempRead / 16;
  
  return TemperatureSum;
  
}
__________________
225 Gal, Glass "Reef Ready" w/ twin Iwaki Pumps & 2 Ocean Clear inline filters. Custom 320 watt LED Lighting system utilizing a 6' Maker's Heat Sink, 12 BridgeLux Vero 18's,3 purpose built 5 channel A6211 Led driver/Controllers, and a 20lb CO2 system w/ Milwaukee Ph Controller.
O2surplus is offline   Reply With Quote
Reply

Thread Tools
Display Modes

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 Off

Forum Jump


All times are GMT. The time now is 11:21 PM.


Powered by vBulletin®
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Copyright Planted Tank LLC 2012