New light controller with arduino...have a question

skuller

New member
Hello guys:

I am trying to build my aquarium led lighting controller with an Arduino Mega (ATmega1280chip), plus an RTC1307 real time clocking module.

Basically I have 6 channels (Different colors) connected to the arduino PWM pins with a CAT4101 driver, not using any resistors nor anything else on the circuit, just the CAT4101 and the RSET resistor.

Now my question is, I have taken several codes from the web for dimmering the leds using RTC time module, but none of them works on my arduino mega, I took a look also on the Pico Reef led in other website, that is exactly what I need..but it doesn't work either.

Is there any code out there or something easy I can use for pwm my leds using rtc for the Arduino Mega?

Also should I use any type of resistor between the PWM ping on the CAT4101 and the Arduino PIN?

This is the circuit I am using:

catalyst_cat4101a.gif


EN/PWM pin on the CAT4101 goes directly to the digital pins 7-12 on my arduino Mega.

Any help or easy code for ArduinoPWM+RTC you can provide me so I can test my circuit?

Thank you in advace.

Steve.
 
This is one of the codes I have found and it will fit perfect for my needs, however when uploaded to the Arduino Mega board my leds keeps always ON at 100%..


Code:
//2.7 Gallon Pico Reef LED Light Controller Version 1.06

//Code written by plant_arms 2012-08-31

//Based on various code libraries avalable on the public domain along with coding compiled by the author.

 

#include <Wire.h>

#include "RTClib.h"



RTC_DS1307 RTC;



int bluePin = 9;				// blue LEDs connected to digital pin5

int whitePin = 10;			   // white LEDs connected to digital pin6



double blueFadeValue = 255;

double whiteFadeValue = 255;



double userWhiteMax =		4;	// maximum percentage intensity of white leds, 0-100 user defined

double userBlueMax =		 9;	// maximum percentage intensity of blue leds, 0-100 user defined

double blueMaxPwm;				 // variable used to convert the userBlueMax value into a PWM value

double whiteMaxPwm;				// variable used to convert the userWhiteMax value into a PWM value



int second;

int hour;

int minute; 

int blueLightsOn =		  9;	  // time of day (hour, 24h clock) to begin blue lights fading on

int whiteLightsOn =		10;	  // time of day (hour, 24h clock) to begin white lights fading on

int whiteLightsOff =	   20;	  // time of day (hour, 24h clock) to begin white lights fading out

int blueLightsOff =		21;	  // time of day (hour, 24h clock) to begin blue lights fading out

double fadeTime =		  60;	  // amount of time in minutes for the fade in/out to last **must be in 60 minute increments** 



 

