Guide: Arduino based LED controller for Current Satellite LED+ - Page 4
Planted Tank Forums
Your Tanks Image Hosting *Tank Tracker * Plant Profiles Fish Profiles Planted Tank Guide Photo Gallery Articles

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


Reply
 
Thread Tools Display Modes
Old 07-26-2013, 03:22 PM   #46
somewhatshocked
Obsessed? Maybe
 
somewhatshocked's Avatar
 
PTrader: (438/100%)
Join Date: Aug 2011
Location: Louisville, KY
Posts: 11,533
Default

This is a terrific DIY! Way cheaper than buying a $100 controller. (You should link to this in your signature)

I think I'm going to bite the bullet and try this out over the weekend. I'm a huge tech geek but I'm sure I'll have tons of questions... since this will be my first fun with Arduino.

Thanks for sharing all the details.
somewhatshocked is online now   Reply With Quote Quick reply to this message
Sponsored Links
Advertisement
 
Old 07-26-2013, 03:27 PM   #47
Indychus
Planted Tank Enthusiast
 
Indychus's Avatar
 
PTrader: (8/100%)
Join Date: Feb 2013
Location: Irmo, SC
Posts: 646
Default

Glad you've enjoyed it so far... I'm working on a random function to kick it into t-storm mode randomly right now, and hopefully RTC will be here today so I can get that going soon. It still has a long way to go!

Sent from my HTC One X using Tapatalk 4 Beta
__________________
The Fraternity of Dirt
Check out my open-source Arduino-Powered Light Controller Guide for Current LED+ and other IR switchable lights.
Indychus is offline   Reply With Quote Quick reply to this message
Old 07-26-2013, 05:25 PM   #48
Indychus
Planted Tank Enthusiast
 
Indychus's Avatar
 
PTrader: (8/100%)
Join Date: Feb 2013
Location: Irmo, SC
Posts: 646
Default

RTC just showed up!

This will allow the unit to keep it's own time without having to reset it any time the power goes out. I'll be back this afternoon hopefully with some details on how to hook it up and some updated code.

This is the TinyRTC V1.1... a DS1307 based real time clock.


__________________
The Fraternity of Dirt
Check out my open-source Arduino-Powered Light Controller Guide for Current LED+ and other IR switchable lights.
Indychus is offline   Reply With Quote Quick reply to this message
Old 07-26-2013, 09:01 PM   #49
Indychus
Planted Tank Enthusiast
 
Indychus's Avatar
 
PTrader: (8/100%)
Join Date: Feb 2013
Location: Irmo, SC
Posts: 646
Default

Here is the 2.0 beta version of the new code including random thunderstorms. The code has been tested and compiles, but the randomness and frequency of the storms has yet to be seen.

This code is in testing and may cause strange operation until verified.

This code:
  • Randomly schedules a time for Storm2 mode.
  • Allows scheduled storm to proceed if chosen time is after 1 pm. Delays 24 hours and chooses new time if not.
  • Has random storm duration from 0-3 hours.
  • Has random after-storm gloom (Dawn/Dusk mode) from 0-1 hours.
  • Should return to previous mode after storm and gloom conclusion.
  • Should allow 1-2 storms per week to proceed.

Code:


///////////////////////////////////////////////////////////////////
// Current Satellite LED+ Controller  V2.0 Beta                  //
//   Indychus...Dahammer...mistergreen @ plantedtank.net         //
//   This code is public domain.  Pass it on.                    //
//   Confirmed on Arduino UNO 1.0.5                              //
//   Req. Time, TimeAlarms, DateTime, DateTimeStrings libraries  //
///////////////////////////////////////////////////////////////////

////////////SETUP//////////////////////////////////////////////////
#include <Time.h>
#include <TimeAlarms.h>
#include <DateTime.h>
#include <DateTimeStrings.h>

int IRledPin =  13;                  // Pin location for IR output

