30.12.2013

Freeduino wireless (2)

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

Довольно давно на рынке существует микросхема nRF24L01+, выпускаемая фирмой Nordic Semiconductors. Она обеспечивает возможность приема или передачи информации на несущей 2,4 ГГц (полоса ISM), методом частотной манипуляции GFSK. Для Arduino это решение удобно не только в силу низкой стоимости чипа, но и по причине подключения через SPI.

Для экспериментов нам понадобится какой-либо беспроводной модуль на основе nRF24L01+, например такой:



Его можно купить практически где угодно, стоить больше 160 рублей он не должен. Следует заметить, что 90% таких модулей ничем друг от друга не отличаются - схема скопирована из реф-дизайна evolution-кита к nRF24L01+, опубликованному производителем. Антенна расположена прямо на печатной плате, что при такой длине волны вполне допустимо и обещает максимальное расстояние до 100 метров (разумеется, с оговоркой про "идеальные условия", в реальности оно будет меньше - сколько именно, придется проверять экспериментально). К слову, существует две версии чипа - nRF24L01 и nRF24L01+, отличающиеся совсем ненамного и совместимые друг с другом (просто имейте ввиду, что если ваш модуль с nRF24L01 - к нему эта статья применима в полном объеме).

Назначение контактов на вилке должно быть следующим (вид сверху):



У модулей с вилкой 2x4 есть одно существенное неудобство - невозможно воткнуть в беспаечную макетку: расположенные в два ряда контакты, увы, будут закорочены попарно. Остается только позавидовать счастливым обладателям модуля от SparkFun, не поскупившимся отдать за это чудо 19.95 USD:

Посмотрим, какие выводы и куда подключать:
  • GND - земля, соединяем с одним из пинов GND на Arduino;
  • VCC - питание модуля,  внимательно - соединяем с пином 3.3В - модуль питается от напряжений 1,9..3,6В, хотя при этом отлично умеет работать с логическими уровнями +5В;
  • CE - расшифровывается как Chip Enable, но речь не про работу всего чипа, а лишь про его радиоинтерфейс - в режиме приема заставляет модуль "прослушивать" эфир в поисках предназначенного ему пакета, в режиме передачи кратковременный импульс CE передает в эфир содержимое буфера FIFO.  Подключим его к пину D8;
  • CSN - SPI: Chip select not, выбор Slave-устройства на шине SPI низким уровнем, подключаем к пину D7;
  • SCK - SPI: Clock, подключаем к пину D13;
  • MOSI - SPI: Master Out, Slave In - подключаем к пину D11;
  • MISO - SPI: Master In, Slave Out - подключаем к пину D12;
  • IRQ - прерывание, пока никуда не подключаем :(
Пины с аппаратной поддержкой SPI (SCK, MOSI, MISO) гарантированно можно найти на шестиконтактной ISP-вилке Arduino:


Если же будете подключаться к боковым гребенкам, учитывайте, что аппаратная поддержка SPI у Mega находится на пинах 50 (MISO), 51 (MOSI), 52 (SCK) и 53 (SS).

Переходник для установки в беспаечную макетку можно соорудить из разъемов PBD08 и PLS8, на кусочке обрезка обычной макетной платы (под пайку):



Итак, паяльник можно откладывать в сторону. Однако прежде чем приступать к написанию скетчей, познакомимся с документацией на чип и поподробней разберемся в том, что он умеет (и что не умеет - разумеется, тоже).

nRF24L01+ способен работать приемником или передатчиком на частотах 2400..2525 МГц, конкретная частота определяется номером частотного канала от 1 до 126, задаваемым через регистр RF_CH. Чтобы приемник и передатчик смогли обмениваться между собой, они обязательно должны быть сконфигурированы для одного и того же канала. Скорость обмена по умолчанию - 2 Мбит/с, но при необходимости ее можно снизить до 1 Мбит/с - в основном это делается для совместимости с ранними версиями чипов Nordec (вот одно из отличий nRF24L01 от nRF24L01+: последний умеет работать еще и на пониженной скорости 250 Кбит/с).

Данные передаются пакетами. Пользовательская часть (в документации называется "Payload") может занимать до 32 байт, остальные поля - служебные:


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

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

Но, к счастью, существует специальный встроенный протокол Enhanced Shockburst (tm), который берет на себя все заботы о гарантированной доставке сообщения между двумя nRF24L01+. Это включает в себя не только прием, проверку правильности и отсылку подтверждающего пакета приемником, но и повторную перепосылку пакета передатчиком. Не правда ли, инженеры Nordic Semiconductors поработали на славу? ;) Для работы протокол использует поле управления пакетом.

