Модуль и будильники

Тема в разделе "Arduino & Shields", создана пользователем Yurok_55, 13 фев 2020.

  1. Yurok_55

    Yurok_55 Нуб

    Здравствуйте!

    Прошу вашей помощи. Сделал Часы с плеером и дисплеем. Добавил будильник. НО:

    Не могу сделать тройной будильник. Нужно оповещение утром (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;
    }
     
  2. alp69

    alp69 Форумчанин

    Если библиотека не позволяет создавать несколько будильников, то часы, минуты, секунды задавать через переменные. После срабатывания первого будильника менять значения переменных на значения следующего будильника.
     
  3. Yurok_55

    Yurok_55 Нуб

    при всём уважении, не совсем понял
     
  4. alp69

    alp69 Форумчанин

    Код (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 будильника. Еще раз акцентирую - возможно не разобрался с количеством возможных будильников. С телефона сложновато смотреть.
     
    Последнее редактирование: 13 фев 2020
    Yurok_55 нравится это.
  5. a1000

    a1000 Гуру

    Библиотека тут не при чём. Сам модуль DS3231 рассчитан на два будильника.
    Ну и на крайний случай организуйте будильники программно. Сверяйте полученное с модуля время с временем звонка. Совпало - включайте музыку. Сможете задать свой трек на каждое время в отдельности.
     
    Yurok_55 и alp69 нравится это.
  6. Yurok_55

    Yurok_55 Нуб

    да всё верно библиотека рассчитана на два будильника.
    Спасибо за совет. Завтра попробую и отпишусь
     
  7. fogary

    fogary Гик

    Вопрос автору.
    Зачем Вам две библиотеку 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" - само значение переменной не используется никак, зачем Вы ее ввели?
     
    Yurok_55 нравится это.
  8. Yurok_55

    Yurok_55 Нуб

    Забыл удалить. делал изначально на других часах, но под руки попались DS3231. Это в принципе не страшно. Спасибо за внимательность - подправлю
     
  9. sanik

    sanik Гик

    Попробуйте простую библиотеку Я очень быстро в ней разобрался и на сайте все подробно расписано Мне очень помогло Можно создать сколько угодно будильников.
    https://lesson.iarduino.ru/page/urok-19-rtc-chasy-s-budilnikom/
     
    Yurok_55 нравится это.