10.06.2009

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

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

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

Итак, прежде всего - подберем компоненты:
  • дисплей для отображения времени
  • пара кнопок для управления
  • зуммер для привлечения внимания хозяйки
  • корпус, в который все это поместится
  • источник питания

Ну и конечно же, Arduino.

Наиболее хорошо для этой цели подходит Arduino Pro: основные разъемы не установлены, можно поставить ровно столько, сколько надо (а также именно то, что требуется - вилки или колодки, нужный разъем питания):



За неимением такого замечательного девайса, придется собирать на макетке. Как обычно - ATmega8-16PU, кварц 16 МГц + 2 конденсатора 22пФ, притянуть сброс через 10К к Vcc, схема птиания на L7805. Поскольку я постоянно собираю Arduino / Freeduino, все это у меня имеется в избыточном количестве.

С эстетической точки зрения, лучше устанавливать часовой дисплей с "двоеточием" по центру, которое мигает раз в секунду при отсчете времени. В минимальном варианте достаточно просто двух цифр с числом оставшихся минут. Поглядывать на таймер надо издалека, поэтому размер и яркость цифр имеют значение - лучше всего подойдет светодиодный дисплей. Удобно использовать индикатор, у которого одноименные выводы уже соединены - все равно мы будем отображать методом мультепликсирования. У меня был красный семисегментный CA56-21EWA (Kingbright), с общим анодом:



В качестве зуммера можно использовать пьезоизлучатель. Часто на материнских платах можно встретить такой вариант:



Это пятивольтовый KPX-G1205B (Kepo Electronics).

В него встроен генератор, позволяющий издавать звуковое колебание заданной частоты простой подачей разности потенциалов на его выводы. Очень удобно, да и ток всего 30 мА (напоминаю, что максимальный ток через выход ATmega - 40 мА). Если не закрывать отверстие, пищит достаточно громко - простой бесчеловечный эксперимент показал, что хозяйка слышит его сквозь какафонию из льющей из водопроводного крана воды и орущего телевизора, причем еще и из другой комнаты. Те, кому повезло меньше, могут использовать схему с транзистором ;)

Кнопки могут быть как тактовые, так и с креплением на корпус. Идеально подойдут влагозащищенные, но это влетит в копеечку. Я выбрал компромиссные SWT-9 с разноцветными колпачками:





Для включения питания идеально подходит классический тумблер MTS-102:



Среди корпусов для РЭА, которые я мог заказать у поставщиков, мне приглянулись черные пластиковые, на защелках. Брать размер 70 х 40 мм я побоялся (как потом выяснилось, абсолютно верно), но вот 90 х 56 мм уже выглядело для такой схемы вполне комфортно, тем более, что в высоту он 30 мм, а значит - дисплей с кнопками и контроллер можно разместить на двух разных платах, соединив их при помощи PLS/PBS:



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

Настало время рисовать схему в Eagle, но прежде подсчитаем, сколько потребуется портов ввода/вывода.

Семисегментная шина требует 7+1=8 выходов: восьмой в данном случае управляет двумя точками по центру. Один сигнал на каждое знакоместо: +4, итого уже 12. Один выход потребуется для пьезоизлучателя, два - для подключения кнопок. В сумме надо 15, а у Arduino всего 13 цифровых выходов, из которых категорически не хотелось бы занимать 0 и 1 - там UART, через которую заливается скетч.

На наше счастье, аналоговые выходы можно перепрограммировать в цифровые оператором DigitalMode. Аналоговый вход 0 будет соответствовать 14-му цифровому, а 5й - 19-му. АЦП нашей схеме не требуется, так что смело можно переводить все шесть выходов в цифровой режим.

Для начала соберем такую схему на мактной плате:



Продолжение следует...

08.06.2009

USBasp

Когда писал статью про Metaboard, обратил внимание на программатор USBasp, по набору деталей и возможностям сильно напоминающий AVR910:



Ради интереса решил повторить на макетке:



По моим впечатлениям, обмен идет гораздо быстрее, чем с AVR910 от prottoss-а.

По причине прямой поддержки со стороны avrdude ( >= 5.2.0), программатор можно использовать с Arduino IDE. Для этого надо дописать несколько строк в файл arduino-0016\hardware\programmers.txt:
usbasp.name=USBasp
usbasp.communication=usb
usbasp.protocol=usbasp

После этого появляется соответствующее меню в ArduinoIDE:



Работает, что характерно ;)

Firmware с исходниками и чертежи печатных плат можно найти на сайте автора (Thomas Fischl).

Традиционные минусы дешевого программатора:
  • не умеет питаться от программируемой схемы
  • нет предохранителя на линии питания USB (ну, это легко добавить)
Как обычно, выложил комплект деталей на "молоток".

05.06.2009

ArduinoIDE 0016

Вчера вышла новая ArduinoIDE версии 0016. Можно качать.

Что новенького?

Новые примеры в разделе Communications (с соответствующими частями для Processing и MAX/MSP) by Tom Igoe.
  • SerialCallResponse - посылает через Serial-порт данные от сенсоров + код для отрисовки на PC
  • SerialCallResponseASCII - тоже самое, но данные передаются в десятичном виде через запятую.

Это для тех, кто пишет обработку поступающих от Arduino данных на Processing.

Поддержка Arduino Pro, Pro Mini 3.3V/8 MHz, а также LilyPad Arduino на ATmega328.

Все прогрессивное человечество уже перешло на ATmega328! А вы? ;) Кстати, одно время в DIP-корпусе этот МК отсутствовал на Маузере и Дижикее - не понимаю, неужели раскупили любители Arduino?...

Добавлены члены write(str) и write(str,buf) в классы Print, Serial и Ethernet Client/Server.

Ну наконец-то! Я испытал это неудобство на собственной "шкуре", когда модифицировал Ethernet Library под UDP. Действительно, базовый родительский класс для вывода - Print, поддерживающий богатое разнообразие входных форматов данных через функцию-член print - число, строка, массив, разные длины целых, разные системы счисления. Но в конечном-то итоге вызывается виртуальный write - именно его и должна перекрывать библиотека-потомок, реализующая вывод данных в определенное устройство. При этом write всегда принимал один-единственный символ - то есть, вывод шел побайтный. Приемлемо в LiquidCrystal, но в Ethernet эта концепция вписалась только по причине исключительной поддержки TCP. Для UDP мне пришлось заводить write_block, но теперь этого делать не надо! Bravissimo!

Улучшено подключение и отключение в классах Ethernet, что позволило сократить число неуспешных соединений и длительных таймаутов.

Например, в Client.connect(): более аккуратная работа с номером сокета, проверка состояния полузакрытия сокета SOCK_FIN_WAIT, дополнительная задержка 1 мс между окончанием установления соединения и проверкой, что оно еще живое... Я-то думал, что там уже нечего вычищать - но нет, работа по повышению стабильности продолжается!

Оптимизировано переполнение timer0, который используется в функциях millis() и micros()

Код стал чуть короче, в сумме это дало экономию 80 байт! Поскольку этот фрагмент кода включается в каждый скетч, "похудение" отразится на результатах компиляции всех скетчей. И - как знать, может кто-то не может втиснуться в размер памяти программ своей ATmega8/168 и не хватает ему для счастья 30-40 байт... Вы же знаете, как на C быстро память расходуется... ;)

Пофикшен макрос bits(), работавший не более, чем для 15 бит.

Бывает.

Добавлена константа ARDUINO с номером версии.

Я считаю - давно пора. Как бы не старалось сообщество, все равно от версии к версии происходят порой жесткие изменения (pulsein в версии 0013), которые хотелось бы контроллировать при написании кода.

Посортировали пункты в меню Tools > Boards.

