31.01.2010

ArduinoIDE 0018

В пятницу, 29.01.2010 вышел очередной релиз ArduinoIDE 0018. На этот раз, хоть и после длительного перерыва, но никаких грандиозных нововведений. Сплошные грандиозные багфиксы. Традиционно, подтянулись к Processing 1.0.9.

Начнем с куска, который присутствует всегда - с библиотеки-ядра (Arduino core).

1. Теперь последовательный порт умеет выключаться. В самом деле - а вдруг оно больше не пригодится? Поэтому, появилась Serial.end():

void HardwareSerial::end()
{
  cbi(*_ucsrb, _rxen);
  cbi(*_ucsrb, _txen);
  cbi(*_ucsrb, _rxcie);
}

cbi - это аналог avr-gcc-шного макроса сброса бита в управляющем регистре МК. После вызова Serial.end() уже ничто не вызовет передачу или прием данных по последовательному порту.

2. Внутри delayMicroseconds() прерывания больше не запрещаются, перед циклом задержки убран cli(). В принципе, это идеологически верно: ведь в delay() же они тоже не запрещаются. Кстати, это дало возможность нормально работать функции millis(). Также, слегка поправили micros(), чтобы она возвращала корректные данные и внутри прерывания тоже.

3. Теперь можно включить и выключить генерацию акустического тона:

void tone(uint8_t _pin, unsigned int frequency, unsigned long duration);
void noTone(uint8_t _pin);

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

4. В MEGA можно использовать аналоговые пины 8-15. А всего-то надо было заменить в строчке

ADMUX = (analog_reference << 6) | (pin & 0x07); 

..0x07 на 0x0f.

Но, как говорится - все ошибаются, и это нормально.

5. Наконец-то можно выводить вещественные числа с заданной точностью:
void print(double, int = 2);    
void println(double, int = 2);

На существующий код это влияния не окажет, потому что новый параметр (число цифр после точки) объявлен по умолчанию двум. И ведь самое обидное, что это уже  умеет Print::printFloat(double number, uint8_t digits), она остается прежней. Положительный момент - излишество не займет много места в памяти программ.

Небольшие изменения в самой IDE:

  • нажатие Shift во время Upload или Verify/Compile делает вывод ошибок более информативным;
  • чествование Serial Monitor продолжается: теперь у него не только отдельное окно, но и собственная горячая клавиша;
  • сделан очередной шаг по защите базовых каталогов. Теперь можно унести все модификации файлов hardware/arduino в SKETCHBOOK/hardware и больше не перетаскивать их при обновлении ArduinoIDE. Обычно, первым страдает boards.txt.  Но в теперь SKETCHBOOK/hardware/figuino/boards.txt будет благополучно объединена с arduino-0018/hardware/arduino/boards.txt. В целом, это позитивный шаг, облегчающий жизнь Arduino-совместимых плат, например того же Sanguino.

Ну и прочее - багофиксы в Firmata и LiquidCrystal, небольшие улучшения в версии для MacOS.

Как всегда - качайте ArduinoIDE по адресу http://arduino.cc/en/Main/Software и помните: это абсолютно бесплатное программное обеспечение! Но раз уж скачали бесплатно - обязательно что-то сделайте и поделитесь с другими: так вы внесете свой посильный вклад в этот знаменитый проект!

28.01.2010

Сторожевая Собака

Недавно в руки мои попало вот такое чудо:


Позвольте представить: разработка ООО "ЛисКо", сторожевой таймер для платежного терминала LDog.


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

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


Плавно подвожу к главному. Внутри LDog притаилась... классическая начинка Arduino! ATmega8-16AU тактируется от кварца 8МГц, а его порт USART подключен к COM-порту через драйвер RS232 от Analog Devices AD232 (тоже самое, что и популярная микросхема MAX232). Есть и гребенка ISP, только классическая 10-ти контактная.

Теперь немного об отличиях. Разумеется, все пины наружу не выведены. Мы ограничены двумя входами, двумя выходами и еще тремя линиями из разъема ISP (MOSI, MISO, SCK). Но зато выходы имеют оптронные развязки, а на одной из них висит MOSFET - специальный полевой транзистор, пропускающий через себя линию питания модема - 12 Вольт. Кстати, питание подается на плату через разъем питания IDE HDD, но есть и место для L7805, в качестве альтернативы.


Лучше один раз увидеть, чем 0x100 раз услышать. Именно поэтому я  нарисовал принципиальную схему:


(кликабельно). Может пригодиться тем, кто занимается постгарантийным ремонтом изделия собственными силами, но учтите: я мог запросто ошибиться. Если найдете ляп - умоляю, черкните комментарий.

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





А как насчет попрбовать использовать LDog с ArduinoIDE?

Для начала отредактируем файл boards.txt и добавим секцию LDog, созданную на основе Arduino NG or older w/ Atmega8. Меняем тактовую частоту и скорость, на которой bootloader принимает скетч. Измените 16000000L на 8000000L, а 19200 на 9600 или скачайте готовый файл. Не забудьте перезапустить ArduinoIDE, чтобы изменения вступили в силу.

Если содержимое памяти ATmega8 надо сохранить, самое время сделать это (вариант для программатора usbasp):

avrdude -C avrdude.conf -c usbasp -p m8 -U flash:r:ldog.hex:i