В довершение существует специальный режим Multiceiver, в котором приемник может быть настроен на получение данных от шести передатчиков, и опять же, с возможностью работы по Enhanced Shockburst. Иными словами - один приемник может "тянуть" данные из шести передатчиков с аппаратным подтверждением и перепосылкой. Правда, есть некоторые ограничения - все устройства надо сконфигурировать на работу в одном частотном канале, с одинаковой скоростью,  длиной адреса и способом формирования CRC. Один адрес передатчика можно выбрать произвольно, а вот остальные пять должны совпадать во всех байтах адреса, кроме последнего (например, 0x1234567801, 0x12345678D5, 0x12345678AA, 0x1234567855, и так далее).

Адрес задает пользователь, и, строго говоря, он может быть произвольным. Но располагается он в самом начале пакета, сразу после преамбулы, которая выглядит в двоичном представлении как 01010101 или 10101010 - такая комбинация не случайна и нужна для правильного пробуждения приемника и его подстройки к частоте передатчика. Чтобы было меньше ложных "отбраковываний" пакетов приемной частью, надо стараться избегать как адресов, похожих на преамбулу (например - 0xAAAAAA или 0x555555), так и адресов, состоящих из вообще одних нулей и единиц (еще два плохих примера - 0xFFFFFF или 0x000000).

Пример схемы (допустим, Freeduino Nano):



Какие библиотеки  для Arduino существуют для работы с nRF24L01+?


Самый простой вариант - библиотека Mirf, которая предоставляет минимальную обвязку (её даже адаптировали для ATtiny). Скачайте последнюю версию библиотеки:
  • на странице Arduino playground, посвященной nRF24L01+;
  • непосредственно из gitHub.
Перед началом работы надо задать пины, к которым подключены CE и CSN, собственный адрес как приемника, длину пользовательской части (payload) и вызывать пару функций. По умолчанию предполагается, что CE подключен к D8, CSN - к D7 (ровно так мы уже и сделали), работа будет идти по каналу 1, длина пакета - 16 байт. Если что-то из перечисленного не совпадает с вашими потребностями, необходимо установить соответствующие значения полей до вызова init() и config(), например: Mirf.cePIN = 10;  в случае, если CE подключен к D10.

В основном, последовательность инициализации выглядит так:
  1. Mirf.spi = &MirfHardwareSpi;
  2. Mirf.init();
  3. Mirf.setRADDR((byte *)"12345");
  4. Mirf.payload = 4;
  5. Mirf.config();

Первая строчка - установление "правильного" алгоритма работы с SPI, носит скорее исторический характер. Сейчас всё равно вся работа осуществляется через встроенную в ArduinoIDE библиотку SPI, но ведь не всегда было так ;) Второй строчкой происходит инициализация пинов и SPI, в третьей мы устанавливаем собственный адрес приемника, длиной 5 байт (символьная строка "12345" дана исключительно для наглядности, на самом деле это 0x3132333435 ;) В четвертой - мы устанавливаем длину пакета 4 байта, и, наконец-то, в пятой конфигурируем чип NRF24L01 и переводим его в режим приема.

Дальше можно принимать и передавать данные.

Прием:

 if(Mirf.dataReady()){
  Mirf.getData((byte *) &packet); 
}
Сначала дожидаемся прихода пакета в буфер, затем считываем его в переменную packet (ее размер должен соответствовать текущей длине payload).

Передача:

Mirf.setTADDR((byte *)"12345");
Mirf.send((byte *)&packet);
while(Mirf.isSending()){
}

Устанавливаем адрес получателя, затем отсылаем packet и при помощи isSending дожидаемся завершения отправки.

К библиотеке прилагаются примеры ping_client и ping_server, которые обмениваются пакетами друг с другом. Чуть интереснее изучить пример  ping_server_interrupt, демонстрирующий работу по прерыванию в режиме энергосбережения: пока нет данных, Arduino пребывает в режиме сна. Однако, как только фиксируется прием нового пакета, он просыпается, принимает пакет из nRF24L01+, отсылает ответный пакет и снова "засыпает". Для корректной работы потребуется подключить ранее неиспользованный пин IRQ на плате радиомодуля - к пину D2 Arduino.

