habrahabr

Модернизация настольных электромеханических часов

  • среда, 12 февраля 2025 г. в 00:00:35
https://habr.com/ru/articles/879724/

У меня есть старые электромеханические часы «Янтарь», которым почти 50 лет. По паспорту их продали в 1976 году. Эти часы дороги мне как память, потому что достались от бабушки с дедушкой.

1. Внешний вид часов
1. Внешний вид часов

Они до сих пор исправно ходят, но точность хода у них низкая. Погрешность набегает настолько быстро, что я перестал их подводить, и показывают они плюс-минус полчаса. Я решил исправить эту проблему, чтобы они радовали не только связанными воспоминаниями, но и надежным выполнением своей функции.

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

Замечание: я не занимаюсь ремонтом часов. Всё написанное о них — результат осмысления материалов в интернете и собственных экспериментов. Если укажете на ошибки — с удовольствием внесу правки. Кроме того, я не буду останавливаться на стандартных вопросах типа «как прошить микроконтроллер», ответы на которые легко найти в интернете.

Почему электромеханические часы ходят неточно и что можно с этим сделать?

Электромеханические часы работают следующим образом. Эталоном времени в них служит баланс, совершающий вращательные колебания под действием возвращающей силы скручивания и раскручивания спиральной пружины. Специальная электронная схема за счет батарейки восполняет потери энергии в механизме, раскачивая баланс. Колебания баланса через анкерную вилку и анкерное колесо преобразуются во вращение шестеренок механизма.

2. Механизм без задней крышки и защитного кожуха, я уже припаял два дополнительных провода для экспериментов
2. Механизм без задней крышки и защитного кожуха, я уже припаял два дополнительных провода для экспериментов

Точность хода электромеханических часов зависит от стабильности периода колебаний баланса. Электрическая схема только передает ему энергию, а частоту колебаний никак не стабилизирует. Колебания баланса не гармонические, их частота зависит от амплитуды. Амплитуда в свою очередь зависит как минимум от заряда батарейки. Температура также влияет на параметры системы, например, на длину и внутренние напряжения спиральной пружины баланса. В связи с этими факторами даже по паспорту точность хода часов должна составлять жалкие ±20 секунд за сутки. По моим ощущениям их реальная точность была в несколько раз хуже, и попытки отрегулировать её ничего не дали.

Прежде чем регулировать точность хода часов, нужно научиться оценивать их погрешность. Можно, конечно, измерять отклонение от точного хода в течение нескольких дней. Но это слишком долго и не очень точно, так как у часов нет секундной стрелки. Другой способ — измерить средний интервал между «тиками» часов. Оказывается, эти интервалы имеют всего несколько стандартных значений. Для конкретного механизма интервал определяется передаточным отношением шестеренок от минутной стрелки до баланса. В моем случае, как и для большинства простых часов, скорость тиканья составляет 18 000 bph, то есть в час происходят 18 000 ударов (полупериодов). Отклонение этого параметра и определяет то, насколько спешат или отстают часы.

Для измерения скорости тиканья я использовал программу Watch Accuracy Meter. Она визуализирует тиканье часов и проводит измерение его параметров. На этих графиках измерения длились одну минуту. Каждая красная точка на них соответствует одному тику. Точки появляются на графике снизу вверх по мере измерения. Они выстраиваются вдоль линий, и наклон линии показывает отклонение параметра bph, выраженное в единицах «секунда за сутки». Два измерения подряд показали отставание часов в 13 и 14 секунд за сутки.

3. Скриншоты из Watch Accuracy Meter
3. Скриншоты из Watch Accuracy Meter

Я много раз пытался отрегулировать точность хода по этому приложению, но через несколько дней часы опять показывали всё что угодно, кроме точного времени. Я предполагал, что причина в неравномерности хода в течение суток из-за веса стрелок. Когда часы показывают 8:45, механизму приходится совершать работу по их подъему, а когда часы показывают 3:15, стрелки наоборот «помогают» механизму. Однако эта гипотеза не подтвердилась. Если измерить bph сначала в одном положении стрелок, а потом перевести в другое и измерить снова, разница получается в 1-2 секунды за сутки, что не тянет на главную причину неточности. Остается либо влияние колебаний температуры, либо ослабление винта регулировки хода из-за вибрации, либо уменьшение амплитуды из-за уменьшения напряжения батарейки.

Также на графиках выше также видна нестабильность колебаний баланса. Точки то выстраиваются вдоль прямых линий, то вдоль волнистых, то размазываются по каким-то областям. Это значит, что период колебания баланса не строго фиксирован, а немного изменяется по каким-то хаотическим закономерностям. По идее, эти отклонения должны усредняться и исчезать за достаточно большие промежутки времени вроде нескольких дней. Но они могут и не исчезать за время измерения, равное одной минуте.

Всё сказанное выше привело меня к мысли о том, что такая конструкция часов с точки зрения обеспечения точности хода имеет принципиально неустранимые недостатки. Чтобы повысить точность хода, их надо доработать. Как это сделать? Очень просто. Я же физик, я знаю всё об этой Вселенной! Надо заменить автоколебания баланса на вынужденные колебания от генератора с кварцевой стабилизацией. Ведь частота вынужденных колебаний механической системы совпадает с частотой вынуждающей силы. Тогда точность хода часов будет обеспечиваться точностью кварцевого генератора.

Техническое задание на доработку

Для повышения точности хода часов я решил собрать новую схему управления. При проектировании я исходил из требований, которые можно сформулировать так:

  • Точность хода. По отставанию или опережению от точного времени часы должны быть на уровне лучших бытовых часов.

  • Питание от аккумуляторов. По конструкции часы питались от больших батареек — элементов D (373 в советских обозначениях). Менять их приходилось не очень часто, где-то раз в несколько лет. В любом случае, с аккумуляторами меньше возни.

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

  • Длительная работа между подзарядками. Если сейчас от батарейки часы работают несколько лет, то и с аккумуляторами заряжать их хотелось бы не сильно чаще. Пусть минимальным требованием будет автономная работа в течение хотя бы полугода.

  • Обратимость доработки. Я не хотел портить часы или какую-либо их часть, чтобы была возможность всё вернуть как было. В идеале, если вытащить аккумуляторы, питающие новую схему, и вставить батарейку, часы должны заработать по-старому.