void setup()               
{ 
  pinMode(IRledPin, OUTPUT);         // Designate IRledPin as Output
  Serial.begin(9600);                // Connect @ (Baud)
  setTime(11,59,55,7,26,13);          // set time (HR,MIN,SEC,MO,DAY,YR)

  ////////////ALARM FUNCTIONS/////////////////////////////////////////
 
  ThunderStorm ();
 
  Alarm.alarmRepeat(7,00,0, DawnDusk);
  Alarm.alarmRepeat(7,00,0, DawnDusk);
  Alarm.alarmRepeat(9,00,0, Cloud2);     // (HR,MIN,SEC,FUNCTION)
  Alarm.alarmRepeat(9,00,0, Cloud2);
  Alarm.alarmRepeat(13,00,0, FullSpec);
  Alarm.alarmRepeat(13,00,0, FullSpec);
  Alarm.alarmRepeat(15,00,0, Cloud2);
  Alarm.alarmRepeat(15,00,0, Cloud2);
  Alarm.alarmRepeat(19,00,0, DawnDusk);
  Alarm.alarmRepeat(19,00,0, DawnDusk);
  Alarm.alarmRepeat(21,00,0, Night2);
  Alarm.alarmRepeat(21,00,0, Night2);
  Alarm.alarmRepeat(00,00,00, ThunderStorm); 
}   
////////////THUNDERSTORMS///////////////////////////////////////////// 
void ThunderStorm ()
{
  // Called everyday at midnight & randomly schedules a storm between 1 & 9 in the evening
  unsigned long RH = random(0,23);                   // Randomizer for thunderstorm
  unsigned long RM = random(0,59);
  unsigned long RS = random(0,59);
  unsigned long TSDuration = random(0,10800);     // Random T-Storm duration from 0-3hr

  Serial.print("Storm = ");
  Serial.print(RH);
  Serial.print(".");
  Serial.print(RM);
  Serial.print(".");
  Serial.print(RS);
  Serial.println();

  if (RH > 12)                             // If random value is after 1 pm, allow storm
  {
    Alarm.alarmOnce(RH,RM,RS,Storm2);
    if ((RH + (TSDuration/3600)) < 19) {
      // If storm is between 1 & 7
      Alarm.alarmOnce((RH + (TSDuration/3600)),RM,RS,Cloud2);
    }
    else if ((RH + (TSDuration/3600)) < 21) {
      // If storm is between 1 & 9
      Alarm.alarmOnce((RH + (TSDuration/3600)),RM,RS,DawnDusk);
    }
    else {
      Alarm.alarmOnce((RH + (TSDuration/3600)),RM,RS,Night2);
    }
  }
}   


////////////CLOCK///////////////////////////////////////////////////
void  loop(){                       
  digitalClockDisplay();
  Alarm.delay(1000);               // Clock display update frequency (msec)
}

void digitalClockDisplay()          // Digital clock
{ 
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println(); 
}

void printDigits(int digits)        // Add :
{
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}


////////////SIGNAL///////////////////////////////////////////////////
// Create Frequency (38khz/26msec)
void pulseIR(long microsecs) 
{  
  cli();                           // kill interupts
  while (microsecs > 0)
  {  
    digitalWrite(IRledPin, HIGH);    // ~3 msec
    delayMicroseconds(7);            // ~delay
    digitalWrite(IRledPin, LOW);     // ~3 msec
    delayMicroseconds(7);            // ~delay
    microsecs -= 26;  
  }
  sei();  
}                           // zombie interupts


////////////FIXTURE FUNCTIONS////////////////////////////////////////
void DeviceID ()
{
  int codes[17][2] = { 
    {
      8840,4320    }
    , 
    {
      620,480    }
    , 
    {
      600,500    }
    , 
    {
      540,1660    }
    , 
    {
      580,520    }
    , 
    {
      520,560    }
    , 
    {
      600,480    }
    , 
    {
      620,480    }
    , 
    {
      540,540    }
    , 
    {
      620,1600    }
    , 
    {
      520,1660    }
    , 
    {
      580,520    }
    , 
    {
      520,1660    }
    , 
    {
      600,1580    }
    , 
    {
      620,1580    }
    , 
    {
      540,1660    }
    , 
    {
      600,1580    } 
  };

  for( int i = 0 ; i < 17; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
  }
}

void Footer ()
{
  int codes[3][2] = { 
    {
      580,1620    }
    ,
    {
      540,38980    }
    ,
    {
      8860,2120    } 
  };

  for( int i = 0 ; i < 3; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
  }
  pulseIR(620);
}

void IR(int codes[15][2]) 
{
  DeviceID();

  for( int i = 0 ; i < 15; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
  }  
  Footer(); 
}

void PowerButton()                             //Fixture power on/off toggle
{
  int codes[15][2] = { 
    {
      600,500    }
    ,
    {
      600,500    }
    ,
    {
      520,560    }
    ,
    {
      600,500    }
    ,
    {
      600,500    }
    ,
    {
      520,560    }
    ,
    {
      580,1620    }
    ,
    {
      540,540    }
    ,
    {
      600,1600    }
    ,
    {
      520,1660    }
    ,
    {
      580,1620    }
    ,
    {
      580,1620    }
    ,
    {
      520,1660    }
    ,
    {
      580,1600    }
    ,
    {
      580,520    } 
  }; 

  Serial.println("Power Toggle");
  IR(codes);
}

void Night2()                                   //Fixture Initialize Night2 Mode
{
  int codes[15][2] = { 
    {
      600,1640    }
    ,
    {
      600,500    }
    ,
    {
      520,560    }
    ,
    {
      600,1620    }
    ,
    {
      600,1640    }
    ,
    {
      520,560    }
    ,
    {
      580,540    }
    ,
    {
      540,540    }
    ,
    {
      600,480    }
    ,
    {
      520,1660    }
    ,
    {
      580,1620    }
    ,
    {
      580,500    }
    ,
    {
      520,500    }
    ,
    {
      580,1600    }
    ,
    {
      580,1560    } 
  }; 

  Serial.println("Night 2 Mode Initialized");
  IR(codes);
}

