Arduino sketches

I basically only have ~100 to 255. So frustrating!
I don't have the voltage, but mine cuts off at about 25-27 or so I think. Thats even way to bright for moon lights.

Have you tested each channel individually? I know my first shield started doing funky things on 2 channels. I have the parts to fix it, but haven't yet since I got the 8 channel shield in.

If you want I have some chips that will give you a true 10V (9.98 I think it was.) If you want I will throw one in the mail for you. They were given to me, so I don't mind passing one on if you think it will help.
PM me your address.
This is what I have. Same as a LM circuit, but all in 1 package. 12V or whatever in, shared GNDs, then 10V out. Easy cheesy.

Edit again: Run the All On sketch and measure each channel, individually, and post back.
 
Last edited:
I don't have the voltage, but mine cuts off at about 25-27 or so I think. Thats even way to bright for moon lights.

Have you tested each channel individually? I know my first shield started doing funky things on 2 channels. I have the parts to fix it, but haven't yet since I got the 8 channel shield in.

If you want I have some chips that will give you a true 10V (9.98 I think it was.) If you want I will throw one in the mail for you. They were given to me, so I don't mind passing one on if you think it will help.
PM me your address.
This is what I have. Same as a LM circuit, but all in 1 package. 12V or whatever in, shared GNDs, then 10V out. Easy cheesy.

Edit again: Run the All On sketch and measure each channel, individually, and post back.

I have it working for now. The link you gave was what I already have, thanks for offering though!

I ran your cloud sketch on the first page and it seemed to work pretty well, but like you, my LEDs just don't get dim enough. There's got to be a way around this cause I can dim my Christmas LEDs way down.

Is it just the drivers we use?


A friend suggested that I add some cheap orange or yellow LEDs in my setup to have on during sunrises and sunsets. Has anyone heard of someone doing this or see it? It'll be really cheap to try at least.
 
This one needs a tiny bit of polishing,
when it prints the % it needs the cursor to be set and maybe set a condition to set where the % is since there is a tiny bug of where it is.
This is the simple menu options,
just uses the number of lines and you shift around and can change their values.
Next I'll have it jump when you hit the end of the first lines/set of options since scrolling one by one is a pain to code and is rather confusing with too much movement.
Hopefully this isn't bloated or crude,
I tried to clean it up without going crazy.
Plus I'll have my final multi menu sketch that should be very clean and should be without any obvious bugs.

This one is very easy to hack for however many numbers of lines your LCD has.
But I need like 15 options and I don't want a mega sized text based LCD,
so I need a slightly more complex sketch...
I'll also if anybody wants a under the hood sketch that interfaces with the UI sketch and actually gets stuff done, converts the UI to what it needs and such......