В каких случаях генерируется прерывание от nRF24L01+?


Это происходит в трех ситуациях и отображается в регистре STATUS при помощи соответствующих битовых полей:
  1. TX_DS - передающая сторона получила от встречной стороны информацию (ACK-пакет), подтверждающую успешный прием;
  2. RX_DR - приемная сторона получила новый пакет данных (и с правильным CRC, и не дубль уже полученного ранее пакета);
  3. MAX_RT - передающая сторона попыталась передать пакет максимально разрешенное количество раз, но так и не получила подтверждения о приеме.  
И, самое важное - после того, как любой из перечисленных битов был установлен, для дальнейшей работы его необходимо сбросить - записать единицу. Обычно, об этом заботится библиотека ;)

Функция Mirf.isSending() как раз и проверяет факт завершения передачи по установке TX_DS или MAX_RT. Но имейте ввиду, что она не отвечает на вопрос о том, был ли пакет благополучно принят на противоположной стороне. После того, как Mirf.isSending() вернет true, чтение регистра STATUS становится бессмысленным - перед выходом функция сбрасывает биты TX_DS и MAX_RT. К счастью, при каждом возникновении MAX_RT увеличивается счетчик PLOS_CNT в специальном регистре OBSERVE_TX, поэтому проверку благополучной доставки можно организовать так:

int readPLOS_CNT() {
  byte reg;
  Mirf.readRegister(OBSERVE_TX,&reg,1);
  return (reg >> PLOS_CNT) & B1111;
}

void loop() {
  
  int prev_plos_cnt = readPLOS_CNT();

  /* ... */
  Mirf.send((byte *)&packet);
  while(Mirf.isSending()){
  }

  if (readPLOS_CNT() != prev_plos_cnt) {
   /* failed :( */else {
   /* success! */
  }
}

Еще можно вообще отказаться от использования Mirf.isSending(), и проверять биты TX_DS и MSX_RT непосредственно чтением регистра STATUS. Но тогда не забывайте сбрасывать их после установки, иначе процесс передачи встанет после первого же пакета.

Как я уже упоминал в самом начале - библиотека реализует действительно минимально необходимый набор функционала. За это приходится расплатиться следующим:
  • длина адресного поля - всегда 5 байт;
  • CRC всегда однобайтовый;
  • длина payload всегда фиксирована;
  • нет поддержки режима multiceiver (прием данных от шести передатчиков).
Что-то решается простейшим исправлением кода библиотеки, что-то можно сделать через запись и чтение управляющих регистров nRF24L01+, что-то (multiceiver или динамическая длина payload) добавить уже и вовсе непросто.

Однако, если у вас возникает слишком много претензий к функционалу Mirf, можно попробовать альтернативу - RF24. В ней конфигурируется буквально всё, в том числе автоматически учитываются различия между nRF24L01 и nRF24L01+. Идеологически библиотека ближе к стандартам Arduino и интуитивно понятнее, особенно начинающим. Например, по аналогии с Mirf есть функция RF24::startWrite, а в дополнение к ней - RF24::send, которая блокирует ход скетча до завершения процесса передачи, чтобы стало понятно - передан пакет успешно или нет, что и сообщается в возвращаемом значении типа bool (прямая замена вышеприведенному коду, который пришлось добавлять для аналогичного контроля в Mirf). 

В комплекте с библиотекой RF24 много полезных примеров, которые демонстрируют использование irq, отправку пользовательских данных в ACK-пакете и прочее. Есть даже примитивный сканер эфира ;)

Куда двигаться дальше? 


Например, по каким-то причинам не устраивает дальность приема: то ли расстояние велико, то ли стен многовато. В этом случае надо брать модуль nRF24L01+ с PA/LNA (Power Amplifier и Low Noise Amplifier):


