The Planted Tank Forum banner

Another Arduino LED light schedule sketch

29806 Views 109 Replies 23 Participants Last post by  boxhead1990
Here is the Arduino code I use to control the schedule of my LED lights.

Back story:
I've been redoing my 14G low-tech and wanted to try out LED, so I ordered a 10W ebay-special and planned to hook it up to an Arduino I had lying around. While waiting for it to arrive, I looked around for examples of how others had handled the software side of things. None of the code I found seemed to fit my needs.
I realize a lot of people have done the same, but I wanted something that allowed for individual schedules for any number of channels, including siesta and different length sunrise/sunset.

So in the end, I wrote my own code to control the lights.

Some things that need to be addressed before looking at the code:

1: This is not a complete sketch to control aquarium lights!
While it would work on a setup identical to mine, it wouldn't on much else. The code is meant as a helping hand for those that are not overly comfortable with programming, and find handling more complicated schedules difficult. I have removed all but the essentials in this sketch.

2: This has nothing to do with your hardware!
Ok, that may not be strictly true. But my point is: There are a lot of great guides out there regarding the hardware side of things, I will only be dealing with the software. This is the part that I have found relatively little of on these forums, whereas the hardware gurus seem very active. I provide a way to control the PWM signal, the rest is up to you.

Now, let's get started! :)

Features:
- Any number of individual channels (limited by you Arduino's number of PWM pins)
- Pretty much any light schedule that repeats every 24 hours
- Suitable for RGB lights
- Reasonably smooth fading w. a resolution of 1/255 updated every second

Hardware requirements:
- Arduino (Uno in my case)
- RTC module (DS1307 is used in the example)
- PWM outputs wired CORRECTLY to your LED drivers

Other requirements:
- Some (not necessarily a lot) proficiency with Arduino coding

There are a lot of comments in the code, and I hope it is not too difficult to understand.

UPDATE:
I have made a considerable rewrite, making it much easier to add more channels.
Concept explained:

A lot of this is explained in the code, but I'll try to summarize it here.
To define a schedule for a channel, you set a series of 'Points'. This should be considered a chart, where the line represents the intensity of light over a 24 hour period.
Intensity is a value in the range 0-255. 0 = OFF, 255 = Fully ON

To make lights turn on in the morning with a 30 minute 'sunrise', you would add 2 Points:
08:00 - Intensity = 0
08:30 - Intensity = 255

Explanation:
From 08:00 to 08:30 channel is going from 0-255

It's pretty simple, really.

:sleep: Enough rambling, here is the code. Let me know if you have questions or find it useful!

Link to source:
[STRIKE]http://codebender.cc/sketch:4232[/STRIKE]
EDIT:
New location of source:
https://github.com/benjaf/LightController
  • Like
Reactions: litzel
41 - 60 of 110 Posts

· Registered
Joined
·
113 Posts
Discussion Starter · #41 ·
Well they are like that sometimes, a lot of the more active people there assume you have quite a bit of experience in both electronics and programming.
Declaration: the 'creation' of the array ( int lightMatrix[x][x][x]; )
Initialization: creating the contents of the array ( lightMatrix = {{x},{x}}; )

But anyway, I have made a very basic sketch to show you how I meant it:
http://codebender.cc/sketch:23963
The variable names etc. are not accurate, but the idea stands.
And it works - just not in the Arduino IDE (programming environment). Arduino has quite at few quirks like that, and I keep forgetting them. I usually use Codebender because it is more 'friendly'!
 

· Registered
Joined
·
113 Posts
Discussion Starter · #42 · (Edited)
If you want to make it 'Arduino IDE Compatible' you will have to replace the contents of the UpdateMatrix() function with one of these for each channel:

// Channel 1:
sunMatrix[0][0][Sunrise_Hr] = 0;
sunMatrix[0][0][Sunrise_Min] = 0;
sunMatrix[0][0][Sunset_Hr] = RiseHour;
sunMatrix[0][0][Sunset_Min] = RiseMin + 2;
sunMatrix[0][0][INTENSITY] = 0;
sunMatrix[0][1][Sunrise_Hr] = RiseHour;
sunMatrix[0][1][Sunrise_Min] = RiseMin + 10;
sunMatrix[0][1][Sunset_Hr] = RiseHour + 12;
sunMatrix[0][1][Sunset_Min] = RiseMin + 7;
sunMatrix[0][1][INTENSITY] = RBlue_max;
sunMatrix[0][2][Sunrise_Hr] = RiseHour + 12;
sunMatrix[0][2][Sunrise_Min] = RiseMin + 12;
sunMatrix[0][2][Sunset_Hr] = 24;
sunMatrix[0][2][Sunset_Min] = 0;
sunMatrix[0][2][INTENSITY] = 0;

It is a somewhat more tedious process!
 

· Registered
Joined
·
26 Posts
Awesome! Awesome! Awesome!

Thank you so much for taking the time!!

One of the comments from the Arduino forum (I was trying not to bother you too much) stated I couldn't shortcut it the way I was trying to do, and I would have to initialize all the elements of the array.

But, I still had hope....;)