void Cloud2()                                         //Fixture Initialize Cloud2 Mode
{ 
  int codes[15][2] = { 
    {
      600,1580    }
    ,
    {
      600,500    }
    ,
    {
      520,1620    }
    ,
    {
      600,500    }
    ,
    {
      600,1600    }
    ,
    {
      520,560    }
    ,
    {
      580,480    }
    ,
    {
      540,540    }
    ,
    {
      600,560    }
    ,
    {
      520,1660    }
    ,
    {
      580,560    }
    ,
    {
      580,1620    }
    ,
    {
      520,560    }
    ,
    {
      580,1600    }
    ,
    {
      580,1640    } 
  };

  Serial.println("Cloud Cover 2 Mode Initialized");
  IR(codes);
}

void FullSpec()                                  //Fixture Initialize Full Spectrum Mode
{
  int codes[15][2] = { 
    {
      600,1580    }
    ,
    {
      600,500    }
    ,
    {
      520,480    }
    ,
    {
      600,1580    }
    ,
    {
      600,1600    }
    ,
    {
      520,560    }
    ,
    {
      580,1600    }
    ,
    {
      540,540    }
    ,
    {
      600,560    }
    ,
    {
      520,1660    }
    ,
    {
      580,1580    }
    ,
    {
      580,540    }
    ,
    {
      520,560    }
    ,
    {
      580,1600    }
    ,
    {
      580,480    } 
  };

  Serial.println("Full Spectrum Mode Initialized");
  IR(codes);
}

void DawnDusk()                         // Fixture Initialize Dawn/Dusk Mode
{
  int codes[15][2] = { 
    {
      600,1660    }
    ,
    {
      600,1560    }
    ,
    {
      520,480    }
    ,
    {
      600,1580    }
    ,
    {
      600,1600    }
    ,
    {
      520,560    }
    ,
    {
      580,500    }
    ,
    {
      540,540    }
    ,
    {
      600,560    }
    ,
    {
      520,500    }
    ,
    {
      580,1580    }
    ,
    {
      580,540    }
    ,
    {
      520,560    }
    ,
    {
      580,1660    }
    ,
    {
      580,1580    } 
  };

  Serial.println("Dawn/Dusk Mode Initialized");
  IR(codes);
}

void Storm2()                         //Fixture Initialize Storm2 Mode
{
  int codes[15][2] = { 
    {
      600,1660    }
    ,
    {
      600,540    }
    ,
    {
      520,480    }
    ,
    {
      600,500    }
    ,
    {
      600,1600    }
    ,
    {
      520,560    }
    ,
    {
      580,500    }
    ,
    {
      540,540    }
    ,
    {
      600,560    }
    ,
    {
      520,1660    }
    ,
    {
      580,1580    }
    ,
    {
      580,1620    }
    ,
    {
      520,560    }
    ,
    {
      580,1660    }
    ,
    {
      580,1580    } 
  };

  Serial.println("Storm2 Mode Initialized");
  IR(codes);
}
__________________
The Fraternity of Dirt
Check out my open-source Arduino-Powered Light Controller Guide for Current LED+ and other IR switchable lights.

Last edited by Indychus; 07-28-2013 at 10:51 PM.. Reason: Edit
Indychus is offline   Reply With Quote Quick reply to this message
Old 07-27-2013, 12:37 AM   #50
mistergreen
No more Bow ties
 
mistergreen's Avatar
 
PTrader: (13/100%)
Join Date: Dec 2006
Location: Cincinnati
Posts: 14,257
Default

if the delayMicroseconds & pulseIR pair are always the same count, you can probably put them in an array and then loop through. It'll make things more tidy.


something like

Code:
int storm1_array[][] = { {1660,600}, {1560,520}, .... }

for( int i = 0 ; i < 15; i++) {
    delayMicroseconds(storm1_array[i][0]);
    pulseIR(storm1_array[i][1]);
}
mistergreen is online now   Reply With Quote Quick reply to this message
Old 07-27-2013, 01:07 AM   #51
Indychus
Planted Tank Enthusiast
 
Indychus's Avatar
 
PTrader: (8/100%)
Join Date: Feb 2013
Location: Irmo, SC
Posts: 646
Default

Nice, thanks for the input. For each set, the first half of the values is the device ID and never changes, so that should work fine for those. I'll go back through and clean that up this weekend.

Sent from my HTC One X using Tapatalk 4 Beta
__________________
The Fraternity of Dirt
Check out my open-source Arduino-Powered Light Controller Guide for Current LED+ and other IR switchable lights.
Indychus is offline   Reply With Quote Quick reply to this message
Old 07-27-2013, 02:59 AM   #52
Dahammer
Algae Grower
 
