Часы ds 3231

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

  1. greck

    greck Нуб

    Доброго времени суток. Подключил модуль DS 3231 к Arduino Uno. При включении монитора порта выдает такое сообщение:"45:165:85 165/165/165 Day of week: ". Пробовал различные библиотеки, но результат практически одинаковый. Отсюда вопрос, что не так в коде программы, или что нужно переписать? Заранее спасибо.

    Сам скетч:

    #include "Wire.h"
    #define DS3231_I2C_ADDRESS 0x68
    // Convert normal decimal numbers to binary coded decimal
    byte decToBcd(byte val)
    {
    return( (val/10*16) + (val%10) );
    }
    // Convert binary coded decimal to normal decimal numbers
    byte bcdToDec(byte val)
    {
    return( (val/16*10) + (val%16) );
    }
    void setup()
    {
    Wire.begin();
    Serial.begin(9600);
    // set the initial time here:
    // DS3231 seconds, minutes, hours, day, date, month, year
    // setDS3231time(30,42,21,4,26,11,14);
    }
    void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
    dayOfMonth, byte month, byte year)
    {
    // sets time and date data to DS3231
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set next input to start at the seconds register
    Wire.write(decToBcd(second)); // set seconds
    Wire.write(decToBcd(minute)); // set minutes
    Wire.write(decToBcd(hour)); // set hours
    Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
    Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
    Wire.write(decToBcd(month)); // set month
    Wire.write(decToBcd(year)); // set year (0 to 99)
    Wire.endTransmission();
    }
    void readDS3231time(byte *second,
    byte *minute,
    byte *hour,
    byte *dayOfWeek,
    byte *dayOfMonth,
    byte *month,
    byte *year)
    {
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set DS3231 register pointer to 00h
    Wire.endTransmission();
    Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
    // request seven bytes of data from DS3231 starting from register 00h
    *second = bcdToDec(Wire.read() & 0x7f);
    *minute = bcdToDec(Wire.read());
    *hour = bcdToDec(Wire.read() & 0x3f);
    *dayOfWeek = bcdToDec(Wire.read());
    *dayOfMonth = bcdToDec(Wire.read());
    *month = bcdToDec(Wire.read());
    *year = bcdToDec(Wire.read());
    }
    void displayTime()
    {
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    // retrieve data from DS3231
    readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
    &year);
    // send it to the serial monitor
    Serial.print(hour, DEC);
    // convert the byte variable to a decimal number when displayed
    Serial.print(":");
    if (minute<10)
    {
    Serial.print("0");
    }
    Serial.print(minute, DEC);
    Serial.print(":");
    if (second<10)
    {
    Serial.print("0");
    }
    Serial.print(second, DEC);
    Serial.print(" ");
    Serial.print(dayOfMonth, DEC);
    Serial.print("/");
    Serial.print(month, DEC);
    Serial.print("/");
    Serial.print(year, DEC);
    Serial.print(" Day of week: ");
    switch(dayOfWeek){
    case 1:
    Serial.println("Sunday");
    break;
    case 2:
    Serial.println("Monday");
    break;
    case 3:
    Serial.println("Tuesday");
    break;
    case 4:
    Serial.println("Wednesday");
    break;
    case 5:
    Serial.println("Thursday");
    break;
    case 6:
    Serial.println("Friday");
    break;
    case 7:
    Serial.println("Saturday");
    break;
    }
    }
    void loop()
    {
    displayTime(); // display the real-time clock data on the Serial Monitor,
    delay(1000); // every second
    }
     
  2. vvr

    vvr Инженерище

    нужно просто настроить
    в библиотеке должно быть описание
     
  3. greck

    greck Нуб

    Посмотрел, вроде нет в библиотеки описания. Прикрепил библиотеку которую использую.Может вы подскажите что нужно настроить.
     

    Вложения:

    • DS3231.zip
      Размер файла:
      10,4 КБ
      Просмотров:
      1.950
  4. X-Dron

    X-Dron Гик

    Батенька, да Вы, наверное, не умеете пользоваться библиотеками. Зачем копировать содержимое методов библиотек в основной код?
    Пользовался я этой библиотекой, работает. Но нарыл другую, которая мне понравилась больше. Для вывода в Serial, файл, на LCD-экран она сразу формирует строки. Для использования значений времени в коде для алгоритмов используется вывод данных в экземпляр класса "Time". Мне не хватало индивидуального задания часов, минут и секунд, поэтому библиотеку модифицировал под себя. Мод во вложении.
    В библиотеке есть примеры.
    Если убрать все комментарии, то вывод в Serial может быть таким:
    Код (Text):
    #include <DS3231.h>

    DS3231  rtc(SDA, SCL);

    void setup()
    {
      Serial.begin(115200);
      rtc.begin();
    }

    void loop()
    {
      // Send Day-of-Week
      Serial.print(rtc.getDOWStr());
      Serial.print(" ");

      // Send date
      Serial.print(rtc.getDateStr());
      Serial.print(" -- ");

      // Send time
      Serial.println(rtc.getTimeStr());

      delay (1000);
    }
    Для работы со значением времени в алгоритмах
    Код (Text):
    #include <DS3231.h>

    DS3231  rtc(SDA, SCL);
    Time RTC_T;

    void setup()
    {
      rtc.begin();
    }

    void loop()
    {
      RTC_T = rtc.getTime();

      // if (RTC_T.hour == 0 && RTC_T.min == 0) bla-bla-bla

      delay (1000);
    }
    Вечером могу выложить код под эти часы с установкой времени по времени компиляции
     

    Вложения:

    • ds3231.zip
      Размер файла:
      401,6 КБ
      Просмотров:
      3.799
    greck нравится это.
  5. X-Dron

    X-Dron Гик

    Библиотеку в предыдущем посту обновил, добавил возможность синхронизации часов по времени компиляции (__TIME__, __DATE__).
    Этот код можно использовать в качестве стандартного решения для DS3231.
    Код (Text):
    #include <DS3231.h>
    #include <EEPROM.h>

    //Массив, содержащий время компиляции
    char compileTime[] = __TIME__;
    char compileDate[] = __DATE__;

    DS3231 Clock(SDA, SCL);
    Time RTC_Time;

    void setup()
    {
      Serial.begin(115200);
      Clock.begin();

      //Получаем число из строки, зная номер первого символа
      byte hour = getInt(compileTime, 0);
      byte minute = getInt(compileTime, 3);
      byte second = getInt(compileTime, 6);
       
      unsigned int hash =  hour * 60 * 60 + minute  * 60 + second;
      if (EEPROMReadInt(0) != hash) {
        //Сохраняем новый хэш
        EEPROMWriteInt(0, hash);
        // Записываем время в часы
        Clock.adjust(compileDate, compileTime);
      }
    }

    void loop()
    {
      //Для запроса времени в структуру "Time"
      //RTC_Time = Clock.getTime();
         
      //Вывод дня недели
      //Serial.print(Clock.getDOWStr());
      //Serial.print(" ");

      //Вывод даты
      //Serial.print(Clock.getDateStr());
      //Serial.print(" -- ");

      //Вывод времени.
      //Serial.println(Clock.getTimeStr());
      delay(1000);
    }

    char getInt(const char* string, int startIndex) {
      return int(string[startIndex] - '0') * 10 + int(string[startIndex+1]) - '0';
    }

    //Запись двухбайтового числа в память
    void EEPROMWriteInt(int address, int value)
    {
      EEPROM.write(address, lowByte(value));
      EEPROM.write(address + 1, highByte(value));
    }
    //Чтение числа из памяти
    unsigned int EEPROMReadInt(int address)
    {
      byte lowByte = EEPROM.read(address);
      byte highByte = EEPROM.read(address + 1);
      return (highByte << 8) | lowByte;
    }
    Методы .getDOWStr, .getTimeStr(), .getTimeStr() имеют необязательные параметры, которые отвечают за формат выводимой строки. Читайте DS3231.pdf в архиве библиотеки.
     
    Jevega, Tomasina, greck и ещё 1-му нравится это.
  6. greck

    greck Нуб

    Спасибо большое, буду разбираться. Просто я начинающий пользователь данных железок. На той недели попали в руки эти платы, заинтересовался... стал разбираться.СПС!
     
  7. greck

    greck Нуб

    Перепробовал почти все библиотеки, которые удалось скачать, а так же различные настройки.....долго мучился, а проблема оказалась в производственном браке (фото прикладываю). Попросил на время другую Arduino и все заработало. Подключил дисплей LCD 16x2 выводит время, дату, температуру на LCD в Цельсия.Прикрепляю скетч и библиотеку, которую использую. Если брать пример Set Serial из библиотеки, то в монитор порта исправно выдается температура с интервалом в минуту. FullSizeRender.jpg [/quote]
     

    Вложения:

    • DS3232RTC-master.zip
      Размер файла:
      15,8 КБ
      Просмотров:
      2.420
    • Time_LCD.zip
      Размер файла:
      612 байт
      Просмотров:
      1.459
    Последнее редактирование: 6 апр 2015
  8. seregareal2

    seregareal2 Нерд

    Ребят, а я вот что то все никак не пойму, как по наступлению на часах нужного времени, заставить сработать другой датчик?
     
  9. imMan

    imMan Нерд

    Я так думаю, что нужно с определенным интервалом опрашивать часы и при наступлении нужного времени выполнять действие
     
  10. Karabas

    Karabas Гик

    А что вас остановило от того, чтобы вынуть чип и выпрямить ногу?

    Запросить время у модуля, сравнить с требуемым значением, если совпало- исполнить. Следует учесть, то, что проверять нужно чаще чем может измениться младший разряд, ну например раз в секунду для точности до минут будет более чем достаточно, если же речь идет не о будильнике, можно и раз в десять секунд, от задачи зависит и загруженности МК.
     
  11. seregareal2

    seregareal2 Нерд

    А простенький пример не приведёт?
     
  12. Karabas

    Karabas Гик

    Если подождете до завтра, с радостью помогу.
     
  13. seregareal2

    seregareal2 Нерд

  14. Karabas

    Karabas Гик

    Просто идея на скорую руку.

    Библиотека RTC.h
    int H; //Установленное время часы
    int M;//Установленное время минуты

    int tmp_h;
    int tmp_m;

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

    if (tmp_h==H && tmp_m==M)
    {
    // ваша функция
    }
     
    seregareal2 нравится это.
  15. seregareal2

    seregareal2 Нерд

    Я вот так понял :)

    Библиотека RTC.h
    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;

    //Мотор

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


    //Свет


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

    //Кулер


    if (tmp_h==H && tmp_m==M && tmp_s==S)
    {
    digitalWrite(led, HIGH);
    else {
    digitalWrite(led, LOW);
    }
    }
     
    Последнее редактирование: 24 янв 2016
  16. seregareal2

    seregareal2 Нерд

    Тогда вот еще - как заставить Мотор отработать 10 секунд, и выключится?
    А Свет заставить проработать 9 часов и выключиться?


    //Мотор

    if (tmp_h==12 && tmp_m==15 && tmp_s==05)
    {
    digitalWrite(led, HIGH);
    else (tmp_h==12 && tmp_m==15 && tmp_s==15) {
    digitalWrite(led, LOW);
    }
    }


    //Свет

    if (tmp_h==12 && tmp_m==00 && tmp_s==00)
    {
    digitalWrite(led, HIGH);
    else (tmp_h==21 && tmp_m==00 && tmp_s==00) {
    digitalWrite(led, LOW);
    }
    }





    Таким кодом?
     
    Последнее редактирование: 24 янв 2016
  17. Sindbad

    Sindbad Гик

    Трудности начнутся при переходе через сутки, если отработаете код для корректного перехода через сутки, увидите, что нужно отрабатывать переход через месяц и т.д.

    Меня эксперименты с таймерами привели вот к этой библиотеке: http://playground.arduino.cc/Code/Time
    Её удобно использовать в дополнение к библиотекам обеспечивающим взаимодействие с микросхемой таймера.
    В ней определены типы данных time_t и tm и процедуры, которые преобразуют их друг в друга.
    time_t - время в секундах от 01 января 1970 г. (страндарт де-факто для храненения времени в языке С)
    tm - структура, поля которой - части времени в привычном и удобном для ввода/вывода виде (год, месяц, число, час, минута, секунда).

    Время полученное с таймера переводим в time_t, таймеры храним тоже в time_t. Тогда проверка наступления времени - одна простая операция сравнения, без логических операций "И" и "ИЛИ".
    Установка таймера тоже тривиальна:
    - либо прибавляем требуемое количество секунд к текущему вермени
    Код (C++):
    alarm_time = current_time + 9 * 60 * 60; //таймер на 9 часов от текущего момента
    - либо формируем структуру tm соответсвующую требуемому моменту срабоатывания будильника и переводим её в time_t
    Код (C++):
    tmp.Second = 0;
    tmp.Minute = 0;
    tmp.Hour = 7;
    tmp.Day = 8;
    tmp.Month =3;
    tmp.Year = 2016-1970;
    alarm_time = makeTime(tmp); // установили таймер на 07 часов утра восьмого марта текущего года
     
    Karabas нравится это.
  18. Karabas

    Karabas Гик

    А можно по подробней про трудности, часовые модули тем и хороши, что выдают текущие время. Пока я вижу трудность в том, если время активации устройства пришлось как раз на 00:00, тогда да,будет пилить еще час. Тут следует добавить проверку времени а еще... Time.h и стандартный счетчик времени :D

    Но в принципе можно вполне обходиться и без, но что то не слишком сложное, но опять же програмные таймеры и прочие.

    Если по простому то можно так
    Для мотора, если он включается в <49 сек, то как то так

    if(tmp_h==12 && tmp_m==15 && tmp_s==05)
    {
    while(time.second < tmp_s+10) {//motor run}
    //motor stop

    А для света просто задать два времени и использовать запись типа

    if((tmp_h==12 && tmp_m==15 && tmp_s==05) || (tmp_h==20 && tmp_m==15 && tmp_s==05))
    {
    digitalWrite(_powerPin, !digitalRead(_powerPin));
    }
    Такая команда просто изменяет состояние указанного пина
     
    Последнее редактирование: 24 янв 2016
  19. gama

    gama Нуб

    Доброго дня. Если не сложно помогите разобраться : имеется ds3231 + mega + lcd16x2 все по i2c. Заработала только с библиотекой DS3232RTC-master.zip. При перезапуске сбивается системно время. Менял батарейки 2 раза (правда не замерил напряжение на них, нужно сделать). В процедуре сетапа естественно при последующем запуске использую функцию RTC.set(now()) -чтение установленного системного времени.

    Первый запуск:

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

    Последующий перезапуск

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

    Karabas Гик

    Попробуйте сделать такую вещь, не устанавливать время в сетапе, а по нажатию кнопки в отдельной функции. Затем, вставив его один раз, сможете пронаблюдать, не сбиваетсяли время при отключении. Как один из вариантов, если включить ваши часы от другого источника питания, либо неверно выбран порт в IDE будет неоткуда взять время для установки.