31.05.2011

Индикатор уровня на Arduino и LoL-shield

Если вы уже знакомы с LoL-shield - до этой идеи просто невозможно не додуматься. Сначала она была озвучена мне Юрием Соловьевым, а затем показана в реализации Andy Doro.

Итак, аудио-сигнал поступает с выхода проигрывающего устройства (плеер, телефон или даже выход звуковой карты на компе) и подается на аналоговый вход Arduino / Freeduino. Далее, он оцифровывается и выводится в виде гистограммки на LoL-Shield.

Библиотека LoL-Shield имеет  базовую функцию, которая позволяет зажигать и гасить один светодиод прямым заданием координат, так что здесь все просто.

А вот для преобразования аналоговых отсчетов в спектрограмму можно воспользоваться классическим алгоритмом БПФ (быстрого преобразования Фурье, или FFT - Fast Fourier transform), для которого тоже существует библиотека. Правда, она до сих пор жила в треде форума, но кто его знает - может быть к моменту прочтения этой статьи она уже будет в составе ArduinoIDE.

Берем стандартный 3,5мм аудио-разъем (обрабатывать будем только один канал, так что можно и монофонический) и подключаем центр к свободному analog5, а землю к GND - все эти линии очень удачно выведены на LoL-Shield.



Теперь надо написать скетч, как я уже говорил - понадобится две библиотеки:
Для установки надо распаковать их в каталог sketchbook/libraries и перезапустить ArduinoIDE.

Библиотека FFT разбивает аудио-диапазон на 64 спектральные полосы, поэтому нам надо как-то трансформировать это в 14 столбцов и 9 уровней по размеру матрицы LoL-Sheild. В целом это выглядит приблизительно так:

/*
FFT for LoL Shield v0.9
by Andy Doro
http://andydoro.com/

based on FFT library and code from the Arduino forums and
the Charlieplexing library for the LoL Shield.
*/

#include <Charliplexing.h>
#include <fix_fft.h>

#define AUDIOPIN 5

char im[128], data[128];
char data_avgs[14];
int i=0,val;

void setup() {
  LedSign::Init();            //Инициализировать LoL-Shield
}

void loop() {

  for (i=0; i < 128; i++){                                     
    val = analogRead(AUDIOPIN);                                    
    data[i] = val;                                       
    im[i] = 0;                                                     
  };

  fix_fft(data,im,7,0);

  for (i=0; i< 64;i++){                                      
    data[i] = sqrt(data[i] * data[i] + im[i] * im[i]);  // получаем абсолютное значение от значения из массива, дальше имеем дело только с положительными числами
  };     
  
  for (i=0; i<14; i++) {
    data_avgs[i] = data[i*4] + data[i*4 + 1] + data[i*4 + 2] + data[i*4 + 3]; // усредняем соседние значения
    data_avgs[i] = map(data_avgs[i], 0, 30, 0, 9); // масштабируем значения под LoL
  }
 
  // вывод в LoLShield
  
  for (int x=0; x < 14; x++) {
   for (int y=0; y < 9; y++) {
     if (y < data_avgs[13-x]) { // 13-x меняет порядок строк так, чтобы частоты от низких к высоким показывались слева направо.
       LedSign::Set(x,y,1);        // set the LED on
     } else {
       LedSign::Set(x,y,0);       // set the LED off
     }
   } 
  }
}


На мой вкус, обновлять гистограмму уровней можно было бы чуть реже, уж больно мельтишит. Но тут, как говорится, дело вкуса:



Скачать скетч и библиотеки одним архивом:

При подготовке статьи использованы материалы c сайтов forum.arduino.cc, jimmieprodgers.com, instructables.com.

20.05.2011

Новости Arduinoстроения

В комментах к статье о Freeduino One пользователь Сергей справедливо обращает внимание на лишние элементы в схемах тактирования, добавленные в Uno и Mega 2560:


Речь про R1 1М и R3 27Ом. Дело в том, что согласно родному ATMEL-овскому даташиту "AVR042: AVR Hardware Design Considerations", эти элементы и так уже есть внутри МК, причем R3 нужен для отдельно взятого случая - если используется резонатор 32758 кГц:



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

Замечу, что именно начиная с Arduino Uno был применен ATmega8u2 и миниатюрный керамический резонатор 16МГц - раньше такого у итальянцев не было (только в Nano v.3, но ее выпускала американская Gravitech).

Что же в итоге? Один из побочных эффектов такого решения - надежное, но зато несколько замедленное возбуждение резонатора после подачи питания, что для домашних Arduino-поделок вроде как вполне приемлемо. Я вот, например, вообще не заметил никаких побочных эффектов - Freeduino ONE работает безупречно.

Но, как говорится, время шло. Вслед за появлением знаменитой Arduino UNO на ATmega328 в DIP, появилась версия на SMD:


Объяснили это очень просто: производство ATMEL не справляется, возник дефицит чипов в DIP-корпусе. Охотно верю - в России SMD-версию достать проще и дешевле. Но если уж на то пошло - в корпусе TQFP32 ножек больше, и появляется целых два лишних входа (digital I/O или АЦП), что является просто находкой для тех, кому надо иметь чуть больше пинов и из-за этого приходится использовать MEGA. Но, увы - идея вывести их на какие-нибудь дополнительные контактные площадки или дырки авторов не посетила :(

Спустя некоторое время появилась и вторая версия Arduino UNO, схему в PDF можно скачать на все той же страничке.

Что изменилось в UNO rev.2

  • теперь уже окончательно керамический резонатор закреплен за основным МК, а нормальный кварц - за ATmega8U2 (альтернативных посадочных мест для вариантов нет);
  • токоограничительный резистор 27 Ом в схеме тактирования - убрали! Зато параллельный 1М - оставили. Видимо, эксперименты продолжаются;
  • линия сброса DTR притянута к земле резистором 1K, который "оторвали" от светодиода L (там было два и один явно лишний - поскольку он является частью микросборки из четырех штук - авторы просто решили пристроить его к делу ;) Получился как бы классический фильтр высоких частот, и смысл этого решения человечеству еще предстоит осознать ;) 
  • четыре ранее неиспользованных вывода ATmega8u2 - PB7, PB6, PB5 и PB4 выведены под вилку 2x2, что-то мне это напомнило о пропавшей X3 для bitbang-а - возможно, скоро нас ждет новая прошивка, которая будет уметь изображать что-то подобное;
  • операционный усилитель LM358 теперь может быть установлен не только в классическом корпусе SO-8, но и в SSOP - миниатюризация продолжается!
Изменения коснулись и EthernetSD shield, появилась rev.06 - и одно изменение там, прямо скажем - революционное: плата подготавливается к поддержке PoE (стандарт IEEE 802.3af). Это такая технология, которая позволяет дистанционно питать устройство по линии Ethernet, для чего в природе существуют специальные PoE-инжекторы и "питающие" коммутаторы. Поддержка требуется также и на стороне самого устройства - для Ethernet Shield это будет специальный PoE-модуль, отделяющий питающее напряжение (+48В DC) от сигнала витой пары перед тем, как подать его на интерфейсную микросхему W5100. 



Arduino с таким шилдом и модулем PoE может питаться дистанционно - теоретически, можно отдалиться по кабелю от источника до 100 метров. Сразу оговорюсь - это решение промышленное (используем по работе в своих аппаратных решениях с 2001 года). Кроме того, Ethernet-shield на чипе W5100 с PoE давно уже существует - разработан компанией Freetronics.


