Часы реального времени (DS1307)

Тема в разделе "Arduino & Shields", создана пользователем Виталий, 27 дек 2014.

  1. Виталий

    Виталий Нерд

    Здравствуйте.
    Есть вот такие часы реального времени:
    [​IMG]
    Вроде бы все работает хорошо, если бы не одно НО.
    Когда загружаешь скетч все работает отлично. Но когда перегружаешь ардуину происходит странное. Дата и время отображается на момент загрузки скетча.

    Ну например: Загружаю я скетч 20.12.2014 в 19:00.
    Через пару дней отключали свет и часы стали выдавать время опять с 20.12.2014 19:00.

    Проверял несколько раз. Эффект всегда одинаков.
    Заливаю тот же самый скетч снова, и дата и время становятся правильным.

    Подскажите, в чем может быть дело?
     
  2. geher

    geher Гуру

    А в скетче в setup() случайно нет инициализации часов каким-то константным временем?
    Собственно, на сам скетч посмотреть бы.
     
  3. Виталий

    Виталий Нерд

    Нет, время там не задается вообще нигде....
    Сам скетч вот:
    Код (Text):
    #include <OneWire.h>
    OneWire  ds(9);

    typedef uint8_t DeviceAddrss[8];
    DeviceAddrss ThermometerGreen = { 0x28, 0xFF, 0x9C, 0x97, 0x3C, 0x04, 0x00, 0xE7 };
    DeviceAddrss ThermometerYellow = { 0x28, 0xFF, 0x28, 0x98, 0x3C, 0x04, 0x00, 0x2D };
    DeviceAddrss ThermometerRed = { 0x28, 0xFF, 0xAD, 0x9F, 0x3C, 0x04, 0x00, 0xB2 };

    #include <LiquidCrystal.h>
    LiquidCrystal lcd(8, 3, 2, 5, 6, 7);  // (RS, E, D4, D5, D6, D7)

    #include <SPI.h>
    #include <SD.h>
    const int chipSelect = 4;

    #include <Wire.h>
    #include "RTClib.h"
    RTC_Millis RTC;

    float actuGreen = 0, maxiGreen = -55, miniGreen = 125;
    float actuYellow = 0, maxiYellow = -55, miniYellow = 125;
    float actuRed = 0, maxiRed = -55, miniRed = 125;

    DateTime timerLog;
    DateTime fndate;

    char filename[13]="dl000000.txt";

    /*
    Тут мы задаем имя LOG файла...
    */
    void FileNameSetup() {
      filename[2] = fndate.day() / 10 + 0x30;
      filename[3] = fndate.day() % 10 + 0x30;
      filename[4] = fndate.month() / 10 + 0x30;
      filename[5] = fndate.month() % 10 + 0x30;
      filename[6] = (fndate.year() % 100) / 10 + 0x30;
      filename[7] = fndate.year() % 10 + 0x30;
    }

    void setup(void) {
      Serial.begin(9600);

      Wire.begin();
      RTC.begin(DateTime(__DATE__, __TIME__));
      timerLog = RTC.now();
      fndate = RTC.now();
      FileNameSetup();
     
      lcd.begin(20, 4);

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(timerLog.day());
      lcd.print(".");
      lcd.print(timerLog.month());
      lcd.print(".");
      lcd.print(timerLog.year());
      lcd.print(" ");
      lcd.print(timerLog.hour());
      lcd.print(":");
      lcd.print(timerLog.minute());
      lcd.print(":");
      lcd.print(timerLog.second());
      lcd.setCursor(4, 3);
      lcd.print(filename);

      pinMode(10, OUTPUT);

      if (!SD.begin(chipSelect)) {
        Serial.println("Card failed, or not present");
        return;
      }

    }

    //  Читаем показания с датчиков температуры
    void Read_s()
    {
      byte i;
      //  byte present = 0;
      //  byte type_s;
      byte data[12];
      byte addr[8];
      float celsius;

      ds.reset();
      ds.select(ThermometerGreen);
      ds.write(0x44, 1);

      ds.reset();
      ds.select(ThermometerYellow);
      ds.write(0x44, 1);

      ds.reset();
      ds.select(ThermometerRed);
      ds.write(0x44, 1);

      delay(190);

      ds.reset();
      ds.select(ThermometerGreen);
      ds.write(0xBE);
      for ( i = 0; i < 9; i++) {
        data[i] = ds.read();
      }
      int16_t raw = (data[1] << 8) | data[0];
      celsius = ((float)(raw >> 1) - 0.25 + ((float)(data[7] - data[6])) / (float)data[7]) / 8 ;
      actuGreen = celsius;
      miniGreen = min(miniGreen, celsius);
      maxiGreen = max(maxiGreen, celsius);

      ds.reset();
      ds.select(ThermometerYellow);
      ds.write(0xBE);
      for ( i = 0; i < 9; i++) {
        data[i] = ds.read();
      }
      raw = (data[1] << 8) | data[0];
      celsius = ((float)(raw >> 1) - 0.25 + ((float)(data[7] - data[6])) / (float)data[7]) / 8 ;
      actuYellow = celsius;
      miniYellow = min(miniYellow, celsius);
      maxiYellow = max(maxiYellow, celsius);

      ds.reset();
      ds.select(ThermometerRed);
      ds.write(0xBE);
      for ( i = 0; i < 9; i++) {
        data[i] = ds.read();
      }
      raw = (data[1] << 8) | data[0];
      celsius = ((float)(raw >> 1) - 0.25 + ((float)(data[7] - data[6])) / (float)data[7]) / 8 ;
      actuRed = celsius;
      miniRed = min(miniRed, celsius);
      maxiRed = max(maxiRed, celsius);
    }

    void printLCD()
    {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Green  Red  Yellow");

      lcd.setCursor(0, 1);
      lcd.print(actuGreen);
      lcd.setCursor(7, 1);
      lcd.print(actuRed);
      lcd.setCursor(15, 1);
      lcd.print(actuYellow);

      lcd.setCursor(0, 2);
      lcd.print(miniGreen);
      lcd.setCursor(7, 2);
      lcd.print(miniRed);
      lcd.setCursor(15, 2);
      lcd.print(miniYellow);

      lcd.setCursor(0, 3);
      lcd.print(maxiGreen);
      lcd.setCursor(7, 3);
      lcd.print(maxiRed);
      lcd.setCursor(15, 3);
      lcd.print(maxiYellow);
    }

    void Loging()
    {
      File dataFile = SD.open(filename, FILE_WRITE);
      if (dataFile) {
        dataFile.print(timerLog.year(), DEC);
        dataFile.print('/');
        dataFile.print(timerLog.month(), DEC);
        dataFile.print('/');
        dataFile.print(timerLog.day(), DEC);
        dataFile.print(' ');
        dataFile.print(timerLog.hour(), DEC);
        dataFile.print(':');
        dataFile.print(timerLog.minute(), DEC);
        dataFile.print(':');
        dataFile.print(timerLog.second(), DEC);
        dataFile.print(";");

        dataFile.print("Green;");
        dataFile.print(actuGreen);
        dataFile.print(";");
        dataFile.print(miniGreen);
        dataFile.print(";");
        dataFile.print(maxiGreen);
        dataFile.print(";");

        dataFile.print("Yellow;");
        dataFile.print(actuYellow);
        dataFile.print(";");
        dataFile.print(miniYellow);
        dataFile.print(";");
        dataFile.print(maxiYellow);
        dataFile.print(";");

        dataFile.print("Red;");
        dataFile.print(actuRed);
        dataFile.print(";");
        dataFile.print(miniRed);
        dataFile.print(";");
        dataFile.print(maxiRed);
        dataFile.print(";");
        dataFile.println();

        dataFile.close();

        Serial.print("Data are written down in the file ");
        Serial.println(filename);
      }
      else {
        Serial.print("error opening ");
        Serial.println(filename);
      }
    }

    void loop(void)
    {
      DateTime now = RTC.now();
      if ( fndate.day() != now.day() ){
        fndate = now;
        FileNameSetup();
      }
    if ( timerLog.minute() != now.minute() ){
        timerLog = now;
        Read_s();
        Loging();
        printLCD();
      }
    }
     
  4. ANV

    ANV Гуру

    А это зачем? RTC.begin(DateTime(__DATE__, __TIME__));
     
  5. Виталий

    Виталий Нерд

    Взято из какого-то примера работы с часами...
     
  6. geher

    geher Гуру

    Смутно подозреваю, что это
    RTC.begin(DateTime(__DATE__, __TIME__));
    как раз и устанавливает время в часах на время компиляции.
     
  7. 9xA59kK

    9xA59kK Гик

    Когда подключал подобные часы тоже искал какую ни будь адекватную библиотеку. Советую попробовать вот эту http://www.seeedstudio.com/wiki/Grove_-_RTC
    Пользуюсь этой, удобная. После первой заливки скетча, установится дата и время. Второй и последующий разы отключить в нем установку часов и даты. Ну и продолжать с ним работать.
    ps// если есть батарейка в часах то установить время и дату достаточно один раз.
    Так же работает и с DS3231
    пример установки времени и даты в этой библиотеке
    void setup()
    {
    //Serial.begin(9600);
    clock.begin();
    clock.fillByYMD(2013,1,19); // Jan 19,2013
    clock.fillByHMS(15,28,30); // 15:28 30"
    clock.fillDayOfWeek(SAT); // Saturday
    clock.setTime(); // write time to the RTC chip
    }
    ----- думаю понятно без комментариев
     
    Последнее редактирование: 27 дек 2014
  8. Виталий

    Виталий Нерд

    Но почему при сбросе (перезагрузке) ардуино время возвращается именно к тому, когда был залит скетч.
    И еще, для пробы заливал другие скетчи из разных примеров для чтения времени. Они все читают дату и время нормально... :(
     
  9. ANV

    ANV Гуру

    Потому что __DATE__ и __TIME__ это директивы предпроцессора, они подставляют время компиляции программы
     
  10. Виталий

    Виталий Нерд

    Спасибо огромное!