Здравствуйте! Прошу вашей помощи. Сделал Часы с плеером и дисплеем. Добавил будильник. НО: Не могу сделать тройной будильник. Нужно оповещение утром (9:00), днем (13:00)и вечером (19:00). Накидал скетч. По аналогии (clock.setAlarm2(0, 13, 10, 10, DS3231_MATCH_H_M_S)) ставил остальные два будильника, но без результата. Может кто подсказать куда "кoпать"?. Были мысли брать отчет от 9:00 + 4 часа(13:00) и 9:00 +10часов (19:00), но реализовать не получилось. Помогите, пожалуйста. работы много и пропускаешь часто нужное время для приема лекарств). Кнопку просто "припаял", для баловства с плеером. Спойлер: Библиотека часов Библиотека на модуль часов от https://github.com/jarzebski/Arduino-DS3231 Сайт библиотеки http://www.jarzebski.pl Код (C++): //************ПОДКЛЮЧАЕМ БИБЛИОТЕКИ*************************************** #include <SoftwareSerial.h> // подключаем библиотеку SoftwareSerial #include <DFPlayer_Mini_Mp3.h> // подключаем библиотеку DFPlayer_Mini_Mp3 #include <OLED_I2C.h> // Подключение библиотеки для дисплея #include <Wire.h> // Подключаем библиотеку для работы с I2C устройствами #include <Time.h> // для часов #include <DS1307RTC.h> #include <DS3231.h> // Подключаем библиотеку для работы с RTC DS3231 //************************************************************************* DS3231 clock; // Связываем объект clock с библиотекой DS3231 RTCDateTime DateTime; // Определяем сущность структуры RTCDateTime (описанной в библиотеке DS3231) для хранения считанных с часов даты и времени RTCAlarmTime Alarm1; // Определяем сущность структуры RTCAlarmTime (описанной в библиотеке DS3231) для хранения считанных с первого будильника настроек даты и времени boolean isAlarm = false; // Логическая переменная для обработки сигнала о срабатывании будильника boolean alarmState = false; // Логическая переменная для обработки индикации при срабатывании будильника bool isClick = 1; int pinButton = 4; SoftwareSerial mySerial(11, 10); // используем PIN 10 и PIN 11 для программного порта// 11 - RX, 10 - TX OLED myOLED(SDA, SCL, 8); extern uint8_t MegaNumbers[]; // Подключение больших шрифтов extern uint8_t SmallFont[]; // Подключение маленьких шрифтов extern uint8_t RusFont[]; #define DS3231_ADDRESS 0x68 byte tMSB, tLSB; float temp3231; void alarmFunction() // Функция, вызываемая при срабатывании будильника { isAlarm = true; // Присваиваем значение "истина" переменной для обработки срабатывания будильника } void setup () { pinMode(pinButton, INPUT_PULLUP); mySerial.begin (9600); // открываем софт-порт clock.begin(); // Инициализируем работу с объектом библиотеки DS3231 clock.enableOutput(false); // Определяем назначение вывода SQW (INT) для генерации прерываний при сработке будильников mp3_set_serial (mySerial); // задаем порт для плеера mp3_set_volume (15); //устанавливаем уровень громкости myOLED.begin(); //***************************************настраиваем будильник*************************************************** clock.setAlarm1(0, 9, 5, 10, DS3231_MATCH_H_M_S); // Установить будильник-каждые 09ч: 5м: 10С в каждый день attachInterrupt(0, alarmFunction, FALLING); // Задаем функцию для обработки прерывания 0 (на пине 2) } //*************************************************************************************************************** void loop () { isClick = ClickButton(isClick); if (isClick == 0) { mp3_play(random(1, 5)); Serial.println("Play"); } tmElements_t tm; (RTC.read(tm)) ; //читаем данные из часов myOLED.setBrightness(255); // устанавливаем яркость. от 0 до 255. При 0 свечение в половину яркости. myOLED.setFont(SmallFont); //Ставим маленький шрифт myOLED.setFont(RusFont); //Используем русскоязычный шрифт // myOLED.printNumI(tm.Wday, 16, 0); switch (tm.Wday+1) // В этой переменной содержится значение дня недели. Начиная с воскресенья { case 1: myOLED.print("DJCRHTCTYMT", CENTER, 0); break; //воскресенье case 2: myOLED.print("GJYTLTKMYBR", CENTER, 0); break; // Отображение дня недели, тут понедельник case 3: myOLED.print("DNJHYBR", CENTER, 0); break; //вторник case 4: myOLED.print("CHTLF", CENTER, 0); break; // итд case 5: myOLED.print("XTNDTHU", CENTER, 0); break; case 6: myOLED.print("GZNYBWF", CENTER, 0); break; case 7: myOLED.print("CE<<JNF", CENTER, 0); break; } myOLED.printNumI(get3231Temp(), 0, 0);// выводим температуру микросхемы часов myOLED.setFont(MegaNumbers); //Подключаем большие шрифты для часов. if(tm.Hour < 10) { myOLED.print("0", 4, 13); myOLED.printNumI(tm.Hour, 26, 13); } else { myOLED.printNumI(tm.Hour, 4, 13); } myOLED.print("/", 51, 13); // Отображение двоеточия if (tm.Minute<10){ //далее отображаем минуты, myOLED.print("0", 75, 13); //если минут менее 10, то отображаем первым 0 myOLED.printNumI(tm.Minute, 97, 13); } else { myOLED.printNumI(tm.Minute, 75, 13); } myOLED.setFont(SmallFont); if (tm.Day<10){ myOLED.print("0", 40, 57); myOLED.printNumI(tm.Day , 46, 57);// Отображение даты } else { myOLED.printNumI(tm.Day , 40, 57); // Отображение даты } myOLED.print("." , 52, 57);// Отображение даты if (tm.Month<10){ myOLED.print("0" , 56, 57);// Отображение даты myOLED.printNumI(tm.Month , 62, 57);// Отображение даты } else{ myOLED.printNumI(tm.Month , 56, 57);// Отображение даты } myOLED.print("." , 68, 57);// Отображение даты myOLED.printNumI(50+1970 , 73, 57);// Отображение даты myOLED.update(); delay(500); myOLED.setFont(MegaNumbers); // Скрытие двоеточия myOLED.print("-", 51, 12); myOLED.update(); delay(500); //первый будьльник (начало)********************************************************** DateTime = clock.getDateTime(); // Считываем c часов текущие значения даты и времени в сущность DateTime Alarm1 = clock.getAlarm1(); // Считываем c первого будильника текущие настройки даты и времени в сущность Alarm1 Serial.println("Alarm: " + String(clock.dateFormat("H:i:s", Alarm1))); // Выводим настройки будильника Serial.println(); // Перевод строки if (isAlarm) // Если поступил сигнал о сработке будильника { mp3_play(random(11, 15)); // Отправляем логическое значение выводу питания светодиода при каждом срабатывании будильника Serial.println("Play"); alarmState = !alarmState; // Меняем это значение на противоположное isAlarm = false; // Отключаем сигнал о сработке будильника clock.clearAlarm1(); // Очищаем состояние сработки будильника } } float get3231Temp() { //temp registers (11h-12h) get updated automatically every 64s Wire.beginTransmission(DS3231_ADDRESS); Wire.write(0x11); Wire.endTransmission(); Wire.requestFrom(DS3231_ADDRESS, 2); //Функция по считыванию и преобразованию температуры микросхемы if(Wire.available()) { tMSB = Wire.read(); //2's complement int portion tLSB = Wire.read(); //fraction portion temp3231 = (tMSB & B01111111); //do 2's math on Tmsb temp3231 += ( (tLSB >> 6) * 0.25 ); //only care about bits 7 & 8 } else { //oh noes, no data! } return temp3231; } // метод обработки нажатия кнопки boolean ClickButton(boolean lastClick) { boolean clickButton = digitalRead(pinButton); if (clickButton != lastClick) { delay(5); clickButton = digitalRead(pinButton); } return clickButton; }
Если библиотека не позволяет создавать несколько будильников, то часы, минуты, секунды задавать через переменные. После срабатывания первого будильника менять значения переменных на значения следующего будильника.
Код (C++): _d = 0; _h = 9; _m = 15; _s = 0; clock.setAlarm1(_d, _h, _m, _s, DS3231_MATCH_H_M_S); Установили на 9.15. После срабатывания будильника меняйте значения соответствующих переменных (_d, _h, _m, _s) на значения нового будильника. P.S. И еще. Не увидел где isAlarm становится true. Будильник может и срабатывает, но условие if (isAlarm) не дает спеть плееру пока isAlarm равно false. И еще. Насколько я понял (возможно не разобрался) библиотека предусматривает только 2 будильника. Еще раз акцентирую - возможно не разобрался с количеством возможных будильников. С телефона сложновато смотреть.
Библиотека тут не при чём. Сам модуль DS3231 рассчитан на два будильника. Ну и на крайний случай организуйте будильники программно. Сверяйте полученное с модуля время с временем звонка. Совпало - включайте музыку. Сможете задать свой трек на каждое время в отдельности.
Вопрос автору. Зачем Вам две библиотеку RTC плюс отдельная функция считывания температуры чипа? Код (C++): #include <DS1307RTC.h> #include <DS3231.h> . . . float get3231Temp() { . . . } Опять же, зачем Вы считываете время двумя методами, сначала: Код (C++): (RTC.read(tm)); //читаем данные из часов а чуть ниже: Код (C++): DateTime = clock.getDateTime(); // Считываем c часов текущие значения даты и времени в сущность DateTime По переменным. "RTCDateTime DateTime" и "RTCAlarmTime Alarm1" - зачем они глобальные (они используются только в одной функции)? "boolean alarmState = false" - само значение переменной не используется никак, зачем Вы ее ввели?
Забыл удалить. делал изначально на других часах, но под руки попались DS3231. Это в принципе не страшно. Спасибо за внимательность - подправлю
Попробуйте простую библиотеку Я очень быстро в ней разобрался и на сайте все подробно расписано Мне очень помогло Можно создать сколько угодно будильников. https://lesson.iarduino.ru/page/urok-19-rtc-chasy-s-budilnikom/