Code:
/*

 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 25 July 2009
 by David A. Mellis
 
 
 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 
byte block[8] = { //creates the solid block charcter 
	B11111,
	B11111,
	B11111,
	B11111,
	B11111,
	B11111,
	B11111,
	B11111
};



const int buttonPinUp = 9;     // the number of the up pushbutton to pin 7
const int buttonPinDown = 10;    // the number of the down pushbutton to pin 8
const int buttonPinLeft = 7;     // the number of the left pushbutton to pin 9
const int buttonPinRight = 8;     // the number of the right pushbutton to pin 10

int buttonStateUp = 0;         // variable for reading the Uppushbutton status
int buttonStateDown = 0;         // variable for reading the Downpushbutton status
int buttonStateLeft = 0;         // variable for reading the leftpushbutton status
int buttonStateRight = 0;         // variable for reading the rightpushbutton status
int Xaxis = 0; //the interger to hold the x axis status for up and down buttons
int Yaxis = 0;  //the interger to hold the y axis status for left and right buttons
int LED = 0; //variable to hold for PWM for LED bank0
int LED1 = 0; //variable to hold for PWM for LED bank1 
int LED2 = 0; //variable to hold for PWM for LED bank2 
int LED3 = 0; //variable to hold for PWM for LED bank3 

int ListEnd = 4; //when to loop back
void setup() {
  // set up the LCD's number of rows and columns: 
  lcd.createChar(0, block); //creates the block charcter
  lcd.begin(20, 4);
  // Print a message to the LCD.
  pinMode(buttonPinUp, INPUT);     //the Up button pin is input
  pinMode(buttonPinDown, INPUT);     //the Down button pin is input
  pinMode(buttonPinLeft, INPUT);     //the Up button pin is input
  pinMode(buttonPinRight, INPUT);     //the Down button pin is input
  
  
}

void loop() {
  Serial.print (Xaxis);
    lcd.setCursor(0 , 0);
   buttonStateDown = digitalRead(buttonPinDown); //writes the button state to their respective interger
   buttonStateUp = digitalRead(buttonPinUp); //writes the button state to their respective interger
   buttonStateRight = digitalRead(buttonPinRight); //writes the button state to their respective interger
   buttonStateLeft = digitalRead(buttonPinLeft); //writes the button state to their respective interger
  
  
  //////////////////////////////////////////Button and State Change////////////////////////////
if (buttonStateUp == HIGH) { //records the up button press    
     (Xaxis = Xaxis - 1);  //takes 1 from the Xaxis state
      delay (60); //delay so that a ton of button presses happen in one intended pressing
    }; 

if (buttonStateDown == HIGH) {   //records the down buttons press  
      (Xaxis = Xaxis + 1);   //adds 1 to the Xaxis state
      delay (60); //delay so that a ton of button presses happen in one intended pressing
    }; 
    
    if (buttonStateLeft == HIGH) {   //records the left buttons press  
     (Yaxis = Yaxis - 1);  //takes 1 from the Yaxis state
      delay (60); //delay so that a ton of button presses happen in one intended pressing
    }; 

if (buttonStateRight == HIGH) {     //records the right buttons press  
      (Yaxis = Yaxis + 1);  //adds 1 to the Yaxis state
      delay (60); //delay so that a ton of button presses happen in one intended pressing
    }; 
    
    
    
    /////XAxis Positioning
   if (Xaxis >= ListEnd) { //if you gone to the end of the list loop it back. Uses ListEnd to determine.
     (Xaxis = 0);
     lcd.clear(); //Clears LCD
 };
   if (Xaxis <= -1) { //if you went past to the start of the list, loop it back. Uses ListEnd to determine.
      lcd.clear(); //Clears LCD
     (Xaxis = 3); //if you go past the start then loop the cursor to the end
   };
   /////YAxis Positioning.
   if (Yaxis >= 21) { //if you gone to the end of the list loop it back. 
     (Yaxis = 0);
     lcd.clear();};//Clears LCD
   if (Yaxis <= -1) { //if you went past to the start of the list, loop it back. 
     (Yaxis = 20 );
     lcd.clear();//Clears LCD
   };
   
   ////////////////////////////////////Scroll Menus//////////////////////////////////////////////////
   
     //////////////////menu 0


    lcd.setCursor(0 , 0); //Sets the cursor to where it needs so that the menu can be printed
    if (Xaxis == 0) { //if your on the right line make valuechanger equate led value
      lcd.write(0); //print the indicator that's at the start of the menu
   if (buttonStateRight == HIGH) { //adds to LED and changes it's value
     (LED = LED + 1 );};
     
     if (buttonStateLeft == HIGH) { //takes from LED changes it's values
     (LED = LED - 1 );};
     
   if (LED >= 101) { //caps LED Value
     (LED = 0);};
   
      if (LED <= -1) { //caps LED Value
     (LED = 100);};} 
  if (Xaxis != 0){ //if your not on the right value of Y axis
  lcd.print (" ");}; //print a blank space
  lcd.print("#0 " ); //then print as usual
  lcd.print(LED); //then print as usual
  lcd.print(" %" ); //then print as usual
//////////////////menu 1


    lcd.setCursor(0 , 1); //Sets the cursor to where it needs so that the menu can be printed
    if (Xaxis == 1) { //if your on the right line make valuechanger equate led value
      lcd.write(0); //print the indicator that's at the start of the menu
   if (buttonStateRight == HIGH) { //adds to LED and changes it's value
     (LED1 = LED1 + 1 );};
     
     if (buttonStateLeft == HIGH) { //takes from LED changes it's values
     (LED1 = LED1 - 1 );};
     
   if (LED1 >= 101) { //caps LED Value
     (LED1 = 0);};
   
      if (LED1 <= -1) { //caps LED Value
     (LED1 = 100);};} 
  if (Xaxis != 1){ //if your not on the right value of Y axis
  lcd.print (" ");}; //print a blank space
  lcd.print("#1 " ); //then print as usual
  lcd.print(LED1); //then print as usual
  lcd.print(" %" ); //then print as usual   
//////////////////menu 2


    lcd.setCursor(0 , 2); //Sets the cursor to where it needs so that the menu can be printed
    if (Xaxis == 2) { //if your on the right line make valuechanger equate led value
      lcd.write(0); //print the indicator that's at the start of the menu
   if (buttonStateRight == HIGH) { //adds to LED and changes it's value
     (LED2 = LED2 + 1 );};
     
     if (buttonStateLeft == HIGH) { //takes from LED changes it's values
     (LED2 = LED2 - 1 );};
     
   if (LED2 >= 101) { //caps LED Value
     (LED2 = 0);};
   
      if (LED2 <= -1) { //caps LED Value
     (LED2 = 100);};} 
  if (Xaxis != 2){ //if your not on the right value of Y axis
  lcd.print (" ");}; //print a blank space
  lcd.print("#2 " ); //then print as usual
  lcd.print(LED2); //then print as usual
  lcd.print(" %" ); //then print as usual  
  
  
//////////////////menu 3
    lcd.setCursor(0 , 3); //Sets the cursor to where it needs so that the menu can be printed
    if (Xaxis == 3) { //if your on the right line make valuechanger equate led value
      lcd.write(0); //print the indicator that's at the start of the menu
   if (buttonStateRight == HIGH) { //adds to LED and changes it's value
     (LED3 = LED3 + 1 );};
     
     if (buttonStateLeft == HIGH) { //takes from LED changes it's values
     (LED3 = LED3 - 1 );};
     
   if (LED3 >= 101) { //caps LED Value
     (LED3 = 0);};
   
      if (LED3 <= -1) { //caps LED Value
     (LED3 = 100);};} 
  if (Xaxis != 3){ //if your not on the right value of Y axis
  lcd.print (" ");}; //print a blank space
  lcd.print("#3 " ); //then print as usual
  lcd.print(LED3); //then print as usual
  lcd.print(" %" ); //then print as usual  
  

  
  
  
  
  
  
  }
 
Last edited:
That's likely inherent to the LED driver you're using, unfortunately. IMHO the best solution in your case would be to do a small dedicated moonlight array - it could even just be common "gumdrop" LEDs, a wall wart, and a resistor. You could put a transistor in the string and drive it from an Arduino pin if you wanted to dim to simulate moon cycles. I just don't think a typical string of HP LEDs will get dim enough, unless on a very large tank with a driver that can go down to 1%.

Is it just the drivers we use?

This is what DZW said about dimming down far enough to use these LEDs as moon lights. They just wont go low enough. I guess its like trying to cruise with a 1000hp dragster motor. Maybe.
I have 2 white LEDs left over, I may try to use them for something.
 
I pulled out those circular 8 white LED PCB combo things(heck the flashlights are so cheap just buy a flashlight), I yanked off the spring, soldered on some wires and now they will be my moonlights since most LED drivers can dim them...
The CAT4101's are so cheap I'm going to use one just for moonlights,
and for the PSU a cellphone charger should suffice.
 
Ok here is what I am using. I cannot for the life of me figure out how the ramp up and down work, nor could I figure out how parts of the other sketches work. This was my first run at doing a controller for my leds and tank. I did not want to use a RTC yet, so I just used the TIME lib that was at arduino.cc. But I would like for the leds to ramp up and down. On my display, I have a max setting for the blues and whites that work now. And I can ramp up and down the setting there. Just need to figure out how to do that.
Code:
#include <Time.h>
#include <LiquidCrystal.h>


LiquidCrystal lcd( 8, 9, 4, 5, 6, 7);

int bluestart = 450;
int whitestart = 480;
int whiteoff = 1080;
int blueoff = 1110;
int minCounter = 0;
int setit = 0;      //for setting the time and date button  
int houree = 0;    //hour var
int minuteee = 0;    //minute var
int secondee = 0;    //second var  
int dayee = 12;      //day var
int monthee = 12;    //month var
int yearee = 2010;    //year var
int analogPin = 0;     // voltage divider network on pin analog 0
int val = 0;           // where it will store the input
int setpoint = 250;      // trying to get a setpoint for temp control
int screencontrol = 0;  //screen control value 
int blueval = 50;    //default setting for lights
int whiteval = 50;    //default setting for lights
int lowater = 2;      // low water setpoint
int fillpump = 4;    //highwater setpoint
int whiteled = 3;     //output for lights
int blueled = 11;      //output for lights
int tanktemp = 78;      //when the temp can be used  
//int lightset = 0;    //no longer needed
int blueval5 = 0;
int whiteval5 = 0;
int blueval4 = 0;
int blueval3 = 0;
int timeingset = 0;

void setup()
{
  lcd.begin(20, 2);
  Serial.begin(9600);          //  setup serial, and testing for me.
  pinMode(whiteled, OUTPUT);    //pwm for lights (white)
  pinMode(blueled, OUTPUT);    //pwm for lights (blue)
}
//                                                clock
void loop() 
{
  lcd.setCursor(0,0);
  printDigits(hour());
  printDigits(minute());
  printDigits(second());

  //--------------------------------------------------------------------------------
  //                    setting up buttons to do things 
  val = analogRead(analogPin);  // read the input pin
  val = map(val, 0, 1023, 0, 50); //remapped the value for the smokers temp probe
  //delay(100);
  if (val == 6) setpoint++;
  if (val == 15) setpoint--;
  if (val == 23) screencontrol++;
  delay(100);
  //-------------------------------------------------------------------------------  
  if (screencontrol == 5) screencontrol=0;//controlls what screen you will be using and the 
  switch (screencontrol) {                 //what the setpoint key will adjust. 
    //--------------------blue values------------------------------------------------
  case 0:
    lcd.setCursor(0,1);
    lcd.print("                ");
    lcd.setCursor(0,1);
    break;
  case 1:
    lcd.setCursor(0,1);
    lcd.print("                ");
    lcd.setCursor(0,1);       
    lcd.print("blue led     ");

    lcd.setCursor(14,1);
    lcd.print(blueval);
    if (val == 6) blueval++;
    if (val == 15) blueval--;
    if (blueval <= 9) blueval = 10;
    if (blueval >= 100) blueval = 100;
    delay(100);       
    break;
    //----------------------------------------------------------------------------
    //---------------------white values---------------------------------------------
  case 2:
    lcd.setCursor(0,1);
    lcd.print("white led    ");
    lcd.setCursor(14,1);
    lcd.print(whiteval);
    if (val == 6) whiteval++;
    if (val == 15) whiteval--;
    if (whiteval <= 10) whiteval =10;
    if (whiteval >= 100) whiteval = 0;
    delay(100);
    break;
    //-------------------------------------------------------------------------------    
    //-----------------------------tank temps----------------------------------------  
  case 3:
    lcd.setCursor(0,1);
    lcd.print("tank temp       ");
    break;
    //------------------------------------------------------------------------------    
    //------------------------setting the clock-------------------------------------  
  case 4:
    if (val == 0) setit ++;
    if (setit >= 3) setit = 0;
    if (val == 35) setTime(houree,minuteee,00,3,8,2010);
    //if (val == 35) lcd.print("set date and time");
    switch (setit){
    case 0:
      lcd.setCursor(0,1);
      lcd.print("                ");
      lcd.setCursor(0,1);
      lcd.print("HOUR  ");
      lcd.setCursor(7,1);
      lcd.print(    houree    );
      if (val == 6) ++houree;
      if (val == 15) --houree;
      if (houree >= 23) houree = 23;
      if (houree <= 00) houree = 00;
      break;
    case 1:
      lcd.setCursor(0,1);
      lcd.print("                ");
      lcd.setCursor(0,1);
      lcd.print("min.  ");
      lcd.setCursor(7,1);
      lcd.print(minuteee);
      if (val == 6) minuteee++;
      if (val == 15) minuteee--;
      if (minuteee >= 59) minuteee = 59;
      if (minuteee <= 00) minuteee = 00;
    }
    blueval5 = map(blueval, 10, 100, 0, 254);
    whiteval5 = map(whiteval, 10, 100, 0, 254);
    if (minCounter > bluestart && minCounter < blueoff) 
    {
      analogWrite(blueled, blueval5);
    }
    else
    {
      analogWrite(blueled, 0);
    }
    if (minCounter > whitestart && minCounter < whiteoff) 
    {
      analogWrite(whiteled, whiteval5);
    }
    else
    {
      analogWrite(whiteled, 0);
    }

  }
  lcd.setCursor(10,0);
  lcd.print(minCounter);
  minCounter = hour() * 60 + minute();
  lcd.setCursor(13,0);
  lcd.print(val);
  //--------------------------light on timer----------------------------------------------
}
void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  lcd.print(":");
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits);
}
 
goldenfamaliy,
First it looks like you have two empty includes on the top so something is probably missing there.

The portion that actually sets the pins for the LEDs( from blueval5 = map(blueval, 10, 100, 0, 254) to the end of the switch block) is under case 4 (setting the clock) in the switch statement. My guess is you want to take it out of there and put it after the outer switch block (right above lcd.setCursor(10,0) )

As long as your input device works (you can move screens etc) once you move the led setting code outside the clock setup you should be good.

The way it is right now, you have to go to the clock setup screen in order for your LED settings to take effect.

THz
 
FWIW I've started work on a first draft of code for the Typhon controller.

This is the "integrated" Arduino with RTC, LCD header, and transistors to drive Meanwells all on one board. The sketch provides a menu system to set various parameters for each channel of LEDs, plus allows you to set the time for the RTC (so you don't have to screw around with running special code to set the RTC).

It's poorly organized at best and definitely a work in progress. The entire menu structure could probably be replaced with a loop and an array, but for now I just wanted to get it running. I'm also planning on storing the various parameters in EEPROM so they're not erased when the device power cycles.

This is "sort of" based on the code I've posted before in this thread, but I modified the setLed() function to return the value that the LED channel is set to - this way, it's available elsewhere in the program. For instance, if you want to display it on the LCD (which this sketch does - the "default" screen for the LCD displays current time and the current value for each LED channel).

Here it is:

Code:
/*
// Typhon firmware
// v0.1 alpha 2010-08-06
// N. Enders
//
// This sketch provides firmware for the Typhon LED controller.
// It provides a structure to fade 4 independent channels of LED lighting
// on and off each day, to simulate sunrise and sunset.
//
// Current work in progress:
// - store all LED variables in EEPROM so they are not reset by a loss of power
//
// Future developments may include:
// - moon phase simulation
// - storm simulation
// 
// Sketch developed in Arduino-18
// Requires LiquidCrystal, Wire, and Button libraries.
// Button is available here: http://www.arduino.cc/playground/Code/Button
 */