Всё остальное - мелкие изменения:

  • микросхема-сборка триггеров Шмидта в схеме сброса W5100 заменена на один маленький триггер в корпусе SOT23-5 - логично, занимает меньше места, нет избыточности;
  • окончательно отказано в праве на монтаж полноразмерному SD-слоту - по сути, он всё это время просто занимал лишнее место; 
  • резистивные делители для коммуникации с SD-картой заменены на буферные микросхемы 74LVC1G125DBV, что тоже логично - работать они будут стабильнее, потреблять - меньше;
  • исключен из схемы светодиод COLL, который должен был показывать коллизии на интерфейсе Ethernet. В защиту такого решения говорит то, что зажигаться он может при подключении через хаб, но где теперь можно найти Ethernet-хаб?!
  • светодиод FULLD вынесен за пределы платы. То есть он как суслик из ДМБ - как бы есть, но на самом деле - его нет.
Последний пункт тем более загадочен тем, что на реальной плате на фото светодиода FULLD нет, а в CAD-файлах он "завис" ни к чему не подключенный. Да и сами brd-файлы с разводкой содержат две воздушные перемычки - недвусмысленный намек на незавершенность и наличие ошибок. В этой связи, конечно, напрашивается вопрос о том, не выйдет ли вскоре еще одна версия. Ну, поживем - увидим ;)

02.05.2011

Наш друг FTDI

Недавно озадачился наконец нормальной печатной платой на замену изотваливаемой раньше при помощи ЛУТ USB-TTL - потому что занятие это интересное и почетное, но все-таки не самое приятное, особенно когда надо повторять изготовление одного и того же. Хочется, наконец, простого человеческого тепла и уюта нормальной паяльной маски.

Я начал перебирать похожие варианты, и среди прочих мне понравился тот, что сотворила ladyada - называется FTDI Friend (как она шутит в блоге - "ftdi friend - это ваш друг, а не враг" ;) Вот так она выглядит:



Конечно, если требуется вытащить наружу все конвертированные сигналы RS-232, лучше брать стандартный модуль FTDI MR232R или Mini USB Adapter. Но в практике Arduino требуется-то как правило всего ничего - RX,TX и DTR. Общеизвестно также, что в забугорье более популярен т.н. FTDI-кабель: чип располагается внутри, а наружу торчат шесть проводков определенного цвета и предназначения. Выводы FTDI friend позиционно повторяют этот кабель, равно как и плата Diavolino.

Для Arduino больше ничего и не надо - разве что сигнал DTR для автосброса вместо RTS (по слухам, последние версии ArduinoIDE научились одинаково правильно работать и с DTR, и c RTS). Перевернем плату, с другой стороны нас ожидает сюрприз: 



Это стандартные перемычки под пайку, выбирающие следующие опции:
  • напряжение питания (Vcc), выдаваемое на гребенку наружу - 5 или 3,3 В (по умолчанию 5);
  • уровни сигналов TTL или, иными словами - напряжение логической единицы  +5В или +3,3В (в оригинале по умолчанию 3,3);
  • сигнал, выдаваемый на контакт RTS - это может быть как сам RTS (классика, по умолчанию), так и DTR (стандарт для Arduino). 
Устанавливать для логической единицы уровень +3,3В вполне допустимо для схем с питанием 5В, поскольку для КМОП-логики по входу единицей будет всё, что выше Vcc/2 (в данном случае 2.5В). Но, сами понимаете, в некоторых случаях это будет работать менее надежно (длинные линии и наводки). Поэтому, для своих плат я по умолчанию поставил перемычки в положение "пятивольтовые сигналы" и "вывести на pin 6 DTR".

Надо заметить, что FTDI friend может служить и bitbang-программатором, подробное руководство о том, как это сделать, можно прочитать у ladyada - здесь. Купить мой вариант можно тут

И, наконец, недавно наткнулся на развитие этого варианта от коммьюнити, называется FTDI BFF:



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


На просторах интернета нашелся еще один гибрид, у которого все сигналы выведены на свободные края платы:


Что остается сказать по этому поводу? Да здравствует Open Hardware и фантазия разработчиков. Ведь чем больше вариантов - тем лучше ;)