It is a tedious process, but I'm too far in to turn back now.

Thank you so much. You have full credit in my code, and shout outs on my You Tube channel and Build thread.
 

· Registered
Joined
·
113 Posts
Discussion Starter · #46 ·
Just read through your build thread - damn, suddenly I'm really appreciating dealing with a small low-tech planted tank! No PH probes with grounding issues, no massive LED driver arrays to burn. Oh, and no touchscreen!
Learning Python and using Qt for GUI is somewhat more forgiving.
Congratulations on getting this far, I'm confident you will be able to complete it at some point :)

// Benjamin
 

· Banned
Joined
·
12 Posts
Thanks for putting this code out there for us!

I'm having a problem that I hope someone can clarify. I would like to have the lights intensify to some medium value (here 150) between 0800 and 1000, then have a midday burst at full intensity from 1200 to 1400 followed by another period of medium intensity from 1500 to 1930 and finally a fade out from 1930 to 2130. With the following schedule the lights go out (0 intensity) at 14:00 and then come back up to 150 at 1500.

// Channel 0:
Channels[0].Pin = 11;
Channels[0].AddPoint(8, 0, 0);
Channels[0].AddPoint(10, 0, 150);
Channels[0].AddPoint(12, 0, 255);
Channels[0].AddPoint(14, 0, 255); Lights go out here instead of fading down
Channels[0].AddPoint(15, 0, 150);
Channels[0].AddPoint(19, 30, 150);
Channels[0].AddPoint(21, 30, 0);

How am I coding this wrong?
 

· Registered
Joined
·
113 Posts
Discussion Starter · #51 ·
After a quick review I have updated the code.
The old version had several bugs in the intensity calculation, so I have merged the 'old' public version and parts of my experimental branch. This means a few changes will have to be made to fit this in to your code, but I believe the benefits are worth some minor changes.

Major differences:
* Channel boilerplate code moved to a library to reduce mess
* Channels are initialized slightly differently
* A 'Points' array must be defined along with 'Channels'
* You can now choose between linear and exponential fading
* Intensity can be defined as integer (0 - 255) or float (0 - 1), but is handled as a float internally
 