PTrader: (0/0%)
Join Date: Oct 2010
Location: Mississippi
Posts: 118
Default

You could take it even further and just have a single function that you call to process the lighting changes, passing an array with the codes in it to the function when you call it. I think I'd also define all of the variables that users may want/need to modify in a library file. That way they'll be easy to find and you want have to go searching through all of the code looking for them.

I've order my fixture, now I just have to get an Arduino and some other parts.
Dahammer is offline   Reply With Quote Quick reply to this message
Old 07-27-2013, 04:08 AM   #53
Indychus
Planted Tank Enthusiast
 
Indychus's Avatar
 
PTrader: (8/100%)
Join Date: Feb 2013
Location: Irmo, SC
Posts: 646
Default

I told you guys my programming was clunky haha. I'm pretty good at getting it to work, but making it elegant and user friendly takes me quite a while. I really need to get the RTC hooked up and working so I don't have to reset the time every time I upload a new sketch. Once that's done my main priority will be decoding the rest of the remote functions and cleaning the code up. I'd like to make a library with everything in it, but I don't have much experience making libraries and I keep getting some crazy errors.

V2.0 is running on my 55 right now, so far so good. It has scheduled a storm for around 5pm tomorrow. I have manually tested the storm's scheduling but tomorrow will be the first automated run.

Sent from my HTC One X
__________________
The Fraternity of Dirt
Check out my open-source Arduino-Powered Light Controller Guide for Current LED+ and other IR switchable lights.
Indychus is offline   Reply With Quote Quick reply to this message
Old 07-27-2013, 05:18 AM   #54
Dahammer
Algae Grower
 
PTrader: (0/0%)
Join Date: Oct 2010
Location: Mississippi
Posts: 118
Default

Haha! I hear that. If it works it works, eye candy is .... well eye candy. I haven't written much code other an occasional Perl script in years but I'll play with it some when I get a chance.

I have my Arduino Uno and companions on their way.
Dahammer is offline   Reply With Quote Quick reply to this message
Old 07-27-2013, 04:05 PM   #55
mistergreen
No more Bow ties
 
mistergreen's Avatar
 
PTrader: (13/100%)
Join Date: Dec 2006
Location: Cincinnati
Posts: 14,257
Default

If you're interested in Dahammer's suggestion it would be something like this

Code:
int storm1_array[][] = { {1660,600}, {1560,520}, .... }
int dawn_array[][] = { {1600,400}, {1450,220}, .... }

void Storm1() {
    IR(storm1_array);
}

void Dawn() {
   IR(dawn_array);
}

void IR(int inArray[][]) {
    for( int i = 0 ; i < 15; i++) {
      delayMicroseconds(inArray[i][0]);
      pulseIR(inArray[i][1]);
    }
}
mistergreen is online now   Reply With Quote Quick reply to this message
Old 07-27-2013, 04:42 PM   #56
Indychus
Planted Tank Enthusiast
 
Indychus's Avatar
 
PTrader: (8/100%)
Join Date: Feb 2013
Location: Irmo, SC
Posts: 646
Default

Thanks guys, I really appreciate the help. I will be out of town most of the weekend, but l will try to implement these suggestions early next week. I'm glad some of you have fixtures and/or Arduinos on the way to test this out on several lights.

Current has said that their IR protocol will be changing soon to help reduce interference with TVs, etc.... But it's easy to hack new protocols. I'm interested to see if different fixtures use the same device ID or not.

Sent from my HTC One X
__________________
The Fraternity of Dirt
Check out my open-source Arduino-Powered Light Controller Guide for Current LED+ and other IR switchable lights.
Indychus is offline   Reply With Quote Quick reply to this message
Old 07-27-2013, 05:30 PM   #57
Dahammer
Algae Grower
 
PTrader: (0/0%)
Join Date: Oct 2010
Location: Mississippi
Posts: 118
Default

The below code saves 2172 bytes. I haven't tested it, so be warned, but it does compile.

Code:
////////////FIXTURE FUNCTIONS////////////////////////////////////////
void DeviceID ()
{
  int codes[17][2] = { {8840,4320}, 
		       {620,480}, 
		       {600,500}, 
		       {540,1660}, 
		       {580,520}, 
		       {520,560}, 
		       {600,480}, 
		       {620,480}, 
		       {540,540}, 
		       {620,1600}, 
		       {520,1660}, 
		       {580,520}, 
		       {520,1660}, 
		       {600,1580}, 
		       {620,1580}, 
		       {540,1660}, 
		       {600,1580} };

  for( int i = 0 ; i < 17; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
  }
}

void Footer ()
{
  int codes[3][2] = { {580,1620},
                      {540,38980},
                      {8860,2120} };
  	                            
  for( int i = 0 ; i < 3; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
    }
    pulseIR(620);
}

