Как подключить часы реального времени (RTC) к Arduino
Нам понадобятся:
- Arduino UNO или иная совместимая плата;
- модуль ZS-042 с часами реального времени DS3231;
- модуль с часами реального времени DS1307;
- модуль с часами реального времени DS1302;
- соединительные провода;
- макетная плата (breadboard);
- персональный компьютер со средой разработки Arduino IDE.
1Подключение к Arduino модуля ZS-042 с часами реального времени DS3231
Модуль ZS-042 с часами реального времени (RTC) имеет следующие характеристики:
- Календарь до 2100 года с отсчётами секунд, минут, часов, числа месяца, месяца, дня недели и года (с учётом високосных годов);
- 12- или 24-часовой формат;
- 2 будильника;
- напряжение питания: 3,3 или 5 В;
- точность: ± 0.432 сек в день;
- внутренний кварцевый генератор с частотой 32768 Гц;
- поддерживаемый протокол: I2C со скоростью от 100 до 400 кГц;
- габариты: 38×22×15 мм;
- диапазон рабочих температур −40…+85°C.
На модуле присутствуют: микросхема таймера реального времени DS3231 (1 на рисунке), микросхема памяти AT24C32 объёмом 32 кбит (2 на рисунке), места для трёх перемычек A0, A1 и A2 (3 на рисунке), с помощью которых можно менять адресацию памяти микросхемы памяти; место для батареи питания размером 2032 (4 на рисунке).
Назначение выводов модуля такое:
Название | Назначение |
---|---|
32K | Выход генератора 32 кГц. |
SQW | Выход прямоугольного сигнала; частота задаётся с помощью регистра управления 0x0E и может составлять 1, 1024, 4096 или 8192 Гц. |
SCL | Шина тактовых импульсов интерфейса I2C. |
SDA | Шина данных интерфейса I2C. |
VCC | Питание – 3.3 или 5 вольт. |
GND | Земля. |
С противоположной стороны модуля выводы SCL, SDA, питание и земля дублируются. На выходе 32K постоянно присутствует сигнал с встроенного кварцевого генератора:
Теперь нужно подключить модуль к Arduino. Мы уже знаем, что линия SDA нужно подключать к пину A4 Arduino UNO и Nano, а линию SCL – к пину A5. Для питания возьмём выход 5V платы Arduino, землю модуля соединим с землёй Arduino.
Вот как это выглядит вживую:
Рассмотрим диаграммы записи и чтения для таймера реального времени DS3231:
Как видно, тут всё стандартно для интерфейса I2C. Осталось только узнать, какие регистры за что отвечают, и мы будем готовы начать обмен данными с таймером DS3231. А вот и карта регистров:
Первым делом нужно выставить дату и время. А затем нужно будет только читать значение времени и календаря. Расширенные функции – установка будильников и т.д. – всё это делается аналогично, поэтому останавливаться на этом не будем. Итак, чтобы выставить дату и время, нас интересуют регистры 0x00…0x06. Для записи значений в них, нужно послать команду записи, указать начальный адрес (0x00), а дальше – 7 байтов, сформированных для нужной даты и времени. Например, чтобы записать дату 02 января 2019 года, среда, и время 17 час 30 мин 02 сек, нужно отправить ведомому устройству с I2C адресом 0x68 массив: 00 02 30 17 03 02 01 19. Скетч, который реализует это, будет таким:
#include <Wire.h> void setup() { Wire.begin(); // старт i2c Wire.beginTransmission(0x68); // начинаем обмен с DS3231 с i2c адресом 0x68 byte arr[] = {0x00, 0x02, 0x30, 0x17, 0x03, 0x02, 0x01, 0x19}; Wire.write(arr, 8); // записываем 8 байтов массива arr Wire.endTransmission(); // завершение передачи } void loop() { // здесь не делаем ничего }
Вот как выглядит диаграмма записи этого массива в память таймера реального времени DS3231:
Таймер запомнит выставленную дату и время. Если подключена батарейка, то данные будут храниться в памяти устройства до сброса или до полного разряда батареи, ведь в этом и есть назначение устройств такого рода. Давайте теперь будем с периодом 1 секунда читать значение времени и выводить в монитор последовательного порта. Для этого напишем вот такой скетч:
Скетч для чтения времени с часов DS3231 (разворачивается)
#include <Wire.h> const byte DS3231 = 0x68; // I2C адрес таймера DS3231 void setup() { Wire.begin(); Serial.begin(9600); } void loop() { Wire.beginTransmission(DS3231); // начинаем обмен с DS3231 Wire.write(byte(0x00)); // записываем адрес регистра, с которого начинаем чтение!!! Wire.endTransmission(); // завершаем передачу byte t[7]; // массив для хранения даты и времени int i = 0; // индекс текущего элемента массива Wire.beginTransmission(DS3231); // начинаем обмен с DS3231 Wire.requestFrom(DS3231, 7); // запрашиваем 7 байтов у DS3231 while(Wire.available()) { // пока есть данные от DS3231 t[i] = Wire.read(); // читаем 1 байт и сохраняем в массив t i++; // инкрементируем индекс элемента массива } Wire.endTransmission(); // завершаем обмен printDateTime(t); // выводим дату и время delay(1000); // пауза 1 секунда } // разбирает считанный массив и выводит дату и время void printDateTime(byte *arr) { if (arr[4]<10) Serial.print("0"); // дополнение нулями слева для выравнивания Serial.print(arr[4], HEX); // выводим дату Serial.print("."); if (arr[5]<10) Serial.print("0"); Serial.print(arr[5], HEX); // выводим месяц Serial.print(".20"); // 2000-ые годы подразумеваются Serial.print(arr[6], HEX); // выводим год Serial.print(" "); if (arr[2]<10) Serial.print("0"); Serial.print(arr[2], HEX); // выводим час Serial.print(":"); if (arr[1]<10) Serial.print("0"); Serial.print(arr[1], HEX); // выводим минуты Serial.print(":"); if (arr[0]<10) Serial.print("0"); Serial.println(arr[0], HEX); // выводим секунды }
Обратите внимание, что каждую итерацию цикла loop() мы записываем адрес регистра 0x00. Если этого не делать, то мы будем каждый раз сдвигаться по карте регистров на 7 позиций, и возвращаемые данные будут совсем не те, что мы ожидаем.
Вот как выглядит в мониторе последовательного порта результат работы данного скетча:
А вот так выглядит временная диаграмма, порождаемая работой этого скетча:
Напоследок давайте немного усложним нашу программу и будем читать также значение температуры:
Скетч для чтения времени и температуры с часов DS3231 (разворачивается)
#include <Wire.h> const byte DS3231 = 0x68; // I2C адрес таймера DS3231 void setup() { Wire.begin(); Serial.begin(9600); } void loop() { Wire.beginTransmission(DS3231); // начинаем обмен с DS3231 Wire.write(byte(0x00)); // записываем адрес регистра, с которого начинаются данные даты и времени Wire.endTransmission(); // завершаем передачу byte dateTime[7]; // 7 байтов для хранения даты и времени int i = 0; // индекс текущего элемента массива Wire.beginTransmission(DS3231); // начинаем обмен с DS3231 Wire.requestFrom(DS3231, 7); // запрашиваем 7 байтов у DS3231 while(Wire.available()) // пока есть данные от DS3231 { dateTime[i] = Wire.read(); // читаем 1 байт и сохраняем в массив dateTime i+=1; // инкрементируем индекс элемента массива } Wire.endTransmission(); // завершаем передачу printDateTime(dateTime); // выводим дату и время Wire.beginTransmission(DS3231); // начинаем новый обмен с DS3231 Wire.write(byte(0x11)); // записываем адрес регистра, с которого начинается температура Wire.endTransmission(); // завершаем передачу i = 0; // обнуляем счётчик элементов массива byte temp[2]; // 2 байта для хранения температуры Wire.beginTransmission(DS3231); // начинаем обмен с DS3231 Wire.requestFrom(DS3231, 2); // запрашиваем 2 байта у DS3231 while(Wire.available()) { temp[i] = Wire.read(); i+=1; } Wire.endTransmission(); printTemp(temp); // выводим температуру delay(1000); // пауза на 1 сек } // выводит дату и время void printDateTime(byte *dateTime) { if (dateTime[4]<10) Serial.print("0"); Serial.print(dateTime[4], HEX); // выводим дату Serial.print("."); if (dateTime[5]<10) Serial.print("0"); Serial.print(dateTime[5], HEX); // выводим месяц Serial.print(".20"); Serial.print(dateTime[6], HEX); // выводим год Serial.print(" "); if (dateTime[2]<10) Serial.print("0"); Serial.print(dateTime[2], HEX); // выводим час Serial.print(":"); if (dateTime[1]<10) Serial.print("0"); Serial.print(dateTime[1], HEX); // выводим минуты Serial.print(":"); if (dateTime[0]<10) Serial.print("0"); Serial.print(dateTime[0], HEX); // выводим секунды } // выводит температуру void printTemp(byte *temp) { Serial.print("\t"); // символ табуляции для разделения между временем и температурой float temperature = getTemp(temp); Serial.print(temperature); Serial.println("oC"); // градусы Цельсия } // преобразует содержимое регистров 0x11 и 0x12 в значение температуры // для подробностей см. datasheet на ds3231 float getTemp(byte *temp){ float temperature = temp[0]; // целая часть temperature += (temp[1]*0.25/100); // дробная часть return temperature; }
Вот как теперь выглядит вывод нашей программы:
Само собой, в интернете полно библиотек для Arduino, которые упрощают работу с часами реального времени DS3231 и модулем ZS-042 в частности. Они делают всю рутинную работу, и вам не нужно будет разбираться с картой регистров и проводить манипуляции с перестановкой полученных байтов, чтобы получить удобочитаемое значение времени. В конце статьи дана ссылка на скачивание архива, в котором лежат несколько библиотек для работы с часами реального времени DS3231 и DS1307.
2Подключение к Arduino модуля с часами реального времени DS1307
Таймер DS1307 в отличие от DS3231 проще по функциональности: он имеет меньше регистров, не имеет встроенного датчика температуры и встроенного генератора тактовой частоты. Не имеет он также и функции будильника. Шина I2C функционирует только на частоте 100 кГц. Модуль с часами реального времени DS1307 может выглядеть вот так:
Здесь номером 1 обозначена микросхема собственно таймера DS1307, номер 2 – микросхема памяти AT24C32 объёмом 32 кбит, 3 – кварцевый резонатор с частотой 32,768 кГц, 4 – держатель для батареи типа 2032. Схема датчика приведена на рисунке:
На модуле имеются две группы контактов: P1 и P2. Группа P2 имеет стандартные выводы для шины I2C, плюс дополнительный вывод DS, к которому можно подключить внешний датчик температуры DS18B20. Группа P1 имеет большее число контактов:
Название | Назначение |
---|---|
SQ | Выход прямоугольного сигнала 30 кГц. |
DS | Подключение внешнего датчика температуры DS18B20. |
SCL | Шина тактирования интерфейса I2C. |
SDA | Шина данных интерфейса I2C. |
VCC | Питание модуля – 3.3 или 5 вольт. |
GND | Земля. |
BAT | Вход питания от внешней батареи с напряжением в диапазоне 2,0…3,5 В. |
Подключение этого модуля к Arduino осуществляется абсолютно так же, как и рассмотренного ранее: VCC модуля – 5V Arduino, GND – GND, SDA – A4, SCL – A5.
Термодатчик DS18B20 подключается по однопроводному интерфейсу 1-Wire к порту DS. По сути, единственная особенность данного порта в том, что он подтянут к питанию через сопротивление 3,3 кОм, т.е. ничего дополнительно для подключения датчика не требуется. Сам датчик на плате изначально отсутствует, его придётся впаивать самостоятельно.
Теперь пришла пора познакомиться с устройством регистров часов DS1307. Карта регистров приведена на рисунке:
Если присмотреться, увидим, что регистры 0x00…0x06 в точности совпадают с аналогичными регистрами рассмотренного таймера DS3231, а регистр 0x07 отвечает за частоту генерируемого прямоугольного сигнала. Кроме того, I2C адрес DS1307 также аналогичен адресу модуля DS3231. Поэтому логично предположить, что скетч установки времени подойдёт и здесь. В этом легко убедиться, если загрузить скетч в Arduino с подключённым модулем DS1307. Не забудьте только обновить установочный массив в соответствии с временем, которое будете выставлять на часах. Пример разобран в предыдущем разделе.
Скетч вывода времени также будет работать с этим модулем. После установки времени загрузим скетч и проверим это. Всё работает!
3Подключение к Arduino модуля с часами реального времени DS1302
Модуль DS1302 может выглядеть, например, так:
На нижней стороне модуля никаких компонентов нет. Как видно, вся «обвязка» микросхемы DS1302 – это кварцевый резонатор.
Назначение выводов микросхемы DS1302 такое (слева в DIP-корпусе, справа – в планарном):
Название вывода DS1302 | Назначение |
---|---|
X1, X2 | Входы для подачи частоты 32,768 кГц с кварцевого резонатора. |
SCLK | Вход тактовой частоты последовательных данных. |
I/O | Вход/выход последовательных данных. |
CE | Вход выбора чипа. Активируется высоким уровнем. |
VCC1 | Дополнительное резервное питание (например, от батареи) для сохранения настроек времени в ПЗУ, 3 В. |
VCC2 | Первичное питание микросхемы, 5 В. |
GND | Земля |
Соответствие выводов микросхемы DS1302 выводам модуля, думаю, очевидно: VCC – это первичное питание 5 В, GND – земля. CLK – вход тактовых импульсов. DAT – ввод/вывод последовательных данных. RST – это CE, который включает логику и показывает микросхеме RTC, что происходит обмен данными (чтение или запись).
Типичная схема подключения RTC микросхемы DS1302:
Самый простой способ управлять DS1302 – это, конечно же, воспользоваться одной из множества готовых библиотек для Arduino, например, этой (она приложена также архивом внизу статьи). Она позволяет выставлять время и считывать его, а также записывать и читать данные из ПЗУ часов.
Думаю, что объяснять, как использовать библиотеку для Arduino, не нужно. В библиотеке есть два примера, в которых подробно расписано, как использовать часы DS1302. Поэтому давайте попробуем разобраться, как работать с часами DS1302 без сторонних библиотек.
Для обмена с микросхемой DS1302 используется последовательный интерфейс, похожий на SPI. Диаграмма передачи данных показана ниже. Видно, что во время чтения или записи данных сначала следует выставить логическую "1" на линии CE. Затем сгенерировать 16 тактовых синхронизирующих импульсов. В это время передаются 16 бит информации.
В первых 8-ми битах передаётся команда (командный байт), а следующие 8 бит – данные. Структура командного байта показана ниже. В нём старший бит всегда "1", младший – признак операции (чтение RD=1 или запись WR=0), а остальные биты – это адрес регистра, с которым взаимодействуем.
Кроме того, DS1302 поддерживает множественную передачу (burst mode). Для этого следует удерживать высокий уровень на линии CE и генерировать необходимое число тактовых импульсов. Данные будут читаться (или записываться) из регистров или ПЗУ последовательно, начиная с заданного адреса и далее. Карта регистров и адресное пространство ПЗУ микросхемы DS1302 показаны на рисунке.
Предлагаю для изучения DS1302 воспользоваться отладочной платой с микросхемой FT2232H и программы SPI via FTDI. Это позволит избежать постоянного программирования Arduino и проводить все эксперименты с часами «на лету».
Единственная сложность в том, что микросхема FT2232H использует 3.3-вольтовую логику, а часы DS1302 – 5-вольтовую. Но ничего страшного, воспользуемся преобразователем логического уровня, благо стоит он копейки, и в применении исключительно прост. У него есть две стороны: одна отвечает за низковольтовую часть (LV), другая – за высоковольтную (HV). У него есть 4 низковольтных входа-выхода (LV1…LV4) и соответствующие им 4 высоковольтных входа-выхода (HV1…HV4). Питание низковольтовой части осуществляется через вывод LV напряжением 3.3 В, высоковольтной – через вывод HV напряжением 5 В. Подробнее написано в этой статье. Схема подключения приведена далее.
К высоковольтной стороне преобразователя подключается модуль DS1302, к низковольтной – микросхема FT2232H. Соответствие выводов такое: CLK – ADBUS0, DAT – ADBUS1 и ADBUS2, RST – ADBUS3. Подключаем соответственно через преобразователь напряжения. Вот так это выглядит вживую:
Когда собрали схему, запустим программу SPI via FTDI и в меню «Устройство» выберем интерфейс SPI, потом нажмём «Подключить». Теперь в левой части главного окна, в рамке «Настройки SPI» снимем галочки с CS active LOW (активация часов DS1302 высоким уровнем, вывод CE) и MSB first (передача байта старшим битом вперёд). Остальные параметры оставим как есть.
Теперь попробуем прочитать 1 байт из регистра секунд 0x81. Он должен меняться каждую секунду, и мы сразу увидим, что наша схема работает. Для чтения регистра секунд настройки программы будут такие (обратите внимание на раздел «Чтение»):
Чтобы увидеть принятые данные, нужно нажать на кнопку с изображением таблицы слева от кнопки «Прочитать».
Чтобы прочитать данные всех регистров, нужно отправить команду BF и запросить столько регистров, сколько нужно. Все данные о дате хранятся в 7-ми регистрах, а восьмой – данные о запрете записи (WP, write protect).
Кстати, если вместо числа "1" ввести число раз "0" (справа от кнопки чтения), то программа будет постоянно опрашивать часы DS1302, и вы увидите в таблице принятых данных как идёт время часов DS1302.
Для записи данных в ПЗУ часов DS1302 в режиме множественной передачи (не по одному байту) следует отправить команду FE и дальше нужные данные. Для чтения данных из ПЗУ в режиме множественной передачи нужно отправить команду FF:
Теперь мы можем устанавливать время на часах DS1302, читать его, а также работать с постоянной энергонезависимой памятью часов. Приведённых примеров должно быть достаточно, чтобы реализовать всё это на Arduino без использования сторонних библиотек.
Библиотеки для работы с часами реального времени DS1307 и DS3231
В приложенном архиве лежат две разные библиотеки для Arduino (используйте ту, которая будет вам наиболее удобна), а также технические описания (datasheet) на микросхемы DS1307 и DS3231.
Установка библиотек проводится стандартным способом: помещением директории с библиотекой в директорию libraries среды Arduino IDE или через меню Sketch Include Library. Проще всего начать знакомство с библиотекой с изучения примеров, которые появятся в меню File Examples после установки библиотеки. Там имеются примеры и установки времени, и чтения показаний часов.
Download attachments:
- Библиотеки для работы с часами реального времени DS1307 и DS3231 (4665 Downloads)
- Схема часов реального времени на датчике DS1307 (1462 Downloads)
- DS1302 datasheet (PDF) (822 Downloads)
- Библиотека для работы с DS1302 (1653 Downloads)
Поблагодарить автора:
Поделиться
Related items
17 comments
-
Алексей Вторник, 14 May 2019 06:05 Ссылка на комментарий
В характеристиках к модулю ZS-042 указано:
- диапазон рабочих температур 0…40°C;
- микросхема DS3231 имеет внутренний термометр с диапазоном от −40…+85°C.
Это как??? Модуль может измерять температуру в диапазоне в котором сам не может работать? -
repon Четверг, 27 Июнь 2019 11:44 Ссылка на комментарий
DS1307 подключил. залил скейчи
Выводит: 00.00.201F E5:01:00 -
Анатолий Вторник, 19 Ноябрь 2019 15:33 Ссылка на комментарий
Здравствуйте. Если в DS1307 нет будильника, как можно реализовать подобную функцию? Необходимо 2 раза в сутки выдавать логический сигнал на запуск шагового двигателя. Помогите пожалуйста.
-
aave1 Вторник, 19 Ноябрь 2019 17:38 Ссылка на комментарий
Анатолий, микросхема DS3231 имеет функцию будильника, и стоит она копейки. Лучше всего на неё заменить.
Если это невозможно, то попробуйте отсчитывать время с помощью функции millis() - http://arduino.ru/Reference/Millis
При этом точность, конечно, будет не ахти какая. Да и если система перезагрузится, то счётчик начнёт считать с начала. -
Анатолий Среда, 20 Ноябрь 2019 10:02 Ссылка на комментарий
Спасибо, я понял, дело не в цене. Просто времени жаль.
Интуитивно кажется: задать время в ардуино, теперь сравниваем.... когда совпало... Ура!
Только я совсем не программист, Понятия не имею как это реализовать. -
Анатолий Воскреснье, 15 Декабрь 2019 10:40 Ссылка на комментарий
Здравствуйте.
С большим интересом изучаю материалы Вашего сайта. Спасибо.
Прошу Вас помочь мне в одном вопросе.
Я купил на Али... Две платки, у разных продавцов (имея в виду - использовать их вместо платы Комплект UNO R3 CH340G + MEGA328P Чип 16 МГц для Arduino UNO R3) для готовых отработанных поделок.
Вот эти платы как написано у продавцов:
1. Nano с Загрузчиком совместимый Nano 3,0 контроллер для arduino CH340 USB драйвер 16 МГц Nano v3.0 ATMEGA328P/168 P https://ru.aliexpress.com/item/32341832857.html?spm=a2g0s.9042311.0.0.274233edVDRWNB
2. Nano Mini USB с Загрузчиком совместимый контроллер Nano 3,0 Для arduino CH340 USB драйвер 16 МГц Nano v3.0 ATMEGA328P https://ru.aliexpress.com/item/32309876432.html?spm=a2g0s.9042311.0.0.274233edVDRWNB
В названии есть некоторые отличия, визуальных различий я не вижу.
Первая загружает проверенный на UNO скетч, а вторая нет.
А теперь вопрос: Эти платы одинаковые и вторая неисправна, или они разные? Тогда как применить вторую?
Заранее благодарю за ответ
С уважением, Анатолий. -
aave1 Понедельник, 16 Декабрь 2019 19:59 Ссылка на комментарий
Анатолий, насчёт плат Arduino Nano, о которых Вы пишете.
Первая, насколько я вижу, использует микросхему CH340 в качестве преобразователя USB в UART, а вторая - FT232. У них разные драйверы. Я думаю, что дело может быть в этом. Драйвер для FT232 скачивается с официального сайта фирмы FTDI. -
Михаил Вторник, 14 Апрель 2020 17:23 Ссылка на комментарий
Большое спасибо за детальный обзор. Вопрос возник при использовании скетча в котором извлекается из модуля не только время но и температура. У меня модуль ds1307, а скетч Ваш для модуля ds3231. Он работает, но температуру показывает странную. По даташиту ds1307 у данного девайса нет регистров 011 и 012 (которые есть у ds3231). Наверно поэтому я извлекаю несуществующие данные. Тогда как если подключить сигнальную ногу ds18b20 к иному порту мк считать можно как обычно по шине oneWire.Подскажите, есть ли возможность считывать температуру в моем случае как и время с модуля ds1307, или только через использование вывода на иной порт мк. Спасибо.!
-
aave1 Четверг, 16 Апрель 2020 05:21 Ссылка на комментарий
Михаил, вы можете подключить свой датчик температуры DS18B20 к выводу DS модуля часов DS1307. Также необходимо соединить питание и землю. Схему модуля и датчика выложу чуть позже.
При этом обращаться к датчику температуры будете по интерфейсу OneWire и отдельному проводу, т.к. он не связан с модулем часов. К сожалению, нельзя не задействовать дополнительный провод, который вы хотите сэкономить. -
Владимир Суббота, 18 Апрель 2020 06:20 Ссылка на комментарий
Здравствуйте! Спасибо за Ваши статьи, очень интересно читать и всё понятно!!!
В Вашем скетче время считывается с модуля РТС каждую секунду и выводится в монитор порта, или на дисплей в случае реальных часов. В одной статье вскользь упоминалось, что лучше сделать отдельный счётчик в программе, а обращаться к модулю РТС гораздо реже, раз в час например, но не упоминалось почему. Так ли это? Имеет ли какое-то значение частота обращений к модулю часов? Ваше мнение?
Спасибо! -
aave1 Суббота, 18 Апрель 2020 15:52 Ссылка на комментарий
Владимир, добрый день! Нет, обращаться к часам можно как угодно часто (учитывая время на передачу данных от RTC до Arduino). По крайней мере, в даташите я не нахожу ограничений на этот счёт. Вероятно, в упоминаемой Вами статье попросту нет необходимости в том, чтобы постоянно иметь актуальное время.
-
Анатолий Вторник, 28 Апрель 2020 07:36 Ссылка на комментарий
Здравствуйте. Хорошо бы еще подключить к этой схеме цифровой индикатор (например tm1637? или подобный....
Спасибо. -
aave1 Вторник, 28 Апрель 2020 17:36 Ссылка на комментарий
Анатолий, отличная идея! Если такой индикатор окажется в моих руках, обязательно подключу!
-
Наталья Понедельник, 04 May 2020 13:20 Ссылка на комментарий
Почему при прошивке программой счета времени последовательного счета не происходит?
Вывод программы:
04.05.2020 16:10:00
04.05.2020 16:10:01
04.05.2020 16:10:00
04.05.2020 16:10:01
04.05.2020 16:10:08
04.05.2020 16:10:09
04.05.2020 16:10:10
04.05.2020 16:10:11
04.05.2020 16:10:10
04.05.2020 16:10:11
04.05.2020 16:10:10
04.05.2020 16:10:11
04.05.2020 16:10:10
04.05.2020 16:10:11
04.05.2020 16:10:18
04.05.2020 16:10:19
04.05.2020 16:10:00
04.05.2020 16:10:01 -
aave1 Суббота, 09 May 2020 15:27 Ссылка на комментарий
Наталья! Обратите внимание, что данные всё-таки приходят и меняются (чётная секунда, потом нечётная), а некоторые вообще совпадают с тем, что нужно. Если изменение времени показать в бинарной форме (тут только секунды), то получится:
00=0_0000 - 0_0100=4
01=0_0001 - 0_0101=5
00=0_0000 - 0_0110=6
01=0_0001 - 0_0111=7
08=0_1000 + 0_1000=8
09=0_1001 + 0_1001=9
10=0_1010 + 0_1010=10
11=0_1011 + 0_1011=11
10=0_1010 - 0_1100=12
11=0_1011 - 0_1101=13
10=0_1010 - 0_1110=14
11=0_1011 - 0_1111=15
10=0_1010 - 1_0000=16
11=0_1011 - 1_0001=17
18=1_0010 + 1_0010=18
19=1_0010 + 1_0010=19
00=0_0000 - 1_0100=20
01=0_0001 - 1_0101=21
Здесь в первом столбце ваши значения секунд, во втором - как это будет в двоичном виде, в третьем - знак "плюс" или "минус" - правильное значение или нет, в четвёртом и пятом - что должно быть (в двоичном и десятичном виде).
По какой-то причине 2-ой разряд (нумерация начинается с нуля) не переключается, там всегда "0". Я предположу, что это какой-то аппаратный сбой. Например, соответствующая ячейка памяти регистра времени у вашего датчика RTC повреждена. Но при этом 4-ый разряд иногда переключается, иногда нет. В таком случае это может быть наводка на проводах, которыми датчик часов соединяется с Arduino. Попробуйте использовать более короткие провода или понизьте скорость шины I2C.