// include the libraries:
#include <LiquidCrystal.h>
#include "Wire.h"
#include <Button.h>



/**** Define Variables & Constants ****/
/**************************************/

// set the RTC's I2C address
#define DS1307_I2C_ADDRESS 0x68
// create the LCD
LiquidCrystal lcd(8, 7, 5, 4, 16, 2);
// define pin for backlight
int bkl         = 6;
// create the menu counter
int menuCount   = 1;
// create the buttons
Button menu     = Button(12,PULLDOWN);
Button select   = Button(13,PULLDOWN);
Button plus     = Button(14,PULLDOWN);
Button minus    = Button(15,PULLDOWN);

// LED variables. These control the behavior of lighting. Change these to customize behavoir
int minCounter = 0;         // counter that resets at midnight. Don't change this.
int oneLed = 9;             // pin for channel 1
int twoLed = 10;            // pin for channel 2
int threeLed = 11;          // pin for channel 3
int fourLed = 2;            // pin for channel 4

int oneVal = 0;             // current value for channel 1
int twoVal = 0;             // current value for channel 2
int threeVal = 0;           // current value for channel 3
int fourVal = 0;            // current value for channel 4

int oneStartMins = 480;     // minute to start blues. Change this to the number of minutes past
                            //    midnight you want the blues to start.
int onePhotoPeriod = 510;   // photoperiod in minutes, blues. Change this to alter the total
                            //    photoperiod for blues.