void setup () {

	Serial.begin(115200);

	Wire.begin();

	RTC.begin();

 

  if (!RTC.isrunning()) { //uncomment the ! to be able to reset the datetime value

	// this will allow you to set RTC to the current computer date and time if uncommented and compiled 

	//RTC.adjust(DateTime(__DATE__, __TIME__));

  }

 

}



   void loop () {

	 setFade();

	 ledRtc();

	 SerialOut();

				  

   }  

   

	

 

 //void setFade class used to covert the user percentage input to a PWM value and set to white/blue  

   void setFade(){

	 blueMaxPwm = (userBlueMax*2.55);  //converts the user input value (0-100) to a PWM value (0-255)

	 whiteMaxPwm = (userWhiteMax*2.55); //converts the user input value (0-100) to a PWM value (0-255)   

   }

	

 

  

 //void ledRtc class to control the leds with the ds1307 timer, absolute value and using the time periods(<= etc) is to gain the correct fade position in case of a power outage

   void ledRtc(){

   

   DateTime now = RTC.now();

   hour = now.hour();

   minute = now.minute();

   second = now.second();

   int totBlueHrOn = hour - blueLightsOn;

   int totBlueHrOff = hour - blueLightsOff;

   int totWhiteHrOn = hour - whiteLightsOn;

   int totWhiteHrOff = hour - whiteLightsOff;

   int totalMinute = minute;

   abs(totBlueHrOn); 

   abs(totBlueHrOff);

   abs(totWhiteHrOn); 

   abs(totWhiteHrOff);

   abs(totalMinute);

   int totalBlueOn   = ((totBlueHrOn*60) + totalMinute);

   int totalBlueOff  = ((totBlueHrOff*60) + totalMinute);

   int totalWhiteOn  = ((totWhiteHrOn*60) + totalMinute);

   int totalWhiteOff = ((totWhiteHrOff*60) + totalMinute);

   

   //fades on blue lights from blueLightsOn through blueLightsOn plus fadeTime and outputs light intensity based on the current time   

   if((hour >= blueLightsOn)&&(hour < (blueLightsOn+(fadeTime/60)))&&(totalBlueOn < fadeTime)){ 

	 blueFadeValue = 255-(blueMaxPwm*(totalBlueOn/fadeTime)); 

	 analogWrite(bluePin, blueFadeValue);

   }

   

   //fades on white lights from whiteLightsOn to whiteLightsOn plus fadeTime and outputs light intensity based on the current time	

   if((hour >= whiteLightsOn)&&(hour <= (whiteLightsOn+(fadeTime/60)))&&(totalWhiteOn <= fadeTime)){  

	 whiteFadeValue = 255-(whiteMaxPwm*(totalWhiteOn/fadeTime)); 

	 analogWrite(whitePin, whiteFadeValue);

   }

  

   //puts blue lights up to full if the fade in period is complete and less than bluelightsoff, so full from 10 to 20:59

   if((hour >= (blueLightsOn+(fadeTime/60)))&&(hour < blueLightsOff)){ 

	 blueFadeValue = 255-blueMaxPwm;

	 analogWrite(bluePin, blueFadeValue);

   }

   

   //puts white lights up to full if the fade in period is complete and less than whitelightsoff, so full from 11 to 19:59

   if((hour >= (whiteLightsOn+(fadeTime/60)))&&(hour < whiteLightsOff)){ 

	 whiteFadeValue = 255-whiteMaxPwm;

	 analogWrite(whitePin, whiteFadeValue);

   }

   

   //fades out whites from whiteLightsOff to whiteLightsOff plus fadeTime and outputs light intensity based on the current time 

   if((hour >= whiteLightsOff)&&(hour < (whiteLightsOff+(fadeTime/60)))&&(totalWhiteOff <= fadeTime)){ 

	 whiteFadeValue = 255-(whiteMaxPwm - (whiteMaxPwm*(totalWhiteOff/fadeTime)));

	 analogWrite(whitePin, whiteFadeValue);

   

  }

  //fade out blues from blueLightsOff to blueLightsOff plus fadeTime and outputs light intensity based on the current time

   if((hour >= blueLightsOff)&&(hour < (blueLightsOff+(fadeTime/60)))&&(totalBlueOff <= fadeTime)){

	 blueFadeValue = 255-(blueMaxPwm - (blueMaxPwm*(totalBlueOff/fadeTime)));

	 analogWrite(bluePin, blueFadeValue);

   

  }

   

   //this sets the white lights to be off from end of whiteLightsOff plus fadeTime to midnight

   if((hour >= (whiteLightsOff+(fadeTime/60))&&(hour <= 24))){  

	 whiteFadeValue = 255;

	 analogWrite(whitePin, whiteFadeValue);

  }  

  

   //this sets the blue lights to be off from end of blueLightsOff plus fadeTime to midnight

   if((hour >= (blueLightsOff+(fadeTime/60))&&(hour < 24))){  

	 blueFadeValue = 255;

	 analogWrite(bluePin, blueFadeValue);

  } 

  

  //this sets the white lights to be off from midnight to whiteLightsOn in case of reset of power outage

   if((hour >= 0)&&(hour < whiteLightsOn)){  

	 whiteFadeValue = 255;

	 analogWrite(whitePin, whiteFadeValue);

  }  

  

   //this sets the blue lights to be off from midnight to blueLightsOn in case of reset or power outage

   if((hour >= 0)&&(hour < blueLightsOn)){  

	 blueFadeValue = 255;

	 analogWrite(bluePin, blueFadeValue);

  } 

}

	  

	   

  

 //SerialOut class to output print statements to the serial lcd display, time, temp, and light prcnt

   void SerialOut(){ 

	//DateTime now = RTC.now();

	//print the time pulled in with spaced 0's

	if (hour < 10) {

	   Serial.print('0');

	   Serial.print(hour);}

	 else {Serial.print(hour);}

	Serial.print(':');

	if (minute < 10) {

	   Serial.print('0');

	   Serial.print(minute);}

	 else {Serial.print(minute);}

	Serial.print(':');

	if (second < 10) {

	  Serial.print('0');

	  Serial.print(second);}

	  else { 

	Serial.print(second);}

	

	Serial.print(100-(whiteFadeValue/2.55));

	Serial.print("%");

		

	 Serial.print(100-(blueFadeValue/2.55));

	Serial.print("%");

	

	Serial.println();

	delay(1000);

 }
 