void PowerButton()                             //Fixture power on/off toggle
{
 int codes[15][2] = { {600,500},
                      {600,500},
                      {520,560},
                      {600,500},
                      {600,500},
                      {520,560},
                      {580,1620},
                      {540,540},
                      {600,1600},
                      {520,1660},
                      {580,1620},
                      {580,1620},
                      {520,1660},
                      {580,1600},
                      {580,520} }; 
  
  Serial.println("Power Toggle");
  DeviceID();

  for( int i = 0 ; i < 15; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
  }  
  Footer(); 
}
 
void Night2()                                   //Fixture Initialize Night2 Mode
{
  int codes[15][2] = { {600,1640},
                       {600,500},
                       {520,560},
                       {600,1620},
                       {600,1640},
                       {520,560},
                       {580,540},
                       {540,540},
                       {600,480},
                       {520,1660},
                       {580,1620},
                       {580,500},
                       {520,500},
                       {580,1600},
                       {580,1560} }; 
   
  Serial.println("Night 2 Mode Initialized");
  DeviceID();

  for( int i = 0 ; i < 15; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
  }
  Footer();
}
     
void Cloud2()                                         //Fixture Initialize Cloud2 Mode
{ 
   int codes[15][2] = { {600,1580},
                        {600,500},
                        {520,1620},
                        {600,500},
                        {600,1600},
                        {520,560},
                        {580,480},
                        {540,540},
                        {600,560},
                        {520,1660},
                        {580,560},
                        {580,1620},
                        {520,560},
                        {580,1600},
                        {580,1640} };
                        
  Serial.println("Cloud Cover 2 Mode Initialized");
  DeviceID();

  for( int i = 0 ; i < 15; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
  }
  Footer();
}
   
void FullSpec()                                  //Fixture Initialize Full Spectrum Mode
{
  int codes[15][2] = { {600,1580},
                       {600,500},
                       {520,480},
                       {600,1580},
                       {600,1600},
                       {520,560},
                       {580,1600},
                       {540,540},
                       {600,560},
                       {520,1660},
                       {580,1580},
                       {580,540},
                       {520,560},
                       {580,1600},
                       {580,480} };
  
  Serial.println("Full Spectrum Mode Initialized");
  DeviceID();

  for( int i = 0 ; i < 15; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
  }
  Footer();
}
    
void DawnDusk()                         // Fixture Initialize Dawn/Dusk Mode
{
  int codes[15][2] = { {600,1660},
                       {600,1560},
                       {520,480},
                       {600,1580},
                       {600,1600},
                       {520,560},
                       {580,500},
                       {540,540},
                       {600,560},
                       {520,500},
                       {580,1580},
                       {580,540},
                       {520,560},
                       {580,1660},
                       {580,1580} };
    
  Serial.println("Dawn/Dusk Mode Initialized");
  DeviceID();

  for( int i = 0 ; i < 15; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
  }
  Footer();
}

void Storm2()                         //Fixture Initialize Storm2 Mode
{
  int codes[15][2] = { {600,1660},
                       {600,540},
                       {520,480},
                       {600,500},
                       {600,1600},
                       {520,560},
                       {580,500},
                       {540,540},
                       {600,560},
                       {520,1660},
                       {580,1580},
                       {580,1620},
                       {520,560},
                       {580,1660},
                       {580,1580} };
    
  Serial.println("Storm2 Mode Initialized");
  DeviceID();

  for( int i = 0 ; i < 15; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
  }
  Footer();
}
Dahammer is offline   Reply With Quote Quick reply to this message
Old 07-27-2013, 05:47 PM   #58
Dahammer
Algae Grower
 
PTrader: (0/0%)
Join Date: Oct 2010
Location: Mississippi
Posts: 118
Default

Using mistergreen's suggestion saves another 272 bytes. You probably won't ever use all of the Uno's memory, but you can't ever tell. I left the code arrays local instead of making them global. If you wanted to make them global you could do that though, but I don't see any benefit other than it would allow you to keep all of them in one spot like at the top of the source. Wish I had an Arduino to play with. Might have to make trip to Radio Shack!

Code:
////////////FIXTURE FUNCTIONS////////////////////////////////////////
void DeviceID ()
{
  int codes[17][2] = { {8840,4320}, 
		       {620,480}, 
		       {600,500}, 
		       {540,1660}, 
		       {580,520}, 
		       {520,560}, 
		       {600,480}, 
		       {620,480}, 
		       {540,540}, 
		       {620,1600}, 
		       {520,1660}, 
		       {580,520}, 
		       {520,1660}, 
		       {600,1580}, 
		       {620,1580}, 
		       {540,1660}, 
		       {600,1580} };

  for( int i = 0 ; i < 17; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
  }
}

void Footer ()
{
  int codes[3][2] = { {580,1620},
                      {540,38980},
                      {8860,2120} };
  	                            
  for( int i = 0 ; i < 3; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
    }
    pulseIR(620);
}

void IR(int codes[15][2]) 
{
  DeviceID();

  for( int i = 0 ; i < 15; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
  }  
  Footer(); 
}