int oneMax = 255;           // max intensity for whites. Same as above.
int oneFadeDuration = 60;   // duration of the fade on and off for sunrise and sunset. Change
                            //    this to alter how long the fade lasts.

int twoStartMins = 480;     // minute to start blues. Change this to the number of minutes past
                            //    midnight you want the blues to start.
int twoPhotoPeriod = 510;   // photoperiod in minutes, blues. Change this to alter the total
                            //    photoperiod for blues.
int twoMax = 255;           // max intensity for whites. Same as above.
int twoFadeDuration = 60;   // duration of the fade on and off for sunrise and sunset. Change
                            //    this to alter how long the fade lasts.

int threeStartMins = 480;   // minute to start blues. Change this to the number of minutes past
                            //    midnight you want the blues to start.
int threePhotoPeriod = 510; // photoperiod in minutes, blues. Change this to alter the total
                            //    photoperiod for blues.
int threeMax = 255;         // max intensity for whites. Same as above.
int threeFadeDuration = 60; // duration of the fade on and off for sunrise and sunset. Change
                            //    this to alter how long the fade lasts.
                            
int fourStartMins = 480;    // minute to start blues. Change this to the number of minutes past
                            //    midnight you want the blues to start.
int fourPhotoPeriod = 510;  // photoperiod in minutes, blues. Change this to alter the total
                            //    photoperiod for blues.
int fourMax = 255;          // max intensity for whites. Same as above.
int fourFadeDuration = 60;  // duration of the fade on and off for sunrise and sunset. Change
                            //    this to alter how long the fade lasts.                            




/****** RTC Functions ******/
/***************************/

// Convert decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

// Sets date and time, starts the clock
void setDate(byte second,        // 0-59
             byte minute,        // 0-59
             byte hour,          // 1-23
             byte dayOfWeek,     // 1-7
             byte dayOfMonth,    // 1-31
             byte month,         // 1-12
             byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.send(0);
   Wire.send(decToBcd(second));
   Wire.send(decToBcd(minute));
   Wire.send(decToBcd(hour));
   Wire.send(decToBcd(dayOfWeek));
   Wire.send(decToBcd(dayOfMonth));
   Wire.send(decToBcd(month));
   Wire.send(decToBcd(year));
   Wire.endTransmission();
}

// Gets the date and time
void getDate(byte *second,
             byte *minute,
             byte *hour,
             byte *dayOfWeek,
             byte *dayOfMonth,
             byte *month,
             byte *year)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  *second     = bcdToDec(Wire.receive() & 0x7f);
  *minute     = bcdToDec(Wire.receive());
  *hour       = bcdToDec(Wire.receive() & 0x3f);
  *dayOfWeek  = bcdToDec(Wire.receive());
  *dayOfMonth = bcdToDec(Wire.receive());
  *month      = bcdToDec(Wire.receive());
  *year       = bcdToDec(Wire.receive());
}

/****** LED Functions ******/
/***************************/
//function to set LED brightness according to time of day
//function has three equal phases - ramp up, hold, and ramp down
int   setLed(int mins,    // current time in minutes
            int ledPin,  // pin for this channel of LEDs
            int start,   // start time for this channel of LEDs
            int period,  // photoperiod for this channel of LEDs
            int fade,    // fade duration for this channel of LEDs
            int ledMax   // max value for this channel
            )  {
  int val = 0;
  if (mins <= start || mins > start + period)  {
    val = 0;
  }
  if (mins > start && mins <= start + fade)  {
    val = map(mins - start, 0, fade, 0, ledMax);
  }
  if (mins > start + fade && mins <= start + period - fade)  {
    val = ledMax;
  }
  if (mins > start + period - fade && mins <= start + period)  {
    val = map(mins - (start + period - fade), 0, fade, ledMax, 0);
  }
  analogWrite(ledPin, val);
  return val;
}

/**** Display Functions ****/
/***************************/
void printMins(int mins,       //time in minutes to print
               boolean ampm    //print am/pm?
              )  {
  int hr = mins/60;
  int mn = mins%60;
  if(hr<13){
    if(hr<10){
      lcd.print(" ");
    }
    lcd.print(hr);
    lcd.print(":");
    if(mn<10){
      lcd.print("0");
    }
    lcd.print(mn);
    if(ampm){
      lcd.print(" AM");
    }
  } else {
    if(hr<22){
      lcd.print(" ");
    }
    lcd.print(hr-12);
    lcd.print(":");
    if(mn<10){
      lcd.print("0");
    }
    lcd.print(mn);
    if(ampm){
      lcd.print(" PM");
    }
  }
}

void printHMS (byte hr,
               byte mn,
               byte sec      //time to print
              )  {
  if(hr<13){
    if(hr<10){
      lcd.print(" ");
    }
    lcd.print(hr, DEC);
    lcd.print(":");
    if(mn<10){
      lcd.print("0");
    }
    lcd.print(mn, DEC);
    lcd.print(":");
    if(sec<10){
      lcd.print("0");
    }
    lcd.print(sec, DEC);
    lcd.print(" AM");
  } else {
    if(hr<22){
      lcd.print(" ");
    }
    lcd.print(hr-12, DEC);
    lcd.print(":");
    if(mn<10){
      lcd.print("0");
    }
    lcd.print(mn, DEC);
    lcd.print(":");
    if(sec<10){
      lcd.print("0");
    }
    lcd.print(sec, DEC);
    lcd.print(" PM");
  }
}



/**** Setup ****/
/***************/

void setup() {
  Wire.begin();
  // set up the LCD's number of rows and columns: 
  pinMode(bkl, OUTPUT);
  digitalWrite(6, HIGH);
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("This is Typhon!!!");
  delay(1000);
  lcd.clear();
  //setDate(1, 15, 11, 5, 5, 8, 10);
}

/***** Loop *****/
/****************/

