PDA

View Full Version : Basic Arduino Controller for LED Systems



SaltyDog
10-07-2011, 10:59 PM
For those of you asking about a simple controller I have made up a shopping list for a basic controller with enclosure and 16x2 LCD that will control the following and leave open 6 extra pins....
2 Temp Sensors (Water and Heatsink)
2 powerheads
1 fan (temp sensor controlled)
1 heater (temp sensor controlled)
1 moonlight (on/off)
1 fuge (on/off)
1 White LEDs
1 Blue LEDs

If your using meanwell drivers you would also need to buy a pkg of 2N2222 Transistors and a 10v DC wallwart to be able to use the 0-5v signal for a 0-10v driver.

Shopping List for basic lighting control

Uno
RTC
Enclosure
Power Supply
Waterproof Temp Sensor
Heatsink Temp Sensor
LCD 16x2 - White on Blue Bkgnd
I2C LCD Controller You will need to download the new Liquidcrystal library from them for this to work.
8 Relay Board 2 powerheads,1 fuge,1 sump, 1 Heater, 1 Fan, 1 moonlight
2-4 - 110 Outlets
1 - 8x7 Radioshack Project Box to hold relays and outlets.
Lots of wires....lol

SaltyDog
10-07-2011, 11:03 PM
And Now your Sketch:


#include <OneWire.h>
#include <DallasTemperature.h>
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68 //set rtc
#include <LiquidCrystal.h> // initialize the library with the numbers of the interface pins
#define ONE_WIRE_BUS 9 //Define the pin of the DS18B20
/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| R E L A Y P A R T |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||*/

const int ledPin1 = A2; // pin number for relay 1 was digital pin 2
const int ledPin2 = A3; // pin number for relay 2 was digital pin 8
int ledState1 = LOW;
int ledState2 = LOW;
long previousMillis1 = 0;
long previousMillis2 = 0;
long interval1 = 30000; // interval at which to blink (milliseconds) for RELAY1
long interval2 = 50000; // interval at which to blink (milliseconds) for RELAY2


/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| L E D D I M M I N G P A R T |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/

int blueramptime = 60 ; // time for blue LEDs to dim on and off in minutes
int whiteramptime = 120 ; // time for white LEDs to dim on and off in minutes
int bluemin = 0 ; // minimmum dimming value of blue LEDs, range of 0-255
int bluemax = 255 ; // maximum dimming value of blue LEDs, range of 0-255
int whitemin = 0 ; // minimum dimming value of white LEDs, range of 0-255
int whitemax = 255 ; // maximum dimming value of white LEDs, range of 0-255
int photoperiod = 360 ; // amount of time array is on at full power in minutes
int ontime = 10 ; // time of day (hour, 24h clock) to begin photoperiod fade in
int blue = 10; // blue LEDs connected to digital pin 3 (pwm)
int white = 11; // white LEDs connected to digital pin 11 (pwm)
int fan = A0; // Fan power relay connected to analog pin 0
int fuge = 4; // fuge light power relay connected to analog pin 1
int moon = 3; // moon light connected to digital pin 3
int heater = A1;



int bluepercent[11] = { 0, 1, 2, 5, 8 ,12, 18, 27, 44, 80, 255 }; // this line is needed if you are using meanwell ELN60-48D
int whitepercent[11] = { 0, 1, 2, 5, 8 ,12, 18, 27, 44, 80, 255 }; // these are the values in 10% increments

//int bluepercent[11] = { 0, 26, 52, 78, 103, 128, 154, 180, 205, 230, 255 }; // this line is needed if you are using meanwell ELN60-48P
//int whitepercent[11] = { 0, 26, 52, 78, 103, 128, 154, 180, 205, 230, 255 }; // these are the values in 10% increments

//int pwm_one = 9; // extra pwm pin for future use

// Connect via i2c, default address #0 (A0-A2 not jumpered)
LiquidCrystal lcd(0);


