#include <RTClib.h>
#include <Wire.h>
#include <DHT.h>
// DHT22 setup
#define DHTPIN 15 // Pin to which the data pin of DHT is connected
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);
// Shift register pins
const int dataPin = 8;
const int clockPin = 9;
const int latchPin = 10;
RTC_DS1307 rtc;
const byte segmentMap[10] = {
B11111100, // 0
B01100000, // 1
B11011010, // 2
B11110010, // 3
B01100110, // 4
B10110110, // 5
B10111110, // 6
B11100000, // 7
B11111110, // 8
B11110110 // 9
};
// Global toggle for temp/humidity switch
bool showTemp = true;
unsigned long lastToggle = 0;
const unsigned long toggleInterval = 5000;
void setup() {
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
Wire.begin();
rtc.begin();
dht.begin();
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
void loop() {
DateTime now = rtc.now();
// Toggle temperature/humidity every 5 seconds
if (millis() - lastToggle > toggleInterval) {
showTemp = !showTemp;
lastToggle = millis();
}
// Get time and date digits
int digits[16] = {
now.hour() / 10, now.hour() % 10,
now.minute() / 10, now.minute() % 10,
now.second() / 10, now.second() % 10,
now.day() / 10, now.day() % 10,
now.month() / 10, now.month() % 10,
(now.year() / 1000) % 10, (now.year() / 100) % 10,
(now.year() / 10) % 10, now.year() % 10
};
// Get the temperature and humidity
float temp = dht.readTemperature();
float hum = dht.readHumidity();
int value = showTemp ? (int)temp : (int)hum;
int th1 = value / 10;
int th2 = value % 10;
for (int i = 0; i < 6; i++) {
updateDisplay(i, digits[i], 2); // Time: Common Cathode
delay(1);
}
for (int i = 0; i < 8; i++) {
updateDisplay(i, digits[i + 6], 3); // Date: Common Anode
delay(1);
}
updateDisplay(0, th1, 4); // Temp/Humidity: Common Anode
delay(1);
updateDisplay(1, th2, 4);
delay(1);
updateLEDs(now.dayOfTheWeek(), showTemp);
}
void updateDisplay(int pos, int num, int ctrlRegister) {
byte seg = segmentMap[num];
// Reverse logic for common anode (date, temp/hum)
if (ctrlRegister != 2) {
seg = ~seg;
}
byte sr1 = seg; // Segment data
byte sr2 = (ctrlRegister == 2) ? ~(1 << pos) : 0xFF; // Time digit enable
byte sr3 = (ctrlRegister == 3) ? (1 << pos) : 0x00; // Date digit enable
byte sr4 = (ctrlRegister == 4) ? (1 << pos) : 0x00; // Temp/Hum digit enable
byte sr5 = 0; // LED unchanged
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, sr5);
shiftOut(dataPin, clockPin, MSBFIRST, sr4);
shiftOut(dataPin, clockPin, MSBFIRST, sr3);
shiftOut(dataPin, clockPin, MSBFIRST, sr2);
shiftOut(dataPin, clockPin, LSBFIRST, sr1);
digitalWrite(latchPin, HIGH);
}
void updateLEDs(int weekday, bool showTemp) {
byte ledBits = 0;
if (weekday >= 0 && weekday <= 6) {
ledBits = (1 << weekday);
}
if (showTemp) {
ledBits |= (1 << 7); // 8th LED for temp/hum toggle
}
// Just update LEDs (no digit selected)
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, ledBits); // SR5
shiftOut(dataPin, clockPin, MSBFIRST, 0); // SR4
shiftOut(dataPin, clockPin, MSBFIRST, 0); // SR3
shiftOut(dataPin, clockPin, MSBFIRST, 0); // SR2
shiftOut(dataPin, clockPin, LSBFIRST, 0); // SR1
digitalWrite(latchPin, HIGH);
}
SUN
MON
TUE
WED
THU
FRI
SAT
TEMP/HUM
TIME HH:MM:SS
DATE DD | MM | YYYY
TEMPERATURE / HUMIDITY