Этот модуль будет стоить чуть дороже, около 10 USD. В его основе nRF24L01+ с точно такой же вилкой, но у него непосредственно к выходным каскадам вместо антенны подключен усилитель, повышающий мощность передатчика и чувствительность приемника. К SMA-коннектору необходимо подключить стандартную антенну для диапазона 2,4 ГГц (можно скрутить с нерабочего WiFi роутера) и правильно сориентировать - получите диапазон до 1000 метров. Правда, сразу вырастут запросы по питанию: модулю потребуются не десятки, а сотни mA, напряжение питания должно быть в диапазоне 3,0..3,6В. В этом случае может уже не получиться питать его от Arduino - если не помогает конденсатор 10 мкФ между 3,3В и землей, просто подключите модуль к отдельному источнику питания.

Да, и еще одно: не исключено пересечение по частотным каналам с другими беспроводными устройствами. Если у вас есть беспроводная клавиатура или мышь на 2,4 ГГц, с очень большой долей вероятности есть шанс разобрав ее увидеть нашего старого знакомого ;) 

Ссылки по теме:



24.11.2013

ARCAdaptor или Игра в Продукт

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



Наверное, каждый, кто увлекается разработкой различных железок на микроконтроллерах, задавался подобными вопросами:
  • А что дальше? 
  • Как сделать из прототипа законченный продукт?
  • Смогут ли им пользоваться другие люди?
  • Зачем мне вообще всё это?

25.07.2013

Freeduino One c microUSB

Однажды, в комментах мне попеняли на "любовь к большим разъемам USB". В другой раз услышал в личной беседе пожелание использовать microUSB, потому что "к нему проще найти кабель".

"Ну что же..." - подумал я, и:


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


Но если серьезно, меня сильно порадовало высвободившееся на плате место, это дает определенный простор для творчества (в прямом и переносном смысле).

07.06.2013

TV-out для Arduino

Если вы когда-нибудь почувствуете, что вашему Arduino-проекту стало тесно на алфавитно-цифровом дисплее 1602, обязательно обратите внимание на проект TellyMate Shield. Он позволяет выводить ту же алфавитно-цифровую информацию на обычный телевизор, через видео-вход.

При определенном везении можно заполучить весьма внушительных размеров дисплей (если телевизор имеет прилично дюймов в диагонали), работающий в режиме телетайпа  38 x 25 знакомест. Впрочем, бросив первый взгляд на схему, ловишь себя на мысли о розыгрыше. В самом деле:


Обычный ATmega8 на тактовой частоте 16 МГц формирует два компонента видеосигнала, которые смешиваются нехитрой схемой из двух резисторов и двух диодов. Группой переключателей S1 устанавливаются режимы работы; согласующий резистор 75 Ом подключается через перемычку и добавлен, скорее, для универсальности (думаю, в большинстве случаев не понадобится).



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


        Serial.begin(57600); //57k6 baud
        Serial.println("Hello, world!");


К сожалению, изображение формируется исключительно черно-белое. Зато внутри имеем полноценный знакогенератор кодовой страницы 437, в котором есть псевдографика:


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


Кроме вывода обычных символов, поддерживаются так называемые ESCAPE-последовательности, которые управляют курсором, удваивавают высоту и/или ширину символов и даже переключают банки шрифтов и переопределяют символы (что, впрочем, возможно только на ATmega328P, где памяти гораздо больше, чем у ATmega8). Таким же образом можно получить версию прошивки и прочую диагностическую информацию.

Чем-то все это напоминает LoL-Shield, особенно приложениями - взгляните на список доступных .ino. Здесь найдется не только классика Life и Snake, но и более изощренные - Maze и даже простейший "графический редактор"!

Поскольку все материалы доступны и открыты для доработки, мы решили немного поэкспериментировать и создать на базе этого шилда русифицированный вариант. Имя "TellyMate", подобно Arduino, является торговой маркой - поэтому пришлось назвать наш вариант Freeduino Teleсhat:


Все детали - PTH, поскольку шилд задумывался изначально в формате кита для самостоятельной сборки - и что может быть лучше, чем собрать всё самостоятельно? ;) Пины RX/TX имеют перемычки под пайку с обратной стороны платы, так что при желании их можно перерезать и подпаять к любым другим пинам. Аналогичным способом  отключается и кнопка сброса - если не хотите, чтобы МК шилда сбрасывался синхронно со  скетчем Arduino.

Краткое руководство по сборке шилда:


Шутка, конечно ;) просто там действительно все элементарно. На howtomakekit.blogspot.ru, как всегда, выложена подробная пошаговая инструкция.