Как работают электромеханические часы

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

4. Оригинальная схема из паспорта
4. Оригинальная схема из паспорта

Сначала рассмотрим ситуацию, когда баланс покоится. Ток в цепи от батарейки проходит через катушку L2, переход база-эмиттер транзистора и резистор. Так как сопротивление резистора велико, 270 кОм, этот ток составляет всего несколько микроампер. Но его достаточно, чтобы приоткрыть транзистор. В таком состоянии схема потребляет около 0,21 мА. Также запомним, что в этом состоянии нижний конденсатор через катушку L1 заряжается до напряжения на переходе база-эмиттер (примерно 0,2 В для германиевого транзистора).

Теперь предположим, что мы запустили колебания баланса внешним воздействием. На балансе есть магниты, которые при колебаниях проходят мимо катушек. При движении магнитов баланса рядом с катушками в них индуцируется ЭДС («напряжение») сначала одной полярности, а потом другой. Почему происходит смена полярности? Когда магниты подходят к катушке, магнитное поле в ней возрастает от нуля до максимума, а когда магниты удаляются, магнитное поле уменьшается опять до нуля. ЭДС равно производной (скорости изменения) магнитного потока и поэтому при переходе через максимум знак ЭДС меняется.

Катушки расположены и подключены так, что всплеск ЭДС в катушке L1 при приближении магнитов складывается с напряжением на нижнем конденсаторе и передается на базу транзистора, полностью открывая его. Ток через открытый транзистор и катушку L2 формирует магнитное поле, которое притягивает приближающиеся магниты и дополнительно разгоняет их, тем самым передавая балансу энергию. Когда магниты начинают удаляться от катушек, в L1 возникает всплеск ЭДС противоположной полярности, который закрывает транзистор. Магнитное поле, создававшееся катушкой L2, исчезает и не препятствует удалению магнитов от катушек.

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

Наглядно процессы в катушках видны на осциллограмме. Здесь проведены измерения напряжений на катушках относительно их общей точки (она же эмиттер транзистора). Желтый луч показывает напряжение на катушке L1. Сначала отрицательный импульс в ней открывает транзистор, и синий луч показывает скачок напряжения на катушке L2 около 1,5 вольта. Затем положительный импульс закрывает транзистор, и синий луч показывает отрицательный всплеск ЭДС, которая тоже наводится в L2.

5. Напряжения на выводах катушек в оригинальной схеме
5. Напряжения на выводах катушек в оригинальной схеме

Нужно отметить, что хоть эта схема и содержит всего несколько деталей, она сделана с должной инженерной изобретательностью и содержит хитрый прием, который я не сразу увидел. Если вы хотите найти его сами, попробуйте ответить на следующие вопросы:

  • Почему на схеме полярность конденсатора противоположна полярности батарейки, то есть нижний минусовой вывод конденсатора подключается через катушки к нижнему плюсовому выводу батарейки?

  • Транзистор подключен явно не как ключ (нагрузка в цепи эмиттера, а не коллектора). Работает ли он как эмиттерный повторитель?

  • Если транзистор остается приоткрытым всё время, а открывается и закрывается на короткое время импульсов, то через него будет протекать ток, впустую расходуя энергию батарейки. Не лучше ли взять схему, в которой не будет полуоткрытого транзистора?

На самом деле в режиме установившихся колебаний транзистор закрыт почти всё время, открываясь только на время коротких импульсов, а среднее потребление схемы падает с 0,21 мА до 0,13 мА! Так происходит потому, что в момент приближения магнита к катушке ЭДС в L1 происходит не только открытие транзистора, но и достаточно быстрый разряд и даже перезаряд нижнего конденсатора через открытый переход база-эмиттер. При удалении магнита от катушек сначала ЭДС противоположной полярности закрывает транзистор, а потом и перезаряженный конденсатор не дает ему открыться. Напряжение на конденсаторе может вернуться к первоначальному только за счет заряда током через резистор, но это медленный процесс из-за высокого сопротивления резистора и высокой емкости конденсатора. Гораздо быстрее происходит следующий всплеск, транзистор открывается и конденсатор опять дозаряжается от всплеска ЭДС противоположной полярности. Это подтверждает осциллограмма напряжения на конденсаторе. На ней видно, что полярность на схеме изображена верно, и большую часть времени потенциал верхней обкладки конденсатора выше потенциала нижней, но разница эта невелика и составляет максимум около 0,05 В:

6. Напряжение на конденсаторе в оригинальной схеме
6. Напряжение на конденсаторе в оригинальной схеме

Для полноты картины я приведу осциллограмму напряжений на катушках, когда батарейка не подключена, а баланс колеблется по инерции. Здесь хорошо видно, что всплески ЭДС в катушках имеют противоположный знак относительно средней точки (эмиттера транзистора). Это значит, что катушки подключены так, что направление витков в них совпадает. Впрочем, то же отмечено и на схеме: конец первой катушки (К1) подключен к началу второй катушки (Н2).

7. Всплески ЭДС при свободном движении баланса
7. Всплески ЭДС при свободном движении баланса

Как переключить часы на работу от внешней схемы

Оригинальная схема подавала импульсы тока на катушку L2, и эти импульсы поддерживали колебания баланса. Новая схема также должна подавать импульсы на эту катушку. К счастью, один вывод катушки L2 подключен исключительно к батарейке, и когда её нет, оставшаяся часть схемы подключается только к другому выводу L2 и тем самым никак нам не помешает.

Отвлечемся пока от всех требований к новой электрической схеме. В этой главе для простоты будем считать, что мы можем собрать какую угодно схему с какими угодно характеристиками. Сфокусируемся на следующем вопросе: что должна выдавать схема, чтобы от неё стабильно запускались и шли наши часы?

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

