Прибор контроля температуры в парнике я собрал на DS1307 в те времена, когда DS3231 стоил вдвое дороже, а я верил, что «часы — они и есть часы». Год прибор отработал, но его журнал уехал от календаря на одиннадцать минут: каждая сверка с телефоном показывала, что врёт не телефон. Замена модуля заняла четыре минуты — и с тех пор это мой самый частый апгрейд: чип дороже в два-три раза, но разницу выкупает уже в первый сезон, без пайки сверх стандартных гнёзд. Слово «врёт» тут точное: чип исправно считал секунды, но его кварц отставал от эталонного времени, и каждое отставание складывалось в минуты журнала.
Здесь я проведу замену по-инженерному: сравню чипы по числам, от которых зависит проект, пройдусь по питанию и батарейкам — там прячутся две ловушки, о которых продавец модулей молчит, — и покажу скетч, который сам разбирается, какой из двух модулей сидит на шине. Разбор точности с полевыми замерами уже сделан в уроке про сравнение DS1307 и DS3231, а цифры ухода за месяц считаны в уроке про дрейф двух чипов — здесь упор на практику замены, а не на теорию ppm. Замена тут не дань моде, а ремонт фундамента: журнал, который врёт, хуже отсутствия журнала.
Коротко о главном до таблицы: DS1307 — счётчик-календарь с внешним кварцем на модуле, DS3231 — счётчик вместе с генератором и термокомпенсацией в одном корпусе. Всё остальное — следствия этой разницы: точность, цена, допустимое питание и даже то, какая батарейка встанет в гнездо.
Вердикт я формулирую так: DS1307 жив в приборах, где часы — украшение экрана, и умирает там, где по меткам строятся графики и расписания. Метеостанция с журналом, полив, логгер — территория DS3231; ёлочная гирлянда с часами на корпусе — территория DS1307, где минуты дрейфа за месяц никто не заметит. Между полюсами сидит третья категория: приборы, которые едут к другим людям, — для них я ставлю DS3231 всегда, потому что не знаю, в какой полосе прибор окажется жить.
Точность: внешний кварц против термокомпенсации
У DS1307 генератора нет: на модуле стоит внешний цилиндрический кварц 32768 Гц, и точность часов равна точности этого кварца с его конденсаторами нагрузки. Паспорт оперирует диапазоном ±20-50 ppm — полторы-четыре секунды в сутки, минута-две за месяц. Дешёвые модули собирают с кварцами без подгонки ёмкости, и в моей партии из десяти штук уход за месяц разошёлся от двух до семи минут: каждая плата врала по-своему, и согласовать журналы между собой не получалось вовсе. Конденсаторы нагрузки на дешёвых платах стоят без подгонки под конкретный экземпляр кварца, поэтому паспортные двадцать ppm на практике разваливаются вдвое-втрое шире.
У DS3231 кварц, датчик температуры и схема компенсации сидят в одном корпусе: каждые 64 секунды чип замеряет кристалл и подстраивает частоту. Паспорт обещает ±2 ppm при 0..+40 °C — около одной минуты в год — и ±3,5 ppm при -40..+85 °C. Подстройка — не магия: раз в 64 секунды чип меряет кристалл и сдвигает делитель на долю герца, сам, без единой строки скетча. Даже по паспорту разница с DS1307 — порядок величины, а на дешёвых кварцах — два порядка, и это та разница, которую видно без приборов: по журналу за неделю.
Условия, без которых цифры врут. Компенсатор греет кристалл, поэтому rtc.getTemperature() на DS3231 показывает температуру корпуса с точностью ±3 °C, а не воздух комнаты; у DS1307 такого метода нет вовсе — в RTClib для него температуру просто не реализовали. Обещание ±2 ppm держится только в диапазоне 0..+40 °C, и для улицы зимой честнее закладывать ±3,5 ppm. И датчик там нужен компенсатору, а не вам: строить по нему термометр комнаты — самообман. Месяц полевых замеров с эталонным модулем и методика подсчёта ppm — в уроке про полевой тест дрейфа.
Между прочим, у DS3231 есть и ручной запас точности: регистр старения сдвигает частоту кварца шагами по 0,1 ppm при комнатной температуре. Им выправляют остаточный уход после полевого теста — когда модуль уехал на несколько секунд за месяц и хочется добить его до предела паспорта. Трогать регистр без месяца замеров — стрельба по своим же часам: сначала цифры дрейфа, потом поправка.
Арифметику ppm стоит один раз прогнать руками: одно ppm — это 0,0864 секунды в сутки, и дальше всё умножается. Паспортные 20 ppm DS1307 — это 1,7 секунды ежесуточно, 50 ppm — 4,3; за месяц набегает 52-130 секунд, та самая минута-две из таблицы. Пересчёт любой точности в секунды за сутки и за год собран в уроке про ppm-калькулятор — держите его под рукой, когда решаете, терпим ли уход конкретного модуля. Условие, при котором DS1307 терпим, простое: вы готовы подправлять время хотя бы раз в месяц; убрать это обязательство может только замена чипа, никакой скетч ppm не вылечит.
| Параметр | DS1307 | DS3231 |
|---|---|---|
| Кварц | внешний, цилиндр 32768 Гц на модуле | встроенный + TCXO с подстройкой каждые 64 с |
| Точность | ±20-50 ppm: 1-2 мин/мес, дешёвые — до семи | ±2 ppm при 0..+40 °C: около 1 мин/год |
| Питание логики | 4,5-5,5 В: от 3,3 В не обязан стартовать | 2,97-5,5 В: работает от обоих напряжений |
| Батарейка | CR2032, плат без зарядной цепи | LIR2032 на типовых платах с зарядкой |
Замена модуля: что меняется на самом деле
Практическая часть замены приятна тем, что почти ничего не меняется. Адрес на шине у обоих чипов 0x68: сканер показывает ту же точку, провода SDA, SCL, VCC и GND остаются на местах — раскладку старого модуля я разбирал в уроке про подключение DS1307. Формат хранения времени тоже совпадает: RTClib прячет разницу чипов за одинаковым API, и поля DateTime приезжают из любого из них одни и те же. Проверка сканером занимает десять секунд и экономит вечер: замена по шине невидима, и если сканер молчит, дело не в смене чипа, а в проводе.
В скетче меняется имя класса: RTC_DS1307 на RTC_DS3231 в объявлении и в вызове begin — две строки, а вызовы now() и adjust() не трогаются. Есть и подсказка от компилятора: если после замены в коде остался getTemperature(), проект с DS1307 не соберётся — у этого класса метода нет, и компилятор ругается раньше любого мультиметра; единственное место, где классы расходятся, — температура, и она же служит тестом. Обратная замена, DS3231 на DS1307, почти всегда шаг назад: платите точностью и получаете жёсткое требование пяти вольт; единственный резон, который я знаю, — ящик валяющихся модулей и проект на выброс.
#include <Wire.h>#include <RTClib.h> RTC_DS3231 rtc3231;RTC_DS1307 rtc1307; void dvoe(int v) { if (v < 10) Serial.print("0"); Serial.print(v);} void pechat(DateTime t) { dvoe(t.day()); Serial.print("."); dvoe(t.month()); Serial.print("."); Serial.print(t.year()); Serial.print(" "); dvoe(t.hour()); Serial.print(":"); dvoe(t.minute()); Serial.print(":"); dvoe(t.second());} void setup() { Serial.begin(9600); Wire.begin(); // У DS3231 в регистрах 0x11-0x12 живёт температура кристалла, LSB - четверти градуса. // DS1307 прокручивает адрес по кругу 0x00-0x07, и на 0x11 отдаёт BCD-минуты. Wire.beginTransmission(0x68); Wire.write(0x11); Wire.endTransmission(); Wire.requestFrom(0x68, 2); byte star = Wire.read(); byte mlad = Wire.read(); Serial.print("Registry 0x11/0x12: "); Serial.print(star, HEX); Serial.print(" "); Serial.println(mlad, HEX); // Кристалл в комнате держит 15-35 C (0x0F..0x23), у LSB старшие биты нулевые. // Признак практический, не паспортный: пограничные платы перепроверяйте заменой класса. bool pohozheNaDS3231 = (star >= 0x0F && star <= 0x23 && (mlad & 0x3F) == 0); if (pohozheNaDS3231 && rtc3231.begin()) { Serial.print("Vernik: DS3231 "); pechat(rtc3231.now()); Serial.print(" t="); Serial.print(rtc3231.getTemperature(), 1); Serial.println(" C (kristall)"); } else if (rtc1307.begin()) { Serial.print("Vernik: DS1307 "); pechat(rtc1307.now()); Serial.println(" (getTemperature zdes ne skompiliruetsya - metoda net)"); } else { Serial.println("Na 0x68 nikogo net: SDA A4, SCL A5?"); }} void loop() {}Прогоните сценарий как есть: раз в четыре секунды монитор печатает две колонки с разницей в секундах — в симе она всегда ноль, и это честная граница модели. Команда Y покажет прогноз на год: 10-26 минут у DS1307 против минуты у DS3231, числа из паспортов с условиями из таблицы. Команда T печатает 23,5 — заглушку движка; на плате это будет температура кристалла, которая после десяти минут работы уходит от комнатной на пару градусов вверх.
После физической замены модуля прогоните три проверки. Время ставится одной строкой adjust — механика в уроке про установку времени. Батарейка обязана соответствовать плате — об этом warn ниже. И гляньте lostPower(): после пайки модуль мог побывать обесточенным, и флаг честно скажет, что в полях лежал мусор. Ресурс и правила замены самих батареек я считал в уроке про CR2032 — у пары CR2032-LIR2032 там собственная драма.
Батарейка при замене — отдельный пункт чек-листа. CR2032 несёт 220 мА·ч, ток храненья у обоих чипов — единицы микроампер, поэтому по бумаге батарейка живёт лет восемь; саморазряд и пружина контакта режут срок примерно вдвое, и я меняю CR2032 по календарю раз в пять лет, а не по индикатору — его у модуля нет. Заодно гляньте год маркировки на корпусе: батарейка, пролежавшая на складе с 2019 года, теряет часть заряда ещё до установки. А если модуль питается круглосуточно от блока, старая CR2032 не худеет вовсе — она работает только тогда, когда свет действительно гаснет.
Ящик запасных модулей я промаркировал изнутри крышки: дата установки батарейки и что за чип. Через год-два отличить DS3231 от DS1307 на глаз уже нельзя — разве что посадить плату на шину и поймать getTemperature(), а для этого нужен стол с проводами. Маркер на скотче дешевле любого расследования, и это не преувеличение: на идентификацию трёх немых модулей у меня ушёл вечер.
- 1. Почему DS1307 не работает на 3,3-вольтовых платах?
- 2. Что меняется в скетче при замене модуля DS1307 на DS3231?
- 3. Что показывает rtc.getTemperature() на DS3231?
- 4. Почему обычную CR2032 нельзя ставить в типовую плату DS3231?
- 5. Сколько набежит на DS3231 за год при ±2 ppm?
- DS1307 — счётчик с внешним кварцем (±20-50 ppm, минуты за месяц); DS3231 — TCXO с компенсацией каждые 64 с (±2 ppm при 0..+40 °C)
- Замена вверх безболезненна: адрес 0x68 общий, провода те же, в скетче меняется имя класса — две строки
- getTemperature() есть только у DS3231 и показывает кристалл (±3 °C), а не комнату; компилятор поймает его на DS1307
- Питание — решающий пункт: DS1307 требует 4,5-5,5 В и молчит от 3,3 В, DS3231 живёт от 2,97 В
- Батарейки: CR2032 — для плат без зарядной цепи, LIR2032 — для типовых DS3231-плат с зарядкой, иначе вздутие
Частые вопросы по теме урока
- Почему DS1307 не работает на 3,3-вольтовых платах?
- Генератор DS1307 питается от логики, и ниже 4,5 В чип не гарантирует ничего. DS3231 живёт от 2,97 В, поэтому для 3,3-вольтовых плат замена единственно возможная. Паспорт требует 4,5-5,5 В: на 3,3 В чип не обязан стартовать
- Что меняется в скетче при замене модуля DS1307 на DS3231?
- Адрес 0x68 общий, провода те же, now() и adjust() те же — меняются две строки с именем класса. Единственный камень — getTemperature(), которого у DS1307 нет. Имя класса в объявлении и в begin — остальное API то же
- Что показывает rtc.getTemperature() на DS3231?
- Датчик стоит внутри для компенсации кварца и мерит кристалл, который сам себя подогревает. Комнату этот метод не показывает, у DS1307 его нет вовсе. Температуру кристалла с точностью ±3 °C — компенсатор греет чип
- Почему обычную CR2032 нельзя ставить в типовую плату DS3231?
- Плата ZS-042 собрана под перезаряжаемую LIR2032: диод и резистор около 200 Ом постоянно подают ток на гнездо. Неаккумуляторная CR2032 от этого вздувается и течёт. Зарядная цепь платы пытается её заряжать, и батарейка вздувается
- Сколько набежит на DS3231 за год при ±2 ppm?
- 2 ppm — это две секунды на миллион секунд, то есть примерно 63 секунды в год. Заявление «±1 минута в год» из паспорта подтверждается и полевыми замерами. Около минуты