Таймер на tiny13 и STLED316

AVR
Надоело мне бегать и следить за часами при засветке фоторезиста или паяльной маски. Да и вообще… И сделал для себя таймер в корпусе от Pilot. Может, кто помнит, был такой тройник. Там как раз много места под фильтр есть.

Под это дело взял самый маленький AVR, а что бы не заморачиваться с выводом на индикатор добавил STLED316. Заодно и кнопки она же подрядилась обслуживать.
Чего нужно от таймера для дома? Правильно — считать время, причем для меня достаточно с точностью до десяти секунд. А вот длительность желательно побольше, например часа полтора для некоторых операций. А так как операции обычно одинаковые то и время соответственно одинаковое, поэтому желательно хранить предыдущие интервалы запуска таймера.
Исходя из этих хотелок сваял таймер со следующими характеристиками:
— время отсчета от 1-й секунды до 99 минут 50 секунд;
— шаг настройки таймера 1 секунда на интервале до 9 мин. 59 сек. и 10 секунд на интервале от 10 минут;
— девять запоминаемых интервалов;
— звуковое и световое оповещение при окончании интервала.
И управление силовой нагрузкой само собой.
Пока рылся в хламе обнаружил зарядник от телефона на 5В-0,7А Маленький и без корпуса. Вот его и приспособил для питания слаботочной части. Силовая же часть сделана без извращений на оптосимисторе и просто симисторе по даташиту на оптосимистр, так что думаю даже и нечего тут силовую часть рисовать. Да и сделать можно на реле, например. Схемка слаботочной части:

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

Как им управлять и чего он может.
При включении читается из eeprom интервал заданный при последнем запуске таймера, так что не надо каждый раз набирать интервал заново.
На индикатор выводится интервал в минутах и секундах до значения длительности от 1 секунды до 9 мин.59 сек. и в минутах и десятках секунд для длительностей от 10 минут и больше.
Кнопками «плюс» и «минус» соответственно увеличивается и уменьшается интервал на одну секунду на длительностях до 10 минут и на 10 секунд на длительностях более 10 минут, за нажатие.
Кнопка «выбор/установка» читает из eeprom следующий запомненный интервал и выводит его на индикатор. Она же возвращает старое значение интервала сразу после остановки таймера.
О смысле кнопок «Старт» и «Стоп» я думаю догадаться можно легко. Единственно нужно иметь в виду, что при нажатии кнопки «Старт» текущее значение таймера записывается вместо старого значения в eeprom и при желании может быть прочитано при следующем старте.
Запуск отсчета включает силовую нагрузку и на индикаторе начинает мигать десятичная точка. Числа на индикаторе показывают оставшееся время до выключения с точностью до десяти секунд. По окончании отчета начинает мигать светодиод и пищит пищалка 20 раз.

Теперь по программе.
Комментариев в коде постарался понаписать побольше, но если кому не хватит, добавлю еще. Компилятор Atmel Studio 6.1 плюс натыренные по разным местам в Интернете исходники.
Часть кода сделал в виде Inline функций т.к. мне так удобнее.
Рабочий интервал хранится в двоично-десятичном коде. Соответственно и операции сложения, вычитания и сравнения несколько специфичны для этого кода.
Секунды считает одинокий таймер в режиме normal с ограничением счетчика. Коэффициент деления подобран так, что бы частота после деления была примерно 2 кГц. С этой частотой пищит пищалка по окончании интервала. В прерывании по переполнению таймера рассчитываются еще несколько интервалов – собственно сами секундные интервалы, интервалы для мигания и пищания, а так же проверяется окончание рабочего интервала если таймер запущен.
В основном цикле читаются клавиши, выводятся цифры на STLED316 и выполняются остальные действия по запуску, остановке и прочим прелестям.
Порт который управляет силовой частью в этой программке используется в качестве битового флага говорящего о состоянии таймера.
Пищание сделано с помощью разрешения –запрещения вывода регистра сравнения OCRB.
После компиляции получится файл timer.hex с прошивкой flash – памяти и timer.eep с прошивкой eeprom. Фьюзы в контроллере не менял, как пришло с завода так и оставил. timer.eep можно не заливать, просто тогда при первом запуске будет калябаляшки на индикаторе. Такое безобразие убирается с помощью клавиш минус или плюс.
Вот вроде и все.
В приложенном архиве файлики для AtmelStudio 6.1 и Diptrace 2.3.1

Update
Комментаторы убедили меня добавить точности. Отобрал таймер у жены и дописал в прошивке несколько строк так, что если интервал таймера устанавливается от 0 мин. 01 сек. до 9 мин. 59 сек., то точность можно устанавливать до 1 (одной) секунды.
Заодно попросил дочку сделать фотки конструкции.
Кишки
Общий вид
Файлы в топике: Timer.zip

Комментарии (15)