void PowerButton()                             //Fixture power on/off toggle
{
 int codes[15][2] = { {600,500},
                      {600,500},
                      {520,560},
                      {600,500},
                      {600,500},
                      {520,560},
                      {580,1620},
                      {540,540},
                      {600,1600},
                      {520,1660},
                      {580,1620},
                      {580,1620},
                      {520,1660},
                      {580,1600},
                      {580,520} }; 
  
  Serial.println("Power Toggle");
  IR(codes);
}
 
void Night2()                                   //Fixture Initialize Night2 Mode
{
  int codes[15][2] = { {600,1640},
                       {600,500},
                       {520,560},
                       {600,1620},
                       {600,1640},
                       {520,560},
                       {580,540},
                       {540,540},
                       {600,480},
                       {520,1660},
                       {580,1620},
                       {580,500},
                       {520,500},
                       {580,1600},
                       {580,1560} }; 
   
  Serial.println("Night 2 Mode Initialized");
  IR(codes);
}
     
void Cloud2()                                         //Fixture Initialize Cloud2 Mode
{ 
   int codes[15][2] = { {600,1580},
                        {600,500},
                        {520,1620},
                        {600,500},
                        {600,1600},
                        {520,560},
                        {580,480},
                        {540,540},
                        {600,560},
                        {520,1660},
                        {580,560},
                        {580,1620},
                        {520,560},
                        {580,1600},
                        {580,1640} };
                        
  Serial.println("Cloud Cover 2 Mode Initialized");
  IR(codes);
}
   
void FullSpec()                                  //Fixture Initialize Full Spectrum Mode
{
  int codes[15][2] = { {600,1580},
                       {600,500},
                       {520,480},
                       {600,1580},
                       {600,1600},
                       {520,560},
                       {580,1600},
                       {540,540},
                       {600,560},
                       {520,1660},
                       {580,1580},
                       {580,540},
                       {520,560},
                       {580,1600},
                       {580,480} };
  
  Serial.println("Full Spectrum Mode Initialized");
  IR(codes);
}
    
void DawnDusk()                         // Fixture Initialize Dawn/Dusk Mode
{
  int codes[15][2] = { {600,1660},
                       {600,1560},
                       {520,480},
                       {600,1580},
                       {600,1600},
                       {520,560},
                       {580,500},
                       {540,540},
                       {600,560},
                       {520,500},
                       {580,1580},
                       {580,540},
                       {520,560},
                       {580,1660},
                       {580,1580} };
    
  Serial.println("Dawn/Dusk Mode Initialized");
  IR(codes);
}

void Storm2()                         //Fixture Initialize Storm2 Mode
{
  int codes[15][2] = { {600,1660},
                       {600,540},
                       {520,480},
                       {600,500},
                       {600,1600},
                       {520,560},
                       {580,500},
                       {540,540},
                       {600,560},
                       {520,1660},
                       {580,1580},
                       {580,1620},
                       {520,560},
                       {580,1660},
                       {580,1580} };
    
  Serial.println("Storm2 Mode Initialized");
  IR(codes);
}
Dahammer is offline   Reply With Quote Quick reply to this message
Old 07-27-2013, 09:17 PM   #59
mistergreen
No more Bow ties
 
mistergreen's Avatar
 
PTrader: (13/100%)
Join Date: Dec 2006
Location: Cincinnati
Posts: 14,257
Default

Making it global helps to organize in one place like if you add another device. You can also move those arrays into another file too like a library. You can also destroy the array too from anywhere if you need extra memory.
mistergreen is online now   Reply With Quote Quick reply to this message
Old 07-28-2013, 12:03 AM   #60
Dahammer
Algae Grower
 
PTrader: (0/0%)
Join Date: Oct 2010
Location: Mississippi
Posts: 118
Default

Quote:
Originally Posted by mistergreen View Post
Making it global helps to organize in one place like if you add another device. You can also move those arrays into another file too like a library. You can also destroy the array too from anywhere if you need extra memory.
True. He was having issues moving code to a library earlier, not sure if he worked that out or not.

I've been working on it in preparation of getting mine going, but I don't have any way of testing it yet, so I'm hesitant to post it. But here is what I have so far if anyone else wants to play with it. Just be WARNED, it may not work. I moved the code arrays to a library file (LED_Controller.h)(wasn't sure what IndyChus was going to name this project) and added code to make use of an RTC. The RTC code requires a library from Adafruit and there is a link at the top of the source. It compiles fine for me, but that's all I've done with it.

Again, I've got several years of rust on my C/C++ hacking, so I'm likely to have made an error somewhere.

Code:
///////////////////////////////////////////////////////////////////
// Current Satellite LED+ Controller                             //
//   Ken Bunton (Indychus)                                       //
//   This code is public domain.  Pass it on.                    //
//   Confirmed on Arduino UNO 1.0.5                              //
//   Req. Time, TimeAlarms, DateTime, DateTimeStrings libraries  //
///////////////////////////////////////////////////////////////////