· Registered
Joined
·
2 Posts
I've looked at this code and it fits my array the most.
Like the idea of "low tech" arduino controlling without LCD displays and so on.
I just need 4 channels and a way to set the starting times... (can't really make sense off the code) I'm pretty noob to this programming bit...

lateron i'm thinking of adding a thunder storm and so on...
can some of you help with the code of adding 2 more channels?
and mabye help me understand the code.
if I want PWM 180 to be 100% and not PWM 255...
 

· Registered
Joined
·
113 Posts
Discussion Starter · #54 ·
So just to be sure I got this right before the examples..
You currently want the following:

4 channels
Simple sunrise / sunset for all channels
Max intensity of ~180

To get 4 channels you have to do the following:
Change this:
Code:
const int MaxChannels = 2;
to this:
Code:
const int MaxChannels = 4;
If all you need is simple sunrise / sunset, you don't need more than 4 points in each channel. So you can safely set MaxPoints to 4 in stead of 10:
Code:
const int MaxPoints = 4;
Then you need to set up the schedules for each channel.
Change the pin / times / intensities in Channel 0 to fit your schedule, and then replace this:
Code:
        // Channel 1:
        channelNo = 1;        // Currently editing channel 1
        pin = 11;                // Channel 1 uses pin 11
        Channels[channelNo] = Channel(pin, MaxPoints, fademode_linear, Points[channelNo]);
        Channels[channelNo].AddPoint(8, 0, 0);
        Channels[channelNo].AddPoint(8, 30, 150);
        Channels[channelNo].AddPoint(11, 0, 255);
        Channels[channelNo].AddPoint(11, 15, 0);
        Channels[channelNo].AddPoint(12, 30, 0);
        Channels[channelNo].AddPoint(12, 45, 255);
        Channels[channelNo].AddPoint(19, 30, 150);
        Channels[channelNo].AddPoint(20, 0, 0);
with the following (set the correct pins / times / intensities to match your setup):
Code:
        // Channel 1:
        channelNo = 1;        // Currently editing channel 1
        pin = 11;                // Channel 1 uses pin 11
        Channels[channelNo] = Channel(pin, MaxPoints, fademode_linear, Points[channelNo]);
        Channels[channelNo].AddPoint(8, 0, 0); // 08:00 - Intensity = 0
        Channels[channelNo].AddPoint(8, 30, 180); // 08:30 - Intensity = 180 
        Channels[channelNo].AddPoint(19, 30, 180); // 19:30 - Intensity = 180
        Channels[channelNo].AddPoint(20, 0, 0); // 20:00 - Intensity = 0
		
	// Channel 2:
        channelNo = 2;        // Currently editing channel 2
	pin = 9;                // Channel 2 uses pin 9
        Channels[channelNo] = Channel(pin, MaxPoints, fademode_linear, Points[channelNo]);
        Channels[channelNo].AddPoint(8, 0, 0);
        Channels[channelNo].AddPoint(8, 30, 180);
        Channels[channelNo].AddPoint(19, 30, 180);
        Channels[channelNo].AddPoint(20, 0, 0);
		
		// Channel 3:
        channelNo = 3;        // Currently editing channel 3
        pin = 6;                // Channel 3 uses pin 6
        Channels[channelNo] = Channel(pin, MaxPoints, fademode_linear, Points[channelNo]);
        Channels[channelNo].AddPoint(8, 0, 0);
        Channels[channelNo].AddPoint(8, 30, 180);
        Channels[channelNo].AddPoint(19, 30, 180);
        Channels[channelNo].AddPoint(20, 0, 0);
What you just did by altering and inserting the above, is to configure channels 0 - 3. No more code needs to be changed, now you have a complete 4-channel setup.

The rest of the code (in the main sketch at least) is quite straightforward. Every loop checks if a second has passed since last time the lights were updated, and then calculates the current intensity levels for each channel.
 

· Registered
Joined
·
408 Posts
Ben,

Love the light code mate ;). I doing some comparison with some other light codes to see about working in the storm stuff.

Do you know if scapegoat's wiki is still up? I clicked on the link and page was not available. Thanks again. Great work!
 

· Registered
Joined
·
113 Posts
Discussion Starter · #56 ·
Ben,

Love the light code mate ;). I doing some comparison with some other light codes to see about working in the storm stuff.

Do you know if scapegoat's wiki is still up? I clicked on the link and page was not available. Thanks again. Great work!
Thanks!
You will probably need to make a few changes to enable an 'effect' overlay, but it should be possible.

I think he made some breaking changes to the wiki. Last time I saw it there was some stuff about CO2 and then my code. I think he had trouble getting people to submit content.
 

· Registered
Joined
·
26 Posts
Hi Benjaf...yep it's me again.

Just having an issue I can't seem to sort, and was hoping you could nudge me in the right direction.

Long story short I am having difficulties with the ramping up of the LEDs. This started happening when I had to undo your nice tidy array in order to integrate my UI.
What is happening is the increasing intensity of the LEDs has become jerky. It ramps up in steps rather than the nice smooth increase from 0 to the max LED vlaue.
Just a rough example...the LEDs come on at about 20%, 40% a few seconds later, and so on. Noticeable increase to the eye.

I've been trying to figure out why this is happening, and correct the issue for some time now, and finally had to bother you yet again.

Funny thing is nothing else is effected. Timing schedules for all the periods is correct with no issues, and the fading from max led value to 0 is still silky smooth.

Do you have any idea what might be causing this?
I could send my code if you need.

Thanks again!
 
41 - 60 of 110 Posts
This is an older thread, you may not receive a response, and could be reviving an old thread. Please consider creating a new thread.
Top