#include <Adafruit_NeoPixel.h>
#include <RTClib.h>
#include <DHT.h>
#include <Bounce2.h>
#include <elapsedMillis.h>
#define LED_PIN 6
#define LED_COUNT 58
#define DHT_PIN 2
#define DHT_TYPE DHT22
#define BUTTON_PIN 3
DHT dht(DHT_PIN, DHT_TYPE);
RTC_DS1307 rtc;
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
Bounce2::Button button = Bounce2::Button();
const uint32_t clockColor = strip.Color(0, 0, 255);
const byte symbols[14] = {
// abcdefg
0B01111110, // 0
0B01000010, // 1
0B01101101, // 2
0B01100111, // 3
0B01010011, // 4
0B00110111, // 5
0B00111111, // 6
0B01100010, // 7
0B01111111, // 8
0B01110111, // 9
0B01110001, // Deg (°)
0B00111100, // C
0B00011111, // b
0B01110011 // q
};
// Display modes
// 0 - time
// 1 - temperature
// 2 - relative humidity
// 3 - cycle between modes
uint8_t displayMode = 0;
uint8_t cycleMode = 0;
float dhtTemperature;
float dhtHumidity;
elapsedMillis dhtTimer;
elapsedMillis cycleTimer;
void setup() {
Serial.begin(9600);
dht.begin();
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
strip.begin();
strip.show();
button.attach(BUTTON_PIN, INPUT_PULLUP);
button.interval(10);
button.setPressedState(LOW);
}
void loop() {
button.update();
if (button.pressed()) {
displayMode = ++displayMode & 3;
if (displayMode == 3) {
cycleMode = 0;
cycleTimer = 0;
}
}
readDHT();
switch (displayMode) {
case 0:
displayTime();
break;
case 1:
displayTemperature();
break;
case 2:
displayHumidity();
break;
case 3:
cycleModes();
break;
}
delay(400);
}
void displaySymbol(uint8_t digit, uint8_t value) {
byte symbol = symbols[value];
uint8_t skip = digit >= 2 ? 2 : 0;
uint32_t color;
uint8_t start = (14 * digit) + skip;
for (uint8_t i = 0; i < 7; i++) {
if ((symbol >> i) & 1) {
strip.setPixelColor(start, clockColor);
strip.setPixelColor(start + 1, clockColor);
}
start += 2;
}
}
void displayTime() {
DateTime now = rtc.now();
strip.clear();
displaySymbol(0, now.hour() / 10);
displaySymbol(1, now.hour() % 10);
displaySymbol(2, now.minute() / 10);
displaySymbol(3, now.minute() % 10);
displayColon(~now.second() & 1);
strip.show();
}
void displayColon(bool state) {
uint32_t color = state ? clockColor : 0;
strip.setPixelColor(28, color);
strip.setPixelColor(29, color);
}
void displayTemperature() {
int temperature = (int) dhtTemperature;
strip.clear();
displaySymbol(0, temperature / 10);
displaySymbol(1, temperature % 10);
displaySymbol(2, 10);
displaySymbol(3, 11);
strip.show();
}
void displayHumidity() {
int humidity = (int) dhtHumidity;
strip.clear();
displaySymbol(0, humidity / 10);
displaySymbol(1, humidity % 10);
displaySymbol(2, 13);
displaySymbol(3, 12);
strip.show();
}
void readDHT() {
if (dhtTimer > 2000) {
dhtTemperature = dht.readTemperature();
dhtHumidity = dht.readHumidity();
dhtTimer = 0;
}
}
void cycleModes() {
switch (cycleMode) {
case 0:
displayTime();
break;
case 1:
displayTemperature();
break;
case 2:
displayHumidity();
break;
}
if (cycleTimer > 5000) {
cycleTimer = 0;
cycleMode = (cycleMode + 1) % 3;
}
}