#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <DHT.h>
#include <Adafruit_NeoPixel.h>
// Define pin numbers
#define DHTPIN 13
#define DHTTYPE DHT22
#define LDR_PIN A0
#define BUTTON1_PIN A8
#define BUTTON2_PIN A9
#define BUTTON3_PIN A10
#define BUTTON4_PIN A11
#define LED_PIN 7
#define LED_RING_PIN 6
#define LED_COUNT 16
// Initialize the LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Initialize the RTC
RTC_DS1307 rtc;
// Initialize the DHT22
DHT dht(DHTPIN, DHTTYPE);
// Initialize the LED ring
Adafruit_NeoPixel ring(LED_COUNT, LED_RING_PIN, NEO_GRB + NEO_KHZ800);
// Menu states
enum MenuState {
MENU_DASHBOARD,
MENU_DATETIME,
MENU_TEMPERATURE,
MENU_HUMIDITY,
MENU_BRIGHTNESS,
MENU_COUNT
};
MenuState currentMenu = MENU_DASHBOARD;
bool inMenu = true;
int currentPage = 0;
bool alarmTriggered = false;
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Initialize LCD
lcd.init();
lcd.backlight();
// Initialize RTC
if (!rtc.begin()) {
lcd.print("Couldn't find RTC");
while (1);
}
if (!rtc.isrunning()) {
lcd.print("RTC is NOT running!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Initialize DHT22
dht.begin();
// Initialize LED
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
// Initialize LED ring
ring.begin();
ring.show();
// Initialize buttons
pinMode(BUTTON1_PIN, INPUT_PULLUP);
pinMode(BUTTON2_PIN, INPUT_PULLUP);
pinMode(BUTTON3_PIN, INPUT_PULLUP);
pinMode(BUTTON4_PIN, INPUT_PULLUP);
// Show initial menu
displayMenu();
}
void loop() {
checkAlarmConditions();
updateLEDRing();
if (digitalRead(BUTTON1_PIN) == LOW) { // Navigate up
delay(200);
if (inMenu) {
currentMenu = (MenuState)((currentMenu - 1 + MENU_COUNT) % MENU_COUNT);
if (currentMenu == MENU_BRIGHTNESS) {
currentPage = 1;
} else {
currentPage = 0;
}
displayMenu();
}
}
if (digitalRead(BUTTON3_PIN) == LOW) { // Navigate down
delay(200);
if (inMenu) {
currentMenu = (MenuState)((currentMenu + 1) % MENU_COUNT);
if (currentMenu == MENU_DASHBOARD) {
currentPage = 0;
} else if (currentMenu == MENU_BRIGHTNESS) {
currentPage = 1;
}
displayMenu();
}
}
if (digitalRead(BUTTON2_PIN) == LOW) { // Return to menu
delay(200);
if (!inMenu) {
inMenu = true;
displayMenu();
}
}
if (digitalRead(BUTTON4_PIN) == LOW) { // Select menu item
delay(200);
if (inMenu) {
inMenu = false;
displayMenuContent(currentMenu);
}
}
if (!inMenu && currentMenu == MENU_DASHBOARD) {
displayDashboard();
delay(1000); // Update dashboard every second
}
}
void displayMenu() {
lcd.clear();
if (currentPage == 0) {
lcd.setCursor(0, 0);
if (currentMenu == MENU_DASHBOARD) lcd.print("- ");
lcd.print("1. Dashboard");
lcd.setCursor(0, 1);
if (currentMenu == MENU_DATETIME) lcd.print("- ");
lcd.print("2. Datum & Zeit");
lcd.setCursor(0, 2);
if (currentMenu == MENU_TEMPERATURE) lcd.print("- ");
lcd.print("3. Temperatur");
lcd.setCursor(0, 3);
if (currentMenu == MENU_HUMIDITY) lcd.print("- ");
lcd.print("4. Luftfeuchtigkeit");
} else {
lcd.setCursor(0, 0);
if (currentMenu == MENU_BRIGHTNESS) lcd.print("- ");
lcd.print("5. Helligkeit");
}
}
void displayMenuContent(MenuState menu) {
lcd.clear();
lcd.setCursor(0, 0);
switch(menu) {
case MENU_DASHBOARD:
displayDashboard();
break;
case MENU_DATETIME:
displayDateTime();
break;
case MENU_TEMPERATURE:
displayTemperature();
break;
case MENU_HUMIDITY:
displayHumidity();
break;
case MENU_BRIGHTNESS:
displayBrightness();
break;
}
}
void displayDashboard() {
lcd.clear();
DateTime now = rtc.now();
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
lcd.setCursor(0, 0);
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print(" C");
lcd.setCursor(0, 2);
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print(" %");
lcd.setCursor(0, 3);
lcd.print("Alarm: ");
lcd.print(alarmTriggered ? "ON" : "OFF");
}
void displayDateTime() {
DateTime now = rtc.now();
lcd.print(now.year(), DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.day(), DEC);
lcd.setCursor(0, 1);
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
}
void displayTemperature() {
float temperature = dht.readTemperature();
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print(" C");
}
void displayHumidity() {
float humidity = dht.readHumidity();
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print(" %");
}
void displayBrightness() {
int brightness = analogRead(LDR_PIN);
float voltage = brightness * (5.0 / 1023.0);
float lux = (voltage / 5.0) * 1000; // Convert to lux assuming a 1k resistor
lcd.print("Brightness: ");
lcd.print(lux);
lcd.print(" lux");
}
void checkAlarmConditions() {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (temperature > 50 || humidity > 70) {
triggerAlarm(true);
} else {
triggerAlarm(false);
}
}
void triggerAlarm(bool state) {
alarmTriggered = state;
if (state) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
}
void updateLEDRing() {
int brightnessValue = analogRead(LDR_PIN);
int ledCount = map(brightnessValue, 0, 1023, 0, LED_COUNT); // Map brightness to LED count
if (!alarmTriggered) {
for (int i = 0; i < LED_COUNT; i++) {
if (i < ledCount) {
// Calculate the color based on the position within the gradient
int red = map(i, 0, LED_COUNT - 1, 255, 0);
int green = map(i, 0, LED_COUNT - 1, 0, 255);
ring.setPixelColor(i, ring.Color(red, green, 0));
} else {
ring.setPixelColor(i, ring.Color(0, 0, 0)); // Turn off
}
}
ring.show();
} else {
for (int i = 0; i < LED_COUNT; i++) {
ring.setPixelColor(i, ring.Color(0, 0, 0)); // Turn off all
}
ring.show();
}
}