Для упрощения новой схемы и для экономии энергии аккумулятора я изначально отказался от идеи иметь обратную связь. Я долго экспериментировал с шириной импульсов и их расположением внутри периода. В итоге остановился на варианте, когда форма напряжения на выходе несколько раз меняется после запуска. Дело в том, что оптимальная форма сигнала в установившемся режиме плохо раскачивает баланс из положения покоя и не выводит его в установившийся режим. А сигнал, который удачно раскачивает баланс, не поддерживает его установившуюся работу.

В дальнейшем тексте и в скетче я буду описывать форму напряжения набором параметров {width1, width2, shift1, shift2} — ширинами импульсов и расстоянием между ними:

8. Параметры генерируемых импульсов тока
8. Параметры генерируемых импульсов тока

Эти параметры безразмерные, они показывают отношение соответствующих интервалов к периоду колебаний T. Сразу после запуска эти параметры инициализируются значениями {0.04, 0.01, 0.48, 0.5187}, а в установившемся режиме становятся равными {0.01, 0.01, 0.5, 0.5}. Для моих часов период T = 400 мс (определяется параметром часов 18 000 bph: 2*3600/18000 = 0,4), и, например, width1 = 0,04 означает длительность первого импульса 0,04*400=16 мс.

В перечисленных значениях параметров есть две особенности. Первая особенность: сразу после старта shift1 + shift2 = 0,9987 < 1. По смыслу это означает повышенную частоту колебаний в самом начале. Без такой подстройки частоты я не смог добиться эффективного раскачивания баланса и стабильного запуска часов. При малой амплитуде колебаний баланса собственная частота повышается, поэтому надо повысить и частоту вынуждающей силы. Затем уже устанавливаются параметры с shift1 + shift2 = 1, которые эффективно поддерживают колебания с амплитудой, близкой к рабочей.

Вторая особенность — несимметричность двух импульсов, составляющих сигнал. Я сделал ширину второго импульса меньше, чем первого, так как при этом баланс стабильно выходит из положения равновесия. Если же ширину сделать одинаковой, баланс просто еле заметно дрожит около положения покоя, и его нужно принудительно подталкивать для запуска, как и в оригинальной конструкции. Кроме того, второй импульс наступает несколько раньше (shift1 < shift2), чтобы импульсы приходили в оптимальные для раскачки моменты. Дело в том, что баланс на моих часах установлен немного несимметрично. Возможно, причина в последствиях предыдущего «ремонта». Я попробовал освободить спираль и исправить несимметричность положения равновесия. Её удалось уменьшить, но не до конца.

После разгона баланса до рабочей амплитуды на первом наборе параметров в течение первых 20 секунд включаются два других промежуточных набора параметров тоже на 20 секунд каждый. В этих шагах происходит постепенное уменьшение суммарной ширины импульсов и симметризация их положения. Уменьшение ширины нужно для экономии энергии: чем меньшее время через катушку течет ток, тем меньше средний расход заряда аккумулятора. Финальная ширина импульсов — около 4 мс — примерно в 2 раза меньше ширины импульсов в оригинальной схеме (рис. 5). Симметризацию положений импульсов можно было бы и не делать, так как при этом импульсы сдвигаются в разные стороны относительно оптимальных положений. Но при случайных изменениях фазы (если баланс убежит немного вперед относительно вынуждающей силы или отстанет), один из импульсов окажется ближе к оптимальному положению и продолжит эффективно передавать энергию. На осциллограмме симметричного сигнала с параметрами {0.016, 0.016, 0.5, 0.5} видно, что средний импульс расположен оптимально (так же, как и на осциллограмме из оригинальной схемы на рис. 5), а крайние импульсы сдвинуты правее, то есть немного опаздывают. Опоздание отключения импульсов приводит к тому, что притяжение магнитов к катушкам в момент их удаления частично замедляет баланс.

9. Напряжения на катушках в новой схеме с параметрами {0.016, 0.016, 0.5, 0.5}. Стрелками отмечены опаздывающие импульсы
9. Напряжения на катушках в новой схеме с параметрами {0.016, 0.016, 0.5, 0.5}. Стрелками отмечены опаздывающие импульсы

Для настройки прошивки под конкретные часы нужно подбирать перечисленные параметры, описывающие форму импульсов. На их значения могут влиять состояние механизма, уровень его износа, особенности расположения катушек, их характеристики. Также нужно правильно настроить регулировочный винт. В оригинальной схеме он определял частоту колебаний. Теперь частота определяется внешней силой и роль винта меняется.

При работе от внешнего генератора со стабильной частотой сигнала регулировочный винт позволяет настроить частоту собственных колебаний в резонанс. Если этого не сделать, то амплитуда колебаний не будет максимальной. Когда собственная частота баланса больше частоты вынуждающей силы, баланс будет опережать импульсы тока, они будут отключаться слишком поздно и начнут подтормаживать баланс, примерно как на осциллограмме выше (рис. 9). При расстройке в другую сторону, когда собственная частота баланса меньше, импульсы будут включаться и отключаться слишком рано, когда магниты еще не успели до конца подойти к оптимальному положению. Видимо, сила притяжения, несмотря на увеличение расстояния, остается достаточной и передает балансу энергию и для преодоления потерь на трение, и для «подталкивания» баланса, чтобы он не отставал от ритма вынуждающей силы. Ситуация отставания баланса на осциллограмме выглядит так:

10. Те же параметры, что и на рис. 9, только частота собственных колебаний уменьшена регулировочным винтом.
10. Те же параметры, что и на рис. 9, только частота собственных колебаний уменьшена регулировочным винтом.
Откуда вообще такая сложность с вынужденными колебаниями баланса?

Действительно, в наивном подходе можно было бы ожидать, что достаточно приложить периодическую силу к системе, и она будет совершать колебания в резонансе. Однако на деле есть две проблемы. Первая: колебания баланса существенно нелинейны и отличаются от гармонических. Вторая: вынуждающая сила действительно зависит от времени, то есть от моментов включения импульсов через катушку. Но еще она зависит и от положения баланса относительно катушки в эти моменты, то есть от текущей фазы колебания: F=F(t, x).