/*
BETA!! NOT TESTED!!!!!!
Requires RTClib & an RTC board for the Arduino to get RTC function
https://github.com/adafruit/RTClib/archive/master.zip
*/

////////////SETUP//////////////////////////////////////////////////
#include <Wire.h>
#include "RTClib.h"
#include "Time.h"
#include "TimeAlarms.h"
#include "LED_Controller.h"


RTC_DS1307 RTC;

int IRledPin =  13;                  // Pin location for IR output

void setup()               
{ 
  pinMode(IRledPin, OUTPUT);         // Designate IRledPin as Output
  Serial.begin(9600);                // Connect @ (Baud)    
  Wire.begin();
  RTC.begin();
  
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  setSyncProvider(syncProvider);     //reference our syncProvider function instead of RTC_DS1307::get()

////////////ALARM FUNCTIONS/////////////////////////////////////////
  Alarm.alarmRepeat(7,00,0, DawnDusk);
  Alarm.alarmRepeat(7,00,1, DawnDusk);
  Alarm.alarmRepeat(9,00,0, Cloud2);     // (HR,MIN,SEC,FUNCTION)
  Alarm.alarmRepeat(9,00,1, Cloud2);
  Alarm.alarmRepeat(13,00,0, FullSpec);
  Alarm.alarmRepeat(13,00,1, FullSpec);
  Alarm.alarmRepeat(15,00,0, Cloud2);
  Alarm.alarmRepeat(15,00,1, Cloud2);
  Alarm.alarmRepeat(19,00,0, DawnDusk);
  Alarm.alarmRepeat(19,00,1, DawnDusk);
  Alarm.alarmRepeat(21,00,0, Night2);
  Alarm.alarmRepeat(21,00,1, Night2);    
  
  
 ////////////THUNDERSTORMS///////////////////////////////////////////// 
  unsigned long RH = random(0,23);                   // Randomizer for thunderstorm
  unsigned long RM = random(0,59);
  unsigned long RS = random(0,59);
  unsigned long TSDuration = random(0,10800000);     // Random T-Storm duration from 0-3hr
  unsigned long RecoveryDelay = random(0,3600000);   // Random after storm gloominess from 0-1hr
  
  Serial.print("RH = ");
  Serial.print(RH);
  Serial.println();
  
    
  if (RH > 12)                             // If random value is after 1 pm, allow storm
  {Alarm.alarmOnce(RH,RM,RS,Storm2);
  
  if (12 < (RH + (TSDuration/3600000)) < 19) 
  {Alarm.alarmOnce((RH + (TSDuration/3600000) + (RecoveryDelay/3600000)),Cloud2);}
  
  if (12 <= (RH + (TSDuration/3600000)) < 21)
  {Alarm.alarmOnce((RH + (TSDuration/3600000)),DawnDusk);}
  
  if ((RH + (TSDuration/3600000)) >= 21)
  {Alarm.alarmOnce((RH + (TSDuration/3600000)),Night2);}
  
  
      RH = random(0,23);                                  // Reset random values after storm
      RM = random(0,59);
      RS = random(0,59);
      TSDuration = random(0,10800000);
      RecoveryDelay = random(0,3600000);}
      
   
if (RH <= 12)                                           // Delay when storm = FALSE
{Alarm.alarmOnce(0,0,0,reset);}}
  
void reset(){
  unsigned long RH = random(0,23);                   // Randomizer for thunderstorm
  unsigned long RM = random(0,59);
  unsigned long RS = random(0,59);
  unsigned long TSDuration = random(0,10800000);     // Random T-Storm duration from 0-3hr
  unsigned long RecoveryDelay = random(0,3600000);}   // Random after storm gloominess from 0-1hr} 


////////////CLOCK///////////////////////////////////////////////////
void  loop(){                       
  digitalClockDisplay();
  Alarm.delay(3600000/4); }              // Clock display update frequency (msec)

time_t syncProvider()     //this does the same thing as RTC_DS1307::get()
{
  return RTC.now().unixtime();
}

void digitalClockDisplay()          // Digital clock
{ Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println(); }

void printDigits(int digits)        // Add :
{Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);}

  
////////////SIGNAL///////////////////////////////////////////////////
// Create Frequency (38khz/26msec)
void pulseIR(long microsecs) 
{  cli();                           // kill interupts
  while (microsecs > 0)
{  digitalWrite(IRledPin, HIGH);    // ~3 msec
   delayMicroseconds(7);            // ~delay
   digitalWrite(IRledPin, LOW);     // ~3 msec
   delayMicroseconds(7);            // ~delay
    microsecs -= 26;  }
sei();  }                           // zombie interupts


