Идея этих часов состоит в том, что стрелки на них двигаются неравномерно, то ускоряясь, то отставая, но тем не менее, в среднем, часы показывают правильное время. Сейчас расскажу, как такие сделать.
Вскрытие
За основу взяты настенные стрелочные кварцевые часы. Они могут быть оформлены как угодно, но в 99% случаев внутри стоит стандартный китайский механизм с пластмассовыми деталями. Вот такой:
Вскрываем корпус, попутно отмечая наличие свободного места, что нам очень на руку.
Аккуратно разбираем механизм, стараясь не забыть, какая шестеренка куда ставится.
Часы приводятся в движение шаговым двигателем, который состоит из статора с обмоткой и ротора с постоянным магнитом. На обмотку раз в секунду подаются электрические импульсы, и с каждым импульсом ротор поворачивается на 180°. Вот двигатель в разобранном виде:
Плата часового генератора закреплена с обратной стороны обмотки. Вот как она выглядит:
Пересадка мозга
Управлять часовым механизмом будет микроконтроллер ATtiny13A, выбранный, в основном, по принципу «ставим, что есть». На двигатель нужно подавать импульсы чередующейся полярности длительностью примерно 100 мс. Каждый импульс перемещает секундную стрелку на одну отметку.
Как видим, все очень просто: подключаем контроллер двумя выводами к обмотке, подаем питание… Стоп! Но ведь часы питаются от одной полуторавольтовой батарейки, а минимальное рабочее напряжение для ATtiny13A — 1,8 вольт. Как быть? На самом деле, контроллеры AVR могут работать и при напряжении питания 1 вольт и даже ниже (например), но при выполнении двух условий. Во-первых, тактовая частота должна быть низкой, в районе десятков килогерц. Во-вторых, тактирование должно осуществляться от внешнего источника.
Где взять внешний тактовый сигнал? Решение очевидно: от штатного часового генератора. Он вырабатывает сигнал частотой 32 768 Гц (215 Гц), снять который можно с одного из выводов кварца (с какого именно — определяется экспериментально). Берем нашу плату и припаиваем к ней провода для снятия питания, тактового сигнала, а также для управления двигателем. Нужно также перерезать дорожки от родного генератора к выводам обмотки.
Схема подключения микроконтроллера проста, как две копейки:
Только прошу обратить внимание на два момента. Во-первых, при сверхнизком напряжении питания выходные ключи портов открываются не полностью, поэтому, для уменьшения сопротивления, выводы запараллелены попарно (PB0 с PB1, и PB2 с PB4). Во-вторых, конденсатор в цепи питания следует поставить танталовый, с минимальным током утечки.
Контроллер смонтирован на обрезке макетной платы и прекрасно расположился в свободном пространстве в углу корпуса:
Поскольку перепрошить МК непосредственно в схеме не удастся, настоятельно советую не припаивать его намерво, а установить в панельку.
Прошивка
Логика работы часов следующая: интервалы между шагами секундной стрелки имеют случайную длительность, но полный оборот она должна проходить ровно за минуту, чтобы не нарушалась точность хода. Экспериментальным путем было установлено, что минимальный интервал между импульсами составляет 1/4 секунды, попытка двигать стрелку быстрее приводит к пропуску шагов. От этого и будем отталкиваться, пусть длительность каждого интервала будет кратна этому минимальному значению. Удобно будет разделить минуту на 240 «тиков» по четверти секунды каждый.
Главная проблема, возникшая при написании прошивки, состояла в том, как случайным образом разбить минуту на 60 интервалов. Потратив пару часов и исписав несколько листов бумаги, я составил два алгоритма. Первый заключался в формировании массива из 240 элементов, в который помещались номера всех «тиков». Затем из массива случайным образом выбирались 59 элементов, каждый из которых представлял собой номер «тика», на котором происходило бы движение стрелки. Второй алгоритм заключался в делении четырехсекундного интервала (16 «тиков») случайным образом на две части, каждая из которых затем также делилась надвое. После выполнения этих операций над 15 интервалами, получалось 60 значений в диапазоне от 1 до 13 «тиков», причем сумма всех этих значений составляла ровно 240.
К сожалению, ни первый, ни второй алгоритмы мне не удалось реализовать на ATtiny13 ввиду крайне малого объема памяти этого МК (1 КБ FLASH и всего 64 байта SRAM). Наверное, какой-нибудь гуру ассемблера смог бы это сделать, но я поступил проще и жестко забил в код одну таблицу длительностей интервалов. То, что ритм движения стрелки будет повторяться каждую минуту, не должно сразу броситься в глаза.
Программа устроена следующим образом. Каждый «тик» (1/4 секунды) по таймеру генерируется прерывание, во время которого проверяется номер «тика», и, если нужно, подается напряжение на обмотку двигателя, а также из таблицы извлекается длительность следующего интервала. Через 100 мс генерируется второе прерывание, по которому напряжение, подаваемое на обмотку, отключается. Всё остальное время контроллер находится в спящем режиме для уменьшения энергопотребления. Ссылка на полный исходный код приведена в конце статьи.
Необходимо также прошить Fuse-биты контроллера для того, чтобы включить режим внешнего тактирования (значения, отличные от заводских, выделены):
SELFPRGEN = 1
DWEN = 1
BODLEVEL1 = 1
BODLEVEL0 = 1
RSTDISBL = 1
SPIEN = 0
EESAVE = 1
WDTON = 1
CKDIV8 = 1
SUT1 = 1
SUT0 = 0
CKSEL1 = 0
CKSEL0 = 0
Спешу заметить, что после установки фьюзов данным образом контроллер нельзя будет перепрошить без внешнего источника тактирования.
Сборка
Итак, контроллер запрограммирован, установлен на плату, котрая, в свою очередь, закреплена в корпусе каплей клея. Можно собирать механизм обратно, крепить стрелки и радоваться полученному результату:
Да, мои часы еще и идут в обратную сторону, что дополнительно сводит с ума случайного наблюдателя.
Ссылки
- Исходный код прошивки: http://pastebin.com/P3y6wBUh
- Аналогичный проект: Vetinari's Clock
- Работа AVR при сверхнизком напряжении питания: Using an AVR as an RFID tag