Русифицированный шрифт мы разместили точно таким же способом, что и автор - в виде ссылки на документ в GDocs, копию которого при необходимости можно сохранить у себя. В открытом документе надо зайти на последнюю закладку, генерирующую hex, и скопировать ее содержимое в файл  fontbank0.c, подменив его в исходниках (можно скачать со страницы проекта). После компиляции получите прошивку c поддержкой кодовой страницы 866. Именно она и зашивается в ATmega8, входящие в комплект наборов Freeduino TeleChat. 

Для вывода русского текста потребуется еще кое-что сделать. Как известно, ArduinoIDE хранит все символы в кодировке UTF-8, и для нормальной работы потребуется их транслировать в кодировку 866. Делать это в оригинальной прошивке нам показалось святотатством - авторы очень скрупулезно рассчитали все задержки в коде. Предлагаем самый простой вариант перекодирующей функции:

byte c1 = 0;

void tele_print_char(char cd) {
  byte c = cd;
  if (  c >= 0x80) { // UTF-8 handling
    if (!c1) {
      c1 = c;
    } else {
      if (c1 == 0xd0) { 
       if (c == 0x81) Serial.print(char(0xf0)); // Ё
        else Serial.print( (char) (c - 0x10));
      }
      if (c1 == 0xd1) {
       if (c == 0x91) Serial.print(char(0xf1)); // ё
        else Serial.print( (char) (c + 0x60));
      }
      c1 = 0;
    }
  } else Serial.print(cd);
} 

void tele_print_str(char *s) {
  for(int i=0;i<strlen(s);i++) tele_print_char(s[i]);
}

void setup()
{
  char letter[]="АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
  Serial.begin( 57600 ) ;
  Serial.println( "Hello World!" ) ;
  tele_print_str( "Привет, мир!\n\r" ) ;
  tele_print_str( letter );
}

void loop()
{
    // do nothing!
}


Купить шилд в собранном виде или в виде комплекта деталей можно здесь.

Для тех, кто любит почитать оффлайн - про TellyMate упоминается в книге У. Соммера "Программирование микроконтроллерных плат Arduino/Freeduino".

07.05.2013

Web-термометр

"Погодная станция своими руками" - вот как можно было бы назвать статью, но я решил пока просто рассказать о том, как соорудить web-термометр, подключить его к домашней LAN  и наблюдать показания через браузер ;)

Для этого нам потребуется Arduino-совместимая плата, поддержка Ethernet и несколько температурных датчиков.


17.04.2013

ArduinoIDE 1.0.4

Новая ArduinoIDE 1.0.4 вышла 11.03.2013, и почти весь ее смысл - исправление ошибок.

Лично мне видится три главных момента:

  • Добавлена новая библиотека GSM, для работы с Arduino GSM Shield. С ее помощью можно не только передавать данные с использованием конструкции Client/Server по аналогии с Ethernet, но и отправлять/получать SMS-сообщения, а также голосовые вызовы;
  • Все драйверы собраны в один пакет, с цифровой подписью для Windows 8. По идее, это упрощает процесс установки, избавляя вас от лишних вопросов и подозрений со стороны операционной системы;
  • Официально исправлены накопившиеся (видимо, за все время) ошибки в бутлоадере Mega2560. Ошибки это были знаменитые, ко многим давно существовали патчи - взять, например, ошибку с незагрузкой скетча, в котором встречается комбинация "!!!". Разумеется, аналогичные изменения войдут и в бутлоадер, прошитый во Freeduino Mega2560.
Впереди - слияние ветки 1.5.x и 1.0.x, но когда именно оно произойдет, пока сказать трудно...

03.04.2013

Температура и влажность (2)

У датчика измерения температуры и влажности DHT-11 (о его возможностях и стыковке с Arduino я подробно писал в предыдущей статье) есть "старший брат", сенсор DHT-22 (часто под этим названием фигурирует AM2302, производимый фирмой AOSONG):



Несколько проигрывая DHT11 по габаритам, этот датчик имеет более широкий диапазон измеряемых величин и обладает большей точностью. Ранние версии даташитов объясняют, что измерением температуры занимается встроенный DS18B20, однако в последних вариантах его заменили на термистор.

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