// Set up the custom fish icon
byte newChar[8] = {
B00000,
B00000,
B10001,
B11011,
B11111,
B11111,
B11001,
B10000
};

byte newChar1[8] = {
B00001,
B00010,
B11101,
B11010,
B11111,
B11110,
B11100,
B00000
};
byte newChar2[8] = {
B00000,
B00000,
B10001,
B11011,
B11111,
B11111,
B10011,
B00001
};
byte newChar3[8] = {
B10000,
B01000,
B10111,
B01011,
B11111,
B01111,
B00111,
B00000
};
byte newChar4[8] = {
B00111,
B01110,
B11100,
B11000,
B11000,
B11100,
B01110,
B00111
};
byte newChar5[8] = {
B01010,
B10000,
B00010,
B01001,
B00100,
B10000,
B00100,
B10001
};
byte newChar6[8] = {
B01010,
B00100,
B00001,
B11011,
B00011,
B00001,
B01000,
B10010
};
byte newChar7[8] = {
B10010,
B00100,
B10000,
B11011,
B11000,
B10000,
B00010,
B01001
};

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

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

/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| R T C C L O C K D S 1 3 0 7 |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/



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


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

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour)); // If you want 12 hour am/pm you need to set
// bit 6 (also need to change readDateDs1307)
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.endTransmission();

Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.receive() & 0x7f);
*minute = bcdToDec(Wire.receive());
*hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.receive());
*dayOfMonth = bcdToDec(Wire.receive());
*month = bcdToDec(Wire.receive());
*year = bcdToDec(Wire.receive());
}



/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| D E F I N E : O N E S E C O N D |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/



void onesecond() //function that runs once per second while program is running
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
lcd.setCursor(0, 0);
if(hour>0)
{
if(hour<=12)
{
lcd.print(hour, DEC);
}
else
{
lcd.print(hour-12, DEC);
}
}
else
{
lcd.print("12");
}
lcd.print(":");
if (minute < 10) {
lcd.print("0");
}
lcd.print(minute, DEC);
//lcd.print(":");
//if (second < 10) {
// lcd.print("0");
//}
//lcd.print(second, DEC);
if(hour<12)
{
lcd.print("am");
}
else
{
lcd.print("pm");
}
//lcd.print(" ");
delay(1000);
}


/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| D E F I N E : F A N S O N |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/
void FansOn()
{
digitalWrite(fan, HIGH);
//analogWrite(fan, 255);

}
/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| D E F I N E : F A N S O F F |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/
void FansOff()
{
digitalWrite(fan, LOW);
//analogWrite(fan, 0);

}
/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| D E F I N E : F U G E L I G H T O N |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/
void FugeOn()
{
digitalWrite(fuge, HIGH);


}
/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| D E F I N E : F U G E L I G H T O F F |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/
void FugeOff()
{
digitalWrite(fuge, LOW);


}
/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| D E F I N E : M O O N L I G H T O N |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/
void MoonOn()
{
digitalWrite(moon, HIGH);
lcd.setCursor(8, 0);
lcd.write(4);
lcd.write(5);


}
/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| D E F I N E : M O O N L I G H T O F F |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/
void MoonOff()
{
digitalWrite(moon, LOW);
lcd.setCursor(8, 0);
lcd.write(6);
lcd.write(7);


}

/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| D E F I N E : R E L A Y 1 |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/




void relay1() //FUNCTION TO TURN ON AND OFF RELAY 1.
{
unsigned long currentMillis = millis();

if(currentMillis - previousMillis1 > interval1)
{
previousMillis1 = currentMillis;
if (ledState1 == LOW)
ledState1 = HIGH;
else
ledState1 = LOW;
digitalWrite(ledPin1, ledState1);
}
}



/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| D E F I N E : R E L A Y 2 |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/




void relay2()
{
unsigned long currentMillis2 = millis();

if(currentMillis2 - previousMillis2 > interval2)
{
previousMillis2 = currentMillis2;
if (ledState2 == LOW)
ledState2 = HIGH;
else
ledState2 = LOW;
digitalWrite(ledPin2, ledState2);
}
}




