Code dump:
/*
NTLamp2
Written by Jeremy Lambert
Copyright 2015 All Rights Reserved
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
*/
//NOTE: DST compensation is in with 24 hour bug fix. set RTC with standard time.
#include <Wire.h>
#include <Adafruit_NeoPixel.h>
#include <Adafruit_LEDBackpack.h>
#include <Adafruit_GFX.h>
#include <avr/power.h>
#include <RTClib.h>
#include <Timer.h>
#include "enums.h"
#define SENSOR_PIN_IRD 3 //analog
#define SENSOR_PIN_PIR 7 //digital
#define LIGHT_PIN 5 //digital...changed this from 4 because I think the timer is on there
#define NUMPIXELS 16 //neopixel ring
#define DEBOUNCE_DELAY 10
#define SUNRISE_DELAY 6000 //should generally be 6000 (6 secs a color click = 30 min sunrise)
#define SUNRISE_TICK_COUNT 300
boolean dimmerActive = false;
int val1 = 0;
int val2 = 0;
int val3 = 0;
int val4 = 0;
//DIMMER CONTROL
int lastPWM = 0;
int smoothPWM = 20;
int readingPWM = 0;
int currentLightPWM = 0;
int DIMMER_STEP = 4;
boolean clockfaceLEDState = false;
uint8_t sunrise_index = 0;
uint8_t mode = INACTIVE;
int tickEvent = -1;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LIGHT_PIN, NEO_GRB + NEO_KHZ800);
RTC_DS1307 RTC;
DateTime Clock;
Timer t;
Adafruit_7segment matrix = Adafruit_7segment();
//uint8_t redList[] = { 0,8,17,26,35,43,52,61,70,79,87,96,105,114,123,131,140,149,158,167,175,184,193,202,211,219,228,237,246,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,254,253,253,252,252,251,250,250,249,249,248,247,247,246,246,245,245,244,243,243,242,242,241,240,240,239,239,238,237,237,236,236,235,235,234,233,233,232,232,231,230,230,229,229,228,228,227,226,226,225,225,224,223,223,222,222,221,220,220,219,219,218,218,217,216,216,215,215,214,213,213,212,212,211,211,210,209,209,208,208,207,206,206,205,205,204,203,203,202,202,201,201,200,199,199,198,198,197,196,196,195,195,194,193,193,192,192,191,191,190,189,189,188,188,187,186,186,185,185,184,184,183,182,182,181,181,180,179,179,178,178,177,176,176,175,175,174,174,173,172,172,171,171,170,169,169,168,168,167,167,166,165,165,164,164,163,162,162,161,161,160,159,159,158,158,157,157,156,155,155,154,154,153,152,152,151,151,150,150,149,148,147,146,145,144,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128
//};
//uint8_t greenList[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,6,8,10,13,15,17,19,21,23,26,28,30,32,34,36,39,41,43,45,47,49,52,54,56,58,60,62,65,67,69,71,73,75,78,80,82,84,86,88,91,93,95,97,99,101,104,106,108,110,112,114,117,119,121,123,125,128,128,130,132,135,137,140,142,145,147,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,149,148,147,146,145,144,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128
//};
//uint8_t blueList[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,5,6,7,9,10,11,12,14,15,16,18,19,20,22,23,24,25,27,28,29,31,32,33,34,36,37,38,40,41,42,44,45,46,47,49,50,51,53,54,55,57,58,59,60,62,63,64,66,67,68,69,71,72,73,75,76,77,79,80,81,82,84,85,86,88,89,90,92,93,94,95,97,98,99,101,102,103,104,106,107,108,110,111,112,114,115,116,117,119,120,121,123,124,125,127,128,129,130,132,133,134,136,137,138,139,141,142,143,145,146,147,149,150,151,152,154,155,156,158,159,160,162,163,164,165,167,168,169,171,172,173,174,176,177,178,180,181,182,184,185,186,187,189,190,191,193,194,195,197,198,199,200,202,203,204,206,207,208,209,211,212,213,215,216,217,219,220,221,222,224,225,226,228,229,230,232,233,234,235,236,237,238,240,241,242,243,244,245,246,247,248,249,250,251,252,253,255
//};
void setup() {
Serial.begin(9600);
Serial.println("start setup");
pinMode(SENSOR_PIN_IRD, INPUT);
Serial.println("start IRD");
pinMode(SENSOR_PIN_PIR, INPUT);
Serial.println("start PIR");
digitalWrite(SENSOR_PIN_PIR, LOW); //no pullup. no need.
Wire.begin();
Serial.println("start wire");
pixels.begin();
Serial.println("start pixels");
RTC.begin();
//RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); //this is for setting the clock with the compile date and time. kinda handy.
//TODO: don't forget to comment out for the final push to device, or it'll reset to whatever time it was compiled every time it's reset
Serial.println("start RTC");
matrix.begin(0x70);
Serial.println("start matrix");
matrix.setBrightness(3);
Serial.println("set brightness");
startUp();
Serial.println("startup");
setColors(0, 0, 0);
Serial.println("set lights off");
Serial.println("end setup");
}
void loop()
{
t.update(); //timer tick update
//clock functions
uint8_t hourval =0, minuteval = 0, secondval = 0;
if(digitalRead(SENSOR_PIN_PIR) == HIGH && !dimmerActive)
{
//Serial.println("face on");
DateTime clock;
clock = RTC.now();
if (CheckDST(clock))
{
hourval = (clock.hour() + 1) % 24;
}
else
hourval = clock.hour();
minuteval = clock.minute();
secondval = clock.second();
matrix.writeDigitNum(0, hourval / 10);
matrix.writeDigitNum(1, hourval % 10);
matrix.writeDigitNum(3, minuteval / 10);
matrix.writeDigitNum(4, minuteval % 10);
bool isEven = false;
if ((secondval % 2) == 0)
{
isEven = true;
}
matrix.drawColon(isEven);
matrix.writeDisplay();
}
else if (!dimmerActive)
{
//Serial.println("FACEOFF");
matrix.clear();
matrix.writeDisplay();
}
//if it's alarm time
if (mode != ALARM)
{
if (hourval==6 && minuteval ==15) //not the best way to do this
{
//sunrise(); //TODO: fix this shit. it hangs sometimes after 1 min
}
}
//LED functions
val1 = analogRead(SENSOR_PIN_IRD);
delay(DEBOUNCE_DELAY);
val2 = analogRead(SENSOR_PIN_IRD);
delay(DEBOUNCE_DELAY);
val3 = analogRead(SENSOR_PIN_IRD);
delay(DEBOUNCE_DELAY);
val4 = analogRead(SENSOR_PIN_IRD);
int avgRead = constrain(((val1 + val2 + val3 + val4) >> 2), 249, 600);
readingPWM = map(avgRead, 250, 600, 256, 0);
int diff = abs(readingPWM - lastPWM);
lastPWM = readingPWM;
if (diff > smoothPWM)
{
return;
}
if (readingPWM > 50 && readingPWM < 256)
{
switch(mode)
{
case INACTIVE:
if (readingPWM > 0) //TODO: huh?
{
mode=LAMP;
Serial.println(readingPWM, DEC);
fadeInWhite(254,3);
delay(500);
}
break;
case LAMP:
Serial.print("Read PWM: ");
Serial.println(readingPWM);
int newval, mapPercent;
if (readingPWM > 60 && readingPWM < 255)
dimmerActive = true;
if (readingPWM > 60 && readingPWM < 150) //lowering
{
newval = currentLightPWM - DIMMER_STEP;
}
else if (readingPWM >150 && readingPWM < 255) //raising
{
newval = currentLightPWM + DIMMER_STEP;
}
if (newval > 255)
newval = 255;
if (newval < 0)
newval = 0;
currentLightPWM = newval;
Serial.print("Light PWM: ");
Serial.println(currentLightPWM);
mapPercent = map(currentLightPWM, 0, 255, 1, 100);
matrix.drawColon(false);
matrix.println(mapPercent, DEC);
matrix.writeDisplay();
setColors(currentLightPWM, currentLightPWM, currentLightPWM);
break;
case ALERT:
case ALARM:
if (readingPWM > 1)
{
setOff();
}
break;
}
}
else if (readingPWM > 1 && readingPWM < 50)
{
Serial.println("off");
setOff();
}
else
{
delay(200);
dimmerActive = false;
}
}
//LIGHT STUFF
void startUp()
{
//for(int i=0;i<300;i++){
//setColors(redList[i], greenList[i], blueList[i]);
//delay(10);
//}
delay(2000);
//== 5 seconds long enough for the PIR to warm up and calibrate
}
void setColors(int r, int g, int b)
{
for(int i=0;i<NUMPIXELS;i++){
pixels.setPixelColor(i, pixels.Color(r,g,b));
pixels.show();
}
}
void fadeInWhite(int level, int stepDelay)
{
for(int s=level;s>0;s--){
setColors(level - s,level-s,level-s);
delay(stepDelay);
currentLightPWM = level;
}
}
void fadeOut(int stepDelay)
{
for(int s=0;s< currentLightPWM + 1;s++){
setColors(currentLightPWM - s,currentLightPWM-s,currentLightPWM-s);
delay(stepDelay);
}
currentLightPWM = 0;
}
void setOff()
{
if (tickEvent >= 0)
{
t.stop(tickEvent);
tickEvent = -1;
}
sunrise_index = 0;
fadeOut(2);
// setColors(0,0,0);
mode = INACTIVE;
delay(1000);
}
void sunrise()
{
mode = ALARM;
tickEvent = t.every(SUNRISE_DELAY, sunrise_tick, SUNRISE_TICK_COUNT);
}
void sunrise_tick()
{
//setColors(redList[sunrise_index], greenList[sunrise_index], blueList[sunrise_index]);
sunrise_index++;
}
bool CheckDST(DateTime tClock)
{
// Daylight saving time starts on the second Sunday in March and ends on the first
// Sunday in November, with the time changes taking place at 2:00 a.m. local time.
// With a mnemonic word play referring to seasons, clocks "spring forward and fall back"—that
// is, in spring (technically late winter) the clocks are moved forward from 2:00
// a.m. to 3:00 a.m., and in fall they are moved back from 2:00 am to 1:00 am.
if (tClock.month() < 3 || tClock.month() > 11) { return false; }
//April to October are in
if (tClock.month() > 3 && tClock.month() < 11) { return true; }
int previousSunday = tClock.day() - tClock.dayOfWeek();
//In march, we are DST if our previous sunday was on or after the 8th.
if (tClock.month() == 3) { return previousSunday >= 8; }
//In november we must be before the first sunday to be dst.
//That means the previous sunday must be before the 1st.
return previousSunday <= 0;
}
full of sexy sunrise alarm data (not implemented) and arduino timing cheats.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.