Для справки, значения fuses: LFUSE=0xff, HFUSE=0xd9.

Вот теперь можно смело зашивать bootloader через ArduinoIDE. После успешного завершения этой операции мы получили ArduinoCompatible-плату, и можем загружать в нее скетчи.

Итак, с точки зрения Arduino, у нас есть:
  • 3 универсальных цифровых пина: digital 11,12,13;
  • выход digital8 со светодиодом. Обратите внимание, что он притянут к VCC -  "зажигайте" его по команде digitalWrite(8, LOW). Одно непринужденное движение паяльника и мы лишеамся светодиода, но получаем еще один универсальный пин
  • 2 входа: digital2 и digital3;
  • выход digital14 с оптронной развязкой;
  • выход digital15 c оптронной развязкой и хексфетом.
Для проверки загрузите пример Digital|Blink и исправьте в самом начале значение ledPin c 13 на 8. Через 10 секунд после загрузки светодиод  должен начать мигать.

И поскольку некоторое количество пинов утратило свою универсальность, можно заготовить скетч-шаблон для LDog:

void setup() {
  pinMode(14, OUTPUT);
  pinMode(15, OUTPUT);
}

Подведем краткие итоги: устройство создано в России, в 2006 году, является закрытой коммерческой разработкой. Приобрести его можно и по сей день, за 1000 рублей (правда, сразу партией в 10 штук). Совместимость с Arduino кажется забавным и одновременно практичным фактом, позволяющим превратить LDog в то устройство, которое подскажет ваша фантазия (в пределах 8К flash, разумеется ;)

В статье использованы материалы сайтов liscom.ru, watchdogs.ru и фото из статьи журнала "Новости Электроники".

26.01.2010

Нанопаяльник

Недавно у меня случилось горе неудача: мой паяльник с регулировкой температуры CT-Brand CT-95A приказал долго жить: иными словами, прекратил регулировать температуру, постоянно нагреваясь, раскаляясь и обжигая мою руку.

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

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

На работе у нас стоит Weller WD2, двухканальный:



Он оснащен термопинцетом, которым не только выпаивают, но и паяют:



У этого инструмента есть замечательная особенность: при укладывании на подставочку, в которую встроен магнитик, срабатывает размещенный в корпусе геркон, после чего нагрев сразу прекращается. Разогрев до прежней температуры происходит за 5-7 секунд, что зверски удобно. Как заметил мой хороший знакомый: "Weller - Мерседес в мире паяльников".

Плохая новость состоит в том, что стоит это счастье около 200 Евро - но только блок питания, без паяльника! Загрустив, я решил поискать что-то подешевле.

И это оказалось самым мучительным занятием.

Есть много разных CT, Luckey, CT-Brand. Чуть выделяется Solomon, но станция этой фирмы у нас на работе тоже есть, и с Weller ее не сравнить. Потом я перебрал Quick, АйОй ;) и прочие шедевры китайской инженерной мысли, не уставая удивляться, как они местами совершенно беззастенчиво копируют дизайн друг у друга. Цена на более-менее приемлемую по качеству и  функционалу станцию была около 4000 рублей, но сколько она прослужит? Вопрос не в том, насколько красиво она снаружи выглядит, а во внутренностях, не говоря уже об удобстве и надежности. А как это проверить в магазине? Я живу хоть и в провинциальном, но достаточно большом городе, где есть возможность "пощупать живьем", однако разбирать паяльную станци уж точно ни один продавец не позволит. Следовательно, снова приходим к вопросу о чем-то качественном: немецкого или японского изготовления.

В отчаянье я посетил сайт Ersa и покрутил картинки от их последней модели массового потребления I-Con Nano. Посмаковав подробности, я практически тут же забыл про нее - это было тоже дороговато: она стоила столько же, сколько и Weller WD1, правда за эти деньги к ней прилагался паяльник.

Вскоре, при очередном посещении одного из своих дилеров, я в завершение беседы обмолвился, что мне нужен хороший инструмент для пайки. В ответ я услышал стандартный вопрос "а какая конкретно модель вам нужна?". И тут я вспомнил про перламутровые пуговицы Nano - все равно на сайте  Ersa.ru было написано, что эта модель появится в продаже только в феврале 2010 года. Но... неким волшебным образом она оказалась на складе и была немедленно вручена мне на просмотр. Опуская подрбности, скажу - я взял только третью, первые две пришлось забраковать - виной треснутое пластиковое прижимное колечко паяльника i-tool nano (а вы думали, что раз вещь сделана в Германии, то она не может дойти до России с дефектом? увы, это горькая правда!). В итоге, я стал счастливым обладателем Lötstation №441:



При весе всего в килограмм, эта станция кажется совсем крохотной (видимо этим объясняется nano в названии), но умеет "разгоняться" до максимальной температуры на 9 секунд, при максимальном нагреве 450 C и мощности 68 Вт.

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



Сам силикон достаточно термостойкий, но если на полной мощности промахнуться жалом мимо отверстия, небольшая точка все-таки остается.

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



Сам паяльник напоминает авторучку, длиной около 16 см, довольно легкий. Чуть выпуклой анатомической формы, он идеально сбалансирован и прочно сидит в руке, как хорошее оружие или фирменное письменное перо. Могу сказать одно - при укладывании его на подставку испытываешь легкое сожаление.