Нелинейные вынужденные колебания в обычных учебных курсах не рассматриваются. Например, в справочнике по физике для инженеров и студентов вузов Яворского и Детлафа о вынужденных колебаниях нелинейных систем написано всего две странички, и в них рассматривается гармоническая вынуждающая сила, зависящая только от времени F=F(t)=F_0 \sin\Omega t:

В нашем случае вынуждающая сила действует на систему не всё время, а включается только в определенные моменты, а величина её определяется фазой колебания. Тем не менее, изложенные сведения о колебаниях всё равно проливают свет на некоторые особенности поведения баланса. Например, когда частота вынуждающей силы заметно выше частоты свободных колебаний, в системе могут устанавливаться колебания разной амплитуды: как большой, так и малой. К счастью, я на опыте не наблюдал тот срыв амплитуды колебаний к малым значениям, о которых написано в пояснении к графику. Видимо, это связано с зависимостью вынуждающей силы от фазы, причем зависимость эта такова, что установившиеся колебания вполне устойчивы. Возникающие от случайных факторов отклонения не нарастают со временем, а как минимум остаются ограниченными или уменьшаются. Тем не менее, в зависимости от начальных условий и характеристики вынуждающей силы баланс может не раскачаться до нужной амплитуды из-за нелинейной природы колебаний.

График из справочника также объясняет возможное применение винта регулировки хода. При расстройке винта и удалении от резонанса амплитуда колебаний падает, но она всё еще может быть практически пригодной при достаточном уровне передачи энергии (то есть при достаточной длительности импульсов). Например, увеличение частоты собственных колебаний равносильно уменьшению частоты вынуждающей силы, то есть перемещению влево по графику. При этом мы можем уйти из области, где существуют два решения, и получить более стабильную работу часов. В промежуточных вариантах я рассматривал именно такой режим работы часов, но с применением временного увеличения частоты вынуждающей силы на старте необходимость работы с неточно настроенным резонансом отпала.

Нужно отметить, что в справочнике рассмотрен простейший случай нелинейной системы с возвращающей силой, содержащей кубическое слагаемое \beta x^3. Для такой системы по мере увеличения амплитуды частота свободных колебаний или растет при \beta > 0 или падает при \beta < 0. В моем случае частота зависит от амплитуды сложнее: сначала она уменьшается, а потом опять растет. Это значит, что в разложении возвращающей силы есть как минимум слагаемое пятой степени, а может быть даже и слагаемые четных степеней. Следующий график иллюстрирует сложную зависимость частоты колебаний от амплитуды:

На нем сначала видно, как из-за совпадения случайных факторов (это всё-таки сложная нелинейная система, в которой может возникать динамический хаос!) баланс получил больше энергии, амплитуда его колебаний увеличилась, из-за нелинейности увеличилась и их частота, баланс стал опережать импульсы тока, вынуждающая сила стала менять знак, передача энергии балансу резко упала, он начал останавливаться, частота упала, баланс перестал опережать импульсы тока и эффективность передачи энергии восстановилась. Затем я отключил питание схемы, амплитуда колебаний постепенно уменьшилась из-за потерь на трение и на совершение полезной работы, и частота колебаний стала опять расти вплоть до остановки (баланс ускорился, так как точки выстроились вдоль линии, загибающейся вправо).

Ясно, что такая нелинейность обусловлена формой спиральной пружины и возникающими в ней напряжениями при деформации. И при таких сложных характеристиках этой колебательной системы наверняка возможно большее количество установившихся режимов колебаний, чем то, о которых написано у Яворского и Детлафа. Вообще мне повезло, что я смог подобрать такие характеристики вынуждающей силы, при которых баланс стартует достаточно надежно и переходит в устойчивый режим колебаний. Ведь для нелинейной системы не очевидна даже сама возможность существования такой вынуждающей силы.

Есть еще один способ физических рассуждений через передачу и преобразование энергии, который допускает обобщение при переходе от вынужденных гармонических колебаний к колебаниям нашей нелинейной системы. Рассмотрим вынужденные колебания линейной системы с малым трением под действием гармонической вынуждающей силы. В резонансе механическая энергия системы в сумме остается постоянной, но в течение периода полностью переходит из кинетической в потенциальную и наоборот, а работа вынуждающей силы идет на пополнение потерь из-за трения. При колебаниях вне резонанса максимальная кинетическая энергия и максимальная потенциальная энергия не равны друг другу. Поэтому кинетическая и потенциальная энергия превращаются друг в друга только частично, а внешняя сила в течение периода должна сначала совершать работу для компенсации недостающей энергии, а потом для для отбора лишней энергии. Чтобы такой процесс мог происходить, между изменениями вынуждающей силы и положением самой системы должен быть сдвиг фаз, обеспечивающий смену знака выполняемой работы.

В случае импульсов, раскачивающих баланс, я как раз и наблюдал фазовые сдвиги между вынуждающей силой и положением баланса на двух предыдущих осциллограммах (рис. 9 и 10). Так как импульсы относительно короткие, можно считать, что почти всё время баланс движется по «графику» x (t) свободных затухающих колебаний, а импульсы вызывают «перескок» на другой «график» свободных колебаний с другими начальными условиями. В резонансе этот «перескок» соответствует увеличению амплитуды колебаний, а вне резонанса нужно дополнительно «ускорять» или «тормозить» баланс, чтобы он не отставал или не спешил.

Как повысить точность хода

Мы разобрались с тем, какую форму импульсов нужно подавать на катушку часов для их запуска и поддержания хода. Теперь рассмотрим, как выдерживать точные интервалы времени между импульсами, чтобы обеспечить нужную точность хода. На практике стабилизация частоты в электронных устройствах выполняется с помощью кварцевого резонатора. Например, в кварцевых часах применяют резонатор с частотой 32 768 Герц. Такое значение выбирается не случайно: из него удобно получить сигнал частотой 1 Герц делением на 2^{15}. И это минимальная частота у современных распространенных кварцевых резонаторов.

