30.06.2009

Кухонный таймер на Arduino (3)

Часть III

(окончание, см. Часть II и Часть I)

Итак, начнем перенос схемы с макетной платы в реальный мир. Поскольку на кухне нет стабилизированного источника +5В, будем полагаться на стандартную схему питания со стабилизатором 7805 (чтобы можно было питать, например, от такого БП на +9В).



Кроме того, надо окончательно определиться с номиналом токоогрничительных резисторов.

При выборе надо учитывать не только максимальный ток через вывод ATmega - 40 мА, но и общий ток на кристалл. Для ATmega8 он составляет 300 мА, но это значение поделено на две части - 100 мА может протекать через порты C0..С5 и 200 мА через все остальные. Пины отдельных сегментов я расположил как раз на выводах C0..C5, следовательно ток через сегмент не может превышать 100/6 = 16,7 мА (будем считать, что все сегменты засвечены - т.е. надо выводить восьмерку).

Из документации на семисегментный дисплей выясняем, что максимальный ток сегмента в нормальном режиме - 30 мА, падение напряжения - 2.0 В при токе 20 мА. Зная, что при последовательном включении сумма падений напряжений на диоде и резисторе равна питанию ( +5В ), получается, что на резисторе "упадет" 5-2=3 В, из чего можно вычислить минимальное сопротивление: R=U/I или 3/0.0167 = 180 Ом. Я решил не рисковать и поставил 220 (ток 13,6 мА).

Тут надо заметить, что есть еще пины, через которые протекает ток всего знакоместа, собирая токи всех сегментов. Простой подсчет показывает, что этот суммарный ток 13,6 x 8 = 109 мА более, чем в два раза первышает 40 мА.

Увы, тут сказывается грубость моих теоретических выкладок - на практике всё вполне надежно работает. Я не учел пару моментов: во-первых, у пина ATmega тоже есть свое внутреннее сопротивление, следовательно реально ток должен быть меньше. во-вторых - при мультиплексировании знакоместо светится только одну миллисекунду, со скважностью 4, что дает возможность скорректировать значение тока 109/4 = 27,25 мА.

Видимо, если вывести на дисплей четыре восьмерки и остановить мультиплексирование, один вывод у ATmega должен выйти из строя. Пока мне жалко губить МК ради такого эксперимента, но, думаю, рано или поздно это у меня получится, хотя бы и случайно ;)

Последнее дополнение, которого нет на схеме: я нашел место для уголовой вилки PLSR, для оперативного заливания новых версии скетчей (конечно, можно было бы установить и ICSP, но так мне показалось удобнее с точки зрения взамодействия с Arduino IDE).

Для размещения я выбрал такой корпус:



На верхней панели надо поместить дисплей и две кнопки, где-то сбоку - тумблер и гнездо питания 2.1/5.5 мм. Сопоставив между собой габариты всех элементов, я пришел к выводу, что схему надо разнести на две платы через вилки и гребенки PLS/PBS: вверху будут кнопки и дисплей, внизу - все остальное. По высоте как раз подходит - заодно не будет болтаться лишних проводов к кнопкам и дисплею.

Первым делом надо вырезать два кусочка макетной платы, под размер корпуса. Можно сразу вставить в них вилки и гребенки PLS/PBS, чтобы убедиться в правильной центровке собранной двуплатной конструкции. Для отрезания гетинакса удобно пользоваться ножницами по металлу, в крайнем случае электролобзиком или мелкой ножовкой по металлу. Надфилем можно аккуратно скруглить углы, чтобы лучше входило в корпус (да и порезаться шансов будет меньше).

Дальше, надо обратить внимание на крепление в корпусе - в данном случае 4 отверстия в нижней плате. Отверстия обычно намечаются маркером и сверлятся мини-дрелью. К сожалению, фирменного DREMEL у меня нет, обхожусь китайской CT-800, хотя - на самом деле, можно воспользоваться даже бытовой ударной дрелью/шуруповертом, главное - аккуратность и точность. Диаметр отверстий можно подбирать под размер саморезов (для этого корпуса подойдет 2,5 мм).

Теоретически, в макетной ничего сверлить не надо, но практически - у нас есть гнездо питания 2,1/5,5 мм с широкими выводами, которое надо еще и расположить на краю платы таким образом, чтобы оно получалось "заподлицо" с одетым внешним корпусом. Возьмите сверло нужного диаметра и просверлите еще три отверстия.

Теперь можно откладывать слесарный инструмент (но недалеко, он еще пригодится) и браться за паяльник. Вот что у меня получилось с нижней платой:



Голубая бочечка - это керамический резонатор 16 МГц. Как и любой керамический резонатор, он будет уступать кварцевому по стабильности и точности (у этого экземпляра - 0.5% погрешности). Для кухонного таймера это кажется несущественным; главный плюс такого резонатора - наличие встроенных конденсаторов нужных номиналов (поэтому у него три пина), что в итоге дает более компактное размещение на плате.



Электролиты надо использовать низкопрофильные - хотя бы 7мм в высоту. Обычные, высотой 11 мм, придется класть "на бок", потому что межплатное расстояние - меньше.



Как и резонатор, конденсатор-фильтр 100 нФ (маркировка 104 обозначает 10 x 10^4 пФ) надо располагать максимально близко к МК.



