Часы ds 3231

Тема в разделе "Arduino & Shields", создана пользователем greck, 21 мар 2015.

  1. Sindbad

    Sindbad Гик

    Вот это:
    Код (C++):
    while(time.second < tmp_s+10) {//motor run}
    Эквивалентно вот этому:
    Код (C++):
    {//motor run};
    delay(10000);
    т.к. все десять секунд висим в цикле не переключаясь на другие задачи. Преимущества отключения по таймеру не используются.

    Трудности начинаются если скетч из "начать в х часов, у минут, z секунд", "закончить в х2 часов, у2 минут, z2 секунд" начать переделывать в скетч действительно позволяющий сделать какое-либо действие через 10 сек или через 9 часов.

    Поясняю "трудности". Пусть нам нужно сделать какое-то действие через 9 часов после текущего момента, тогда можно записать:
    Код (C++):
    alarmOn = true;
    alarm_h = current_h + 9;
    if (alarm_h > 23) alarm_h = alarm_h - 24;
    alarm_m = current_m;
    alarm_s = current_s;
    Затем вставить в loop() проверку
    Код (C++):
    if (alarmOn && current_h == alarm_h && current_m == alarm_m && current_s == alarm_s) {
      alarmOn = false;
      // действия по таймеру
    }
    Имеем следующие проблемы:
    1. Громоздкая и выносящая мозг формула вычисления значений переменных времени контролируемого события.
    2. Громоздкое условие проверяющее наступление события.
    3. В условии нельзя использовать операции "больше" и "меньше", следовательно если по каким-либо причинам в нужную секунду условие не будет проверено, то событие "уйдет на следующий круг", т.е. на следующие сутки.
    4. Необходимость использовать дополнительную переменную-флаг
     
  2. seregareal2

    seregareal2 Нерд

    У меня что то ругается....


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

    int motor = 9;
    int led = 8;

    int H; //Установленное время часы
    int M;//Установленное время минуты
    int S;//Установленное время секунды

    int tmp_h;
    int tmp_m;
    int tmp_s;

    tmp_h = time.Hours;
    tmp_m = time.minutes;
    tmp_s = time.second;

    void setup () {
    {
    setTime(17, 35, 30, 28, 12, 2015);//выставляем текущее время
    //RTC.set(now());
    }


    //Мотор


      if (tmp_h==9 && tmp_m==00 && tmp_s==00) {
        //Включаем на 10 секунд
      digitalWrite(motor, HIGH);
     
    } else  (tmp_h==9 && tmp_m==00 && tmp_s==15) {
        //Выключаем
      digitalWrite(motor, LOW);
    }




    if (tmp_h==21 && tmp_m==00 && tmp_s==00) {
        //Включаем на 10 секунд
      digitalWrite(motor, HIGH);
     
    } else  (tmp_h==21 && tmp_m==00 && tmp_s==15) {
      //Выключаем
      digitalWrite(motor, LOW);
    }


    //Свет


    if (tmp_h==6 && tmp_m==00 && tmp_s==00) {
       //Включаем свет
    digitalWrite(led, HIGH);

    } else (tmp_h==22 && tmp_m==00 && tmp_s==00) {
        //Выключаем свет
    digitalWrite(led, LOW);
    }


    //Кулер (Пока нериализованно)
    /*

    if (tmp_h==H && tmp_m==M && tmp_s==S)
    {
    digitalWrite(9, HIGH);
    }
    else
    {
    digitalWrite(9, LOW);
    }

    }
    */



    void loop()
     
     

    Вложения:

  3. seregareal2

    seregareal2 Нерд

    Вот, так то лучше


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

    int motor = 9;
    int led = 8;

    int H; //Установленное время часы
    int M;//Установленное время минуты
    int S;//Установленное время секунды

    int tmp_h,tmp_m,tmp_s;

    tmp_h = time.Hours;
    tmp_m = time.minutes;
    tmp_s = time.second;

    void setup () {

    //Мотор

    if (tmp_h==9 && tmp_m==00 && tmp_s==00) {
    //Включаем на 10 секунд
    digitalWrite(motor, HIGH);

    }
    else (tmp_h==9 && tmp_m==00 && tmp_s==15); {
    //Выключаем
    digitalWrite(motor, LOW);
    }

    if (tmp_h==21 && tmp_m==00 && tmp_s==00) {
    //Включаем на 10 секунд
    digitalWrite(motor, HIGH);

    }
    else (tmp_h==21 && tmp_m==00 && tmp_s==15);
    {
    //Выключаем
    digitalWrite(motor, LOW);
    }

    //Свет

    if (tmp_h==6 && tmp_m==00 && tmp_s==00) {
    //Включаем свет
    digitalWrite(led, HIGH);

    }
    else (tmp_h==22 && tmp_m==00 && tmp_s==00);
    {
    //Выключаем свет
    digitalWrite(led, LOW);
    }

    }

    //Кулер (Пока нериализованно)
    /*

    if (tmp_h==H && tmp_m==M && tmp_s==S)
    {
    digitalWrite(9, HIGH);
    }
    else
    {
    digitalWrite(9, LOW);
    }

    }
    */


    void loop(){}
     
     

    Вложения:

  4. Sindbad

    Sindbad Гик

    Ругается компилятор на то, что пытаетесь вычислить выражение, содержащее переменную, вне тела функции. Вот такое присваивание вне тела функции использовать нельзя:
    Код (C++):
    tmp_h = time.Hours;
    Но он ведь не только на это ругается, правда?

    Посмотрите в справочнике по языку как допустимо писать оператор if-else и как он работает.
     
  5. seregareal2

    seregareal2 Нерд

    Так же как и в справочнике написанно
     

    Вложения:

  6. Karabas

    Karabas Гик

    В else не должно быть условий, это то, что выполниться в случае, если не одно из условий не выполненно.

    А так же, возможно, компилятор ругается на то, что вы используете мой код с неправильной библиотекой, прикладываю ту, что сам использую.
    Код (C++):
    //    ОПИСАНИЯ ПАРАМЕТРОВ ФУНКЦИЙ:
    //
    //    в библиотеке реализованы 4 функции: begin, settime, gettime и period.
    //    функция begin вызывается первой и предназначена для инициализации модуля, выбора шины, и выводов arduino
    //    количество и порядок вызовов функций settime, gettime и period, значения не имеет.
    //
    //    инициализация модуля
    //    time.begin(название, RST или SS, CLK, DAT) если модуль работает на шине I2C или SPI, то достаточно указать только название модуля, например: time.begin(RTC_DS3231);
    //                           если модуль работает на шине SPI, а аппаратный вывод SS занят, то номер назначенного вывода SS для модуля указывается вторым параметром, например: time.begin(RTC_DS1305,22);
    //                           если модуль работает на трехпроводной шине, то указываются номера всех выводов, например: time.begin(RTC_DS1302, 1, 2, 3); // RST, CLK, DAT
    //    запись даты и времени
    //    time.settime(сек,мин,час,д,м,г,дн)       должен присутствовать хотябы 1 параметр
    //                           часы указываются в 24-часовом формате, год указывается от 0 до 99, день недели указывается числом: 1-ПН, 2-ВТ, ... 6-СБ, 0-ВС.
    //                           если предыдущий(ие) параметр(ы) надо оставить без изменений, то указывается отрицательное значение
    //    чтение даты и времени
    //    time.gettime("строка с параметрами")       функция получает и выводит строку заменяя описанные ниже символы на текущее время
    //                           указанные символы эдентичны символам для функции date() в PHP
    //                        s  секунды                       от      00    до       59  (два знака)
    //                        i  минуты                        от      00    до       59  (два знака)
    //                        h  часы в 12-часовом формате     от      01    до       12  (два знака)
    //                        H  часы в 24-часовом формате     от      00    до       23  (два знака)
    //                        d  день месяца                   от      01    до       31  (два знака)
    //                        w  день недели                   от       0    до        6  (один знак: 0-воскресенье, 6-суббота)
    //                        D  день недели наименование      от     Mon    до      Sun  (три знака: Mon Tue Wed Thu Fri Sat Sun)
    //                        m  месяц                         от      01    до       12  (два знака)
    //                        M  месяц наименование            от     Jan    до      Dec  (три знака: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
    //                        Y  год                           от    2000    до     2099  (четыре знака)
    //                        y  год                           от      00    до       99  (два знака)
    //                        a  полдень                               am   или       pm  (два знака, в нижнем регистре)
    //                        A  полдень                               AM   или       PM  (два знака, в верхнем регистре)
    //                           строка не должна превышать 50 символов
    //                           пример: gettime("d-m-Y, H:i:s, D"); ответит строкой "01-10-2015, 14:00:05, Thu"
    //                           пример: gettime("s");               ответит строкой "05"
    //    чтение даты и времени в виде цифр
    //    time.gettime()                   без параметра
    //                           результат читается из переменных:
    //                        time.seconds  секунды     0-59
    //                        time.minutes  минуты      0-59
    //                        time.hours    часы        1-12
    //                        time.Hours    часы        0-23
    //                        time.midday   полдень     0-1 (0-am, 1-pm)
    //                        time.day      день месяца 1-31
    //                        time.weekday  день недели 0-6 (1-понедельник, 6-суббота, 0-воскресенье)
    //                        time.month    месяц       1-12
    //                        time.year     год         0-99
    //    не обязательная функция
    //    time.period(минуты)               указывает минимальный период чтения времени из модуля в минутах. (от 1 до 255 минут)
    //                           пример:
    //                           если после вызова функции time.period(5); в течении 5 минут несколько раз была вызвана функция gettime,
    //                           то запрос времени к модулю пройдёт только в первый раз, а ответом на все остальные вызовы функции gettime
    //                           будет результат последнего полученного от модуля времени + время прошедшее с этого запроса
    //                           уменьшение числа запросов уменьшает время обработки запросов, разгружает шину, и уменьшает потребляемый модулем ток
    //                           при отсутствии вызова функции time.period(минуты), ответ на запрос даты и времени будет всегда читаться из модуля
     
     

    Вложения:

    • RTC.zip
      Размер файла:
      1 МБ
      Просмотров:
      639
  7. Sindbad

    Sindbad Гик

    Не вижу в справочнике после else круглых скобочек
     
  8. seregareal2

    seregareal2 Нерд

    Ааа, да, мой косяк...
    Тогда как правильно будет?
     
  9. Karabas

    Karabas Гик

    Никаких скобок с условиями, просто:
    else { //код }
     
  10. Sindbad

    Sindbad Гик

    Если после else убрать скобки и условие, то это будет синтаксически правильно. Но сформулированная Вами цель "включить вовремя и выключить вовремя" достигнута не будет. Как реализовать такие алгоритмы - см. мои сообщения в этой теме. Ваш же простой алгоритм, когда заранее известно точно время включения и точное время выключения, реализуется так:
    Код (C++):
    if (tmp_h==21 && tmp_m==00 && tmp_s==00) {
      //Включаем
      digitalWrite(motor, HIGH);
    };

    if (tmp_h==21 && tmp_m==00 && tmp_s==15) {
      //Выключаем
      digitalWrite(motor, LOW);
    };
     
    Т.е. два независимых друг от друга оператора условия. При каждом проходе (выполнении) функции loop() эти условия проверяются раз за разом. В какой-то момент условие оказывается верным и микроконтроллер выполняет соответствующее действие.
     
  11. seregareal2

    seregareal2 Нерд

    в конечном итоге у меня получилось так

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


    RTC    time;



    int motor = 9;
    int led = 8;

    int h; //Установленное время часы
    int m;//Установленное время минуты
    int s;//Установленное время секунды

    int tmp_h,tmp_m,tmp_s;



    void setup () {
    delay(300);
    Serial.begin(9600);
    time.begin(RTC_DS3231);
    time.settime(0,51,21,27,10,15,2);  // 0  сек, 51 мин, 21 час, 27, октября, 2015 года, вторник
     
     
     
     
     
     
    tmp_h = time.Hours;
    tmp_m = time.minutes;
    tmp_s = time.seconds;
     




    //Мотор

    if (tmp_h==9 && tmp_m==00 && tmp_s==00) {
    //Включаем на 10 секунд
    digitalWrite(motor, HIGH);
    }

    if (tmp_h==9 && tmp_m==00 && tmp_s==10); {
    //Выключаем
    digitalWrite(motor, LOW);
    }

    if (tmp_h==21 && tmp_m==00 && tmp_s==00) {
    //Включаем на 10 секунд
    digitalWrite(motor, HIGH);
    }

    if (tmp_h==21 && tmp_m==00 && tmp_s==15);{
    //Выключаем
    digitalWrite(motor, LOW);
    }








    //Свет

    if (tmp_h==6 && tmp_m==00 && tmp_s==00) {
    //Включаем свет
    digitalWrite(led, HIGH);
    }


    if (tmp_h==22 && tmp_m==00 && tmp_s==00); {
    //Выключаем свет
    digitalWrite(led, LOW);
    }

    }






    //Кулер (Пока нериализованно)
    /*

    if (tmp_h==H && tmp_m==M && tmp_s==S)
    {
    digitalWrite(9, HIGH);
    }
    else
    {
    digitalWrite(9, LOW);
    }

    }
    */





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

    Вложения:

  12. seregareal2

    seregareal2 Нерд

    как я понял, вот эту строчку нужно устанавливать только один раз для установки часов, а дальше ее не использовать?

    Код (C++):
    time.settime(0,51,21,27,10,15,2);  // 0  сек, 51 мин, 21 час, 27, октября, 2015 года, вторник
    вот только часы устанавливают эту дату даже когда строка закоментированна
     
    Последнее редактирование: 28 янв 2016
  13. sbhidden

    sbhidden Нуб

    А что?
    никто не думал использовать опрос линии прерывания с микросхемы? и будильники??
    как говорится... задал время - ждешь сигнала. дождался - выполнил действие, задал новый будильник...
     
  14. Karabas

    Karabas Гик

    Вот ровно сегодня утром пришла такая же идея :)
     
  15. dad151

    dad151 Нуб

    Добрый день!
    Проблема с компиляцией.
    Библиотека RTS, модуль DS3231/
    При компиляции выдает ошибку
    в чем дело?
    Пробовал разные библиотеки, та же самая ошибка
     

    Вложения:

    • RTC.zip
      Размер файла:
      1 МБ
      Просмотров:
      326
    • TIME.ino
      Размер файла:
      7,7 КБ
      Просмотров:
      434
    • ошибка.txt
      Размер файла:
      12,8 КБ
      Просмотров:
      738
  16. MaximJF

    MaximJF Нуб

    Здравствуйте!
    Возникает сложность с форматом времени /даты ds3231,(библиотеку использую DS1307RTC - может это мешать?). Помогите разобраться, при чтении в серийном мониторе - всё корректно, при записи в файл на SD карту - время/дата превращаются в какие-то цифры вида:
    95.27,253:251:237,24,20,426
    9527- дата, 253:251:237 - время, 24,20,426 - мои параметры.
    Кусок кода записи в файл:
    Код (C++):
    String dataString = (String(tm.Day) + "." + String(tm.Month) + "," + String(tm.Hour) + ":" + String(tm.Minute) + ":" + String(tm.Second) + "," + String(t) + "," + String(h) + "," + String(sensor));
      myFile = SD.open("SOLAR.csv", FILE_WRITE);
      // if the file opened okay, write to it:
      if (myFile) {
        Serial.println(sensor);
        myFile.println(dataString);
        myFile.close();
    Весь код:
    Код (C++):
    #include <SPI.h>
    #include <SD.h>
    File myFile;

    ////////////////////////
    #include <DS1307RTC.h>

    #include <Wire.h>
    #include <Time.h>
    #include <DS1307RTC.h>
    #include "DHT.h"
    #define DHTPIN 2     // what pin we're connected to
    #define DHTTYPE DHT11   // DHT 22  (AM2302)
    DHT dht(DHTPIN, DHTTYPE);
    int BUZZER = 6;
    [SIZE=14px]int analogPin = 0;
    /[/SIZE]

    void setup()
    {
      ////////////////////////////////
      dht.begin();

      // Open serial communications and wait for port to open:
      Serial.begin(9600);
      ///while (!Serial) {
      ///; // wait for serial port to connect. Needed for Leonardo only
      ///}
      Serial.print("Initializing SD card...");
     
      if (!SD.begin(10)) {
        Serial.println("initialization failed!");
        tone(BUZZER, 3900, 300);
        delay (500);
        tone(BUZZER, 3900, 300);
        delay (500);
        tone(BUZZER, 3900, 300);
        return;
      }
      else
      {
        Serial.println("initialization done.");
        tone(BUZZER, 3900, 1000);
      }

    }
    void loop()
    {
      tmElements_t tm;

      int h = dht.readHumidity();
      int t = dht.readTemperature();

      // читаем данные с датчика и делим на коэффициент
      int sensor = analogRead(analogPin);/////int sensor = analogRead(analogPin) / 2.515;

      String dataString = (String(tm.Day) + "." + String(tm.Month) + "," + String(tm.Hour) + ":" + String(tm.Minute) + ":" + String(tm.Second) + "," + String(t) + "," + String(h) + "," + String(sensor));
      myFile = SD.open("SOLASR.csv", FILE_WRITE);
      // if the file opened okay, write to it:
      if (myFile) {
        Serial.println(sensor);
        myFile.println(dataString);
        myFile.close();
        tone(BUZZER, 3900, 1);
        delay (1500);
      }

      else {
        Serial.println("error writing to SOLAR.csv");
      }
    }
    Код для вывода в сериал - стандартный из программы
    Код (C++):
    #include <Wire.h>
    #include <Time.h>
    #include <DS1307RTC.h>

    void setup() {
      Serial.begin(9600);
      while (!Serial) ; // wait for serial
      delay(200);
      Serial.println("DS1307RTC Read Test");
      Serial.println("-------------------");
    }

    void loop() {
      tmElements_t tm;

      if (RTC.read(tm)) {
        Serial.print("Ok, Time = ");
        print2digits(tm.Hour);
        Serial.write(':');
        print2digits(tm.Minute);
        Serial.write(':');
        print2digits(tm.Second);
        Serial.print(", Date (D/M/Y) = ");
        Serial.print(tm.Day);
        Serial.write('/');
        Serial.print(tm.Month);
        Serial.write('/');
        Serial.print(tmYearToCalendar(tm.Year));
        Serial.println();
      } else {
        if (RTC.chipPresent()) {
          Serial.println("The DS1307 is stopped.  Please run the SetTime");
          Serial.println("example to initialize the time and begin running.");
          Serial.println();
        } else {
          Serial.println("DS1307 read error!  Please check the circuitry.");
          Serial.println();
        }
        delay(9000);
      }
      delay(1000);
    }

    void print2digits(int number) {
      if (number >= 0 && number < 10) {
        Serial.write('0');
      }
      Serial.print(number);
    }
     
  17. sbhidden

    sbhidden Нуб

    Смотрим здесь:
    Код (C++):
        Serial.println(sensor);
        myFile.println(dataString);
     
    Пробуем так:
    Код (C++):
        Serial.println(dataString);
        myFile.println(dataString);
     
    Далее смеемся над своей невнимательностью и читаем мануалы на тему как работает такая запись:
    Код (C++):
    String(tm.Day)
     
  18. MaximJF

    MaximJF Нуб

    Спасибо за ответ!
    В первом замечании всё верно, это для вывода в монитор данных только датчика и есть.
    А про String(tm.Day) расскажите пожалуйста поподробнее, или скажите, где почитать?
     
  19. sbhidden

    sbhidden Нуб

  20. Karabas

    Karabas Гик

    Возникли у меня странности с этиим модулем. Нужны были по быстрому часы, вобщем все собрал-настроил вроде порядок. Библиотеку использовал RTC (ту что выкладывал), с ней проще, сразу можно читать из переменных цифровые значения.
    Но вот глюк, поставил 31 февраля 2016 года- и оно это приняло, ладно думаю, мало ли, вызываю дату- так и есть 31 февраля! Как так то!? Разве в ней нет проверки даты, а как же с високосными годами?

    К тому же если я меняю день, месяц или год (каждый щелчек энкодера обновляет значение и тут же его выводит на экран), название дня не изменяется.
     
    Последнее редактирование: 29 апр 2016