/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| S E T U P |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/


void setup() {
pinMode(ledPin1, OUTPUT); // set the digital pin as output:
pinMode(ledPin2, OUTPUT); // set the digital pin as output:
pinMode(fan, OUTPUT); // Set analog pin 0 as a output
pinMode(fuge, OUTPUT); // Set analog pin 1 as a output
pinMode(moon, OUTPUT); // Set analog pin 3 as a output
pinMode(heater, OUTPUT);
pinMode(fan, OUTPUT);
sensors.begin(); // Start up the DS18B20 Temp library

SaltyDog
10-07-2011, 11:04 PM
/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| S E T U P - D I S P L A Y |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/



byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
Wire.begin();

// Change these values to what you want to set your clock to.
// You probably only want to set your clock once and then remove
// the setDateDs1307 call.
second = 00;
minute = 15;
hour = 23;
dayOfWeek = 25; // Sunday is 0
dayOfMonth = 4;
month = 4;
year = 11;

//Use the next line for setting the clock
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);

analogWrite(blue, bluemin);
analogWrite(white, whitemin);
lcd.createChar(0, newChar);
lcd.createChar(1, newChar1);
lcd.createChar(2, newChar2);
lcd.createChar(3, newChar3);
lcd.createChar(4, newChar4);
lcd.createChar(5, newChar5);
lcd.createChar(6, newChar6);
lcd.createChar(7, newChar7);
lcd.begin(20, 4); // set up the LCD's number of rows and columns:
lcd.setCursor(0, 0);
lcd.setCursor(0, 0);
lcd.write(0);
lcd.write(1);
lcd.setCursor(3, 0);// set the cursor to column 0, line 0
lcd.print("My Marine Tank");
lcd.setCursor(18, 0);
lcd.write(3);
lcd.write(2);
lcd.setCursor(4, 1);
lcd.print("Version 1.01");
delay(5000);
lcd.clear();
//lcd.setCursor(7, 1);
//lcd.print("M:");
lcd.setCursor(11, 0);
lcd.print("B:");
lcd.print(33*bluemin/85);
lcd.setCursor(16, 0);
lcd.print("W:");
lcd.print(33*whitemin/85);
lcd.setCursor(11, 1);
lcd.print("L: ");
lcd.setCursor(0, 1);
lcd.print("W: ");


}




/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| L O O P |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/