ПоказательDS18B20DHT11DHT22
Допустимый диапазон t,°C-55..+1250..+50-40..+80
Погрешность измерения t, min±0.5°C@-10..+85°C±2°C@0..+50°C±0.5°C@+15..+55°C
Погрешность измерения t, max±2°C±2°C±1°C
Разрешение шкалы t,°C0.5/0.25/0.125,/0.062510.1
Допустимый диапазон RH, %-20..950..99.9
Погрешность измерения RH, min-±4% +25°C±2% +25°C
Погрешность измерения RH, max-±5%±4%
Разрешение шкалы RH, %-10.1

Точность измерения относительной влажности возрастает для значений меньших 12% и больших 90%, а также имеет некоторый гистерезис. Считывание очередного значения возможно не чаще, чем один раз в 2 секунды. Более подробно можно прочесть в документации: AM2302.pdf.

Подключение DHT22 к Arduino выглядит аналогично DHT11. Пины имеют идентичное назначение, схема подключения не отличается, да и протокол общения с датчиком, по сути, тот же.




Отличия начинаются в трактовке считываемых значений. Мы по-прежнему получаем от сенсора по 40 бит:
  1. Старшая часть значения влажности;
  2. Младшая часть значения влажности;
  3. Старшая часть значения температуры;
  4. Младшая часть значения температуры;
  5. Контрольная сумма.
Значение относительной влажности и температуры выдаются в десятых долях, например: если прочитано 010Dh, то эту цифру надо перевести в десятичный формат (269), а затем разделить на 10 - получится 26,9. И, кстати, отрицательные значения температуры кодируются единицей в старшем разряде считываемого 16-битного значения: 1000 0000 0110 0101 означает -10,1 °C.


Существует несколько вариантов библиотек для Arduino (и вы можете написать свой собственный!), вот наиболее известные:
В примере ниже я использую именно последний вариант, он простой и универсальный (работает не только с DHT22, но и с DHT11).  Архив с библиотекой надо распаковать в каталог sketchbook/libraries и перед загрузкой скетча в Arduino не забыть исправить значение константы DHT22_PIN на номер пина, к которому подключен вывод DATA датчика:

#include <dht.h>

dht DHT;

#define DHT22_PIN 6