Применить в электромеханических часах делитель частоты 32 768 Герц не так просто, так как период колебаний баланса 400 мс, что соответствует нецелому числу колебаний кварца (32768*0,4=13107,2). В принципе можно одной микросхемой-счетчиком поделить частоту часового кварца на 2^{16} и получить стабильный двухсекундный интервал. А уже внутри этого интервала сгенерировать 10 импульсов, по 2 импульса на каждые 400 мс. Генерацию импульсов можно сделать какой-нибудь другой схемой, которая будет работать от менее точного эталона времени. На общую точность хода часов сдвиги импульсов внутри двухсекундного интервала не повлияют. Такая хардверная часть явно сложнее обычного микроконтроллера с кварцевой стабилизацией частоты, поэтому какой-либо разумной альтернативы микроконтроллеру я не увидел.

11. Получение импульсов с периодом 400 мс с помощью деления частоты 32 768 Гц
11. Получение импульсов с периодом 400 мс с помощью деления частоты 32 768 Гц

Для этой самоделки я заказал китайский клон Arduino Nano. Первые эксперименты показали, что на нем нет нормальной стабилизации частоты. Точность хода изменялась на десятки секунд за сутки при изменении напряжение питания в рабочем интервале литий-ионного аккумулятора от 3 до 4,2 В. Дело в том, что на этих платах установлен не кварцевый, а керамический резонатор. Делать стабилизацию напряжения в энергоэффективной схеме не получится, нужен другой подход.

У меня в запасе был голый микроконтроллер Atmega 328 PU. После проработки я остановился на следующем варианте схемы. К микроконтроллеру подключил кварц на 32 768 Герц. Часовой кварц взял из старых китайских наручных электронных часов, которые повсюду продавались в первой половине 90-х за один доллар. Платка от них пролежала у меня больше 30 лет и наконец-то пошла в дело! Тактирование микроконтроллера настроил на 8 МГц от внутренней RC-цепочки, а таймер 2 — от внешнего кварца.

12. Предварительная схема генератора импульсов на микроконтроллере
12. Предварительная схема генератора импульсов на микроконтроллере

Сначала я хотел повторить в софте изложенную выше идею с кварцевой стабилизацией двухсекундных интервалов таймером 2 и генерацией 10 импульсов внутри этих двухсекундных интервалов от другого таймера (рис. 11). Но выяснилось, что другие таймеры не работают в достаточно глубоких режимах сна и будут зря расходовать энергию аккумулятора. Поэтому я решил «в экселе» вычислить моменты начала и окончания каждого из 10 импульсов, округлить до целого количества интервалов, отсчитываемых таймером 2 и зашить их как константны в скетче.

Для проверки идеи я думал сделать так, чтобы прерывание таймера 2 происходило 32 768 раз в секунду, а обработчик прерывания проверял, нужно ли изменить уровень на выходном пине. Но почему-то прерывания срабатывали только в два раза реже. В ходе исследования понял, что с точки зрения энергоэффективности лучше, если прерывания не происходят так часто, а срабатывают только тогда, когда нужно в следующий раз переключить уровень на выходе. Для этого используется режим CTC. В нем прерывание происходит в момент, когда значение регистра счетчика TCNT2 становится равным значению в регистре OCR2A. При возникновении прерывания счетчик TCNT2 автоматически сбрасывается, и следующее прерывание произойдет в тот момент, когда TCNT2 опять досчитает до OCR2A. Таким образом, записывая в OCR2A разные значения из обработчика прерываний, мы можем управлять моментом наступления следующего прерывания. Правда, особенность таймера 2 такова, что счетчик TCNT2 — восьмибитный. Чтобы отсчитывать нужные интервалы времени, мне пришлось установить предделитель таймера 2 в 32. С таким предделителем счетчик TCNT2 инкрементируется 1024 раза в секунду и тем самым может отсчитывать интервалы до 250 мс с шагом в 1/1024 секунды. Такая длительность как раз подходит для типового импульса в 20 мс и интервала между ними 180 мс. Недостаток такого подхода состоит в заметном кванте «дискретизации» 1/1024 секунды и связанному джиттеру («дрожанию») — отклонению моментов начала и окончания импульсов от их точных значений. Например, импульс в 20 мс и пауза в 180 мс превращаются в чередование импульсов длительности 19,53125 мс и 20,5078125 мс, а также пауз длительности 179,6875 мс и 180,6640625 мс.

Практические измерения показали, что джиттер, связанный с квантом времени 1/1024 секунды, не мешает нормальной работе часов. Однако частота кварца оказалась меньше номинальной, и часы отставали бы на 3-4 секунды за сутки. Реальный квант времени оказался чуть больше, чем 1/1024 секунды. Чтобы скорректировать это отклонение, можно было бы ввести программный счетчик квантов и где-то раз в 24 секунды уменьшать на 1 квант интервал между импульсами. Я же решил перейти от работы с целочисленными интервалами к float и скорректировать длину каждого импульса и паузы. В обработчике прерывания скетч вычисляет, через какое количество квантов времени должно произойти следующее прерывание, округляет их до целого числа, а ошибку из-за округления сохраняет на будущее и учтет в следующем прерывании:

float remainder = 0; // Накопленное отклонение

// Через какое количество квантов должно сработать прерывание в следующий раз
float getNextInterval() {
  // ...
}

// Следующее значение, которое будет записано в 8-битный регистр сравнения OCR2A
uint8_t getNextStop() {
  remainder += getNextInterval(); // Учтем накопленную ошибку
  uint8_t stepNum = round(remainder); // Округляем до целого числа квантов
  remainder -= stepNum; // Ошибку из-за округления переносим на следующий раз

  return stepNum - 1;
}

// Обработчик прерывания таймера 2
ISR(TIMER2_COMPA_vect) {
  OCR2A = getNextStop();
  // ...
}

Понятно, что из-за работы с дробными числами возможна не только потеря точности, но и накопление этой ошибки со временем. Но даже если это накопление и будет происходить, оно приведет к опережению или отставанию часов, и может быть скомпенсировано точно так же, как и отклонение частоты кварца от номинальной. Также у типа данных float в Atmega328 есть и другой недостаток: они не поддерживаются аппаратно и эмулируются программно. Скорость работы с ними раз в 10 меньше скорости работы с целыми числами. Для моих целей проблем из-за скорости нет, так как микроконтроллер всё равно вынужден ждать окончания записи в регистр OCR2A перед очередным уходом в сон, и нет разницы в том, будет ли он перед этим делать вычисления или дожидаться в пустом цикле.