void loop()
{
onesecond();
relay2();
relay1();





/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| L O O P - D I M F U N C T I O N |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/

byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
int daybyminute = ((hour * 60) + minute); //converts time of day to a single value in minutes


int bluerampup;
if (daybyminute >= (ontime*60))
bluerampup = (((ontime*60) + blueramptime) - daybyminute);
else
bluerampup = blueramptime;

int whiterampup;
if (daybyminute >= (ontime*60 + blueramptime))
whiterampup = (((ontime*60) + blueramptime + whiteramptime) - daybyminute);
else
whiterampup = whiteramptime;

int whiterampdown;
if (((ontime * 60) + photoperiod + blueramptime + whiteramptime) <= daybyminute)
whiterampdown = (((ontime*60) + photoperiod + blueramptime + 2*whiteramptime) - daybyminute);
else
whiterampdown = whiteramptime;

int bluerampdown;
if (((ontime * 60) + photoperiod + blueramptime + 2*whiteramptime) <= daybyminute)
bluerampdown = (((ontime*60) + photoperiod + 2*blueramptime + 2*whiteramptime) - daybyminute);
else
bluerampdown = blueramptime;






/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| L O O P - F A D E I N |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/


if (daybyminute >= (ontime*60))
{
if (daybyminute <= ((ontime*60) + blueramptime + (whiteramptime/10*9))) //if time is in range of fade in, start fading in + (whiteramptime/10*9)
{
// Turn the fans on.
FansOn();
// Turn the fuge off.
FugeOff();
// Turn the moon lights off.
MoonOff();
// fade blue LEDs in from min to max.

for (int i = 1; i <= 10; i++) // setting ib value for 10% increment. Start with 0%
{
analogWrite(blue, bluepercent[i]);
lcd.setCursor(13, 1);
lcd.print(i);
lcd.print(" ");

int countdown = ((bluerampup*60)/10); // calculates seconds to next step
while (countdown>0)
{
onesecond(); // updates clock once per second
countdown--;
relay2();
relay1();
}
}

// fade white LEDs in from min to max.
for (int i = 1; i <= 10; i++) // setting i value for 10% increment. Start with 0%
{
analogWrite(white, whitepercent[i]);
lcd.setCursor(18, 1);
lcd.print(i);
lcd.print(" ");

int countdown = ((whiterampup*60)/10); // calculates seconds to next step
while (countdown>0)
{
onesecond(); // updates clock once per second
countdown--;
relay2();
relay1();
}
}
}
}


/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| L O O P - M A X V A L U E |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/



if (daybyminute >= ((ontime * 60) + blueramptime + whiteramptime))
{
if ( daybyminute < ((ontime * 60) + blueramptime + whiteramptime + photoperiod)) // if time is in range of photoperiod, turn lights on to maximum fade value
{
// Turn the fans on.
FansOn();
// Turn the fuge off.
FugeOff();
// Turn the moon lights off.
MoonOff();

analogWrite(blue, 255);
lcd.setCursor(13, 1);
lcd.print(10);
lcd.print(" ");
analogWrite(white, 255);
lcd.setCursor(18, 1);
lcd.print(10);
lcd.print(" ");

}
}



/*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| L O O P - F A D E O U T |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/



if (((ontime * 60) + photoperiod + blueramptime + whiteramptime) <= daybyminute)
{
if (((ontime * 60) + photoperiod + whiteramptime + 2*blueramptime + (blueramptime/10*9)) >= daybyminute)
{
// Turn the fans on.
FansOn();
// Turn the fuge off.
FugeOff();
// Turn the moon lights off.
MoonOff();

// fade white LEDs out from max to min in increments of 1 point:
for (int i = 10; i >= 0; i--) // setting i value for 10% increment. Start with 10%
{
analogWrite(blue, 255);
lcd.setCursor(13, 1);
lcd.print(10);
lcd.print(" ");

analogWrite(white, whitepercent[i]);
lcd.setCursor(18, 1);
lcd.print(i);
lcd.print(" ");

int countdown = ((whiterampdown*60)/10); // calculates seconds to next step
while (countdown>0)
{
onesecond(); // updates clock once per second
countdown--;
relay2();
relay1();
}

}

// fade blue LEDs out from max to min in increments of 1 point:
for (int i = 10; i >= 0; i--) // setting i value for 10% increment. Start with 10%
{
analogWrite(blue, bluepercent[i]);
lcd.setCursor(13, 1);
lcd.print(i);
lcd.print(" ");

int countdown = ((bluerampdown*60)/10); // calculates seconds to next step
while (countdown>0)
{
onesecond(); // updates clock once per second
countdown--;
relay2();
relay1();
}
}
}
}

// DS18B20 display
sensors.requestTemperatures(); // Send the command to get temperatures
delay(250);
float temp1=0, temp2=0;
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(13, 1);

//lcd.print("Led Temp:");
lcd.print(sensors.getTempFByIndex(1));
lcd.print((char)223);
lcd.print("F");

lcd.setCursor(2, 1);
//lcd.print("Tank Temp: ");
lcd.print(sensors.getTempFByIndex(0));
lcd.print((char)223);
lcd.print("F");

if ( (temp1) > 98)
{
digitalWrite(fan, HIGH);
}
else if ( (temp1) < 92)
{
digitalWrite(fan, LOW);
}

if ( (temp2) < 78 )
{
digitalWrite(heater, HIGH);
}
else if ( (temp2) > 82 )
{
digitalWrite(heater, LOW);
}

// lcd.print(sensors.getTempCByIndex(0));
// lcd.print((char)223);
// lcd.print("C");

//delay(500);
//*||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| Night Time |||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||*/

if (((ontime * 60) + photoperiod + (2 * blueramptime) + (2 * whiteramptime)) < daybyminute)
{

FansOff();
FugeOn();
MoonOn();
}


} // END LOOP

