Da bin ich wieder habe jetzt ein RTC_mini Modul und [Erstes Projekt: Wecker :)] gefunden darauf aufbauend https://wolles-elektronikkiste.de/ds3231-basierter-wecker versucht.
wenn ich jetzt diesen Code ändere geht es nicht.
Ich ändere lediglich in den Zeilen
19 die const 3 auf 4
20 die const 4 auf 7
// https://wolles-elektronikkiste.de/ds3231-basierter-wecker
// 22.04.2025 kopiert und erweitert Tempanzeige
// ds3231_alarm_clock_with_switch.ino
#include <Wire.h>
#include <RTClib.h> // library for the DS3231
#include <LiquidCrystal_I2C.h> // library for the LCD display
#define SNOOZE_TIME 60 // set snooze time
#define SET_INCREMENT_DELAY 260 // incrementation time for settings
#define MAX_ALARM_DURATION 20000 // maximum duration of an alarm
volatile bool setItemKeyPressed = false; // flag for item key
volatile bool setValueKeyPressed = false; // flag for value key
volatile unsigned long lastLow; // needed to handle bouncing
bool alarmOn = false; // alarm activated
// mit anderen Eingängen keine Funktion
// müssen Interrupteingänge fortlaufend genutzt werden ?
const int setItemPin = 2; // choose item to set / time setting mode
const int setValuePin = 3;//4; // set (increment) value / alarm setting mode
const int alarmPin = 4;//7; // Pin for the alarm switch
typedef enum TIME_UNIT { // needed for struct "timeElement"
YEAR,
MONTH,
DAY,
HOUR,
MINUTE,
SECOND
} timeUnit;
typedef enum SET_MODE { // setting modes
DATE_TIME,
ALARM
} setMode;
struct timeElement { // for date/time/alarm setting
timeUnit tUnit;
uint16_t tMin; // minimum value
uint16_t tMax; // maximum value
char tname[7]; // name to display
};
timeElement tElementYear = { YEAR, 2025, 2050, "Year" };
timeElement tElementMonth = { MONTH, 1, 12, "Month" };
timeElement tElementDay = { DAY, 1, 31, "Day" };
timeElement tElementHour = { HOUR, 0, 23, "Hour" };
timeElement tElementMinute = { MINUTE, 0, 59, "Minute" };
RTC_DS3231 rtc; // create RTC_DS3231 object
DateTime alarmTime = DateTime(2014, 1, 1, 7, 0, 0);
LiquidCrystal_I2C lcd(0x27, 20, 2); // create display object (address, columns, rows)
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
lcd.clear();
if (!rtc.begin()) {
Serial.println(F("Couldn't find RTC"));
while (1) {}
}
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // // set rtc to date/time of compilation
rtc.disable32K(); // stop signal at the 32K pin
rtc.clearAlarm(1);
rtc.clearAlarm(2);
rtc.disableAlarm(1);
rtc.disableAlarm(2);
rtc.writeSqwPinMode(DS3231_OFF); // stop signal at the SQW pin
/* pressing the item or value button will cause a low signal at the corresponding pin
and trigger an interrupt */
pinMode(setItemPin, INPUT_PULLUP);
pinMode(setValuePin, INPUT_PULLUP);
pinMode(alarmPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(setItemPin), setItemKeyISR, FALLING);
attachInterrupt(digitalPinToInterrupt(setValuePin), setValueKeyISR, FALLING);
setItemKeyPressed = false;
setValueKeyPressed = false;
}
void loop() {
if (millis() % 1000 == 0) { // update date/time every second
printDateTime();
delay(1);
}
if (setItemKeyPressed) { // item key = date/time setting key
goIntoSetMode(DATE_TIME);
}
if (setValueKeyPressed) { // value key = alarm key
goIntoSetMode(ALARM);
}
if (rtc.alarmFired(1) && alarmOn) {
alarmAction(); // act on alarm
}
checkAlarmSetting(); // check whether alarm was (de-)activated
}
void checkAlarmSetting() {
if (!digitalRead(alarmPin) && !alarmOn) {
alarmOn = true;
lcd.setCursor(15, 1);
lcd.print("A"); // display alarm flag
rtc.setAlarm1(alarmTime, DS3231_A1_Hour);
} else if (digitalRead(alarmPin) && alarmOn) {
alarmOn = false;
lcd.setCursor(15, 1);
lcd.print(" "); // delete alam flag
rtc.disableAlarm(1);
}
}
void goIntoSetMode(setMode settingMode) {
alarmOn = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Press 1 sec"));
delay(1000); // press 1 second to go into setting mode
if (digitalRead(setItemPin) == LOW || digitalRead(setValuePin) == LOW) {
lcd.setCursor(0, 0);
lcd.print(F("Setting Mode"));
lcd.setCursor(0, 1);
if (settingMode == DATE_TIME) {
lcd.print(F("Date/Time"));
} else {
lcd.print(F("Alarm"));
}
/* wait until button is released */
while (digitalRead(setItemPin) == LOW) {}
while (digitalRead(setValuePin) == LOW) {}
delay(50); // debouncing
if (settingMode == DATE_TIME) {
setDateTime();
} else {
setAlarmTime();
}
}
setItemKeyPressed = false;
setValueKeyPressed = false;
}
void setDateTime() { // date/time setting procedure
DateTime now = rtc.now(); // get current time
uint16_t tItem = 0;
tItem = setDateTimeElement(&tElementYear, now.year());
adjustRTC(YEAR, tItem);
now = rtc.now();
tItem = setDateTimeElement(&tElementMonth, now.month());
adjustRTC(MONTH, tItem);
now = rtc.now();
tItem = setDateTimeElement(&tElementDay, now.day());
adjustRTC(DAY, tItem);
now = rtc.now();
tItem = setDateTimeElement(&tElementHour, now.hour());
adjustRTC(HOUR, tItem);
now = rtc.now();
tItem = setDateTimeElement(&tElementMinute, now.minute());
adjustRTC(MINUTE, tItem);
adjustRTC(SECOND, 0);
lcd.clear();
if (alarmOn) {
lcd.setCursor(15, 1);
lcd.print("A"); // display "alarm is on" flag
}
printDateTime();
}
void setAlarmTime() { // procedure to set an alarm
uint16_t value = 0;
value = setDateTimeElement(&tElementHour, alarmTime.hour());
alarmTime = DateTime(alarmTime.year(), alarmTime.month(), alarmTime.day(), value, alarmTime.minute(), 0);
value = setDateTimeElement(&tElementMinute, alarmTime.minute());
alarmTime = DateTime(alarmTime.year(), alarmTime.month(), alarmTime.day(), alarmTime.hour(), value, 0);
lcd.clear();
char alarmTimeBuf[] = "hh:mm";
alarmTime.toString(alarmTimeBuf);
lcd.setCursor(0, 0);
lcd.print("Alarm: ");
lcd.print(alarmTimeBuf);
delay(1000); // Show Alarm Time for one second
lcd.clear();
printDateTime();
}
void alarmAction() {
lcd.clear();
unsigned long alarmStart = millis();
/* alarm was fired, not key pressed, and alarm did not exceed max. duration */
while (!setItemKeyPressed && !setValueKeyPressed && (millis() - alarmStart < MAX_ALARM_DURATION)) {
lcd.setCursor(5, 0);
lcd.print(F("Alarm!"));
delay(500);
lcd.clear();
delay(500);
if (millis() < alarmStart) { // if millis() overflow occured
alarmStart = 0;
}
}
/* wait till buttons are released: */
while (digitalRead(setItemPin) == LOW || digitalRead(setValuePin) == LOW) {}
rtc.clearAlarm(1);
delay(50); // debouncing
DateTime now = rtc.now();
if (millis() - alarmStart < MAX_ALARM_DURATION) {
alarmTime = now + TimeSpan(SNOOZE_TIME); // set new alarm (snooze)
rtc.setAlarm1(alarmTime, DS3231_A1_Hour);
lcd.setCursor(15, 1);
lcd.print("S"); // display snooze flag
} else {
alarmOn = false;
}
setItemKeyPressed = false;
setValueKeyPressed = false;
}
/* This functions sets a time element. Pressing the value key increments the value until
the maximum value is reached. Pressing the item key will return. */
uint16_t setDateTimeElement(timeElement *tE, uint16_t currentSet) {
char buf[13];
clearLineLCD(0);
lcd.setCursor(0, 0);
sprintf(buf, "Set %s: ", tE->tname);
lcd.print(buf);
lcd.setCursor(12, 0);
sprintf(buf, "%02d", currentSet);
lcd.print(buf);
setItemKeyPressed = false;
while (!setItemKeyPressed) {
if (setValueKeyPressed) {
while (digitalRead(setValuePin) == LOW) {
currentSet++;
if (currentSet > tE->tMax) {
currentSet = tE->tMin;
}
lcd.setCursor(12, 0);
sprintf(buf, "%02d", currentSet);
lcd.print(buf);
delay(SET_INCREMENT_DELAY);
}
}
}
setItemKeyPressed = false;
return currentSet;
}
void printDateTime() { // display date/time
DateTime now = rtc.now();
char datBuf[] = "DDD, DD.MM.YYYY"; // define the date format
char timeBuf[] = "hh:mm:ss"; // define the time format
Serial.println(now.toString(datBuf)); // print date
Serial.println(now.toString(timeBuf)); // print time
lcd.setCursor(0, 0);
lcd.print(datBuf); // display date
lcd.setCursor(0, 1);
lcd.print(timeBuf); // display time
// eingefügt
lcd.setCursor(10, 1);
lcd.print(rtc.getTemperature());
}
void adjustRTC(timeUnit tU, uint16_t value) { // adjust year, month, day etc.
DateTime now = rtc.now();
switch (tU) {
case (YEAR):
rtc.adjust(DateTime(value, now.month(), now.day(), now.hour(), now.minute(), now.second()));
break;
case (MONTH):
rtc.adjust(DateTime(now.year(), value, now.day(), now.hour(), now.minute(), now.second()));
break;
case (DAY):
rtc.adjust(DateTime(now.year(), now.month(), value, now.hour(), now.minute(), now.second()));
break;
case (HOUR):
rtc.adjust(DateTime(now.year(), now.month(), now.day(), value, now.minute(), now.second()));
break;
case (MINUTE):
rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), value, now.second()));
break;
case (SECOND):
rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), value));
break;
}
delay(10);
}
void clearLineLCD(int line) { // clears on line on the display
char buf[17];
sprintf(buf, "%16s", " ");
lcd.setCursor(0, line);
lcd.print(buf);
}
void setItemKeyISR() { // ISR for pressed item key
if (millis() - lastLow >= 300) { // ignore bouncing when button is released
setItemKeyPressed = true;
}
lastLow = millis();
}
void setValueKeyISR() { // ISR for pressed value key
if (millis() - lastLow >= 50) { // ignore bouncing when button is released
setValueKeyPressed = true;
}
lastLow = millis();
}
liege ich falsch mit meiner Vermutung das Interrupteingänge fortlaufend benutzt werden müssen wie im Beispiel also 2 3 4 und ich mir den Fehler mit der Zuweisung
2 4 7 geschaffen habe?
Gruß
Walter