/*
* Clock and counter with WS2811 LED strip (128 LEDs).
*/
#include <FastLED.h>
#include <Wire.h>
#define SWT_PIN 2
#define LED_PIN 5
#define NUM_LEDS 128
#define DS1307_ADDRESS 0x68
CRGB leds[NUM_LEDS];
CHSV colourOfNumbers(160, 255, 255);
int hue = 0;
int counter = 0;
uint8_t clear = 0x00;
const int digits[10][12] =
{
{8, 9, 10, 14, 18, 22, 23, 24},
{7, 10, 14, 15, 16, 17, 18, 21},
{7, 8, 11, 14, 16, 18, 21, 24},
{7, 11, 14, 16, 18, 22, 24},
{9, 10, 11, 16, 21, 22, 23, 24, 25},
{7, 9, 10, 11, 14, 16, 18, 22, 23, 25},
{8, 9, 10, 14, 16, 18, 21, 22, 23, 25},
{7, 8, 11, 16, 18, 24, 25},
{7, 8, 10, 11, 14, 16, 18, 21, 22, 24, 25},
{7, 9, 10, 11, 14, 16, 18, 22, 23, 24, 25},
};
void setup()
{
pinMode(SWT_PIN, INPUT_PULLUP);
Wire.begin();
FastLED.addLeds<WS2811, LED_PIN, GRB>(leds, NUM_LEDS);
}
void displayNumber(int position, int number, CHSV colour)
{
for (int i = 0 ; i < 12 ; i++) {
if (digits[number / 10][i] != 0) {
leds[(digits[number / 10][i] + position)] = colour;
}
if (digits[number % 10][i] != 0) {
leds[(digits[number % 10][i] + 28 + position)] = colour;
}
}
}
void displayDots(int position, CHSV colour)
{
leds[position] = colour;
leds[position + 2] = colour;
}
void beginDS1307()
{
// Read the values (date and time) of the DS1307 module
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(clear);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS, 0x07);
}
uint8_t decToBcd(uint8_t value)
{
return ((value / 10 * 16) + (value % 10));
}
uint8_t bcdToDec(uint8_t value)
{
return ((value / 16 * 10) + (value % 16));
}
void loop()
{
beginDS1307();
uint8_t seconds = bcdToDec(Wire.read());
uint8_t minutes = bcdToDec(Wire.read());
uint8_t hours = bcdToDec(Wire.read() & 0xff);
hue = (hue + 1) % 2550;
colourOfNumbers.hue = hue / 10;
if (digitalRead(SWT_PIN) == LOW) {
counter = (counter + 1) % 10000;
displayNumber(0, counter / 100, colourOfNumbers);
if ((counter / 100) & 1)
displayDots(64, colourOfNumbers);
displayNumber(70, counter % 100, colourOfNumbers);
} else {
counter = 0;
displayNumber(0, hours, colourOfNumbers);
if (seconds & 1)
displayDots(64, colourOfNumbers);
displayNumber(70, minutes, colourOfNumbers);
}
FastLED.show();
FastLED.clear();
}