Have you connected the ground going in to your driver to the ground going in to the arduino? Without that, the driver can't really tell what the PWM signal is as it doesn't have a common reference.

The other thing that springs to mind (ignoring obvious things like wiring issues, connecting drivers to pins which are not PWM or not the ones being used in your code) is whether the drivers actually support 0-5V PWM but I wouldn't expect the LEDs to be coming on full if that was the case.

Tim
 
Perkint:

Yes, the ground is connected to the ground (negative) of the arduino board and the entire circuit, I tested the PWM function of the Mega board with an example that comes with the Arduino program and it works perfectly, so I assume cabling is ok.


The issue is with that code and the Mega board, since I need PWM dimmering with RTC and need a code like that.
 
I'm not going to act like I know what I'm talking about but I have a working Arduino based touch screen light fixture. When I first set mine up, I tested with this simple 2 bank code. Don't remember where I stole it from but it works with a RTC.

Code:
/*
 Arduino LED controller for reef aquariums

// paramterized LED lighting control for reef aquariums
// use a DS1307 RTC to kick off lighting schedules
//   fade up on a given slope
//         delay a set amount
//         fade back down
//   such that the photoperiod lasts the correct amount of time


//  Circuit
// 
// PWM pins described below connected to dimming circuits on drivers
// ledMaster pin below connected to a 120V AC relay to turn the LED drivers on and off (optional)
// grounds from drivers connected to arduino ground
// DS1307 RTC connected via I2C
//
//
//

*/

// Pins to control LEDs. Change these if you're using different pins.
int blueLed = 9;     // LED PWM channel for blues
int whiteLed = 10;   // LED PWM channel for whites

// Set up RTC
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68

// RTC variables
byte second, rtcMins, oldMins, rtcHrs, oldHrs, dayOfWeek, dayOfMonth, month, year;

// Other 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 blueStartMins = 480;    // minute to start blues. Change this to the number of minutes past
                            //    midnight you want the blues to start.
int whiteStartMins = 480;   // minute to start whites. Same as above.
int bluePhotoPeriod = 510;  // photoperiod in minutes, blues. Change this to alter the total
                            //    photoperiod for blues.
int whitePhotoPeriod = 510; // photoperiod in minutes, whites. Same as above.
int fadeDuration = 60;      // duration of the fade on and off for sunrise and sunset. Change
                            //    this to alter how long the fade lasts.
int blueMax = 255;          // max intensity for blues. Change if you want to limit max intensity.
int whiteMax = 255;         // max intensity for whites. Same as above.