Я подобрал корректировочный коэффициент, компенсирующий отклонение частоты кварца от номинальной, с помощью Watch Accuracy Meter. Максимальная длительность измерения в нем 4 минуты, что позволяет измерить и скорректировать погрешность до ±¼ секунды за сутки, или ±7 секунд в месяц. Для отладки схемы я подключал к её выходу небольшой динамик, который будет «тикать» вместо настоящего механизма. Такой прием позволяет наблюдать характеристики генерируемых импульсов. Результат представлен на первой картинке. На ней хорошо виден джиттер из-за заметного кванта дискретизации. На второй картинке — тиканье часов, подключенных к генератору. На ней джиттера нет, а возникающие отклонения хода быстро исчезают.

13. Визуализация кварцевой стабилизации генератора. Слева — импульсы, поданные напрямую на динамик (есть заметный джиттер), справа — ход настоящих часов (джиттер сглажен). На правом графике нет большого разброса точек, как на других графиках, так как параметры системы были таковы, что амплитуда колебаний баланса была ниже обычной.
13. Визуализация кварцевой стабилизации генератора. Слева — импульсы, поданные напрямую на динамик (есть заметный джиттер), справа — ход настоящих часов (джиттер сглажен). На правом графике нет большого разброса точек, как на других графиках, так как параметры системы были таковы, что амплитуда колебаний баланса была ниже обычной.

В завершение обсудим, какую вообще точность можно ожидать от кварцевой стабилизации. Как написано в википедии, производители обычных часовых кварцев гарантируют долгосрочную стабильность частоты около6\cdot 10^{-6}, что соответствует ±15 секунд в месяц. Кроме того, уход частоты при отклонении температуры от расчетной (25…28 °C) на ±10 градусов будет давать ошибку примерно3\cdot 10^{-6}. Выходит, точности настройки с помощью Watch Accuracy Meter более чем достаточно, так как она по порядку сравнима и с долгосрочным дрейфом частоты, и с отклонениями из-за изменения температуры.

Как добиться минимального расхода заряда аккумулятора

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

Пусть к примеру схема потребляет в среднем 10 миллиампер. Может показаться, что это небольшой ток: таково потребление обычного светодиода. Но для типовой емкости аккумулятора в 2000 мА*ч схема проработает 200 часов, или немногим больше недели. Я точно не готов приносить настольные часы каждую неделю к зарядному устройству и заряжать их в течение нескольких часов.

Погружение в тему энергоэффективности микроконтроллеров можно начать со статьи на сайте Алекса Гайвера. По советам оттуда я собрал схему не на отладочной плате Ардуино, а на отдельном голом микроконтроллере Atmega 328 без лишних компонентов, впустую расходующих ток. Так как к выводам микроконтроллера подключен часовой кварц частотой 32,7 кГц, от которого работает таймер 2, я настроил тактирование на частоту 8 МГц от внутренней RC-цепочки. Кроме того, применил наиболее глубокий режим сна (SLEEP_MODE_PWR_SAVE), в котором таймер 2 всё еще работает.

Я измерил, какой средний ток потребляет схема выше (рис. 12) с относительной шириной импульсов {0.05, 0.01}. Величина оказалась равной примерно 0,23 мА, или 230 мкА. Если отключить нагрузку в виде катушки часов, сам микроконтроллер потребляет около 25 мкА. Из них 23 мкА тратится на микроконтроллер в режиме сна, а еще примерно 2-3 мкА среднего потребления добавляют пробуждения в момент обработки прерывания. В принципе, на этом можно было бы остановиться, потому что среднее потребление в 0,23 мА дает время автономной работы около года от полностью заряженного аккумулятора в 2000 мА*ч. Но я продолжил исследование дальше и стал думать, как еще снизить потребление энергии.

Из чисел выше видно, что почти 90% от всего потребления связано с нагрузкой. Однако сама нагрузка потребляет только около трети этой энергии, потому что она имеет сопротивление 354 ома и подключена через резистор на 680 ом. Этот резистор гасит избыточное напряжение. Старая схема подавала на катушку импульсы напряжения 1,5 В, а новая схема выдает напряжение питания 3,7 ± 0,5 В. Для экономии энергии нужно преобразовывать напряжение другим способом.

Для понижения напряжения от литий-ионного аккумулятора до расчетных 1,5 вольт можно было бы использовать готовые DC-DC преобразователи, но у них достаточно высокий для нашего применения собственный ток потребления и, следовательно, низкий КПД на малых токах. Попытки собрать преобразователь самостоятельно ничего не дали. Нагружать микроконтроллер генерацией ШИМ-сигнала и сглаживать его пассивными компонентами я не стал. В итоге решил заказать микросхему LM2665 и сделать на её основе «уполовиниватель» напряжения на «летающем» конденсаторе.

Преобразователи на «летающем» конденсаторе работают на высокой частоте (160 кГц в случае LM2665). С такой частотой происходит коммутация того самого летающего конденсатора: сначала он подключается к источнику тока, а затем к потребителю. В зависимости от других деталей в схеме и их коммутации может получиться преобразователь из V в 2V, V/2 или −V. На эту тему есть хорошее видео на канале Major Tom Workshop с объяснением теории и сборкой работающей схемы на дискретных компонентах.

Я заказал LM2665, так как у меня всё равно не было полевых транзисторов для сборки дискретного аналога. Когда они пришли с Алиэкспресса, я собрал «уполовиниватель» напряжения по схеме из даташита и измерил КПД при работе в стационарном режиме от 3,7 вольт на нагрузку в 384 ома при постоянном токе потребления. При номиналах керамических конденсаторов в 2,2 мкФ КПД составил около 95%. Я подумал, что могу уменьшить номинал летающего конденсатора, чтобы за один рабочий цикл он переносил меньший заряд и чтобы напряжение на выходе преобразователя было меньше. Преобразователь с конденсатором в 38 нФ понизил напряжение с 3,68 В до 1,50 В с не очень высоким КПД 79%. Я оставил в схеме 0,1 мкФ, дающий преобразование с 3,67 В до 1,71 В и КПД в 90,6%. Так как при замене резистора на преобразователь на LM2665 напряжение получилось немного выше расчетного, без особых усилий удалось сократить длительность импульсов, подаваемых на катушку часов, до {0.035, 0.005}, оставив надежность работы на том же уровне. В этом варианте среднее потребление тока схемой составило 130 мкА.

