/*
Tix Clock
Deze code implementeert een Tix-klok op een Arduino-bord met behulp van een RTC-module
(Real-Time Clock) en NeoPixel LED-strips. Een Tix-klok is een klok die de tijd weergeeft
met behulp van LED's gerangschikt in de vorm van de cijfers 0 tot 9. Deze klok toont de
uren en minuten op afzonderlijke LED-strips, waarbij elk cijfer wordt weergegeven met
zijn respectievelijke aantal LED's.
De circuit:
- RTC-module (bijv. DS3231) voor het bijhouden van de tijd
- NeoPixel LED-strips voor het weergeven van de tijd
- Knoppen voor het handmatig aanpassen van de tijd
*/
=========================================================================================================================
#include <RTClib.h>
#include <Adafruit_NeoPixel.h>
RTC_DS3231 rtc; // Initialisatie van de Real-Time Clock (RTC) module
// Definities voor de pinnen die de LED-strips aansturen
#define LED_PIN_HOUR_TENS 13 // Pin voor het eerste cijfer van het uur
#define LED_PIN_HOUR_ONES 12 // Pin voor het tweede cijfer van het uur
#define LED_PIN_MINUTES_TENS 8 // Pin voor het eerste cijfer van de minuten
#define LED_PIN_MINUTES_ONES 7 // Pin voor het tweede cijfer van de minuten
// Aantal LED's op elke LED-strip
#define LED_COUNT_HOUR_TENS 3 // Aantal LED's voor het eerste cijfer van het uur
#define LED_COUNT_HOUR_ONES 9 // Aantal LED's voor het tweede cijfer van het uur
#define LED_COUNT_MINUTES_TENS 6 // Aantal LED's voor het eerste cijfer van de minuten
#define LED_COUNT_MINUTES_ONES 9 // Aantal LED's voor het tweede cijfer van de minuten
// Pinnen voor de knoppen om de tijd aan te passen
#define HOUR_INC_BUTTON_PIN 2 // Pin voor de knop om het uur te verhogen
#define HOUR_DEC_BUTTON_PIN 3 // Pin voor de knop om het uur te verlagen
#define MIN_INC_BUTTON_PIN 4 // Pin voor de knop om de minuten te verhogen
#define MIN_DEC_BUTTON_PIN 5 // Pin voor de knop om de minuten te verlagen
// Initialisatie van de NeoPixel LED-strips
Adafruit_NeoPixel stripHourTens(LED_COUNT_HOUR_TENS, LED_PIN_HOUR_TENS, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripHourOnes(LED_COUNT_HOUR_ONES, LED_PIN_HOUR_ONES, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripMinutesTens(LED_COUNT_MINUTES_TENS, LED_PIN_MINUTES_TENS, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripMinutesOnes(LED_COUNT_MINUTES_ONES, LED_PIN_MINUTES_ONES, NEO_GRB + NEO_KHZ800);
bool tijd = true;
bool alarm = false;
// Setup functie=========================================================================================================
void setup() {
Serial.begin(9600); // Start de seriële communicatie voor debugging
if (!rtc.begin()) { // Controleer of de RTC-module correct is geïnitialiseerd
Serial.println("Kon de RTC niet vinden!"); // Foutmelding als de RTC niet gevonden kan worden
while (1); // Blijf hier hangen als de RTC niet gevonden kan worden
}
if (rtc.lostPower()) { // Controleer of de RTC de stroom is kwijtgeraakt
Serial.println("RTC is gestopt met werken, laten we de tijd instellen!"); // Melding als de RTC is gestopt met werken
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Stel de tijd opnieuw in op het moment van compileren
}
// Configureer de pinnen van de knoppen als input met pull-up weerstand
pinMode(HOUR_INC_BUTTON_PIN, INPUT_PULLUP);
pinMode(HOUR_DEC_BUTTON_PIN, INPUT_PULLUP);
pinMode(MIN_INC_BUTTON_PIN, INPUT_PULLUP);
pinMode(MIN_DEC_BUTTON_PIN, INPUT_PULLUP);
// Start de NeoPixel LED-strips
stripHourTens.begin();
stripHourOnes.begin();
stripMinutesTens.begin();
stripMinutesOnes.begin();
// Initialiseer alle pixels op de LED-strips als 'uit'
stripHourTens.show();
stripHourOnes.show();
stripMinutesTens.show();
stripMinutesOnes.show();
}
//FUNCTIES:=============================================================================================================
// Functie om alle LED's op een strip uit te zetten
void clearLEDs(Adafruit_NeoPixel &strip) {
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, 0); // Zet de LED uit
}
strip.show();
}
// Functie om een aantal willekeurige LED's op een strip te laten oplichten
void randomLights(Adafruit_NeoPixel &strip, int count, uint32_t color) {
clearLEDs(strip); // Schakel eerst alle LED's uit op de strip
int ledPositions[strip.numPixels()]; // Array om gebruikte posities bij te houden
int usedPositions = 0;
while (usedPositions < count) {
int randomPos = random(strip.numPixels()); // Kies een willekeurige positie op de strip
bool alreadyUsed = false;
// Controleer of de positie al eerder is gebruikt
for (int i = 0; i < usedPositions; i++) {
if (ledPositions[i] == randomPos) {
alreadyUsed = true;
break;
}
}
if (!alreadyUsed) {
ledPositions[usedPositions] = randomPos; // Sla de gebruikte positie op
usedPositions++;
strip.setPixelColor(randomPos, color); // Stel de kleur in voor de verlichte LED's
}
}
strip.show(); // Laat de veranderingen zien op de LED-strip
}
// Functie om de tijd aan te passen
void adjustTime(int &timeValue, int minValue, int maxValue, int increment) {
timeValue += increment;
if (timeValue < minValue) {
timeValue = maxValue; // Terug naar het maximum als de waarde kleiner is dan het minimum
} else if (timeValue > maxValue) {
timeValue = minValue; // Terug naar het minimum als de waarde groter is dan het maximum
}
}
// Functie om de tijd te laten zien
void KLOK() {
DateTime now = rtc.now(); // Haal de huidige tijd op van de RTC-module
int hour = now.hour(); // Haal het uur op
int minute = now.minute(); // Haal de minuten op
// Verdeel de tijd in uren en minuten
int hourTens = hour / 10; // Tientallen van uren
int hourOnes = hour % 10; // Eenheden van uren
int minTens = minute / 10; // Tientallen van minuten
int minOnes = minute % 10; // Eenheden van minuten
// Toon de minuten op de LED-strips als de minuten zijn veranderd
static int prevMinOnes = -1;
static int prevMinTens = -1;
if (minOnes != prevMinOnes || minTens != prevMinTens) {
randomLights(stripMinutesTens, minTens, stripMinutesTens.Color(0, 255, 0)); // Groene LED's voor tientallen van minuten
randomLights(stripMinutesOnes, minOnes, stripMinutesOnes.Color(170, 0, 255)); // Paarse LED's voor eenheden van minuten
prevMinOnes = minOnes;
prevMinTens = minTens;
}
// Toon de uren op de LED-strips als de uren zijn veranderd
static int prevHourOnes = -1;
static int prevHourTens = -1;
if (hourOnes != prevHourOnes || hourTens != prevHourTens) {
randomLights(stripHourTens, hourTens, stripMinutesTens.Color(0, 0, 255)); // Blauwe LED's voor tientallen van uren
randomLights(stripHourOnes, hourOnes, stripMinutesOnes.Color(255, 0, 0)); // Rode LED's voor eenheden van uren
prevHourOnes = hourOnes;
prevHourTens = hourTens;
}
}
// Controleer of de knoppen zijn ingedrukt om de tijd aan te passen
void ADJUST TIME(){
if (digitalRead(HOUR_INC_BUTTON_PIN) == LOW) { // and not HOUR_DEC_BUTTON_PIN) == LOW
adjustTime(hour, 0, 23, 1); // Verhoog het uur met 1
rtc.adjust(DateTime(now.year(), now.month(), now.day(), hour, minute, 0)); // Pas de tijd aan op de RTC-module
counterSetTime := 0;
delay(150); // Debouncing vertraging om meerdere knopdrukken te voorkomen
}
if (digitalRead(HOUR_DEC_BUTTON_PIN) == LOW) {
adjustTime(hour, 0, 23, -1); // Verlaag het uur met 1
rtc.adjust(DateTime(now.year(), now.month(), now.day(), hour, minute, 0)); // Pas de tijd aan op de RTC-module
counterSetTime := 0;
delay(150); // Debouncing vertraging om meerdere knopdrukken te voorkomen
}
if (digitalRead(MIN_INC_BUTTON_PIN) == LOW) {
adjustTime(minute, 0, 59, 1); // Verhoog de minuten met 1
rtc.adjust(DateTime(now.year(), now.month(), now.day(), hour, minute, 0)); // Pas de tijd aan op de RTC-module
counterSetTime := 0;
delay(150); // Debouncing vertraging om meerdere knopdrukken te voorkomen
}
if (digitalRead(MIN_DEC_BUTTON_PIN) == LOW) {
adjustTime(minute, 0, 59, -1); // Verlaag de minuten met 1
rtc.adjust(DateTime(now.year(), now.month(), now.day(), hour, minute, 0)); // Pas de tijd aan op de RTC-module
counterSetTime := 0;
delay(150); // Debouncing vertraging om meerdere knopdrukken te voorkomen
}
counterSetTime = counterSetTime + 1;
if (counterSetTime > 5000) {
adjust time := false;
modus := true;
counterSetTime := 0;
}
}
//Functie alarm instellen
void ALARM(){
clearLEDs(strip);
delay(10000);
alarm := false;
klok := true;
modus := true;
}
//Functie Klok modus bepalen
void MODUS(){
if (digitalRead(HOUR_INC_BUTTON_PIN) == LOW && digitalRead(HOUR_DEC_BUTTON_PIN) == LOW) {
counterToSetAlarm = counterToSetAlarm + 1; //count the amount of loops that the 2 buttons are pressed.
if (counterToSetAlarm > 5000) {
klok := false;
modus := false;
adjust alarm := true;
counterToSetAlarm := 0;
}
}
else{ // The two buttons are not pressed
CounterToSetAlarm = 0;
}
if (digitalRead(MIN_INC_BUTTON_PIN) == LOW && digitalRead(MIN_DEC_BUTTON_PIN) == LOW) {
counterToSetTime = counterToSetTime + 1; //count the amount of loops that the 2 buttons are pressed.
if (counterToSetTime > 5000) {
modus := false;
adjust time := true;
counterToSetTime := 0;
}
}
else{ // The two buttons are not pressed
CounterToSetAlarm = 0;
}
}
// Hoofdprogramma========================================================================================================
void loop() {
//functies oproepen:
if (adjust time) {
ADJUST TIME();
}
if (adjust alarm) {
ADJUST ALARM();
}
if (klok){
KLOK();
}
if (modus){
MODUS();
}
if (alarm){
ALARM();
}
}