void loop() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  getDate(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  minCounter = hour * 60 + minute;

  //set outputs
  oneVal = setLed(minCounter, oneLed, oneStartMins, onePhotoPeriod, oneFadeDuration, oneMax);
  twoVal = setLed(minCounter, twoLed, twoStartMins, twoPhotoPeriod, twoFadeDuration, twoMax);
  threeVal = setLed(minCounter, threeLed, threeStartMins, threePhotoPeriod, threeFadeDuration, threeMax);
  fourVal = setLed(minCounter, fourLed, fourStartMins, fourPhotoPeriod, fourFadeDuration, fourMax);
  

  //iterate through the menus
  if(menu.uniquePress()){
    if(menuCount < 19){
      menuCount++;
    }else {
      menuCount = 1;
    }
  lcd.clear();
  }
  if(menuCount == 1){
    //main screen turn on!!!
    lcd.setCursor(0,0);
    printHMS(hour, minute, second);
    lcd.setCursor(0,1);
    lcd.print(oneVal);
    lcd.print(" ");
    lcd.print(twoVal);
    lcd.print(" ");
    lcd.print(threeVal);
    lcd.print(" ");
    lcd.print(fourVal);
  }

  if(menuCount == 2){
    //set start time for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 Start");
    lcd.setCursor(0,1);
    printMins(oneStartMins, true);
    if(plus.uniquePress() && oneStartMins < 1440){
      oneStartMins++;
    }
    if(minus.uniquePress() && oneStartMins > 0){
      oneStartMins--;
    }
  }

  if(menuCount == 3){
    //set end time for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 End");
    lcd.setCursor(0,1);
    printMins(oneStartMins+onePhotoPeriod, true);
    if(plus.uniquePress() && onePhotoPeriod < 1440 - oneStartMins){
      onePhotoPeriod++;
    }
    if(minus.uniquePress() && onePhotoPeriod > 0){
      onePhotoPeriod--;
    }
  }

  if(menuCount == 4){
    //set fade duration for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 Fade");
    lcd.setCursor(0,1);
    printMins(oneFadeDuration, false);
    if(plus.uniquePress() && oneFadeDuration > onePhotoPeriod/2){
      oneFadeDuration++;
    }
    if(minus.uniquePress() && oneFadeDuration > 0){
      oneFadeDuration--;
    }
  }

  if(menuCount == 5){
    //set intensity for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 Max");
    lcd.setCursor(1,1);
    lcd.print(oneMax);
    if(plus.uniquePress() && oneMax < 255){
      oneMax++;
    }
    if(minus.uniquePress() && oneMax > 0){
      oneMax--;
    }
  }

  if(menuCount == 6){
    //set start time for channel two
    lcd.setCursor(0,0);
    lcd.print("Channel 2 Start");
    lcd.setCursor(0,1);
    printMins(twoStartMins, true);
    if(plus.uniquePress() && twoStartMins < 1440){
      twoStartMins++;
    }
    if(minus.uniquePress() && twoStartMins > 0){
      twoStartMins--;
    }
  }

  if(menuCount == 7){
    //set end time for channel two
    lcd.setCursor(0,0);
    lcd.print("Channel 2 End");
    lcd.setCursor(0,1);
    printMins(twoStartMins+twoPhotoPeriod, true);
    if(plus.uniquePress() && twoPhotoPeriod < 1440 - twoStartMins){
      twoPhotoPeriod++;
    }
    if(minus.uniquePress() && twoPhotoPeriod > 0){
      twoPhotoPeriod--;
    }
  }

  if(menuCount == 8){
    //set fade duration for channel two
    lcd.setCursor(0,0);
    lcd.print("Channel 2 Fade");
    lcd.setCursor(0,1);
    printMins(twoFadeDuration, false);
    if(plus.uniquePress() && twoFadeDuration > twoPhotoPeriod/2){
      twoFadeDuration++;
    }
    if(minus.uniquePress() && twoFadeDuration > 0){
      twoFadeDuration--;
    }
  }

  if(menuCount == 9){
    //set intensity for channel two
    lcd.setCursor(0,0);
    lcd.print("Channel 2 Max");
    lcd.setCursor(1,1);
    lcd.print(oneMax);
    if(plus.uniquePress() && twoMax < 255){
      twoMax++;
    }
    if(minus.uniquePress() && twoMax > 0){
      twoMax--;
    }
  }

  if(menuCount == 10){
    //set start time for channel three
    lcd.setCursor(0,0);
    lcd.print("Channel 3 Start");
    lcd.setCursor(0,1);
    printMins(threeStartMins, true);
    if(plus.uniquePress() && threeStartMins < 1440){
      threeStartMins++;
    }
    if(minus.uniquePress() && threeStartMins > 0){
      threeStartMins--;
    }
  }

  if(menuCount == 11){
    //set end time for channel three
    lcd.setCursor(0,0);
    lcd.print("Channel 3 End");
    lcd.setCursor(0,1);
    printMins(threeStartMins+threePhotoPeriod, true);
    if(plus.uniquePress() && threePhotoPeriod < 1440 - threeStartMins){
      threePhotoPeriod++;
    }
    if(minus.uniquePress() && threePhotoPeriod > 0){
      threePhotoPeriod--;
    }
  }

  if(menuCount == 12){
    //set fade duration for channel three
    lcd.setCursor(0,0);
    lcd.print("Channel 3 Fade");
    lcd.setCursor(0,1);
    printMins(threeFadeDuration, false);
    if(plus.uniquePress() && threeFadeDuration > threePhotoPeriod/2){
      threeFadeDuration++;
    }
    if(minus.uniquePress() && threeFadeDuration > 0){
      threeFadeDuration--;
    }
  }

  if(menuCount == 13){
    //set intensity for channel three
    lcd.setCursor(0,0);
    lcd.print("Channel 3 Max");
    lcd.setCursor(1,1);
    lcd.print(threeMax);
    if(plus.uniquePress() && threeMax < 255){
      threeMax++;
    }
    if(minus.uniquePress() && threeMax > 0){
      threeMax--;
    }
  }

  if(menuCount == 14){
    //set start time for channel four
    lcd.setCursor(0,0);
    lcd.print("Channel 4 Start");
    lcd.setCursor(0,1);
    printMins(fourStartMins, true);
    if(plus.uniquePress() && fourStartMins < 1440){
      fourStartMins++;
    }
    if(minus.uniquePress() && fourStartMins > 0){
      fourStartMins--;
    }
  }

  if(menuCount == 15){
    //set end time for channel four
    lcd.setCursor(0,0);
    lcd.print("Channel 4 End");
    lcd.setCursor(0,1);
    printMins(fourStartMins+fourPhotoPeriod, true);
    if(plus.uniquePress() && fourPhotoPeriod < 1440 - fourStartMins){
      fourPhotoPeriod++;
    }
    if(minus.uniquePress() && fourPhotoPeriod > 0){
      fourPhotoPeriod--;
    }
  }

  if(menuCount == 16){
    //set fade duration for channel four
    lcd.setCursor(0,0);
    lcd.print("Channel 4 Fade");
    lcd.setCursor(0,1);
    printMins(fourFadeDuration, false);
    if(plus.uniquePress() && fourFadeDuration > fourPhotoPeriod/2){
      fourFadeDuration++;
    }
    if(minus.uniquePress() && fourFadeDuration > 0){
      fourFadeDuration--;
    }
  }

  if(menuCount == 17){
    //set intensity for channel four
    lcd.setCursor(0,0);
    lcd.print("Channel 4 Max");
    lcd.setCursor(1,1);
    lcd.print(fourMax);
    if(plus.uniquePress() && fourMax < 255){
      fourMax++;
    }
    if(minus.uniquePress() && fourMax > 0){
      fourMax--;
    }
  }

  if(menuCount == 18){
    //set hours
    lcd.setCursor(0,0);
    lcd.print("Set Time: Hrs");
    lcd.setCursor(0,1);
    printHMS(hour, minute, second);
    if(plus.uniquePress() && hour < 24){
      hour++;
    }
    if(minus.uniquePress() && hour > 0){
      hour--;
    }
  setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }
  
  if(menuCount == 19){
    //set minutes
    lcd.setCursor(0,0);
    lcd.print("Set Time: Mins");
    lcd.setCursor(0,1);
    printHMS(hour, minute, second);
    if(plus.uniquePress() && minute < 60){
      minute++;
    }
    if(minus.uniquePress() && minute > 0){
      minute--;
    }
  setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }
}
 
