Помогите разобраться с часами DS3231

Тема в разделе "Arduino & Shields", создана пользователем Mr.cap, 10 мар 2016.

  1. Mr.cap

    Mr.cap Нуб

    Не могу понять в чем проблема, все идеально работает (в нужное время загорается светодиод и в нужное время тухнет), но стоит внести изменение и поставить знак ">=" заместо "==", то все перестает нормально работать. При достижении времени, когда светодиод должен потухнуть, он вместо этого начинает гореть в пол силы, тухнуть на 5-8 секунд и снова гореть в пол силы. Зачем мне знак ">=" спросите Вы. Мне он нужен, чтобы при пропадании и появлении питания, светодиод продолжал гореть, а не дожидаться следующего дня, чтобы включиться ровно в ХХ часов и ХХ минут. Вопрос: что я делаю не так, что при смени знака "==" на ">=" все перестает нормально работать?
    Код (C++):
    #include <config.h>
    #include <ds3231.h>
    #include <RTC.h>
    #include <Wire.h>

    RTC    time;
    #define BLUE_LED 12
    void setup() {
        delay(300);
        Serial.begin(9600);
        time.begin(RTC_DS3231);
        pinMode(BLUE_LED, OUTPUT);
        //time.settime(10,26,19,28,02,16,7);  // 0  сек, 51 мин, 21 час, 27, октября, 2015 года, вторник
    }
    void loop()
    {
        if(millis()%1000==0){ // если прошла 1 секунда
          Serial.println(time.gettime("d-m-Y, H:i:s, D")); // выводим время
          delay(1); // приостанавливаем на 1 мс, чтоб не выводить время несколько раз за 1мс
        }
        if (time.Hours==13 && time.minutes==15 && time.seconds==5 && time.day==2 && time.month==3)
          {
          digitalWrite(BLUE_LED, HIGH);
          }
        if (time.Hours==22 && time.minutes==45 && time.seconds==35 && time.day==2 && time.month==3)
          {
          digitalWrite(BLUE_LED, LOW);
          }
    }
     
    Последнее редактирование: 10 мар 2016
  2. Securbond

    Securbond Гуру

  3. nailxx

    nailxx Официальный Нерд Администратор

    А какие именно знаки вы меняете? Можете привести изменённый скетч, который не работает?
     
  4. Mr.cap

    Mr.cap Нуб

    Вот не рабочий скетч:
    Код (C++):
    #include <config.h>
    #include <ds3231.h>
    #include <RTC.h>
    #include <Wire.h>

    RTC    time;
    #define BLUE_LED 12
    void setup() {
        delay(300);
        Serial.begin(9600);
        time.begin(RTC_DS3231);
        pinMode(BLUE_LED, OUTPUT);
        //time.settime(10,26,19,28,02,16,7);  // 0  сек, 51 мин, 21 час, 27, октября, 2015 года, вторник
    }
    void loop()
    {
        if(millis()%1000==0){ // если прошла 1 секунда
          Serial.println(time.gettime("d-m-Y, H:i:s, D")); // выводим время
          delay(1); // приостанавливаем на 1 мс, чтоб не выводить время несколько раз за 1мс
        }
        if (time.Hours>=13 && time.minutes>=15 && time.seconds>=5)
          {
          digitalWrite(BLUE_LED, HIGH);
          }
        if (time.Hours>=22 && time.minutes>=45 && time.seconds>=35)
          {
          digitalWrite(BLUE_LED, LOW);
          }
    }
     
  5. nailxx

    nailxx Официальный Нерд Администратор

    Смотрите, в 22:50:40 у вас срабатывают оба условия. Светодиод попеременно то включается, то гаснет, что воспринимается, как горение в полсилы. По ходу течения секунд некоторые условия перестают срабатывать — светодиод «залипает» на некоторое время.

    Я бы сделал так:

    Код (C++):
    bool isDayTime = time.Hours >= 13 &&
        time.minutes >= 15 &&
        time.seconds >= 5 &&
        time.Hours <= 22 &&
        time.minutes <= 45 &&
        time.seconds < 35;

    digitalWrite(BLUE_LED, isDayTime);
     
  6. nailxx

    nailxx Официальный Нерд Администратор

    Сам ерунду написал. Вот так правильно:

    Код (C++):

    int cmpTime(const RTC& rtc, byte hour, byte minunte, byte second)
    {
      if (rtc.Hours > hour)
        return 1;
      else if (rtc.Hours < hour)
        return -1;
     
      if (rtc.minutes > minute)
        return 1;
      else if (rtc.minutes < minute)
        return -1;

      if (rtc.seconds > second)
        return 1;
      else if (rtc.seconds < second)
        return -1;

      return 0;
    }


    bool isDayTime =
      cmpTime(time, 13, 15, 5) > 0 &&
      cmpTime(time, 22, 45, 35) < 0;

    digitalWrite(BLUE_LED, isDayTime);
     
  7. Mr.cap

    Mr.cap Нуб

    Спасибо большое за ответ, но у меня чет не получается скомпилировать скетч. Может я что-то не то делаю. Вот скет, который не получается скомпилировать:
    Код (C++):
    #include <config.h>
    #include <ds3231.h>
    #include <RTC.h>
    #include <Wire.h>

    RTC    time;
    #define BLUE_LED 12
    void setup() {
        delay(300);
        Serial.begin(9600);
        time.begin(RTC_DS3231);
        pinMode(BLUE_LED, OUTPUT);
        //time.settime(10,26,19,28,02,16,7);  // 0  сек, 51 мин, 21 час, 27, октября, 2015 года, вторник
    }
    void loop()
    {
        if(millis()%1000==0){ // если прошла 1 секунда
          Serial.println(time.gettime("d-m-Y, H:i:s, D")); // выводим время
          delay(1); // приостанавливаем на 1 мс, чтоб не выводить время несколько раз за 1мс
        }
        int cmpTime(const RTC& rtc, byte hour, byte minunte, byte second)
    {
      if (rtc.Hours > hour)
        return 1;
      else if (rtc.Hours < hour)
        return -1;
      if (rtc.minutes > minute)
        return 1;
      else if (rtc.minutes < minute)
        return -1;

      if (rtc.seconds > second)
        return 1;
      else if (rtc.seconds < second)
        return -1;

      return 0;
    }


    bool isDayTime =
      cmpTime(time, 13, 15, 5) > 0 &&
      cmpTime(time, 22, 45, 35) < 0;

    digitalWrite(BLUE_LED, isDayTime);
    }
    Вот список ошибок, возникший при компиляции:
    C:\Users\Юзер\Desktop\Ардуино проекты\Все что связано с временем\sketch_mar03a\sketch_mar03a.ino: In function 'void loop()':

    sketch_mar03a:24: error: a function-definition is not allowed here before '{' token

    sketch_mar03a:45: error: 'cmpTime' was not declared in this scope

    exit status 1
    a function-definition is not allowed here before '{' token
    12.JPG
     
  8. nailxx

    nailxx Официальный Нерд Администратор

    Код (C++):
    #include <config.h>
    #include <ds3231.h>
    #include <RTC.h>
    #include <Wire.h>

    #define BLUE_LED 12

    RTC time;

    void setup() {
        delay(300);
        Serial.begin(9600);
        time.begin(RTC_DS3231);
        pinMode(BLUE_LED, OUTPUT);
        //time.settime(10,26,19,28,02,16,7);  // 0  сек, 51 мин, 21 час, 27, октября, 2015 года, вторник
    }


    int cmpTime(const RTC& rtc, byte hour, byte minunte, byte second)
    {
        if (rtc.Hours > hour)
            return 1;
        else if (rtc.Hours < hour)
            return -1;

        if (rtc.minutes > minute)
            return 1;
        else if (rtc.minutes < minute)
            return -1;

        if (rtc.seconds > second)
            return 1;
        else if (rtc.seconds < second)
            return -1;

        return 0;
    }

    void loop()
    {
        if (millis() % 1000 == 0) { // если прошла 1 секунда
            Serial.println(time.gettime("d-m-Y, H:i:s, D")); // выводим время
            delay(1); // приостанавливаем на 1 мс, чтоб не выводить время несколько раз за 1мс
        }

        bool isDayTime =
            cmpTime(time, 13, 15, 5) > 0 &&
            cmpTime(time, 22, 45, 35) < 0;

        digitalWrite(BLUE_LED, isDayTime);
    }
     
     
  9. Mr.cap

    Mr.cap Нуб

    Огромное Вам спасибо. Все работает! Только Вы там не много ошиблись, я исправил)) В строке: int cmpTime(const RTC& rtc, byte hour, byte minunte, byte second) -- ошибка в "byte minunte", правильно -- byte minute.
    Вот скомпилированный скетч:
    Код (C++):
    #include <config.h>
    #include <ds3231.h>
    #include <RTC.h>
    #include <Wire.h>

    #define BLUE_LED 12

    RTC time;

    void setup() {
        delay(300);
        Serial.begin(9600);
        time.begin(RTC_DS3231);
        pinMode(BLUE_LED, OUTPUT);
        //time.settime(14,02,21,10,03,16,4);  // 0  сек, 51 мин, 21 час, 27, октября, 2015 года, вторник
    }


    int cmpTime(const RTC& rtc, byte hour, byte minute, byte second)
    {
        if (rtc.Hours > hour)
            return 1;
        else if (rtc.Hours < hour)
            return -1;

        if (rtc.minutes > minute)
            return 1;
        else if (rtc.minutes < minute)
            return -1;

        if (rtc.seconds > second)
            return 1;
        else if (rtc.seconds < second)
            return -1;

        return 0;
    }

    void loop()
    {
        if (millis() % 1000 == 0) { // если прошла 1 секунда
            Serial.println(time.gettime("d-m-Y, H:i:s, D")); // выводим время
            delay(1); // приостанавливаем на 1 мс, чтоб не выводить время несколько раз за 1мс
        }

        bool isDayTime =
            cmpTime(time, 21, 03, 5) > 0 &&
            cmpTime(time, 21, 59, 35) < 0;

        digitalWrite(BLUE_LED, isDayTime);
    }
     
  10. nailxx

    nailxx Официальный Нерд Администратор

    You're welcome
     
  11. fogary

    fogary Гик

    Я извиняюсь, но разве оператор return не вызовет принудительный выход из функции? Иными словами, всегда будет проверяться только первое условие, остальные условия не будут проверяться никогда.
     
  12. nailxx

    nailxx Официальный Нерд Администратор

    Если в первом условии не сработает ни if, ни else if, исполнение пойдёт дальше.