Да они же целую кучу плат добавили (см. выше) - вот наверное оно распухло... Ну-ка, взглянем:


Ну просто красота. Нет предела совершенству!

Добавили "Copy to HTML".

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

/*
* Blink
*
* The basic Arduino example. Turns on an LED on for one second,
* then off for one second, and so on... We use pin 13 because,
* depending on your Arduino board, it has either a built-in LED
* or a built-in resistor so that you need only an LED.
*
* http://www.arduino.cc/en/Tutorial/Blink
*/

int ledPin = 13; // LED connected to digital pin 13

void setup() // run once, when the sketch starts
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}

void loop() // run over and over again
{
digitalWrite(ledPin, HIGH); // sets the LED on
delay(1000); // waits for a second
digitalWrite(ledPin, LOW); // sets the LED off
delay(1000); // waits for a second
}

(напрямую вставил в блог из ArduinoIDE, ничего не менял).

Пофикшено (вроде бы) "Couldn't determine program size".

У меня такое бывало, периодически. С чем связано - так и не смог установить со 100%-ой точностью.

Автоматическая генерация зависимостей для Makefile.

Этого тоже недоставало, когда шла работа над библиотеками... Когда один скетч - не актуально, но стоит добавить файлов - и Arduino могла просто не компильнуть нужный исходник. Приходилось сносить объектный файл вручную.

03.06.2009

Metaboard

Название: Metaboard
Процессор: ATmega8/88/168/328P
Тактовая частота: 16МГц
Совместимость с Shield-платами: нет
Совместимость с Arduino IDE: есть, неполная
Страница проекта: http://metalab.at/wiki/Metaboard



Metaboard - Arduino-совместимая плата с USB, но без USB-чипа. USB реализовано в микропрограмме ATmega, код основан на драйвере V-USB от Objective Development ( я касался этого вопроса, когда писал про AVR910 на USB ). Принципиальная схема:



Специально для этой платы был разработан bootloader, который принимает по USB скомпилированный скетч от Arduino IDE, а потом запускает его. Получается весьма симпатичное и экстремально дешевое решение для Arduino с USB, которое можно собрать своими руками. Вот что у меня получилось на беспаечной макетной плате за четверть часа:



На странице проекта можно скачать схему и чертеж односторонней печатной платы в формте Eagle: обратите внимание, что практически все простарнство между колодками входов и выходов Arduino пустое - там насверлили дырок и устроили макетное поле. Кстати, не ищите ICSP-разъем - автор предлагает желающим припаять его на макетное поле, если уж им так его недостает ;)