void setup()
{
  Serial.begin(115200);
  Serial.println("DHT TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT_LIB_VERSION);
  Serial.println();
  Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
}

void loop()
{
  // READ DATA
  Serial.print("DHT22, \t");
  int chk = DHT.read22(DHT22_PIN);
  switch (chk)
  {
    case DHTLIB_OK:  
                Serial.print("OK,\t"); 
                break;
    case DHTLIB_ERROR_CHECKSUM: 
                Serial.print("Checksum error,\t"); 
                break;
    case DHTLIB_ERROR_TIMEOUT: 
                Serial.print("Time out error,\t"); 
                break;
    default: 
                Serial.print("Unknown error,\t"); 
                break;
  }
  // DISPLAY DATA
  Serial.print(DHT.humidity, 1);
  Serial.print(",\t\t");
  Serial.println(DHT.temperature, 1);

  delay(2000);
}


После старта программы надо вызвать окно Serial Monitor-а (Ctrl+Shift+M):



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

Диапазон питания датчика составляет +3.3...+5.5В, поэтому его можно с успехом использовать с трехвольтовыми Arduino и конструировать довольно компактные и малопотребляющие конструкции - например, при помощи Freeduino Pro Mini.  Рекомендуемая длина кабеля, соединяющего DHT22 с MCU при питании от 3.3В не должна превышать 100 см

Купить DHT22 можно, например, здесь.

Ссылки по теме:

01.02.2013

Ethernet Shield своими руками

Классический Ethernet Shield от Arduino на микросхеме Wiznet W5100 появился одним из первых, перенес уже как минимум три существенных ревизии, а также интегрирован в плату Arduino Ethernet.



Тем не менее, использование W5100 - вовсе не единственный способ добавить немного LAN в ваше устройство на основе Arduino. Давным-давно фирма Microchip выпустила Ethernet-контроллер ENC28J60, который изготавливается не только в SMD-исполнении, но и в DIP-корпусе, что сделало его незаменимым для DIY-любителей. От себя замечу, что это единственный Ethernet-контроллер в DIP-е, который вообще попадал мне в руки.



Если сравнивать W5100 и ENC28J60, сразу же выяснится, что их основная общая черта - способность работать по шине SPI и тем самым экономить пины микроконтроллера для других задач. Но по техническим характеристикам ENC28J60 уступает - он не может пощеголять ни аппаратной поддержкой TCP, ни скоростью 100 Мбит.

Но, быть может, вашему проекту оно и не надо?

Когда говорят о скорости 100 Мбит/с, подразумевают скорость работы физического интерфейса (а не скорость поступления полезных данных, которая всегда меньше). К сожалению, Arduino UNO/Mega работает на тактовой частоте 16 МГц и способен выполнять только 16 000 000 операций в секунду (одна инструкция за такт - на то он и RISC ;). Вероятно, он не справится со сложным потоком медиаданных, зато на обмен небольшими порциями управляющей информации - вполне способен. Скорее всего, вы не почувствуете разницу между 10 и 100 Мбит/с, если будете считывать состояние датчиков или давать управляющие команды. Сетевые интерфейсы, способные работать на 100 Мбит/с, как правило, поддерживают и 10 Мбит/с - если только эта скорость не будет запрещена в конфигурации сетевого устройства принудительно каким-то злым маньяком системным администратором.

Что касается аппаратной поддержки TCP, который обеспечивает гарантированную доставку данных для многих протоколов, включая http, то здесь тоже все относительно просто: микросхема W5100 работает с четырьмя соединениями одновременно, обрабатывая перезапросы; в микросхеме ENC28J60 такой возможности нет (хотя она и поддерживает подсчет контрольной суммы, а также имеет буфер на 8 килобайт). То, что не делается аппаратно - приходится реализовывать программно, хоть и нагружая МК Arduino. Для программиста прикладного уровня (читаем - для рядового Arduino-пользователя типа нас с вами) это решается использованием соответствующей библиотеки, с оглядкой на свободную память микроконтроллера. Опытным путем я установил, что разница по объему скетчей хоть и есть, но не такая драматически большая, как мне показалось с первого взгляда.

Что нужно для того, чтобы состыковать ENC28J60 с Arduino? Да практически тоже самое, что и W5100:
  • схема тактирования (кварц 25 МГц + емкости);
  • питание +3,3В;
  • шина SPI c согласованием уровней логических сигналов  (+5В у Arduino и +3,3В у контроллера Ethernet);
  • развязка с линией (трансформатор, разрядник и резисторы - желательно 1%-ые);
  • внешний "точный" (1%-ый) резистор для работы опорного источника напряжения.
Собственно, все эти компоненты вполне реально существуют в выводном исполнении - так почему бы не воспользоваться? Схемы можно найти в изобилие в интернете, например - вот вариант из Instructables.



Автономные модули и шилд-платы с ENC28J60 в SMD-исполнении давно доступны на EBay и у  прочих интернет-магазинов (в особенности, конечно же, в китайских) - но это всего лишь железо, реализация одной и той же, по сути, схемы. Программная часть наиболее грамотно разрабатывается JeeLabs, можно даже найти инструкции по миграции с EthernetShield на EtherCard (так называется их вариант кита для самостоятельной сборки). Идея же представить набор для самостоятельной сборки по праву принадлежит Open Electronics, а библиотеку можно скачать на GitHub.



Основываясь на этой разработке, свет увидела Freeduino EtherCard R1:




Схема оставлена практически без изменений. Вот несколько моментов, которые их отличают:
  1. Шилд подключается по SPI, но через проходную вилку - таким образом, к нему можно подключить еще один SPI-шилд, например MicroSD shield;
  2. Все резисторы, которые требуют повышенной точности, взяты действительно 1%-ые;
  3. Шилд стыкуется с платой максимально компактно - обратите внимание, что в отличие от оригинала, он полностью "сел" на плату (обратите внимание на разъем USB и край печатной платы шилда, чтобы понять, о чем я говорю);
  4. Бочкообразные электролиты несоразмерной емкости 470 мкФ заменены на низкопрофильные.
Купить шилд в собранном виде или в виде kit-а можно здесь, пошаговая инструкция по сборке доступна здесь.

При использовании библиотеки, не забывайте в инициализации ether.begin дописывать третий параметр - номер пина, к которому подключено разрешение работы. Библиотека по умолчанию предполагает D8, но в этом шилде - D10

Возьмите прилагающийся к библиотеке пример testDHCP и найдите строчки:

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
    Serial.println( "Failed to access Ethernet controller");

Впишите номер пина в конце следующим образом:

  if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0) 
    Serial.println( "Failed to access Ethernet controller");