Жало в комплекте - это 0102CDLF16, имеет форму "лопатка" и выглядит приблизительно так (на чертеже размеры 0102CDLF20, которое шире на 0,4 мм):



Любое другое жало - под заказ. Стоит 25 USD, заказ обрабатывается 2-3 недели. Не сочувствуйте, я знал, на что шел ;) Правда, в каталоге есть и конусы, и "волна", и "клюв"... глаза просто разбегаются.



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

У меня весьма небольшой рабочий стол, поэтому размеры блока и его компоновка - просто идеальны:



145 х 80 х 103 мм.

Ну а вот так устроено днище - вверху сетевой провод, внизу - провод паяльника.



Теперь о функциях. Кроме вспоминания температуры нагрева после включения, есть калибровка, а также установка времени режима ожидания (0-60 минут). Если станция обнаруживает в течение заданного диапазона отсутствие значимых потерь энергии, она дает остыть паяльнику до 250 C и поддерживает уже эту температуру. Для выхода надо либо охладить жало на 5 градусов, либо нажать на одну из кнопок. Герконовый контакт термопинцета Weller ведет себя по-другому: взял в руку, а он уже и нагревается; пока несешь к месту пайки - уже и нагрелся. Процесс входа в ожидание делает Nano нечувствительным к охлаждению: немедленно выйти из него можно только нажав на кнопку (имеется ввиду тот интервал времени, пока он остывает до 250 С - это секунд 30).

Еще для этого паяльника есть софт. Да, вы не ослышались! Его можно скачать на странице ersa.com/nano, общается он с паяльником через microSD-карту:



Как видите, можно задать не только время входа в режим ожидания, но и температуру остывания, а также время до отключения (по умолчанию, после входа в режим ожидания, через 10 минут неиспользования паяльник и вовсе выключится). Еще можно задать режим работы - по умолчанию температура изменяется свободно, но можно определить три фиксированных значения, которые быстро переключаются кнопками на лицевой панели. В дополнении можно еще и keylock включить - тогда кнопками вообще ничего нельзя будет поменять (защита от шутниковвредителей на производстве). Также можно выставить предельную мощность нагрева в виде энергетического уровня от 1 до 3: от него зависит скорость нагрева, а также ее точность. Если запаиваемые элементы чувствительны к перегреву, надо установить в единицу.

После выставления всех параметров нажимаете Write, они записываются в корень SD-карты в виде файла NANO.CFG. Карту с файлом надо вставить в станцию и подождать, пока она будет прочитана. Дальше можно ее смело изымать - параметры сохранятся в энергонезависимой памяти I-Con Nano.

Сколько она мне прослужит - покажет время, но надеюсь больше гарантийного срока, который на нее определен аж в целых 12 месяцев ;)

25.01.2010

Уроки Wiring (3)

Урок 3. Из чего сделан скетч?

(продолжение, начало см. Урок 2. ArduinoIDE)

В предыдущем уроке мы даже толком не разобрали текст нашего скетча "Blink". Присмотримся к нему повнимательнее:

/*
  Blink
 
 Turns on an LED on for one second, then off for one second, repeatedly.
 
 The circuit:
 * LED connected from digital pin 13 to ground.
 
 * Note: On most Arduino boards, there is already an LED on the board
 connected to pin 13, so you don't need any extra components for this example.
 
 
 Created 1 June 2005
 By David Cuartielles
 
 http://arduino.cc/en/Tutorial/Blink
 
 based on an orginal by H. Barragan for the Wiring i/o board
 
 */

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

// The setup() method runs once, when the sketch starts

void setup()   {                
  // initialize the digital pin as an output:
  pinMode(ledPin, OUTPUT);     
}

// the loop() method runs over and over again,
// as long as the Arduino has power

void loop()                     
{
  digitalWrite(ledPin, HIGH);   // set the LED on
  delay(1000);                  // wait for a second
  digitalWrite(ledPin, LOW);    // set the LED off
  delay(1000);                  // wait for a second
}

Поспешу оговориться: если вы уже программировали на C/С++, разобраться не составит труда. Остальным придется потрудиться, но помните: язык создавался с оглядкой на дизайнеров (людей гуманитарного склада ума), что вынудило авторов сто раз думать о простоте и понятности, прежде чем вводить новый оператор в синтаксис.

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

Пока что запомните: если в строке встретилось два слеша //, то они, вместе со всеми символы правее, до конца этой строки компилятору глубоко безразличны. Если в комментарий надо превратить сразу несколько строк, то его начинают с  /* и заканчивают */.   Таким образом, вышеприведенный код для компилятора будет значительно проще и короче:

int ledPin =  13;

void setup()   {                
  pinMode(ledPin, OUTPUT);     
}

void loop()                     
{
  digitalWrite(ledPin, HIGH);   
  delay(1000);                  
  digitalWrite(ledPin, LOW);   
  delay(1000);                  
}


Кстати, комментирование применяют и для отладки, чтобы временно "выключить" фрагмент скетча. В ArduinoIDE для этого есть горячая клавиша Ctrl+/, которая позволяет быстро закомментировать или раскомментировать выделенный фрагмент текста.

Итак, первая строка скетча:

int ledPin =  13;