Corvette Reefer
10-08-2011, 03:21 PM
thats pretty sweet!!! looks super comlicated, but iv been thinking about somthing to use thats simple for led system

SaltyDog
10-08-2011, 03:40 PM
This unit will give you a 0-5v PWM for CAT4101 Drivers or buckpucks.....if your going with meanwells or any other LED driver that requires a 0-10vPWM signal follow the guidelines in the attached pic.Make sure the 12v power supply is under 600mA.

Dan_cochran
02-26-2012, 07:24 AM
SaltyDog,, I almost have my build done, but running into a few issues with he code i was using.

my screen scroll works, temps works, clock works, relay 1 and 2 shut on and off, 3 and 4 don't do anything?
I will test the led ramp up and down i hope today, I have three 48p drivers, no pots. 24 rb cree , 12 white cree.

The moon and sump light I was wanting on the same outlet, and fans to be temp controlled on another out let.
4 relays, 4 outlets

the code i have has the \ph, and orp
But I do not plan on building the sensors any time soon.

ebay parts, all from same seller
I have the ebay uno with 16x2 and buttons
4 relay 5v
rtc
2 temp sensors

all the other odd and end parts i went to radio shack.

but like i said, So far I am at a loss on why the last 2 relays do not come on, if i swap channels they will.
Thats why I think its the code.

If you can help, just let me know and i will post what pins i have what on, and the code i have.
I will play with the code you have posted, just to see if i have any luck ;)

firefightered
01-26-2013, 03:53 PM
I to am building one of these controllers but it looks like this one has been abandoned. where did everyone go? I need help......

RedfordReefer
01-26-2013, 09:58 PM
What do you need help with?

firefightered
01-26-2013, 10:56 PM
I'm, looking for the pin placements for the LCD. I have a 5 button 16x2 LCD and cannt figure out the pin placements. Can you help?

RedfordReefer
01-28-2013, 06:24 PM
Yeah. Let me look at the code. I'll have to decipher the Arduino code. It'll take me a bit.

RedfordReefer
01-28-2013, 06:52 PM
There is a custom library involved.

LiquidCrystal lcd(0);

This instantiates a new object of type LiquidCrystal. Looks like it's on pins A0 - A2 and uses an I2C bus to communicate. I am not overly familiar with the Arduino (I am a .NET developer), but it seems like you'd need a LCD that uses I2C.

firefightered
02-02-2013, 06:37 PM
this is what I get on my
















This is what I get on my LCD. I want it to display the differant fields and the 5 buttons to work. Can anyone help me?

speedstar
02-07-2013, 10:44 AM
What value thermistor for the temp sensor? 10K

SaltyDog
08-13-2013, 02:50 PM
The resistor value for the ds18b20 is 4.7k

Sent from my SAMSUNG-SGH-I717 using Tapatalk 2

SaltyDog
08-13-2013, 02:54 PM
To use the LCD that is used within the sketch you will need to purchase the Adafruit LCD backpack for $10. The backpack uses I2C where as the parallel LCD would use up too many pins on the Uno.

Sent from my SAMSUNG-SGH-I717 using Tapatalk 2

Bigfish246
08-17-2014, 09:35 AM
To use the LCD that is used within the sketch ..........

Sent from my SAMSUNG-SGH-I717 using Tapatalk 2

Hi, first of all, thanks so much for sharing your hard work, much appreciated.

Which IDE did you use to compile? I am getting errors with the 1.0.5 version. Will not even get past the "LiquidCrystal lcd(0);" ,lol. :o