И все тут же заработает (при наличии подключенной сетки с DHCP-сервером, конечно же ;)

21.01.2013

Используем HNYDuino R2

Новогодние праздники давно окончились, а после крещения многие уже избавились от своих новогодних деревьев. Конечно, если только это не HNYDuino R2 - с ней можно развлекаться хоть круглый год. Рассмотрим более подробно, как именно это делается ;)




11.01.2013

RelayShield HighPower

С момента выпуска RelayShield прошло около года. По традиции, мы проанализировали  отзывы пользователей и создали новую версию:


Основная идея - реализовать возможность переключения больших токов. Соответственно, место шести реле заняли четыре, зато более мощных (10А,  250VAC или 30VDC). Как и предыдущий вариант, этот тоже никак не соприкасается с Arduino-совместимой платой при стыковке:


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


Управляющие выходы реле находятся на пинах D7, D6, D3 и D4 соответственно. Контактные группы каждого реле обозначены как:

  • NOx - Normal Open, разомкнутый в исходном состоянии контакт;
  • NCx - Normal Close, замкнутый в исходном состоянии контакт;
  • COMx - Common, общий.
Управление несложное - надо перевести пин в режим цифрового выхода при помощи pinMode(N, OUTPUT), затем записать в него соответствующее значение (HIGH или LOW) через digitalWrite:
  • LOW (исходное состояние): замкнуты NCx и COMx, NO ни с чем не соединен;
  • HIGH: замкнуты NOx и COMx, NC ни с чем не соединен.

Купить RelayShield HighPower можно здесь.

08.01.2013

Как подключить шилд к Nano

Все, кто потратил на сравнение Arduino-совместимых плат хотя бы минут десять, успели усвоить простые истины:
  1. Полноразмерные платы типа Arduino UNO удобны для пристыковывания шилдов;
  2. Миниатюрные платы типа Arduino Nano чудо как хороши в комплекте с беспаечной макеткой.
Но что, если требуется ровно наоборот?...

Существуют полноразмерные Arduino-совместимые платы, на которые не напаяны колодки - вместо них можно впаять штыри и воткнуть таким образом в макетку (как правило, на них даже два ряда отверстий - одно для стандартного arduino pinout, второе - на сетке 2,54 мм), хотя по смыслу такое подходит скорее для обычной макетной платы - к которой без паяльника лучше не подходить.

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

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

Вот что она умеет:
  • изображать arduino pinout 1.0, включая ICSP-вилку для стыковки с последними Ethernet-платами (и прочими вариантами, которые используют для коммуникаций пины с аппаратной поддержкой SPI);
  • разъем питания с защитным диодом и опциональной возможностью запитывания от стабилизированного источника +5В;
  • посадочные места для пинов A6 и A7 - если они все-таки используются в конструируемом вами устройстве;
  • посадочные места для резисторов-подтяжек I2C, если вдруг понадобится;
  • кнопку сброса (хотя она и кажется бесполезной на первый взгляд).
Когда я разводил этот вариант, то довольно скоро сообразил, что поместить Nano сверху не получится из-за недопустимой высоты - она просто не даст возможность нахлобучить шилды , при стандартной высоте колодок в 8 мм.

И хотя вопрос решался увеличением высоты колодок, я решил отказаться от этой затратной со всех точек зрения идеи (стоимость этих экзотических высоких колодок и результирующая высота и прочность конструкции) и поместил Nano с противоположной стороны ;) Иными словами -  колодки для шилдов и для Nano смотрят в разные стороны:


Я, конечно, понимаю - истинный фанат платформы Arduino просто обязан иметь в своем арсенале как минимум Nano, UNO, и Mega, а следовательно - в таком переходнике не нуждается. Тем не менее, по себе знаю, что прототипизация происходит очень спонтанно и результат качественно зависит от того, что оказалось под руками в конкретный момент времени. В результате это может выглядеть так:




Что до меня лично - я, наконец, получил возможность питать и Nano, и UNO от одного блока питания - быть может, эта идея еще кому-то понравится ;)

Купить кит или собранную плату можно здесь. А руководство по сборе кита (поясняющее отдельные моменты конструкции) - прочитать здесь.