Это объявление переменной с именем ledPin. Компилятор забронирует в памяти микроконтроллера пару байт для хранения целого числа, позволяя вам начиная с этого места обращаться к нему по имени 'ledPin'. Заодно он присвоит ему начальное значение 13.

Следующая конструкция обязательно должна присутствовать в любом сектче:

void setup() {
}

Забегая вперед - это определение функции. Однако, функция setup особенная: она исполняется один раз после старта скетча (по включению питания Arduino или после сброса). Туда можно смело вынести все действия, которые должны выполниться один раз, например - настройка скорости последовательного порта или выбор режима работы универсальных пинов (на ввод или на вывод). Все эти действия должны быть вписаны между открывающей и закрывающей фигурными скобками { }.

И, кстати, сейчас там только одна строчка:

pinMode(ledPin, OUTPUT);

Оператор языка Wiring 'pinMode' устанавливает для одного из указанных пинов режим ввода или вывода. В данном случае номер пина берется из переменной ledPin (напоминаю, что там было число 13, а следовательно - речь про digital13, к которому подключен тестовый светодиод L), режим задается константой OUTPUT, что логически подготавливает нас к тому, что через этот пин будет что-то выводиться.

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

void loop() {
}

Функция loop также должна быть в любом скетче - она вызывается сразу после завершения setup, а потом снова и снова... до бесконечности. Может быть, это покажется вам немного странным, но в применении к микроконтроллерам вообще и к Ардуино в частности, встречается довольно часто: надо постоянно опрашивать кнопки и датчики, давать команды на моторы или реле, выводить данные на дисплей. Собственно, именно поэтому однократно исполняемые действия и вынесены в setup - если что-то надо сделать один раз, сделайте именно в ней.

Разберем, из чего состоит тело loop:

digitalWrite(ledPin, HIGH);

Это еще один оператор языка Wiring, который переключает состояние пина в одно из двух возможных. HIGH соответствует логической единице (она же - напряжение питания микроконтроллера, для Duemilanova это +5 Вольт), LOW - логическому нулю, это меньше +0,5 В.

Светодиод L подключен в Arduino следующим образом:



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

Итак, оператор digitalWrite(ledPin, HIGH) формирует +5В на выходе 13 и зажигает таким образом светодиод L.

delay(1000);

Эта команда delay заставляет микроконтроллер остановиться и ничего не делать целую 1000 миллисекунд - безумно много! Кстати, 1000 мс = 1 с ;)

digitalWrite(ledPin, LOW);

Этой командой светодиод отключается (см. выше).
Дальше снова происходит задержка в одну секунду.
А потом... тело loop заканчивается, но поскольку он вызывается беспрерывно, то управление снова переходит на начало - исполняется digitalWrite(ledPin, HIGH), и так далее.

Визуально можно представить так:



Если бы у нас под руками был специальный прибор осциллограф, то подключив его к digital13 мы увидели бы примерно такую картину:



Говоря строгим языком, мы добились на этом выходе колебаний с частотой 0,5 Гц ( 1 Гц  соответствует одному полному колебанию в секунду). Меняя две величины задержки в delay, можно добиваться другой частоты мигания, а если они начать менять их отношение, то изменится скважность сигнала (сейчас мы получили то, что обычно называют меандр).

Но чтобы пользоваться Arduino все это знать необязательно. Все мигает, как и задумано, не так ли? ;)

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

В следующем уроке мы подробнее разберем основные конструкции языка Wiring.

21.01.2010

Arduino и Android

Сегодня наткнулся на проект Arduino+Android: www.amarino-toolkit.net.




Состоит из приложения Amarino для Android и библиотеки MeetAndroid, которую надо подключать к скетчу в Arduino. Пока предполагается, что связь будет устанавливаться с ArduinoBT или с обычным Arduino через bluetooth-шилд, поэтому сами понимаете, насколько сужается диапазон применения проекта.

Общий смысл - унификация взаимодействия с подключаемыми к Arduino схемами. В приложении Amarino надо задать события и получаемые от скетча сообщения. В самом скетче надо унаследоваться от класса MeetAndroid ( в свою очередь, он унаследован от класса Print и немного расширяет его функции, работая через Serial ). Дальше пишите callback-функцию опроса устройства и регистрируете ее в экземпляре MeetAndroid. Это дает возможность Amarino асинхронно дергатьопрашивать через Arduino схему и получать данные (в основном, числа). Например:

#include <meetandroid.h>

// you can define your own error function to catch messages
// where not fuction has been attached for

MeetAndroid meetAndroid(error);

void error(uint8_t flag, uint8_t values){
  Serial.print("ERROR: ");
  Serial.print(flag);
}

int onboardLed = 13;

void setup()  
{
  // use the baud rate your bluetooth module is configured to 
  // not all baud rates are working well, i.e. ATMEGA168 works best with 57600
  Serial.begin(57600); 

  // register callback functions, which will be called when an associated event occurs.
  // - the first parameter is the name of your function (see below)
  // - match the second parameter ('A', 'B', 'a', etc...) with the flag on your Android application
  meetAndroid.registerFunction(compass, 'F');  
  pinMode(onboardLed, OUTPUT);
  digitalWrite(onboardLed, HIGH);
}


void loop() 
{
  meetAndroid.receive(); // you need to keep this in your loop() to receive events
}


/*
 * This method is called constantly.
 * Compass events are sent several times a second.
 *
 * note: flag is in this case 'F' and numOfValues is 1 
 * since compass event sends exactly one single int value for heading
 */