На этом фото показано подключение адаптера USB-TTL к вилке PLSR4, на которой, как нетрудно догадаться, Vcc (+5В), GND, Rx и Tx. Соединения удобно делать однопиновыми проводами с разъемами BLS:



Однако, если USB-TTL под рукой не оказалось, придется искать другие способы: например, адаптер COM-TTL, легко собираемый на одной микросхеме MAX232CPE. Или классический - установить вилку ICSP и прошивать HEX-файл, получающийся после компиляции из Arduino IDE (ищите в каталоге скетча, там создается подкаталог applet со всеми промежуточными данными), но для этого понадобится программатор, например - тот же Usbasp.



Пьезоэлемент пришлось расположить на нижней плате из-за толщины, но это все равно оказалось приемлемо: слышно его очень хорошо.

Теперь пора приниматься за верхнюю плату:





Часть соединительных проводов можно "пропустить" под корпусом индикатора, но это надо делать до его установки, а сам индикатор не опускать "до упора" на плату.



Самое время проверить правильность монтажа: соединить две платы и посмотреть, как оно заработает.





Как видите - все компоненты на нижней плате аккуратно уместились в межплатное расстояние.

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





Отверстия под разъем питания и тумблер вырезаются скальпелем:



Подаем питание на устройство, и... ждем 10 секунд, пока появятся мигающие нули. Почему так долго? Это происходит из-за бутлоадера, который был прошит в ATmega8, если вы дали хотя бы раз команду "Burn Bootloader" из Arduino IDE. Кстати, именно он может стать причиной активизации злых аппаратных духов.

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

На 3-4 итерации я решил внимательно разобраться, в чем же, собственно, дело. Для этого я добился повторения состояния "поломки" таймера, после чего прочитал флеш-память ATmega8: обнаружились отличия в 16 байтах по сравнению с тем, что зашивали изначально. Следовательно, память ATmega была чем-то испорчена. И, как вы уже догадались, это был опрометчиво оставленный в памяти Bootloader.

Рекомендую в готовом изделии выключить бутлоадер и запретить запись в память программ (не путать с возможностью программирования через ICSP) при помощи установки соответствующих fuse-и lock-битов. Если бутлоадер все-таки нужен - как правило, для отладки - советую обязательно включить BOD - Brown-out Detector, встроенный в ATmega и по умолчанию в Arduino выключенный. Корень проблемы в том, что бутлоадер может исполнять SPM-инструкции (Store Program Memory), которые модифицируют код программной секции. В момент включения питания происходит масса переходных процессов: возрастает напряжение питания, разгоняется резонатор. Необходимо дождаться их стабилизации, прежде чем начинать выполнение инструкций, иначе поведение МК может быть непредсказуемым - с чем я и столкнулся. Для нейтрализации этого эффекта применяют стандартные схемы - т.н. "супервизоры" питания, которые следят за уровнем входного напряжения и удерживают сигнал сброса контроллера до тех пор, пока оно не достигнет нормального уровня. Но поскольку в ATmega оно уже есть (BOD), остается просто активировать его через fuse-биты и выбрать напряжение триггера (в нашем случае Vcc = 5В, поэтому выбираем 4В).

Финальные значения fuse-битов: HFUSE = 0xCB, LFUSE = 0x1F.

Вот, пожалуй, и всё. С помощью доступных компонентов и минимальных навыков программирования/паяния получено имеющее практическую ценность изделие - простой кухонный таймер. Таким образом я завоевал для своего хобби "место под солнцем", очистив его в глазах родственников от ярлыка бесцельного и дорогостоящего времяпрепровождения.

Что может быть прекраснее? ;)

7 комментариев:

  1. Замутил подобный вариант на протошилде - заработало. Подключил ds1307 - превратил в часы - работают. После задействовал последний порт - подключил третью кнопку. Пытаюсь превратить в полноценный девайс - часы + календарь, таймер, будильник....

    ОтветитьУдалить
  2. Ну так это же прекрасно! Как получится - готов разместить здесь авторскую статью-продолжение ;)

    И печатную плату соорудить могу, раз уж на то пошло ;)

    ОтветитьУдалить
  3. Почту за честь =) надеюсь на днях дорисую внятный скетч - можно будет похвастаться ;)

    ОтветитьУдалить
  4. Нарисовал что-то более или менее как-то работающее. В принципе все еще очень сыро, но я уже показал бы, дабы выслушать конструктивную критику =)

    ОтветитьУдалить
  5. Можно сначала мне на мыло: general@idanilov.ru.

    ОтветитьУдалить
  6. Извините, вы пишите: (у этого экземпляра - 5% погрешности), что становится заметно при наносекундных задержках.

    Но 5% от 24 часов -- это 72 минуты, и совсем не наносекунды!

    ОтветитьУдалить
  7. Спасибо за внимательность! С точностью я, конечно же, ошибся - если память мне не изменяет, именно у этого экземпляра она 0.5%.

    А по существу - всё логично. Чем больше величина измеряемого временного интервала, тем больше абсолютное значение ошибки (поскольку второе выражено в процентах от первого).

    Брали бы сразу год ;)

    ОтветитьУдалить