LM2665 имеет управляющий вход SD (shutdown). Преобразование напряжения происходит при нулевом потенциале на SD и останавливается при высоком. Я проверил, что потребление LM2665 в режиме выключенной генерации не превосходит 1 мкА. Поэтому вход SD хорошо подходит для управления формированием импульсов, нужно только помнить, что его логика инверсная. Итоговая схема кварцевого генератора на микроконтроллере для часов получилась такой:

14. Окончательная схема генератора импульсов на микроконтроллере. LM2665 подключена правильно по схеме деления пополам из даташита. Я опустил конденсаторы по питанию, но в готовом устройстве надо припаять электролитический и керамический как можно ближе к микроконтроллеру
14. Окончательная схема генератора импульсов на микроконтроллере. LM2665 подключена правильно по схеме деления пополам из даташита. Я опустил конденсаторы по питанию, но в готовом устройстве надо припаять электролитический и керамический как можно ближе к микроконтроллеру

Обратите внимание на подключение микросхемы LM2665. Кажется, что у неё перепутаны вход и выход (V+ и OUT), но это типовое включение из даташита для деления напряжения пополам.

При окончательной наладке часов я попробовал исправить несимметричное положение равновесия баланса и запрограммировал динамическое изменение параметров импульсов после старта. Благодаря этому в рабочем режиме удалось снизить длительность двух импульсов в периоде до 0,01. Среднее потребление тока при этом составляет 75 мкА, и еще 3 мкА потребляется защитой на модуле заряда аккумуляторов. Арифметический подсчет дает автономность работы в несколько лет. Но я бы не стал доверять такому расчету, так как по порядку величины потребления мы уже приближаемся к величине саморазряда литий-ионных аккумуляторов, и автономность во многом будет зависеть от их качества.

Для полноты стоит отметить, что у меня была другая идея по уменьшению тока через катушку. Вместо того чтобы ограничить ток резистором на 680 ом, можно включить в качестве нагрузки последовательно соединенные катушки L1 и L2 через резистор ом на 200-300. Так как количество витков у общей катушки увеличивается, для обеспечения той же силы магнитного притяжения надо уменьшить ток. А уменьшение тока как раз дает экономию энергии аккумулятора. Как следует из осциллограмм и схемы, катушки L1 и L2 намотаны и подключены так, что образуют одну общую катушку с одинаковым направлением витков, и их магнитное поле будет складываться. Однако на практике подключение обеих катушек при том же токе приводило не к увеличению вынуждающей силы, а к её уменьшению. В этом скорее всего виновата остальная часть старой схемы, подключенная к катушке L1, которую я не отключал. Вы можете пробовать этот способ вместо преобразователя на LM2665 на свой страх и риск, потому что подключать катушки в таком нештатном режиме может быть неправильно, так как толщина провода в L1 может быть меньше, чем в L2.

Результаты

Схему я собрал на макетной плате. LM2665 припаял на дополнительный кусочек текстолита из-за её крошечного размера. Плату, контроллер заряда на TP4056 и аккумуляторы закрепил на кусочке оргстекла, который приклеил к корпусу часов.

15. Собранная схема
15. Собранная схема

У меня были литий-ионные аккумуляторы формата 14500 (размер пальчиковой батарейки AA) емкостью 900 мА*ч, я поставил два аккумулятора в параллель. Но с итоговым потреблением схемы (80 мкА) можно смело оставлять один аккумулятор, его хватит надолго.

Перечисленные вначале требования я выполнил целиком. Правда, с обратимостью доработки есть особенность: чтобы часы пошли по-старому от батарейки, нужно отсоединить новую схему. Если не отсоединять, катушка L2 окажется включенной параллельно с конденсатором С4, а это может вызвать дополнительный расход энергии батарейки из-за изменившихся процессов в схеме. Я, правда, не измерял возможный отрицательный эффект, он может оказаться незначительным, или даже наоборот положительным.

Финальная версия скетча для Ардуино:

#include <avr/sleep.h>

/**
 * Настройка скетча под конкретную схему и экземпляр часов
 */
#define OUTPUT_PIN 3
#define VALUE_ON LOW
#define VALUE_OFF HIGH

const uint16_t phaseNum = 4; // Количество фаз внутри одного периода

/**
 * Матрица с описанием ширин и положений импульсов.
 * После запуска скетча каждая строчка применяется на 20 секунд.
 * Последняя строчка остается действовать на всё время работы.
 * 
 * Строки содержат параметры {pulseWidth1, pulseWidth2, pulseShift1, pulseShift2}:
 *   - доля времени первого импульса в периоде
 *   - доля времени второго импульса в периоде
 *   - доля времени между центром первого и второго импульса
 *   - доля времени между центром второго импульса и первого из следующего периода.
 * В установившемся режиме pulseShift1 + pulseShift2 должно быть 1
 */
const float parameters[][4] = {
    {0.04, 0.01, 0.48, 0.5187},
    {0.03, 0.01, 0.48, 0.52},
    {0.02, 0.01, 0.49, 0.51},
    {0.01, 0.01, 0.50, 0.50}
};

// Количество тиков таймера 2 в один период колебаний баланса часов
// 409.5830016 для перечисленных значений
const float timerTicksInPeriod = 32768 // Номинальная частота кварца
  * (1 - 0.0000415) // Подгоночный множитель из-за отклонения от номинальной частоты
  * 0.4 // Период баланса часов в секундах, 0.4 = 18000 bph (полупериодам в час)
  * 1/32 // Внутреннее деление частоты кварца в микроконтроллере
;

/**
 * Длительности фаз, выраженные в тиках таймера. Должны быть меньше 255,
 * так как у таймера 2 счетчик однобайтовый
 */