Last edited:
terhaz, I seen that after posting, and it is fixed at the moment. Now I am just working on the ramp up and down. The screen control is kinda cool, I learned how to use the switch statements and it made it alot easier. The lcd that I am using has 5 buttons on a voltage divider network going to analog 0. It took me a bit to figure out how to use them, but they do work well.

the missing includes were liquidCrystal.h and time.h
 
What do you mean by ramp up and down? Slowly going from 0 to max and the beginning and the other way around at the end? If that's the case, just look at the code DWZM posted on the previous page, that is all you need.


On a side note, since everyone is posting code here, here is the code for my Hydra. I'm planning to have it in some working form by the end of next week (when I'm going on vacation and it _must_ be working) (NOTE: very experimental at this point so don't upload to your chip as it is :) ):

http://svn.geodar.com/hydra/trunk/

What works: PH reading, Clock display, IR remote control learning, menu for setting start/end/duration times, lcd brightness, clock/date setup, multiple channels of blues and whites, delay between channels (for directional light), moonlight setup. Relay support via second MCP chip. Temperature monitoring via LM35 temp IC.

TODO:
finish logic for setting start/end times for leds via UI.
add support for relay configuration via UI
add event based actions and configuration via UI (for dosing, alarms etc)
Make sure things work :)

EDIT: a lot of this code is not mine BTW, just popular pieces from the net.
 
Last edited:
As it turns out, posting that Typhon code above has motivated me to work out some bugs. This is the revised code. It fixes some screen artifacts and two typos. Also, for the sake of "readability" I switched from using a full byte (0-255) to store the brightness values for LED channels to using a percentage (0-100).

PHP:
/*
// Typhon firmware
// v0.1 alpha 2010-08-06
// N. Enders
//
// This sketch provides firmware for the Typhon LED controller.
// It provides a structure to fade 4 independent channels of LED lighting
// on and off each day, to simulate sunrise and sunset.
//
// Current work in progress:
// - store all LED variables in EEPROM so they are not reset by a loss of power
//
// Future developments may include:
// - moon phase simulation
// - storm simulation
// 
// Sketch developed in Arduino-18
// Requires LiquidCrystal, Wire, and Button libraries.
// Button is available here: http://www.arduino.cc/playground/Code/Button
 */

// include the libraries:
#include <LiquidCrystal.h>
#include "Wire.h"
#include <Button.h>



/**** Define Variables & Constants ****/
/**************************************/

// set the RTC's I2C address
#define DS1307_I2C_ADDRESS 0x68
// create the LCD
LiquidCrystal lcd(8, 7, 5, 4, 16, 2);
// define pin for backlight
int bkl         = 6;
// create the menu counter
int menuCount   = 1;
// create the buttons
Button menu     = Button(12,PULLDOWN);
Button select   = Button(13,PULLDOWN);
Button plus     = Button(14,PULLDOWN);
Button minus    = Button(15,PULLDOWN);

// LED variables. These control the behavior of lighting. Change these to customize behavoir
int minCounter = 0;         // counter that resets at midnight.
int oldMinCounter = 0;         // counter that resets at midnight.
int oneLed = 9;             // pin for channel 1
int twoLed = 10;            // pin for channel 2
int threeLed = 11;          // pin for channel 3
int fourLed = 3;            // pin for channel 4

int oneVal = 0;             // current value for channel 1
int twoVal = 0;             // current value for channel 2
int threeVal = 0;           // current value for channel 3
int fourVal = 0;            // current value for channel 4

int oneStartMins = 480;     // minute to start this channel.
int onePhotoPeriod = 510;   // photoperiod in minutes for this channel.
int oneMax = 100;           // max intensity for this channel, as a percentage
int oneFadeDuration = 60;   // duration of the fade on and off for sunrise and sunset for
                            //    this channel.

int twoStartMins = 480;
int twoPhotoPeriod = 510;
int twoMax = 100;
int twoFadeDuration = 60;

int threeStartMins = 480;
int threePhotoPeriod = 510;
int threeMax = 100;
int threeFadeDuration = 60;
                            
int fourStartMins = 480;
int fourPhotoPeriod = 510;  
int fourMax = 100;          
int fourFadeDuration = 60;  




/****** RTC Functions ******/
/***************************/

// Convert decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

// Sets date and time, starts the clock
void setDate(byte second,        // 0-59
             byte minute,        // 0-59
             byte hour,          // 1-23
             byte dayOfWeek,     // 1-7
             byte dayOfMonth,    // 1-31
             byte month,         // 1-12
             byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.send(0);
   Wire.send(decToBcd(second));
   Wire.send(decToBcd(minute));
   Wire.send(decToBcd(hour));
   Wire.send(decToBcd(dayOfWeek));
   Wire.send(decToBcd(dayOfMonth));
   Wire.send(decToBcd(month));
   Wire.send(decToBcd(year));
   Wire.endTransmission();
}

// Gets the date and time
void getDate(byte *second,
             byte *minute,
             byte *hour,
             byte *dayOfWeek,
             byte *dayOfMonth,
             byte *month,
             byte *year)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  *second     = bcdToDec(Wire.receive() & 0x7f);
  *minute     = bcdToDec(Wire.receive());
  *hour       = bcdToDec(Wire.receive() & 0x3f);
  *dayOfWeek  = bcdToDec(Wire.receive());
  *dayOfMonth = bcdToDec(Wire.receive());
  *month      = bcdToDec(Wire.receive());
  *year       = bcdToDec(Wire.receive());
}

/****** LED Functions ******/
/***************************/
//function to set LED brightness according to time of day
//function has three equal phases - ramp up, hold, and ramp down
int   setLed(int mins,    // current time in minutes
            int ledPin,  // pin for this channel of LEDs
            int start,   // start time for this channel of LEDs
            int period,  // photoperiod for this channel of LEDs
            int fade,    // fade duration for this channel of LEDs
            int ledMax   // max value for this channel
            )  {
  int val = 0;
  if (mins <= start || mins > start + period)  {
    val = 0;
  }
  if (mins > start && mins <= start + fade)  {
    val = map(mins - start, 0, fade, 0, ledMax);
  }
  if (mins > start + fade && mins <= start + period - fade)  {
    val = ledMax;
  }
  if (mins > start + period - fade && mins <= start + period)  {
    val = map(mins - (start + period - fade), 0, fade, ledMax, 0);
  }
  analogWrite(ledPin, map(val, 0, 100, 0, 255));
  return val;
}

/**** Display Functions ****/
/***************************/