void compass(byte flag, byte numOfValues)
{
  // we use getInt(), since we know only data between 0 and 360 will be sent
  int heading = meetAndroid.getInt(); 
  flushLed(heading); // silly, you should have better ideas
}

void flushLed(int time)
{
  digitalWrite(onboardLed, LOW);
  delay(time);
  digitalWrite(onboardLed, HIGH);
}


Здесь определяется функция compass, которая получает от Android целое число и зажигает светодиод L на соответствующее ему число миллисекунд.

Можно также отправлять непрерывные потоки данных - видимо, для построения графиков.

Проект находится в зачаточном состоянии, поддерживает 1.5 и 1.6 версии платформы Android, а вот 2.0 - нет, но она на подходе. Все исходники, естественно, доступны. Думаю, порадует фанов Arduino и Android - я пока что гуглофоном не обзавелся, увы :( А пока - пожелаю ему всяческих успехов!

20.01.2010

Уроки Wiring (2)

Урок 2. ArduinoIDE

(продолжение, начало см. Урок 1. Что внутри Arduino?)

Чтобы программировать, нам потребуется ArduinoIDE. Хорошая новость состоит в том, что она абсолютно бесплатная, с открытым исходным кодом. Отправляемся на страницу http://arduino.cc/en/Main/Software и выбираем самую-самую последнюю версию под нужную операционную систему. На момент написания статьи это была сборка 0017, официально поддерживались Windows, MacOS и Linux, энтузиасты сделали пакеты для OpenSolaris.

Для Windows архив занимает чуть больше 80 Мбайт, зато там есть всё необходиме, в том числе драйвера.

Итак, что делает программист, получая в распоряжение свежехакнутуюустановленную IDE? Первым делом - пишет программу HelloWorld, которая только и делает, что выдает на экран "Hello, world!". Зато, после этого можно расслабиться: две трети дела сделано - осталось всего лишь написать программный продукт, который потрясет мир.

Итак, распаковываем arduino-0017.zip в какую-либо папку (в этом поможет свободный PeaZip). Инсталляция не требуется, поэтому просто запускаем из этой папки arduino.exe (можете набраться храбрости и сделать ярлык на рабочем столе ;).

После запуска мы увидим что-то наподобие этого:



Вверху привычно маячит строка меню, ниже - спартанский тулбар для вызова наиболее частых операций; белое поле - собственно область редактора, где надо писать программу (в терминах Ардуино - "набросок" или sketch). Черное поле - информационный экран для выдачи ругани диагностических сообщений ArduinoIDE.

Пусть в качестве "Hello World" наша Duemilanova помигает своим тестовым светодиодом L. Создатели дистрибутива заботливо разместили необходимый нам скетч в секции примеров, остается только загрузить:



Самое время подключить Arduino к нашему компьютеру с помощью кабеля USB A-B. Если все верно, загорится светодиод PWR, а остальные слегка мигнут. Дотошные могут понажимать на кнопку сброса и посмотреть, как светодиод L вспыхивает при каждом нажатии. Если он будет вспыхивать и без нажатия - не пугайтесь, именно так и происходит, когда в Arduino еще не загружено ни одной рабочей программы.

Единственный момент - надо утрясти вопрос с драйверами. Обычно, после подключения последовательно обнаруживаются два устройства: FT232R USB UART и USB Serial Port:





Устанавливать надо, естественно, оба устройства. В ответ на удивленные возгласы Windows надо послать ее за драйверами в каталог:

arduino-0017\drivers\FTDI USB Drivers

В итоге вы должны добраться до такой страницы:



Если это произошло, то теперь при подключении Arduino в диспетчере устройств будет появляться еще один COM-порт. Если у вас их много, то надо зайти в

Панель управления -> Система -> Оборудование -> Диспетчер устройств

...и поискать USB Serial Port (не отключайте Arduino!). При желании его можно здесь же изменить (Свойства | Port Settings | Advanced Settings):





ОК, номер порта выяснили, теперь возвращаемся обратно в ArduinoIDE и сообщаем ей об этом  через меню Tools | Serial Port:



Затем, чтобы компилятор правильно оттранслировал скетч в исполняемый код, надо установить тип платы и микроконтроллера. Внимательно прочитайте название микроконтроллера на своей плате Ардуино, затем выберите свой вариант в меню Tools | Board:



Если вы на этом шаге перепутаете тип микроконтроллера, то скетч просто не загрузится в Arduino после компиляции. А вот если вы спутаете тип платы, возможен легкий курьез - скетч будет работать либо в два раза быстрее, либо в два раза медленнее, чем задумано ;) Для простоты, будем предполагать, что у нас Duemilanova с ATmega328, так как именно этот вариант наиболее распространен. Если у вас на чипе написано ATmega168-20PU или ATmega8-16PU, можете купить ATmega328P на замену (никаких переделок в схеме - вынули старый, поставили новый). Таким образом, памяти под скетч станет гораздо больше.

Все готово, теперь выбираем меню Upload to I/O Board или нажимаем кнопку Ctrl+U:





Ждем. Произойдет следующее:
  • скетч будет скомпилирован (сначала преобразован из Wiring в язык C, потом в объектный код и наконец в загрузочный файл);
  • ArduinoIDE сбросит плату, что приведет к остановке работающего в настоящий момент скетча и старту специальной микропрограммы-bootloader-а;
  • Загрузочный файл будет передан в Arduino (мигают светодиоды L, Rx - чуть ярче, Tx - чуть слабее);
  • Память Arduino будет прочитана и произойдет сравнение с исходным файлом - верификация (мигают светодиоды L, Rx - чуть слабее, Tx - чуть ярче);
  • Bootloader нехотя передаст управление скетчу.
Итак, если все верно, светодиод L начнет мигать, приветствуя мир и сообщая о том, что наш первый скетч заработал:




Что дальше? В следующем уроке мы разберем скетч "Blink" более подробно.

17.01.2010

Простое повышение точности АЦП Arduino

Несколько слов в продолжение рассуждений о точности АЦП (см. предыдущую статью про измерение температуры). На эту тему написан не один десяток хороших книг, поэтому выделим основную проблему: для АЦП Arduino измерение идет относительно так называемого источника эталонного напряжения (который иногда называют ИОН - источник опорного напряжения).

Выбор этого источника происходит при вызове функции analogReference(type), где type может принимать одно из трех значений:
  • DEFAULT: напряжение питания, около 5 Вольт (по умолчанию, после старта скетча);
  • INTERNAL: встроенный ИОН - 1.1 Вольт для ATmega168 и 2.56 Вольт для ATmega8;
  • EXTERNAL: напряжение на пине AREF.
Я не случайно написал "около 5 Вольт", потому что в действительности питание шины USB составляет 4,40 .. 5,25 В, а стабилизатора L7805 - 4,65 .. 5,35 В. Простой математический подсчет показывает, что диапазон 0,7 В "выливается" в 14% от ожидаемых 5.00 Вольт. А теперь обратите внимание, что один шаг нашего 10-битного АЦП составляет 5.00/1024 = 0,0048828, и 0,7 Вольт в пересчете analogRead составит 143 единицы.

Это подводит нас к грустному, но неотвратимому выводу - точность лучше одного вольта при использовании DEFAULT нам заказана. Может быть, нам поможет INTERNAL?

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

Надо каким-то образом подать внешнее опорное напряжение на наш АЦП, да поточнее (это вариант EXTERNAL). В этом нам могут помочь:

  • Точный резистор: если поискать, то можно найти с погрешностью 1%,  0,1% и даже 0,01%. Есть и лучше, но это уже крутая экзотика. Из закона Ома известно, что падение напряжения на резисторе равно произведению тока на сопротивление. ОК, сопротивление-то повышенной точности, но как зафиксировать ток? Вероятно, потребуется генератор тока - это небольшая схема на операционном усилителе.
  • Диод: проводя ток в прямом направлении, он попутно "съедает" вполне фиксированное напряжение. Диод ведет себя не так, как резистор - для него закон Ома не писан, но зависимость от тока все-таки есть: достаточно взглянуть на графики вольт-амперной характеристики Vf(If) в документации.
  • Стабилитрон: это модификация диода (синоним "диод Зенера" :), который изначально предназначен для стабилизации напряжения. В простых схемах, не критичных к потерям энергии, его допустимо использовать с оглядкой на мощность. К сожалению, под рукой обычно оказываются только стандартные BX55C или BX79C, а у них погрешность 5%.
Тем не менее, вот простейшая схема стабилизатора питания +5В на стабилитроне (использована в Arduino minimum):

Более продвинутый вариант стабилитрона - это микросхема LM385-1.2, которая работает подобно стабилитрону, но обеспечивает падение напряжения 1.235 Вольта с точностью 1-2% (чем меньше ток, тем выше точность). Используются они практически повсеместно, выпускаются в корпусе SO и TO-92:




Если подключить LM385 к AREF, то получится, что мы сузим диапазон измерений от 0 до 1.235 Вольт, что не всегда удобно. В этом случае надо либо искать похожий чип на другое напряжение, либо, пожертвовав одним аналоговым пином, оставить схему DEFAULT:



Этот прием я использовал в схеме SMPReaderUSB, для измерения напряжения внутренней литиевой батареи модуля МПО-10. Резистор R9 22К выбран с таким расчетом, чтобы через LM385 протекал небольшой ток, как и положено по его документации. Измеряемый вход BATT притянут через R10 22K к земле на тот случай, если модуль не подключен и вход ADC0 повис в воздухе.

Далее, происходит считывание с двух аналоговых пинов - к одному подключен измеряемый источник напряжения BATT (ADCm), к другому - LM385 (ADC385). Оба значения передаются в хост-программу на PC, которая вычисляет пропорцию:

 Um = ADCm * 1,235 / ADC385

Значение опорного напряжения в этой формуле не участвует, и хотя зависимость по-прежнему есть, выведя это значение из формулы мы понизили его влияние на пару порядков (речь про ошибку квантования). Такой способ позволяет улучшить точность до 0,03 В, что - согласитесь - для Arduino весьма неплохо!

(в статье использованы материалы из руководства по языку Arduino)

16.01.2010

ЛУТ: какой утюг лучше? (2)

Возвращаясь к вопросу об утюгах.




При помощи совершенно случайно попавшего в мои руки датчика Pt100 и трансдьюсера PD-11T производства польской фирмы LUMEL, мне таки удалось измерить температуру обоих утюгов в режиме максимального нагревания.