float durations[phaseNum];

void initDurations(size_t step) {
  const float avgPulseWidth = 0.5 * (parameters[step][0] + parameters[step][1]);

  durations[0] = timerTicksInPeriod * parameters[step][0];
  durations[1] = timerTicksInPeriod * (parameters[step][2] - avgPulseWidth);
  durations[2] = timerTicksInPeriod * parameters[step][1];
  durations[3] = timerTicksInPeriod * (parameters[step][3] - avgPulseWidth);
}

/**
 * Логика корректировки параметров от стартовых значений к установившимся.
 * Функция correctParameters() вызывается при каждом срабатывании таймера.
 */

// Счетчик прерываний. Примерно равен кол-ву десятых долей секунды с момента запуска
// (за период 400 мс происходят 4 прерывания)
uint16_t intCount = 0; 

void correctParameters() {
  if (intCount > 601) {
    return;
  }

  if (intCount == 201) {
    initDurations(1);
  } else if (intCount == 401) {
    initDurations(2);
  } else if (intCount == 601) {
    initDurations(3);
  }
  intCount++;
}

/**
 * Логика, описывающая длительность срабатывания таймера 2 в следующий раз.
 */

// Значение накопленной ошибки из-за дискретизации таймера. От -0.5 до 0.5.
// Ошибка должна прибавляться к длительности текущей фазы.
float remainder = 0;

// Следующее значение, которое будет записано в 8-битный регистр сравнения OCR2A
uint8_t nextStopAfter; 
uint16_t phaseIdx = 0; // номер текущей фазы

uint8_t getNextStop() {
  remainder += durations[phaseIdx];
  uint8_t step = round(remainder);
  remainder -= step;

  phaseIdx++;
  if (phaseIdx >= phaseNum) {
    phaseIdx = 0;
  }

  return step - 1; // Подгоночное вычитание 1
}

/**
 * Далее настраивается таймер 2, обработчик его прерывания и режим энергосбережения
 */

void setup() {
  pinMode(OUTPUT_PIN, OUTPUT);
  digitalWrite(OUTPUT_PIN, VALUE_OFF);
  initDurations(0);

  // Немного подождем, пока установится генерация от внешнего кварца в таймере 2.
  delay(1000);

  // Отключаем прерывания на время настройки таймера
  cli();

  // Настройка таймера 2 на работу с внешним кварцем
  ASSR = (1 << AS2); // Подключаем внешний кварц
  TCCR2A = (1 << WGM21); // Режим CTC
  TCCR2B = (0 << CS22) | (1 << CS21) | (1 << CS20); // Предделитель 32

  TCNT2 = 0; // Устанавливаем начальное значение счетчика

  ADCSRA &= ~(1 << ADEN); // Отключаем ADC
  TIMSK2 = (1 << OCIE2A); // Разрешаем прерывание по совпадению

  sei(); // Включаем прерывания

  set_sleep_mode(SLEEP_MODE_PWR_SAVE); // Настройка спящего режима

  // Предрасчитаем время установки таймера
  nextStopAfter = getNextStop();
}

// Прерывание таймера 2
ISR(TIMER2_COMPA_vect) {
  // Сразу запишем сдедующее значение, вычисленное в прошлый раз,
  // чтобы опять установить таймер 2
  OCR2A = nextStopAfter; 

  // Пока оно записывается, установим значение на выходе
  digitalWrite(OUTPUT_PIN, phaseIdx % 2 == 0 ? VALUE_OFF : VALUE_ON);
  // Корректируем параметры в переходном режиме после запуска
  correctParameters();
  // Вычислим время установки таймера на следующий раз
  nextStopAfter = getNextStop();

  // Дождемся окончания записи в регистр OCR2A для установки таймера 2
  while (ASSR & (1 << OCR2AUB)) {
  }
}

void loop() {
  sleep_enable(); // Разрешаем переход в сон
  sleep_cpu();    // Уходим в спящий режим

  // После пробуждения выполнение продолжится отсюда
  sleep_disable(); // Отключаем сон
}

Сейчас после окончательной доработки и прошивки часы прошли недели две без остановок. Определить какое-либо отставание или опережение сложно, так как у часов нет секундной стрелки. Я их настроил точно и буду полгода наблюдать за ходом. За это время пройдет часть зимы, весна и часть лета, так что влияние температурных колебаний в течение года как-то усреднится. При заметном накоплении ошибки пересчитаю подгоночный коэффициент и обновлю прошивку.

Чтобы предвосхитить некоторые комментарии, сразу отмечу, что можно пойти дальше и предложить такую систему, в которой корректировочный коэффициент будет меняться не перепрошивкой, а динамически. Например, часы с модулем Wi-Fi раз в несколько дней подключаются к ntp-серверу, вычисляют набегающую ошибку и подстраивают коэффициент для её минимизации. Недостаток получения времени через Wi-Fi заключается в необходимости мониторинга его работоспособности. При сбоях в получении точного времени часы смогут откатываться к коэффициенту из прошивки и ходить так же (не)точно, как и сейчас, но вы об этом можете узнать нескоро. Альтернативный вариант повышения точности без получения сигналов из внешнего мира — добавить в схему терморезистор, находящийся в термическом контакте с кварцем, и раз в 10 минут измерять его температуру. Исходя из температуры микроконтроллер определяет значение поправочного коэффициента по заранее составленным таблицам для конкретных экземпляров кварцевого резонатора и терморезистора. По такому принципу работает известная микросхема часов реального времени DS3231. Теоретически для сверки времени можно было бы использовать и её, но я не нашел в даташите упоминаний о существовании режима пониженного энергопотребления в районе десятков микроампер.

Когда я задумывался о возможности модернизировать часы и искал материалы по теме в интернете, находил максимум сообщения на форумах о причинах низкой точности часов. Если бы я нашел хотя бы десятую часть изложенного в этой статье, то раньше решился бы на доработку. Надеюсь, что у меня получилось вдохновить тех желающих, кто чувствует в себе достаточно навыков, и отговорить тех, у кого навыков пока недостаточно. И наверняка комментаторы подскажут, как улучшить подход, схему и элементную базу.