// format a number of minutes into a readable time
void printMins(int mins,       //time in minutes to print
               boolean ampm    //print am/pm?
              )  {
  int hr = mins/60;
  int mn = mins%60;
  if(hr<13){
    if(hr<10){
      lcd.print(" ");
    }
    lcd.print(hr);
    lcd.print(":");
    if(mn<10){
      lcd.print("0");
    }
    lcd.print(mn);
    if(ampm){
      lcd.print(" AM");
    }
  } else {
    if(hr<22){
      lcd.print(" ");
    }
    lcd.print(hr-12);
    lcd.print(":");
    if(mn<10){
      lcd.print("0");
    }
    lcd.print(mn);
    if(ampm){
      lcd.print(" PM");
    }
  }
}

// format hours, mins, secs into a readable time
void printHMS (byte hr,
               byte mn,
               byte sec      //time to print
              )  {
  if(hr<13){
    if(hr<10){
      lcd.print(" ");
    }
    lcd.print(hr, DEC);
    lcd.print(":");
    if(mn<10){
      lcd.print("0");
    }
    lcd.print(mn, DEC);
    lcd.print(":");
    if(sec<10){
      lcd.print("0");
    }
    lcd.print(sec, DEC);
    lcd.print(" AM");
  } else {
    if(hr<22){
      lcd.print(" ");
    }
    lcd.print(hr-12, DEC);
    lcd.print(":");
    if(mn<10){
      lcd.print("0");
    }
    lcd.print(mn, DEC);
    lcd.print(":");
    if(sec<10){
      lcd.print("0");
    }
    lcd.print(sec, DEC);
    lcd.print(" PM");
  }
}

/**** Setup ****/
/***************/

void setup() {
  Wire.begin();
  // set up the LCD's number of rows and columns: 
  pinMode(bkl, OUTPUT);
  digitalWrite(6, HIGH);
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("This is Typhon!!!");
  delay(1000);
  lcd.clear();
  //setDate(1, 15, 11, 5, 5, 8, 10);
}

/***** Loop *****/
/****************/

void loop() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  getDate(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  oldMinCounter = minCounter;
  minCounter = hour * 60 + minute;

  //set outputs
  oneVal = setLed(minCounter, oneLed, oneStartMins, onePhotoPeriod, oneFadeDuration, oneMax);
  twoVal = setLed(minCounter, twoLed, twoStartMins, twoPhotoPeriod, twoFadeDuration, twoMax);
  threeVal = setLed(minCounter, threeLed, threeStartMins, threePhotoPeriod, threeFadeDuration, threeMax);
  fourVal = setLed(minCounter, fourLed, fourStartMins, fourPhotoPeriod, fourFadeDuration, fourMax);
  

  //iterate through the menus
  if(menu.uniquePress()){
    if(menuCount < 19){
      menuCount++;
    }else {
      menuCount = 1;
    }
  lcd.clear();
  }
  if(menuCount == 1){
    //main screen turn on!!!
    if (minCounter > oldMinCounter){
      lcd.clear();
    }
    lcd.setCursor(0,0);
    printHMS(hour, minute, second);
    lcd.setCursor(0,1);
    lcd.print(oneVal);
    lcd.setCursor(4,1);
    lcd.print(twoVal);
    lcd.setCursor(8,1);
    lcd.print(threeVal);
    lcd.setCursor(12,1);
    lcd.print(fourVal);
  }

  if(menuCount == 2){
    //set start time for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 Start");
    lcd.setCursor(0,1);
    printMins(oneStartMins, true);
    if(plus.uniquePress() && oneStartMins < 1440){
      oneStartMins++;
    }
    if(minus.uniquePress() && oneStartMins > 0){
      oneStartMins--;
    }
  }

  if(menuCount == 3){
    //set end time for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 End");
    lcd.setCursor(0,1);
    printMins(oneStartMins+onePhotoPeriod, true);
    if(plus.uniquePress() && onePhotoPeriod < 1440 - oneStartMins){
      onePhotoPeriod++;
    }
    if(minus.uniquePress() && onePhotoPeriod > 0){
      onePhotoPeriod--;
    }
  }

  if(menuCount == 4){
    //set fade duration for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 Fade");
    lcd.setCursor(0,1);
    printMins(oneFadeDuration, false);
    if(plus.uniquePress() && oneFadeDuration > onePhotoPeriod/2){
      oneFadeDuration++;
    }
    if(minus.uniquePress() && oneFadeDuration > 0){
      oneFadeDuration--;
    }
  }

  if(menuCount == 5){
    //set intensity for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 Max");
    lcd.setCursor(1,1);
    lcd.print(oneMax);
    if(plus.uniquePress() && oneMax < 100){
      lcd.clear();
      oneMax++;
    }
    if(minus.uniquePress() && oneMax > 0){
      lcd.clear();
      oneMax--;
    }
  }

  if(menuCount == 6){
    //set start time for channel two
    lcd.setCursor(0,0);
    lcd.print("Channel 2 Start");
    lcd.setCursor(0,1);
    printMins(twoStartMins, true);
    if(plus.uniquePress() && twoStartMins < 1440){
      twoStartMins++;
    }
    if(minus.uniquePress() && twoStartMins > 0){
      twoStartMins--;
    }
  }

  if(menuCount == 7){
    //set end time for channel two
    lcd.setCursor(0,0);
    lcd.print("Channel 2 End");
    lcd.setCursor(0,1);
    printMins(twoStartMins+twoPhotoPeriod, true);
    if(plus.uniquePress() && twoPhotoPeriod < 1440 - twoStartMins){
      twoPhotoPeriod++;
    }
    if(minus.uniquePress() && twoPhotoPeriod > 0){
      twoPhotoPeriod--;
    }
  }

  if(menuCount == 8){
    //set fade duration for channel two
    lcd.setCursor(0,0);
    lcd.print("Channel 2 Fade");
    lcd.setCursor(0,1);
    printMins(twoFadeDuration, false);
    if(plus.uniquePress() && twoFadeDuration > twoPhotoPeriod/2){
      twoFadeDuration++;
    }
    if(minus.uniquePress() && twoFadeDuration > 0){
      twoFadeDuration--;
    }
  }

  if(menuCount == 9){
    //set intensity for channel two
    lcd.setCursor(0,0);
    lcd.print("Channel 2 Max");
    lcd.setCursor(1,1);
    lcd.print(twoMax);
    if(plus.uniquePress() && twoMax < 100){
      lcd.clear();
      twoMax++;
    }
    if(minus.uniquePress() && twoMax > 0){
      lcd.clear();
      twoMax--;
    }
  }

  if(menuCount == 10){
    //set start time for channel three
    lcd.setCursor(0,0);
    lcd.print("Channel 3 Start");
    lcd.setCursor(0,1);
    printMins(threeStartMins, true);
    if(plus.uniquePress() && threeStartMins < 1440){
      threeStartMins++;
    }
    if(minus.uniquePress() && threeStartMins > 0){
      threeStartMins--;
    }
  }

  if(menuCount == 11){
    //set end time for channel three
    lcd.setCursor(0,0);
    lcd.print("Channel 3 End");
    lcd.setCursor(0,1);
    printMins(threeStartMins+threePhotoPeriod, true);
    if(plus.uniquePress() && threePhotoPeriod < 1440 - threeStartMins){
      threePhotoPeriod++;
    }
    if(minus.uniquePress() && threePhotoPeriod > 0){
      threePhotoPeriod--;
    }
  }

  if(menuCount == 12){
    //set fade duration for channel three
    lcd.setCursor(0,0);
    lcd.print("Channel 3 Fade");
    lcd.setCursor(0,1);
    printMins(threeFadeDuration, false);
    if(plus.uniquePress() && threeFadeDuration > threePhotoPeriod/2){
      threeFadeDuration++;
    }
    if(minus.uniquePress() && threeFadeDuration > 0){
      threeFadeDuration--;
    }
  }

  if(menuCount == 13){
    //set intensity for channel three
    lcd.setCursor(0,0);
    lcd.print("Channel 3 Max");
    lcd.setCursor(1,1);
    lcd.print(threeMax);
    if(plus.uniquePress() && threeMax < 100){
      lcd.clear();
      threeMax++;
    }
    if(minus.uniquePress() && threeMax > 0){
      lcd.clear();
      threeMax--;
    }
  }

  if(menuCount == 14){
    //set start time for channel four
    lcd.setCursor(0,0);
    lcd.print("Channel 4 Start");
    lcd.setCursor(0,1);
    printMins(fourStartMins, true);
    if(plus.uniquePress() && fourStartMins < 1440){
      fourStartMins++;
    }
    if(minus.uniquePress() && fourStartMins > 0){
      fourStartMins--;
    }
  }

  if(menuCount == 15){
    //set end time for channel four
    lcd.setCursor(0,0);
    lcd.print("Channel 4 End");
    lcd.setCursor(0,1);
    printMins(fourStartMins+fourPhotoPeriod, true);
    if(plus.uniquePress() && fourPhotoPeriod < 1440 - fourStartMins){
      fourPhotoPeriod++;
    }
    if(minus.uniquePress() && fourPhotoPeriod > 0){
      fourPhotoPeriod--;
    }
  }

  if(menuCount == 16){
    //set fade duration for channel four
    lcd.setCursor(0,0);
    lcd.print("Channel 4 Fade");
    lcd.setCursor(0,1);
    printMins(fourFadeDuration, false);
    if(plus.uniquePress() && fourFadeDuration > fourPhotoPeriod/2){
      fourFadeDuration++;
    }
    if(minus.uniquePress() && fourFadeDuration > 0){
      fourFadeDuration--;
    }
  }

  if(menuCount == 17){
    //set intensity for channel four
    lcd.setCursor(0,0);
    lcd.print("Channel 4 Max");
    lcd.setCursor(1,1);
    lcd.print(fourMax);
    if(plus.uniquePress() && fourMax < 100){
      lcd.clear();
      fourMax++;
    }
    if(minus.uniquePress() && fourMax > 0){
      lcd.clear();
      fourMax--;
    }
  }

  if(menuCount == 18){
    //set hours
    lcd.setCursor(0,0);
    lcd.print("Set Time: Hrs");
    lcd.setCursor(0,1);
    printHMS(hour, minute, second);
    if(plus.uniquePress() && hour < 23){
      hour++;
    }
    if(minus.uniquePress() && hour > 0){
      hour--;
    }
  setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }
  
  if(menuCount == 19){
    //set minutes
    lcd.setCursor(0,0);
    lcd.print("Set Time: Mins");
    lcd.setCursor(0,1);
    printHMS(hour, minute, second);
    if(plus.uniquePress() && minute < 59){
      minute++;
    }
    if(minus.uniquePress() && minute > 0){
      minute--;
    }
  setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }
}