Итак, "маломощный" Braun на 1900 Вт выдает нагрев около 173 градусов по шкале цельсия, а вот его китайский noname собрат на 2200 Вт - всего 159.

И хотя точность этих абсолютных величин, увы, мне неизвестна, но разница в 10-15 градусов весьма реальна и дает ощутимый эффект, о котором я писал - отпечатки на 173 градусах гораздо устойчивее к смыванию ацетоном и механическим воздействиям.

10.01.2010

Sanguino Pro

Название: Sanguino Pro
Процессор: ATmega644P-20AU
Тактовая частота: 16 МГц
Совместимость с Shield-платами: нет
Совместимость с Arduino IDE: да (надо пропатчить, переписав некоторые файлы)
Веб-сайт проекта: http://www.dh-global.com/index.php?option=com_content&view=article&id=10&Itemid=11.
Дата первого упоминания: 03.01.2010

Проект Sanguino появился гораздо раньше, чем Arduino Mega, в попытке преодолеть ограничение на предельный размер скомпилированного скетча. Очень приятно узнать, что он до сих пор жив и радует нас новыми модификациями (кстати, сейчас Sanguino совместим с последней ArduinoIDE 0017).

На этот раз - Sanguino Pro:


Идею развила и закрепила D&H Global Enterprise, согласно CC-SA указавшую на шелкографии имя разработчика оригинальной платы: Zach Hoeken.

Как и оригинальные Arduino Pro, эти платы идут без COM/USB портов, а колодки пинов не напаяны. В результате есть возможность приспособить плату для своих потребностей, не переплачивая за ненужное. Остальные характеристики соответствуют процессору ATmega644P:
  • всего 32 универсальных пина
  • 8 аналоговых
  • 6 с поддержкой ШИМ / PWM
  • 64K Flash-памяти программ
  • 4K ОЗУ 
  • 2K EEPROM
  • 2 аппаратных UART
Sanguino Pro совместима по контактам с оригинальной Sanguino, поддерживая таким образом преемственность и совместимость со старыми проектами.



Первый раз вижу, чтобы документацию на плату выкладывали не только в формате Eagle, но также добавляли результат Gerber. Те, кто мечтает развернуть собственное производство печатных плат, получают отличный шанс разобраться в том, как всё оформляется на конкретном рабочем проекте: sanguinopro.zip.

Стоимость этой платы в интернет-магазине самого D&H Global Enterprise составляет 28 USD.

09.01.2010

Удвоение пинов Arduino (2)

Часть 2. Размножение входов или shiftIn

(окончание, начало см. Часть 1. Размножение выходов или shiftOut)

Представим себе обратную ситуацию – есть много входов (например, от датчиков контактного типа или, попросту говоря - кнопок), которые надо считывать. И если универсальные пины Arduino легким движением руки при помощи оператора pinMode() превращаются в брюки во входы или выходы, то время вспомнить, что за такую универсальность приходится расплачиваться довольно сложной схемой пина, в которой, на самом-то деле, входная и выходная части отделены друг от друга.

Для рассмотренной в предыдущей части микросхемы 74HC595 существует "брат-близнец" 74HC597 - Serial-out Shift register w/Latches, который работает с точностью до наоборот: по команде "защелкивает" данные на входе, которые затем можно считать последовательно:



Работать с такой микросхемой надо аналогичным образом, учитывая назначение выводов:

  • D0-D7 - параллельные входы;
  • Ds - последовательный вход от предыдущего чипа (для каскадирования);
  • Q - последовательный выход;
  • MR - инверсный сигнал сброса (активен в LOW);
  • SHCP - синхронизация регистра
  • STCP - синхронизация защелки
  • PL - инверсный сигнал записи с параллельных входов (активен в LOW).
Схема:

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

Кстати, защелка по входу в нашем применении не нужна, можно использовать чип и без оной. Рассмотрим CD4021B, восьмибитный регистр с последовательным или параллельным входом и последовательным выходом:



PI-# - в данном случае расшифровывается как Parallel In, всего восемь входов.

CLOCK - вход тактовых импульсов, которые должен генерировать микроконтроллер, при каждом происходит сдвиг на один разряд.

PARALLEL/SERIAL CONTROL - официально управляет режимом по входу - единица соответствует параллельному входу, ноль - последовательному. На практике получается чуть интереснее: пока режим параллельный - по каждому фронту CLOCK происходит обновление состояния всех восьми бит регистра. Если мы хотим "зафиксировать" состояние всех восьми выводов в определенный момент времени, надо дать один CLOCK в параллельном режиме, а потом перейти в последовательный - и прочесть 8 бит - при этом счетчик заполнится тем, что поступит со входа SERIAL IN, а Arduino к этому моменту получит все 8 бит информации, записанной в режиме параллельного ввода. Поэтому, иногда этот вход на схемах маркируют как latch - по смыслу того, что он делает.

Q6, Q7, Q8 - это выходы соответствующих разрядов последовательного счетчика, для использования всех восьми разрядов надо считывать данные с Q8.

Вообще, серия 4000В - не очень скоростная (соответствует нашей 1561), максимальное быстродействие 90 нс. Учтите, что мы-то ее будем использовать не на предельном питании +15 В, так что готовьтесь к 160...320 нс, тактировать её можно с частотой 3..6 МГц. Немного, но для считывания, например, механических контактных групп - вполне подойдет.

