Created
December 13, 2014 04:09
-
-
Save ilmaestro/0bc0ba78f5ee739bb706 to your computer and use it in GitHub Desktop.
Revisions
-
ilmaestro created this gist
Dec 13, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,249 @@ /***** AquaLight - Versin 2.0 (rewritten after accidentally deleting my project after a year) Ryan Kilkenny - 12/26/2010 basic functions: * RTC - timing functions * Serial LCD - Clock Display, future menu system * PWM - LED light control program * light modes 0 dark: all lights off 1 daylight: 5 hours of constant daylight 2 highlight: 2 - 3 hours of light changes, white to blue, bright blue 3 moonlight: 4 hours of dim blues * timing - start time: 2pm - daylight (2pm - 7pm) - highlight (7pm - 9pm) - moonlight (9pm - 1pm) - dark ***/ #include <Time.h> #include <TimeAlarms.h> #include <Wire.h> #include <DS1307RTC.h> #include <math.h> //global constants #define WHITE_PIN 3 #define BLUE_PIN 11 #define DARK_MODE 0 #define DAYLIGHT_MODE 1 #define HIGHLIGHT_MODE 2 #define MOONLIGHT_MODE 3 #define MODE_MENU 0 #define INTENSITY_MENU 1 #define NUM_MENUS 2 #define NUM_LIGHTMODES 4 //global variables int Lightmode = DARK_MODE; int DisplayMenu = MODE_MENU; int CurrentHour; int TestMode = 0; char* DisplayMenus[NUM_MENUS] = {"Mode", "Intensity"}; //24 hour clock times int DarkHour = 2; int DaylightHour = 14; int HighlightHour = 19; int MoonlightHour = 21; char* LightmodeStrings[NUM_LIGHTMODES] = {"Dark", "Day", "Show", "Moon"}; //light mode display values //light intensities int WhiteIntensity = 255; int BlueIntensity = 255; int WhiteVariance = 0; int BlueVariance = 0; //Timer durations int DisplayTimerDur = 1000; int DisplayTimer; int DisplayMenuTimerDur = 10000; int DisplayMenuTimer; int SetLightmodeTimerDur = 30000; int SetLightmodeTimer; int SetLightIntensityTimerDur = 500; int SetLightIntensityTimer; int HighlightTimerDur = 5000; int HighlightTimer; int HighlightLatch = 0; /*********** MAIN SETUP ***********/ void setup() { Serial.begin(9600); randomSeed(analogRead(0)); //seed with analog noise beginPwm(); beginSerialLCD(); beginRTC(); beginLightTest(); beginTimers(); clearLCD(); } /*********** MAIN LOOP ***********/ void loop() { int currentMillis = millis(); //Check display Menu //Check lightmode timer if (currentMillis - DisplayMenuTimer >= DisplayMenuTimerDur) { DisplayMenu++; if(DisplayMenu >= NUM_MENUS) DisplayMenu = MODE_MENU; DisplayMenuTimer = millis(); } //Check display timer if (currentMillis - DisplayTimer >= DisplayTimerDur) { CurrentHour = hour(); digitalDisplay(); DisplayTimer = millis(); } //Check lightmode timer if (currentMillis - SetLightmodeTimer >= SetLightmodeTimerDur) { setLightMode(); SetLightmodeTimer = millis(); } //Check intensity timer if (currentMillis - SetLightIntensityTimer >= SetLightIntensityTimerDur) { setLighting(); setIntensity(WhiteIntensity, BlueIntensity); SetLightIntensityTimer = millis(); } } /********** Display Functions **********/ void digitalDisplay(){ // digital clock display of the time selectLineOne(); Serial.print(hour()); printDigits(minute()); printDigits(second()); Serial.print(" "); Serial.print(month()); Serial.print("/"); Serial.print(day()); selectLineTwo(); switch (DisplayMenu) { case MODE_MENU: Serial.print("Mode: "); Serial.print(LightmodeStrings[Lightmode]); Serial.print(" "); break; case INTENSITY_MENU: Serial.print("Int:"); printDigits999(WhiteIntensity); Serial.print("w "); printDigits999(BlueIntensity); Serial.print("b "); break; } } /*********** Setup Functions ***********/ void beginLightTest() { TestMode = 1; for(int i = 0; i < 4; i++) { Lightmode = i; setLighting(); setIntensity(WhiteIntensity, BlueIntensity); clearLCD(); selectLineTwo(); Serial.print("Mode: "); Serial.print(i); //Serial.println(); delay(3000); } TestMode = 0; CurrentHour = hour(); setLightMode(); } void beginTimers() { //setTime(8,29,0,1,1,10); // set time to 8:29:00am Jan 1 2010 //setTime(18,0,0,26,12,10); // set time to 8:29:00am Jan 1 2010 //Alarm.timerRepeat(30, taskSetLightMode); // check lightMode every 30 seconds resetTimers(); } void beginRTC() { setSyncProvider(RTC.get); // the function to get the time from the RTC if(timeStatus()!= timeSet) Serial.println("Unable to sync with the RTC"); else Serial.println("RTC has set the system time"); } void beginSerialLCD() { delay(500); //wait clearLCD(); selectLineOne(); Serial.print("AquaLight v2.0"); delay(2000); clearLCD(); } void beginPwm() { //pins 3,11 have a base of 31250 Hz int divisor = 64; // 488.28125 Hz setPwmFrequency(WHITE_PIN, divisor); setPwmFrequency(BLUE_PIN, divisor); } void setPwmFrequency(int pin, int divisor) { byte mode; if(pin == 5 || pin == 6 || pin == 9 || pin == 10) { switch(divisor) { case 1: mode = 0x01; break; case 8: mode = 0x02; break; case 64: mode = 0x03; break; case 256: mode = 0x04; break; case 1024: mode = 0x05; break; default: return; } if(pin == 5 || pin == 6) { TCCR0B = TCCR0B & 0b11111000 | mode; } else { TCCR1B = TCCR1B & 0b11111000 | mode; } } else if(pin == 3 || pin == 11) { switch(divisor) { case 1: mode = 0x01; break; case 8: mode = 0x02; break; case 32: mode = 0x03; break; case 64: mode = 0x04; break; case 128: mode = 0x05; break; case 256: mode = 0x06; break; case 1024: mode = 0x7; break; default: return; } TCCR2B = TCCR2B & 0b11111000 | mode; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,137 @@ /*********** Light Modes ***********/ void dark() { WhiteIntensity = 255; BlueIntensity = 255; } void daylight() { if (TestMode == 1) { WhiteIntensity = 10; BlueIntensity = 10; return; } if (random(100) == 42) { WhiteVariance = random(240); BlueVariance = random(240); } WhiteIntensity = fadeTowards(WhiteIntensity, 10 + WhiteVariance, 1); BlueIntensity = fadeTowards(BlueIntensity, 10 + BlueVariance, 1); } void highlight() { if (TestMode == 1) { WhiteIntensity = 255; BlueIntensity = 10; return; } int timerDiff = millis() - HighlightTimer; if (timerDiff >= HighlightTimerDur) { switch (HighlightLatch) { case 0: //fade out the white, fade in the blue WhiteIntensity = fadeTowards(WhiteIntensity,255,1); BlueIntensity = fadeTowards(BlueIntensity,10,1); if (BlueIntensity <= 10) HighlightLatch = 1; //goto next sequence break; case 1: //fade out the blue WhiteIntensity = fadeTowards(WhiteIntensity,255,1); BlueIntensity = fadeTowards(BlueIntensity,255,1); if (BlueIntensity > 254) HighlightLatch = 2; //goto next sequence break; case 2: //fade in the white WhiteIntensity = fadeTowards(WhiteIntensity,10,1); BlueIntensity = fadeTowards(BlueIntensity,255,1); if (WhiteIntensity < 11) HighlightLatch = 3; //goto next sequence break; case 3: //fade out the white WhiteIntensity = fadeTowards(WhiteIntensity,255,1); BlueIntensity = fadeTowards(BlueIntensity,255,1); if (WhiteIntensity < 11) HighlightLatch = 0; //goto next sequence break; } HighlightTimer = millis(); } } void moonlight() { if (TestMode == 1) { WhiteIntensity = 255; BlueIntensity = 254; return; } if (random(100) == 50) { BlueVariance = random(5); } WhiteIntensity = 255; BlueIntensity = fadeTowards(BlueIntensity, 250 + BlueVariance, 1); } /********** Light Functions **********/ void setLighting() { switch(Lightmode) { case DARK_MODE: dark(); break; case DAYLIGHT_MODE: daylight(); break; case HIGHLIGHT_MODE: highlight(); break; case MOONLIGHT_MODE: moonlight(); break; default: dark(); } } void setIntensity(int white, int blue) { analogWrite(WHITE_PIN, white); analogWrite(BLUE_PIN, blue); } int fadeTowards(int input, int dest, int increment) { int output; if (input > dest) { output = input - increment; } else if (input < dest) { output = input + increment; } else { output = input; } return output; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,60 @@ /*********** Sparkfun Serial LCD Functions ************/ void selectLineOne(){ //puts the cursor at line 0 char 0. Serial.print(0xFE, BYTE); //command flag Serial.print(128, BYTE); //position } void selectLineTwo(){ //puts the cursor at line 0 char 0. Serial.print(0xFE, BYTE); //command flag Serial.print(192, BYTE); //position } void goTo(int position) { //position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0 if (position<16){ Serial.print(0xFE, BYTE); //command flag Serial.print((position+128), BYTE); //position }else if (position<32){Serial.print(0xFE, BYTE); //command flag Serial.print((position+48+128), BYTE); //position } else { goTo(0); } } void clearLCD(){ Serial.print(0xFE, BYTE); //command flag Serial.print(0x01, BYTE); //clear command. } void backlightOn(){ //turns on the backlight Serial.print(0x7C, BYTE); //command flag for backlight stuff Serial.print(157, BYTE); //light level. } void backlightOff(){ //turns off the backlight Serial.print(0x7C, BYTE); //command flag for backlight stuff Serial.print(128, BYTE); //light level for off. } void serCommand(){ //a general function to call the command flag for issuing all other commands Serial.print(0xFE, BYTE); } void printDigits(int digits){ // utility function for digital clock display: prints preceding colon and leading 0 Serial.print(":"); if(digits < 10) Serial.print('0'); Serial.print(digits); } void printDigits999(int digits) { if (digits < 100) Serial.print('0'); if (digits < 10) Serial.print('0'); Serial.print(digits); } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,69 @@ /***** Timer functions *****/ void resetTimers() { DisplayTimer = millis(); SetLightmodeTimer = millis(); SetLightIntensityTimer = millis(); HighlightTimer = millis(); DisplayMenuTimer = millis(); } /* taskSetLightMode - checks the current hour and sets the lighting mode get all diffs: CurrentHour - Lightmode Hour rule out any negatives (where current hour already past time) special case: when should moonlight end? if hour is between midnight and next dark hour, all diffs will already be negative if hour is 1, next dark hour is 2, and last moon hour was 21 */ void setLightMode() { int darkDiff = getHourDiff(CurrentHour, DarkHour); int daylightDiff = getHourDiff(CurrentHour, DaylightHour); int highlightDiff = getHourDiff(CurrentHour, HighlightHour); int moonlightDiff = getHourDiff(CurrentHour, MoonlightHour); //make sure these are in the same order as the lightModes.. then we won't have to compare to figure out which mode is which value. byte diffs[] = {darkDiff, daylightDiff, highlightDiff, moonlightDiff}; //set all negatives to 99 for(int i = 0; i < 4; i++) { if(diffs[i] < 0) { diffs[i] = 99; } } //find minimum value int minimum = diffs[0]; int minCount = 0; for(int i = 0; i < 4; i++) { if(diffs[i] < minimum) { minimum = diffs[i]; minCount = i; } } Lightmode = minCount; setLighting(); } int getHourDiff(int currenthour, int diffHour) { int result = 99; if (currenthour == 0) currenthour = 24; //check if we're in the special case hour if (currenthour < DarkHour && diffHour > DarkHour) { result = currenthour + (24 - diffHour); // example: 1am -> 1 + (24 - 14) = 11, so 11 hours since 2pm } else { result = currenthour - diffHour; } return result; }