RSS свернуть / развернуть
Дискретность в десять секунд слишком велика, как по мне. Конечно, всё зависит от мощности источника УФ излучения, но мне, например, пришлось подбирать экспозицию с точностью до плюс-минус две секунды. Так что имхо, надо бы подправить дискретность установки…
0
Поддерживаю, есть ситуации, в которых разница в одну секунду совершенно четко видна (вплоть до «получится» vs «не получится»).
+1
Давно уже использую Ordyl Alpha 340, бывало и 1.5 мин. засвечивал и 2. Большой разницы не увидел. Правда и нормы не высокие — 0.2/0.2 обычно. К тому же жена этот таймер использует для своих нужд, а у нее там вообще плюс минус 5 минут, зато длительность час и более. Но при желании переделать конечно можно. Либо сдвинуть десятичную точку при индикации либо добавить разряд в индикатор.
0
Давно уже использую Ordyl Alpha 340, бывало и 1.5 мин. засвечивал и 2. Большой разницы не увидел.
Это не значит, что ее нет. По моим наблюдениям и по имеющейцся информации, оптимальные условия работы фоторезиста складываются тогда, когда выдержка после калибровки составляет около 45сек +- 15сек, причем эти условия мало отличаются для тех фоторезистов, которые я проверял. Как правило, для получения выдержки в этом интервале надо увеличить мощность ламп и/или уменьшать расстояние. После этого калибровка выдержки становится гораздо острее и +- секунда становится заметно. Даже если оптимум получается в районе минуты, +- 10 секунд легко могут оказаться по разные стороны и достаточно далеко от оптимума.
+1
Не слишком внимательно посмотрел код, но вот пару вещей сразу можно улучшить.

Макрос установки/сброса бит для Long переписал бы как:
#define SetBitValLong(reg, bit, val) do{if (val==0) (reg) &= (~(1UL<<(bit)));\
else (reg) |= (1UL<<(bit));}while(0)
То есть вместо long применить unsigned long, потому что при изменении бита 31 некоторые компиляторы ругаются на смену знака числа.

В функции OutLED — ну не стоило бы использовать макро
SetBitVal(PORTB, DI, (BitIsSet(cmd, i)?1:0));
для переменных в цикле for. Код огромный генерится, он же каждый проход вычисляет бит в разной позиции. Лучше в цикле всегда выплевывать младший бит, и затем сдвигать вправо выводимое число. т.е.:
SetBitVal(PORTB, DI, ((cmd&1)?1:0));
cmd >>= 1;
+1
Спасибо за оба комментария. SetBitValLong в этом проекте не используется поэтому про практическое применение не могу ничего сказать, а вот перенос сдвига за пределы макроса дал 22 байта экономии. Еще раз спасибо.
Попутно могу заметить со мной сыграла шутку привычка писать прототипы функций. Глянул в объявлении, что входной параметр const и дальше уже принял это как руководство к действию. Надо было еще головой подумать.
0
Интересный проектик, но вот да, дискретность в 10 сек это всё же большой минус. Мне было бы лень впихивать это в attiny13, имхо проще взять atmega48, оно и дешевле вышло бы.
0
  • avatar
  • mChel
  • 12 сентября 2013, 16:45
может быть и дешевле, но такой цели не ставилось. Вот когда налажу производство тогда и подумаю :)
А насчет единиц секунд можно конечно и сделать, надо только еще код ужать. Например разбить на два диапазона до 9.59 и от 10.00 Это потребует по моим прикидкам байт 70-90 флэша Если есть еще предложения — велкам.
0
да, дискретность в 10 сек это всё же большой минус
Это не просто «минус», это фатально для засветки. у меня что фотек, что ристон, больше двух секунд не прощают…
Мне было бы лень впихивать это в attiny13, имхо проще взять atmega48, оно и дешевле вышло бы.
Тут такое дело… Обычно такие проекты собираются «что есть прям_щас под рукой». Я в свой таймер вообще воткнул мегу16(или 32?) просто потому, что она есть и надо куда-нить пристроить.
0
Это не просто «минус», это фатально для засветки. у меня что фотек, что ристон, больше двух секунд не прощают…
убедили — добавил точности на сколько смох.
0
Как у вас всё плохо, с этим вашим фоторезистом. То ли дело ЛУТ — ни каких заморочек. 2 секунды — 2 минуты — пофигу.
0
То ли дело ЛУТ — ни каких заморочек. 2 секунды — 2 минуты — пофигу.
Точно. Сколько времени ни трать, а двустороннюю плату толком не совместить :)
+1
рискую нарваться на холивар, но все же замечу, что из трех составляющих изделия (материал, инструмент, технология) фоторезист снижает именно требования к технологии и инструменту за счет применения более качественного материала. А ЛУТ выдвигает примерно равные требования ко всем трем составляющим. ПОэтому провал например в используемых материалах в ЛУТ приведет к некачественному изделию, а вот если фоторезист будет некачественый, то можно будет подтянуть качество более точной технологией или применением более совершенного инструмента. Чем я думаю evsi и занимается последние триста лет :)
0
Здравствуйте. Не могли бы вы мне помочь? forum.easyelectronics.ru/viewtopic.php?f=4&t=22395&p=398156#p398156
0
В вашем индикаторе установлены транзисторные ключи которые открываются (а значит и зажигают соответсвующую цифру) при соединении базы с земляной шиной. А STLED как раз делает наоборот — подает на вывод DIGIT положительный импульс для зажигания цифры. Поэтому можно пойти двумя путями — либо удалить транзисторы из индикатора и соединить STLD с общими анодами напрямую, либо инвертировать линии DIGIT любым доступным способом.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.