////////////FIXTURE FUNCTIONS////////////////////////////////////////
void DeviceID ()
{
  for( int i = 0 ; i < 17; i++) {
    pulseIR(DeviceID_codes[i][0]);
    delayMicroseconds(DeviceID_codes[i][1]);
  }
}

void Footer ()
{
 for( int i = 0 ; i < 3; i++) {
    pulseIR(Footer_codes[i][0]);
    delayMicroseconds(Footer_codes[i][1]);
    }
    pulseIR(620);
}

void IR(int codes[15][2]) 
{
  DeviceID();

  for( int i = 0 ; i < 15; i++) {
    pulseIR(codes[i][0]);
    delayMicroseconds(codes[i][1]);
  }  
  Footer(); 
}

void PowerButton()                             //Fixture power on/off toggle
{
  Serial.println("Power Toggle");
  IR(PowerButton_codes);
}
 
void Night2()                                   //Fixture Initialize Night2 Mode
{
  Serial.println("Night 2 Mode Initialized");
  IR(Night2_codes);
}
     
void Cloud2()                                         //Fixture Initialize Cloud2 Mode
{
  Serial.println("Cloud Cover 2 Mode Initialized");
  IR(Cloud2_codes);
}
   
void FullSpec()                                  //Fixture Initialize Full Spectrum Mode
{
  Serial.println("Full Spectrum Mode Initialized");
  IR(FullSpec_codes);
}
    
void DawnDusk()                         // Fixture Initialize Dawn/Dusk Mode
{
  Serial.println("Dawn/Dusk Mode Initialized");
  IR(DawnDusk_codes);
}

void Storm2()                         //Fixture Initialize Storm2 Mode
{
  Serial.println("Storm2 Mode Initialized");
  IR(Storm2_codes);
}
Here is the library file:
Code:
//   LED_Controller.h

int DeviceID_codes[17][2] = { {8840,4320},{620,480},{600,500},{540,1660},{580,520}, 
                              {520,560},{600,480},{620,480},{540,540},{620,1600}, 
                              {520,1660},{580,520},{520,1660},{600,1580},{620,1580}, 
                              {540,1660},{600,1580} };

int Footer_codes[3][2] = { {580,1620},{540,38980},{8860,2120} };
                           
int PowerButton_codes[15][2] = { {600,500},{600,500},{520,560},{600,500},{600,500},
                                 {520,560},{580,1620},{540,540},{600,1600},{520,1660},
                                 {580,1620},{580,1620},{520,1660},{580,1600},{580,520} };
                                  
int Night2_codes[15][2] = { {600,1640},{600,500},{520,560},{600,1620},{600,1640},
                            {520,560},{580,540},{540,540},{600,480},{520,1660},
                            {580,1620},{580,500},{520,500},{580,1600},{580,1560} };
                                  
int Cloud2_codes[15][2] = { {600,1580},{600,500},{520,1620},{600,500},{600,1600},
                            {520,560},{580,480},{540,540},{600,560},{520,1660},
                            {580,560},{580,1620},{520,560},{580,1600},{580,1640} };  

int FullSpec_codes[15][2] = { {600,1580},{600,500},{520,480},{600,1580},{600,1600},
                              {520,560},{580,1600},{540,540},{600,560},{520,1660},
                              {580,1580},{580,540},{520,560},{580,1600},{580,480} };
                              
int DawnDusk_codes[15][2] = { {600,1660},{600,1560},{520,480},{600,1580},{600,1600},
                              {520,560},{580,500},{540,540},{600,560},{520,500},
                              {580,1580},{580,540},{520,560},{580,1660},{580,1580} };
                              
int Storm2_codes[15][2] = { {600,1660},{600,540},{520,480},{600,500},{600,1600},
                            {520,560},{580,500},{540,540},{600,560},{520,1660},
                            {580,1580},{580,1620},{520,560},{580,1660},{580,1580} };
Also, I don't see how the thunderstorm code can work as is if the random hour is <= 12. That last alarm calls reset() and it looks like reset() attempts to change variables that are local to setup(). And setup() doesn't execute any time other than at startup (as I understand the Arduino), so you'd probably need the thunderstorm code in it's on function, so you could call it with the event to re-randomize them.

Last edited by Dahammer; 07-28-2013 at 04:05 PM.. Reason: Fixed error
Dahammer is offline   Reply With Quote Quick reply to this message
Reply

Tags
arduino, automation, current led+, diy, light controller

Quick Reply
Message:
Options

Register Now

In order to be able to post messages on the The Planted Tank Forum forums, you must first register.
Please enter your desired user name, your email address and other required details in the form below.
User Name:
Password
Please enter a password for your user account. Note that passwords are case-sensitive.
Password:
Confirm Password:
Email Address
Please enter a valid email address for yourself.
Email Address:

Log-in

Human Verification

In order to verify that you are a human and not a spam bot, please enter the answer into the following box below based on the instructions contained in the graphic.



Thread Tools
Display Modes

Posting Rules
You may post new threads
You may post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 02:37 PM.


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