Однако, не спешите радоваться :( В этой жизни за все приходится расплачиваться.

1. Размер bootloader-а для ATmega8 вырос до 2К. Оригинальный занимал 1К и оставлял для скетча 7168 байт, теперь же будет доступно 6144. Это все еще весьма много, но будет сильно ограничивать при подключении библиотек. Так что надо брать сразу ATmega168 - тем более, что в этом случае размер доступной памяти не изменится. Правда, придется забыть и про фокус с +1К к свободной памяти, про который я как-то уже писал.

2. Аппаратный последовательный порт, обитающий на пинах Rx/Tx ATmega, остается "как бы" незадействованным. То есть, использовать-то его можно, но, в отличие от Diecimila / Duemilanova, он никак не связан с USB. Код Objective Development работает по прерывыаниям и обязательным условием является заведение сигнала D- на пин ATmega, поддерживающий прерывания. Таким образом, вместо обычных PD0 и PD1 для загрузки скетчей используются PD2 и PD4.

3. Автосброса - нет. Обычно, Arduino IDE "опускает" перед загрузкой скетча DTR, чтобы сформировать сигнал сброса на МК. Для приложения (в данном случае - ArduinoIDE) это выглядит довольно просто - надо вызвать соответствующую функцию Win32 API. После этого управление получит драйвер FT232RL, который сформирует соответствующий служебный пакет данных и передаст его по USB, далее его примет FT232 и переведет свою специально выделенную ножку "DTR" в состояние логического нуля, что, в свою очередь, вызовет сброс на МК.

Но в Metaboard нет отдельного внешнего чипа, который играл бы роль внешней цепи сброса. Сброс возможен только по нажатию кнопки на плате. По сбросу запускается bootloader, который опрашивает PD7 ( digital 7 по обозначениям Arduino ). Если там логический ноль, то bootloader начинает ожидать ( бесконечно долго! ) заливание скетча, а по окончании передает ему управление. В противном случае управление сразу передается по нулевому адресу.

На первый взгляд кажется, что вы теряете digital 7, но его заземление требуется только на время заливки скетча ( вы еще не успели забыть, что здесь по USB нельзя общаться через Hardware Serial? ). В любом случае, придется стараться собирать схему так, чтобы digital 7 не использовался на вход и был по крайней мере притянут к Vcc.

Кстати, чтобы код Objective Development работал, надо обязательно ставить кварц, никаких керамических или внутренних RC-цепочек использовать нельзя.

Для тех, у кого еще не успело пропасть желание собрать из комплекта деталей и макетки практически полноценный Arduino, для достижения этой цели надо еще чуть-чуть поработать. Разберем на примере ATmega8.

Скачайте и распакуйте bootloader: http://www.obdev.at/products/vusb/usbasploader.html.

Нам потребуется hex-файл firmware\hexfiles\mega8_16mhz.hex, поместим его в дерево файлов Arduino IDE, в каталог arduino-0015\hardware\bootloaders\atmega8\.

Поскольку этот bootloader работает не по протоколу stk500, то придется заводить отдельную секцию в boards.txt:

meta8.name=Metaboard w/ ATmega8

meta8.upload.protocol=usbasp
meta8.upload.maximum_size=6144
meta8.upload.speed=19200

meta8.bootloader.low_fuses=0xdf
meta8.bootloader.high_fuses=0xc8
meta8.bootloader.path=atmega8
meta8.bootloader.file=mega8_16mhz.hex
meta8.bootloader.unlock_bits=0x3F
meta8.bootloader.lock_bits=0x0F

meta8.build.mcu=atmega8
meta8.build.f_cpu=16000000L
meta8.build.core=arduino


Как видите, кое-что изменилось: название протокола - usbasp, уменьшился на 1К upload.maximum_size, bootloader.file указывает на скачанный на предыдущем шаге бутлоадер, а bootloader.high-fuse задает размер бутлоадера, равный . Теперь можно перестартовать Arduino IDE, выбрать в списке плат "Metaboard w/ ATmega8". Если МК не прошит, то теперь это можно сделать через стандартное Tools->Burn Bootloader->w/ Parallel Programmer ( разумеется, вилка ICSP должна быть установлена ;).

Теперь надо скачать драйвер USBasp, иначе устройство будет обнаружено, но использовать его не получится. Идем на страницу http://www.fischl.de/usbasp/, качаем и распаковываем самый последний архив. При подключении Metaboard, на запрос об обновлении драйверов, подсовываем каталог bin\win-driver\libusb_0.1.12.1.

Все, теперь можно работать, только не забудьте выставить какой-то номер COM-порта, Arduino IDE формально требуется его определить, хотя в данном случае он ну никак не нужен.

UPD: совместимый с Metaboard вариант MKBoard R1 можно купить здесь (в виде набора деталей или в сборе). 

Резюме: самый дешевый способ собрать Arduino с USB самостоятельно. Особенно актуально, если скетчу не надо обмениваться с PC информацией через библиотеку Serial.

01.06.2009

Калькулятор fuse-битов

Случайно наткнулся на прикольный калькулятор fuse-битов, позволяет наглядно выбрать fuse-биты для устройств AVR - по смыслу. В какой-то степени даже может заменить datasheet.

Хотя, в datasheet все-таки тоже смотреть надо, мало ли что ;)