terahz - looking forward to reviewing your Hydra code. I decided to code the Typhon first since it was a less monumental task. Have you had any luck with Ethernet on the Hydra?
 
Last edited by a moderator:
Hmm, it looks like there is a bug with the "code" tag in vBulletin. It's dropping text surrounded by < > characters. Look at the includes at the top of my sketch. I had LiquidCrystal.h and Button.h there enclosed in less than/greater than signs but it dropped it.
 
terahz - looking forward to reviewing your Hydra code. I decided to code the Typhon first since it was a less monumental task. Have you had any luck with Ethernet on the Hydra?

Still have the chip unplugged since I first tested it :(. I'll get to it, I promise! Just wanted to have the first CPU at some relatively working state before starting to poke at the second. Which reminds me, I had completely forgotten that the two CPUs will have to "talk" to each other somehow...
 
Right, there's that, too. :lol:

My take on that would be to write a super-generic "communication" function to run on the slave that took three arguments: action, pin, and value. The idea being that the master could send an action, pin, and value to the slave and have it do something. For instance, write to pin 12 the value HIGH. Or, Read from analog 0, and so on. The "actions" could be standard Arduino read/writes, or special commands, like "initialize one-wire on pin 3."

On a side note - as you can see in the post I made above, beerguy discovered that if you use the PHP tags instead of the CODE tags, it does not drop the includes. We should all probably start doing that in this thread to preserve the code.
 
I won a RTC on Ebay for a whopping $3 so now the real fun begins. I know a lot of the info is in this thread here and there, but here's a great page I found to help setting up the RTC. Just thought Id pass it on encase someone else can use it too.
http://www.ladyada.net/learn/breakoutplus/ds1307rtc.html


I plan to get the day stuff going soon, probably Saturday. Its not near as complex as the full on controller stuff, but what I want it sunrise, clouds, full sun, clouds, then sunset. Hopefully pretty much like a normal day. Is anyone working on the para-phrasing stuff to get the info from a real reef?
 
Looking around that site I came across the Xbee stuff. Is anyone using this? Is it really as easy as it makes it seem on the tutorial? I could use this to finally package my controller behind my canopy.
 
It IS easy but IMHO somewhat limited in fuctionality and a little expensive. It basically lets you send serial data without a cable. I'm a little confused on exactly why you'd need it to put the controller behind your canopy - what would the controller be communicating with via Xbee?
 
I think he may have a similar sort of issue I do. I am planning on running pendant style. So power, ground, and pwm to each canopy. Minimum of four wires. I sort of decided to place a arduino in each canopy (down 2 wires up one voltage regulator). If I am reading the SparkFun info correctly some of the XBee chips have PWMs (2). For about the same price I could put a XBee in the pendant and only have one controller.

No worry about time of day being off from three controllers (2 pendants and tank control). Which means storms are easier to program. You could place more XBees in the pendant (or maybe another chip) and control multiple banks of LEDs.

[EDIT]
However the XBEE/Arduino shield is expensive ($80) at least compared to most of the other components.
 
Back
Top