/****** LED Functions ******/
/***************************/
//function to set LED brightness according to time of day
//function has three equal phases - ramp up, hold, and ramp down
void 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
            )  {
  if (mins > start && mins <= start + fade)  {
    analogWrite(ledPin, map(mins - start, 0, fade, 0, ledMax));
  }
    if (mins > start + period && mins <= start + period - fade)  {
    analogWrite(ledPin, ledMax);
  }
    if (mins > start + period - fade && mins <= start + period)  {
    analogWrite(ledPin, map(mins - start + period - fade, 0, fade, ledMax, 0));
  }
}

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

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  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));
   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 from the ds1307
void getDateDs1307(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());
}

void setup()  { 
  
// init I2C  
  Wire.begin();
} 

/***** Main Loop ***********/
/***************************/
void loop()  { 
  // get time from RTC and put in hrs and mins variables
  getDateDs1307(&second, &rtcMins, &rtcHrs, &dayOfWeek, &dayOfMonth, &month, &year);
  minCounter = rtcHrs * 60 + rtcMins;

  // determine if it is day or night, and act accordingly
  if ((minCounter > blueStartMins || minCounter > whiteStartMins)
           && (minCounter < blueStartMins + bluePhotoPeriod || minCounter < whiteStartMins + whitePhotoPeriod))  {   //day
    // set LED states
    setLed(minCounter, blueLed, blueStartMins, bluePhotoPeriod, fadeDuration, blueMax);
    setLed(minCounter, whiteLed, whiteStartMins, whitePhotoPeriod, fadeDuration, whiteMax);
  }
  else  {   //night
    analogWrite(blueLed, 0);
    analogWrite(whiteLed, 0);
  }
    
  // Get ready for next iteration of loop
  delay(1000);
}
 
Perkint:

Yes, the ground is connected to the ground (negative) of the arduino board and the entire circuit, I tested the PWM function of the Mega board with an example that comes with the Arduino program and it works perfectly, so I assume cabling is ok.


The issue is with that code and the Mega board, since I need PWM dimmering with RTC and need a code like that.
So using example code, you can use your board to control dimming on your drivers?

If so it must be a coding issue, either compatibility with your set up or simple error.

Can you hook the board to your laptop and add some print commands to see what the program is trying to do?

Tim
 
Only time i had issues with my CATs were when grounds were missing... Is the power supply for the LEDs also common ground? What about the 5V source to the drivers?

The pwm pin can understand 3-6V pwm, so you should be fine there. I assume the arduino pulls down the signal internally so no resistor should be needed.

What i would do is use the simplest blinking led code (but using pwm) you can to see it all does obey pwm commands. I edited the example blink to use pwm...

PHP:
/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */
 
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 9;

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);    
}

// the loop routine runs over and over again forever:
void loop() {
  analogWrite(led, 255);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  analogWrite(led, 0);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}

Reading over that to make sure it all is okay it occurred to me that i don't recall your code specifying the pins as outputs ever. I don't know what it would do if they are not, but you probably cant go banging them around if they are inputs.
 
Thank you guys

Yes, a simple fading with PWM analogWrite works perfect, that is why I am so confused...may be is something wrong with my Mega board?
The Pokahpolice code worked perfectly for a few hours...now it's not :-(

Will see if I can get another arduino board to test the codes, however the blink and fading analog works great!
 
Neither of the other codes have specified the LED pins as outputs, which the example codes always do. I don't actually do arduino stuff so i don't know if its fine to ignore that, but it cant hurt to add it, really. Change your setup to this:

PHP:
void setup () {
	Serial.begin(115200);
	Wire.begin();
	RTC.begin();
  if (!RTC.isrunning()) { //uncomment the ! to be able to reset the datetime value
	// this will allow you to set RTC to the current computer date and time if uncommented and compiled 
	//RTC.adjust(DateTime(__DATE__, __TIME__));
  }
}
 
Back
Top