Читает дату с DS3231 не правильно

Нет ответов
alexbel620017
Offline
Зарегистрирован: 26.03.2017

Ребята, подскажите кто знает - при синхронизации с GPS иногда в модуль часов записывается не правильно дата. Год 2000, а месяц и дата нулевые. При этом время (часы и минуты) всегда верные. Читается из DS3231 в этом случае: 31 декабря 95 года. А иногда синхронизация проходит нормально - с правильной записью года, дня и месяца. Как получается что данные с GPS (прошедшие проверку if (gps.encode(c))) косячат при "вынимании" из них даты?...

Проект в самом начале, это далеко не законченный вариант кода, модули привинчиваю по очереди.

#include <DS1307RTC.h>
#include <DS3231.h>
#include <Time.h>
#include <TinyGPS.h>
#include <SPI.h>
#include <Ethernet2.h>
#include <SD.h>

// ------------------------- сеть ---------------------------------
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);

// ------------------------- часы ---------------------------------
DS3231 Clock;
TinyGPS gps;

void getgps(TinyGPS &gps);

bool newdata = false;
bool Century = false;
bool h12;
bool PM;
bool rzr = false;                                // флаг Разрешения Записи Регистратора, - только после GPS синхронизации!
int Y;
//int Mpr;
//int Dpr;
byte m, s, h, d, M;
int msri = 0;                              // старший разряд минут
int mmri = 0;                              // младший разряд минут
int hsri = 0;                              // старший разряд часов
int hmri = 0;                              // младший разряд часов
unsigned long mln = 10000;                 // переменная задержки для первой синхронизации с GPS (1 минута)
unsigned long sinhr;                       // переменная в мсек задающ. период синхронизации
unsigned long start;                       // переменная в мсек задающ. цикл считывания данных gps
unsigned long decim;                       // переменная в мсек задающ. период децимальных точек
unsigned long registr;                     // переменная в мсек задающ. период записи регистратора (5 мин)
unsigned long treg = 10000;               // период записи регистратора 5 мин

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
  SD.begin(22);

  setSyncProvider(RTC.get);                 // библиотечная команда извлечения данных из модуля часов

  // ------------------------------------------ GPS для часов ------------------------------------------

  Ethernet.begin(mac, ip);
  server.begin();
  Serial.println(Ethernet.localIP());

  sinhr = millis();
  decim = millis();
  registr = millis();

  pinMode(23, OUTPUT);                      // CS для W5500
  pinMode(22, OUTPUT);                      // CS SD-карты
  pinMode(24, OUTPUT);                      // CS модуля NRF24
  digitalWrite(24, HIGH);

}
// ==========================================================================================================================================================================
// ===================================================================== L O O P ============================================================================================

void loop() {
  // --------------------------------------- часы ----------------------------------------

  Y = 2000 + Clock.getYear();               // получение года из модуля часов DS3231
  M = Clock.getMonth(Century);              // получение месяца из модуля часов DS3231
  d = Clock.getDate();                      // получение дня из модуля часов DS3231
  h = Clock.getHour(h12, PM);               // получение часов из модуля часов DS3231
  m = Clock.getMinute();                    // получение минут из модуля часов DS3231

  msri = m / 10;                            // вычисление единиц и десятков минут и часов
  mmri = m - ((m / 10) * 10);
  hsri = h / 10;
  hmri = h - ((h / 10) * 10);

  // ------------------------------------- Cеть ------------------------------------------

  EthernetClient client = server.available();   //слушаем входящего клиента
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println("Connection: close");      // the connection will be closed after completion of the response
  client.println("Refresh: 2");            // refresh the page automatically every 5 sec
  client.println();
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");

  for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
    int sensorReading = analogRead(analogChannel);
    client.print("analog input ");
    client.print(analogChannel);
    client.print(" is ");
    client.println(sensorReading);
    client.println("<br />");
  }
  delay(1);                                 // дали время браузеру на приём данных
  client.stop();                            // закрыли соединение

  //---------------------------- работа GPS модуля ---------------------------------------

  //Serial.println(mln);
  if (millis() - sinhr > mln) {   // таймер для синхронизации на сутки (86400000)
    newdata = false;
    start = millis();
    while (millis() - start < 2000)
    {
      if (Serial1.available())
      {
        char c = Serial1.read();    // чтение массива, переданного NEO-6M
        Serial.print(c);          // вывести на печать массив из NEO-6M
        if (gps.encode(c))          // проверка данных на правильность
        {
          newdata = true;
          break;                    // остановить цикл при нормальной декодировке
        }
      }
    }
    if (newdata)
    {
      getgps(gps);                  // при нормальной декодеровке уходим на выполнение getgps(TinyGPS &gps)
    }
  }

  // -------------------------- SD карта ---------------------------------------------

  if ((millis() - registr) > treg) {   // таймер для записи регистратора на 5 мин
    if (Y != 2095) {
      if (rzr == true) {
        SD.begin(22);
        String logStringData = "";                            // формирование строки с данными
        String p;                                             // переменная для минут меньше 10, чтобы минуты были с нулём
        if (m < 10) {
          p = "0" + String(m);
        }
        else {
          p = String(m);
        }
        // формируем строку с данными, в начале - время записи, потом инфа
        logStringData = String(h) + ":" + p + " > " + "полезная информация\r\nопять полезная инфа\r\n";   // для примера с переводом строки   ( \r\n )
        String DirectName = String(Y) + "/" + String(M);     // Создаём имя папки из месяца и года
        SD.mkdir(DirectName);
        // Открываем файл, но помним, что одновременно можно работать только с одним файлом.
        // Если файла с таким именем не будет, ардуино создаст его.
        String logStringName = DirectName + "/" + String(d) + ".txt";          // формируем текстовый файл на один день максимум 12 знаков в названии файла
        Serial.println (logStringName);
        File dataFile = SD.open(logStringName, FILE_WRITE);

        // Если все хорошо, то записываем строку:
        if (dataFile) {
          dataFile.println(logStringData);             // в файл записываем строку данных с переводом строки
          dataFile.close();                            // закрываем файл
          // здесь надо будет вывести индикацию удачной записи в Nextion в виде зелёного кружка
          Serial.println(logStringData);
        }
        // Если все плохо, то рисуем красный кружок на Nextion
        else {
          // рисуем красный кружок в Nextion
          Serial.println("error opening");
        }
        mln = 56400;                            // постоянная на синхронизацию по GPS (сутки)
        registr = millis();
      }
    }
  }
}                                             // конец loop

// ----------------- подпрограмма вывода данных из gps и синхронизации модуля часов (раз в сутки)-----

void getgps(TinyGPS & gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  // вынимание данных из массива, полученного из модуля gps
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths);
  //Mpr = month;                              // промежуточная перем. для разрешения записи SD (с GPS есть правильная дата)
  //Dpr = day;                                // промежуточная перем. для разрешения записи SD (с GPS есть правильная дата)
  hour = hour + 5;                           // переделка час. пояса
  if (hour > 23)                             // избежание 25, 26 часов на дисплее
  {
    hour = hour - 24;
  }
  rzr = true;                                          // разрешение на работу регистратора (исп. данные GPS для записи в регистратор)
  // - непосредственно синхронизация -
  setTime(hour, minute, second, day, month, year);      // устанавливаем: часы, минуты, секунды (и день, месяц, год)
  RTC.set(now());                                      // применяем значение
  sinhr = millis();
  //Serial.print("       есть синхр ");
}