// GIANT HIDDEN SHELF CLOCK 24H //
#include <Adafruit_NeoPixel.h>
#include <RTClib.h>
RTC_DS3231 rtc;
// Create a variable to hold the time data
DateTime MyDateAndTime;
// Which pin on the Arduino is connected to the NeoPixels?
#define LEDCLOCK_PIN 6
#define LEDDOWNLIGHT_PIN 5
#define LEDSECONDS_PIN 9
#define LIGHTSENSOR_PIN A0
#define PIR_PIN 4
// How many NeoPixels are attached to the Arduino?
#define LEDCLOCK_COUNT 252
#define LEDDOWNLIGHT_COUNT 8
#define LEDSECONDS_COUNT 27
// Declare our NeoPixel objects:
Adafruit_NeoPixel stripClock(LEDCLOCK_COUNT, LEDCLOCK_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripDownlighter(LEDDOWNLIGHT_COUNT, LEDDOWNLIGHT_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripSeconds(LEDSECONDS_COUNT, LEDSECONDS_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
uint32_t AMBER = stripClock.Color(255, 100, 0);
uint32_t AQUA = stripClock.Color(50, 255, 255);
uint32_t BLACK = stripClock.Color(0, 0, 0);
uint32_t BLUE = stripClock.Color(0, 0, 255);
uint32_t CYAN = stripClock.Color(0, 255, 255);
uint32_t GOLD = stripClock.Color(255, 222, 30);
uint32_t GREEN = stripClock.Color(0, 255, 0);
uint32_t JADE = stripClock.Color(0, 255, 40);
uint32_t MAGENTA = stripClock.Color(255, 0, 20);
uint32_t OLD_LACE = stripClock.Color(253, 245, 230);
uint32_t ORANGE = stripClock.Color(255, 40, 0);
uint32_t PINK = stripClock.Color(242, 90, 255);
uint32_t PURPLE = stripClock.Color(180, 0, 255);
uint32_t RED = stripClock.Color(255, 0, 0);
uint32_t TEAL = stripClock.Color(0, 255, 120);
uint32_t WHITE = stripClock.Color(255, 255, 255);
uint32_t YELLOW = stripClock.Color(255, 150, 0);
uint32_t clockHourColour = GREEN;
uint32_t clockMinuteColour = RED;
uint32_t clockSecondsColour = BLUE;
int clockFaceBrightness = 0;
//Smoothing of the readings from the light sensor so it is not too twitchy
const int numReadings = 12;
int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
long total = 0; // the running total
long average = 0; // the average
byte UTC = 1; // 1 for Bavaria
unsigned long previousMillis = 0;
unsigned int Wait_Time = 5000; // 5 sec for waiting for next sensor activation
void setup()
{
Serial.begin(9600);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
// When time needs to be set on a new device, or after a power loss, the
// following line sets the RTC to the date & time this sketch was compiled
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
// When time needs to be re-set on a previously configured device, the
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
stripClock.begin(); // INITIALIZE NeoPixel stripClock object (REQUIRED)
stripClock.show(); // Turn OFF all pixels ASAP
stripClock.setBrightness(100); // Set inital BRIGHTNESS (max = 255)
stripDownlighter.begin(); // INITIALIZE NeoPixel stripClock object (REQUIRED)
stripDownlighter.show(); // Turn OFF all pixels ASAP
stripDownlighter.setBrightness(50); // Set BRIGHTNESS (max = 255)
stripSeconds.begin(); // INITIALIZE NeoPixel stripClock object (REQUIRED)
stripSeconds.show(); // Turn OFF all pixels ASAP
stripSeconds.setBrightness(100); // Set BRIGHTNESS (max = 255)
//smoothing
// initialize all the readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++)
{
readings[thisReading] = 0;
}
//Initialisierung mit Blinken aller LEDs
for(int counter = 0; counter < 5; counter++)
{
stripClock.fill(RED, 0, LEDCLOCK_COUNT);
stripClock.show();
delay(1000);
stripClock.clear();
stripClock.show();
delay(1000);
}
for(int counter = 0; counter < 5; counter++)
{
stripDownlighter.fill(RED, 0, LEDDOWNLIGHT_COUNT);
stripDownlighter.show();
delay(1000);
stripDownlighter.clear();
stripDownlighter.show();
delay(1000);
}
for(int counter = 0; counter < 5; counter++)
{
stripSeconds.fill(RED, 0, LEDSECONDS_COUNT);
stripSeconds.show();
delay(1000);
stripSeconds.clear();
stripSeconds.show();
delay(1000);
}
}
void loop()
{
//read the time
//readTheTime();
//display the time on the LEDs
//displayTheTime();
//Record a reading from the light sensor and add it to the array
readings[readIndex] = analogRead(LIGHTSENSOR_PIN); //get an average light level from previouse set of samples
//Serial.print("Light sensor value added to array = ");
//Serial.println(readings[readIndex]);
readIndex = readIndex + 1; // advance to the next position in the array:
// if we're at the end of the array move the index back around...
if (readIndex >= numReadings) {
// ...wrap around to the beginning:
readIndex = 0;
}
//now work out the sum of all the values in the array
int sumBrightness = 0;
for (int i=0; i < numReadings; i++)
{
sumBrightness += readings[i];
}
//Serial.print("Sum of the brightness array = ");
//Serial.println(sumBrightness);
// and calculate the average:
int lightSensorValue = sumBrightness / numReadings;
//Serial.print("Average light sensor value = ");
//Serial.println(lightSensorValue);
//set the brightness based on ambiant light levels
//clockFaceBrightness = map(lightSensorValue,50, 1000, 200, 1);
//stripClock.setBrightness(clockFaceBrightness); // Set brightness value of the LEDs
//Serial.print("Mapped brightness value = ");
//Serial.println(clockFaceBrightness);
//stripClock.show();
//(red * 65536) + (green * 256) + blue ->for 32-bit merged colour value so 16777215 equals white
//stripDownlighter.fill(16777215, 0, LEDDOWNLIGHT_COUNT);
//stripDownlighter.show();
//delay(5000); //this 5 second delay to slow things down during testing
//display the time on the LEDs only if PIR is active
if (digitalRead(PIR_PIN))
{
previousMillis = millis();
if (millis() - previousMillis <= Wait_Time)
{
displayTheTime();
//set the brightness based on ambiant light levels
clockFaceBrightness = map(lightSensorValue,50, 1000, 200, 1);
stripClock.setBrightness(clockFaceBrightness); // Set brightness value of the LEDs
//Serial.print("Mapped brightness value = ");
//Serial.println(clockFaceBrightness);
stripClock.show();
//(red * 65536) + (green * 256) + blue ->for 32-bit merged colour value so 16777215 equals white
stripDownlighter.fill(16777215, 0, LEDDOWNLIGHT_COUNT);
stripDownlighter.show();
}
}
else
{
stripClock.clear();
stripClock.show();
stripDownlighter.clear();
stripDownlighter.show();
stripSeconds.clear();
stripSeconds.show();
}
}
void readTheTime()
{
// Ask the clock for the data.
DateTime now = rtc.now();
// And use it
Serial.println("");
Serial.print("Time is: "); Serial.print(now.hour());
Serial.print(":"); Serial.print(now.minute());
Serial.print(":"); Serial.println(now.second());
Serial.print("Date is: 20"); Serial.print(now.year());
Serial.print(":"); Serial.print(now.month());
Serial.print(":"); Serial.println(now.day());
}
void displayTheTime()
{
stripClock.clear(); //clear the clock face
// Ask the clock for the data.
DateTime now = rtc.now();
int firstMinuteDigit = now.minute() % 10; //work out the value of the first digit and then display it
displayNumber(firstMinuteDigit, 0, clockMinuteColour);
int secondMinuteDigit = floor(now.minute() / 10); //work out the value for the second digit and then display it
displayNumber(secondMinuteDigit, 63, clockMinuteColour);
int firstHourDigit = now.hour() + UTC;
if (summertime_EU (now.year(), now.month(), now.day(), now.hour(), 1))
{
firstHourDigit = firstHourDigit + 1;
}
firstHourDigit = firstHourDigit % 10;
displayNumber(firstHourDigit, 126, clockHourColour);
int secondHourDigit = now.hour() + UTC;
if (summertime_EU (now.year(), now.month(), now.day(), now.hour(), 1))
{
secondHourDigit = secondHourDigit + 1;
}
secondHourDigit = floor(secondHourDigit / 10);
displayNumber(secondHourDigit, 189, clockHourColour);
if (now.second() % 2)
{
stripSeconds.fill(16777215, 3, 3);
stripSeconds.fill(16777215, 12, 3);
stripSeconds.fill(16777215, 21, 3);
stripSeconds.show();
}
else
{
stripSeconds.fill(0, 0, LEDSECONDS_COUNT);
stripSeconds.show();
}
}
void displayNumber(int digitToDisplay, int offsetBy, uint32_t colourToUse)
{
switch (digitToDisplay){
case 0:
digitZero(offsetBy,colourToUse);
break;
case 1:
digitOne(offsetBy,colourToUse);
break;
case 2:
digitTwo(offsetBy,colourToUse);
break;
case 3:
digitThree(offsetBy,colourToUse);
break;
case 4:
digitFour(offsetBy,colourToUse);
break;
case 5:
digitFive(offsetBy,colourToUse);
break;
case 6:
digitSix(offsetBy,colourToUse);
break;
case 7:
digitSeven(offsetBy,colourToUse);
break;
case 8:
digitEight(offsetBy,colourToUse);
break;
case 9:
digitNine(offsetBy,colourToUse);
break;
default:
break;
}
}
boolean summertime_EU(int year, byte month, byte day, byte hour, byte tzHours)
{
// European Daylight Savings Time calculation by "jurs" for German Arduino Forum
// input parameters: "normal time" for year, month, day, hour and tzHours (0=UTC, 1=MEZ)
// return value: returns true during Daylight Saving Time, false otherwise
if (month<3 || month>10) return false; // keine Sommerzeit in Jan, Feb, Nov, Dez
if (month>3 && month<10) return true; // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep
if (month==3 && (hour + 24 * day)>=(1 + tzHours + 24*(31 - (5 * year /4 + 4) % 7)) || month==10 && (hour + 24 * day)<(1 + tzHours + 24*(31 - (5 * year /4 + 1) % 7)))
return true;
else
return false;
}