Схема будет выглядеть очень похожим образом:



Номинал резисторов на этой схеме - 10К, смысл академический - нельзя "бросать" вход КМОП-схемы в плавающем состоянии, на нем должен быть устойчивый потенциал.

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

#define DATA  9
#define LATCH 8
#define CLOCK 7

#define CLKUS 1 

byte dataInput; 

void setup() {
  pinMode(DATA,INPUT);
  pinMode(LATCH,OUTPUT);
  pinMode(CLOCK,OUTPUT);
  
  Serial.begin(9600);
}

void loop() {
  
  dataInput = 0;
  digitalWrite(LATCH,HIGH); // Parallel mode

  for (int i=7; i>=0; i--) {
   digitalWrite(CLOCK,HIGH); 
   delayMicroseconds(CLKUS);
   dataInput |= (digitalRead(DATA) ? (1<<i) : 0);
   digitalWrite(CLOCK,LOW);    
   delayMicroseconds(CLKUS);
   if (i==7) digitalWrite(LATCH,LOW); // Serial Mode
  }
  
  Serial.println(dataInput, BIN);
  delay(1000);
}

В основном теле loop() раз в секунду происходит считывание всех кнопок путем кратковременной подачи высокого уровня на пин LATCH. Дальше в цикле формируется восемь перепадов CLOCK и данные запишутся в соответствующие разряды переменной dataInput, после чего будут в двоичном формате выведены в последовательный порт (наблюдайте результаты в мониторе последовательного порта). Задержки умышленно даны с запасом, если есть желание - попробуйте их уменьшить до предела по документации.

Прием с каскадированием для повышения разрядности:



Скетч при этом почти не изменится:

#define DATA  9
#define LATCH 8
#define CLOCK 7

#define CLKUS 1 

word dataInput; 

void setup() {
  pinMode(DATA,INPUT);
  pinMode(LATCH,OUTPUT);
  pinMode(CLOCK,OUTPUT);
  
  Serial.begin(9600);
}

void loop() {
  
  dataInput = 0;
  digitalWrite(LATCH,HIGH); // Parallel mode

  for (int i=15; i>=0; i--) {
   digitalWrite(CLOCK,HIGH); 
   delayMicroseconds(CLKUS);
   dataInput |= (digitalRead(DATA) ? (1<<i) : 0);
   digitalWrite(CLOCK,LOW);    
   delayMicroseconds(CLKUS);
   if (i==15) digitalWrite(LATCH,LOW); // Serial Mode
  }
  
  Serial.println(dataInput, BIN);
  delay(1000);
}


Разрядность переменной, в которую читается состояние увеличилась в два раза - с 8 до 16 бит, чтение выполняется за 16 тактов. В остальном - тоже самое.

Часто бывает так, что импортный чип достать сложнее, зато наш (советский или белорусский) валяется без дела, да так и просится в схему. Мне в свое время сильно помог К561ИР9 (функциональный аналог CD4035B):



RESET - сброс всех разрядов в ноль в произвольный момент времени.

PI1..PI4 - параллельные входы, как в CD4021.

Q1..Q4 - это параллельные выходы, как в 74HC595 (см. часть 1)

J/K - это последовательный вход. Замечу, что он выполнен в виде J/K триггера, и если J и К соединить, то получится D-триггер, как в CD4021.

P/S - управление режимом ввода, как в CD4021. По логической единице будут записаны данные с параллельных входов, по нулю - с последовательного входа J/K.

T/C - прямой/дополнение (true/complement). Микросхема универсальна до такой степени, что умеет менять знак у выводимого кода (т.е. выдавать не само число, а дополнение к нему). Нам это навряд ли понадобится, поэтому притянем этот вход к Vcc - это вечный true.

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



Можно использовать скетчи от предыдущих примеров практически без изменений:
  • в режиме ввода считывать данные последовательным кодом с digital9
  • в режиме вывода подавать последовательный код через digital10.
В последнем случае, увы, комбинация на выходах Q1..Q3 будут сдвигаться. А если бы не этот недостаток, то при наличии защелки на выходе получился бы идеальный вариант - универсальная схема, которая поможет расширить и входы, и выходы!

Время взвешивать за и против.

Плюсы Arduino / Seeeduino Mega: компактность, гибкость, быстродействие, попутно получаем 128К  памяти программ.

Плюсы логических микросхем: цена решения, на надо платить за лишнее/неиспользуемое, нагрузочная способность линии, доступность.

Казалось бы, на этом можно ставить точку, но... спустя какое-то время появилась и третья статья про увеличение числа пинов Arduino.

(в тексте использованы материалы статьи Parallel to Serial Shifting-In with a CD4021BE).

Обновленный сайт Arduino

Зашел в очередной раз на arduino.cc и увидел магическую надпись:


YOU ARE ACCESSING AN OLD VERSION OF THE ARDUINO SERVER, PLEASE READ THIS NOTE FOR DETAILS


Далее разъясняется, что это "старый сервер", и вы сюда попали потому, что еще не прошло обновление DNS.

Готовьтесь к изменениям! ;)

UPD: мигрировали под CentOS 5.4. Уж не знаю, чем оно им поможет, но нагрузка на этот сайт немаленькая, это точно!