Показаны сообщения с ярлыком Arduino. Показать все сообщения
Показаны сообщения с ярлыком Arduino. Показать все сообщения

01.03.2021

LiquidCrystalRus - небольшое обновление

Недавно в проект LiquidCrystalRus на GitHub пришло issue по поводу того, что функция print при попытке выводить некоторые неалфавитно-цифровые символы из знакогенератора дисплеев на основе HD44780U, несправедливо их калечит. И я решил скорректировать алгоритм трансляции - чтобы он применялся строго к символам русского алфавита. Чуть больше кода из-за проверок, но зато можно так:

lcd.print("Дисковод 5\xf0");

На экране мы увидим:  Дисковод 5¼

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

Надеюсь, кому-то пригодится )

30.03.2015

LiquidCrystalRus для 1.6.1

Недавно вышла очередная ArduinoIDE 1.6.1, одним из новшеств которой выступил новый gcc версии 3.4.5. И поскольку с каждой версией gcc синтаксис становится всё строже и строже - без неприятностей не обошлось.

В частности, перестала компилироваться библиотека поддержки вывода русского языка LiquidCrystalRus, из-за неверного (с точки зрения gcc) использования директивы PROGMEM, о чем ко мне посыпались сообщения от уважаемых пользователей (за что им хочу выразить особую благодарность).

Изменения там совсем крошечные, но если после установки новой ArduinoIDE ваш проект с LiquidCrystalRus в составе перестал компилироваться, не паникуйте, а скачайте и установите LiquidCrystalRus-1.6.0.zip.

Напоминаю, что проект также доступен на GitHub: https://github.com/mk90/LiquidCrystalRus.

UPDATE: подобно оригинальному LiquidCrystal, LiquidCrystalRus не умеет работать с дисплеями, подключенными как-то иначе, чем к пинам Arduino (например, по I2C), но зато и не требует для работы дополнительных библиотек: и в результате поддержка русского языка обходится дополнительно в 500 байт flash и 7 байт SRAM. 

09.05.2014

Книжная полка

Недавно издательство БХВ порадовало нас книгой Виктора Петина "Проекты с использованием контроллера Arduino"



К сожалению, полноценной рецензии выдать не могу, доступно только оглавление:
  • краткий обзор плат Arduino;
  • описание всех операторов языка Wiring;
  • описание встроенной библиотеки Serial;
  • описание встроенной библиотеки LiquidCrystal и даже пара слов про LiquidCrystalRus;
  • описание встроенных библиотек EEPROM, Ethernet, OneWire, SD, Stepper;
  • разбор подключения мыши и клавиатуры PS/2 - библиотека ps2dev;
  • работа с датчиками iButton, DS18B20, DHT11 и DHT12;
  • подключение к светодиодным матрицам;
  • примеры стыковки с RFID-приемниками, купюроприемниками, датчиками расстояния HC-SR04;
  • освещается вопрос обмена данными с помощью ИК, в том числе различные типы кодирования;
  • работа с ходовой частью робота через микросхему L293D;
  • использование приемопередатчика Bluetooth HC-05, а также NRF24L01 с помощью библиотеки Mirf;
  • вывод на экран телевизора с помощью библиотеки TVOut, с примерами игровых программ;
  • работа с USB через USB Host Shield;
  • немного про ROS (распределенная операционная система для роботов) и X10 (умный дом).
Приятно, что книги про Arduino на русском все-таки выходят - даже оглавление само по себе указывает путь к практическим решениям. Я специально сопроводил его ссылками на соответствующие статьи (в первую очередь на русском языке).

Будет ли достаточно этой книги именно для вашего проекта? Лично я ожидал хоть что-то про использование Arduino Due и Leonardo (они упоминаются в обзоре), изменение прошивок ATmega16u2 (на последних Uno и Mega), про использование программатора - в реальности рано или поздно этот вопрос возникает (хотя на тему программирования ATMEL недостатка в литературе нет, например книга Ревича). Стоило бы посвятить больше места шилд-платам.... Хотя, стоп! Надо сказать автору "большое спасибо" уже за это издание (лучшее "спасибо" - это легально купленный экземпляр книги, особенно если хотите продолжения ;).

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

А примеры из книги можно скачать здесь.

30.03.2014

А все-таки она вертится!

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



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 ГГц, с очень большой долей вероятности есть шанс разобрав ее увидеть нашего старого знакомого ;) 

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



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 см

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

15.12.2012

Температура и Влажность

Из серии статей про измерения температуры незаслуженно выпал сенсор DHT11, представляющий собой недорогой цифровой датчик температуры и влажности в одном корпусе:



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

Насколько важна влажность в помещении? Считается, что оптимум лежит около 50% - именно при такой влажности растения, люди и животные будут чувствовать себя комфортно. В частности - люди меньше болеют вирусными заболеваниями, а растения не рискуют превратиться в экибану.

Вот так устроен этот датчик внутри (а ведь он заменяет собой целый психрометр):


С одной стороны микроплатки - аналоговый сенсор, с другой - микросхема, оцифровывающая измерения и реализующая интерфейс с MCU. 

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

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

(для тех, кто склонен путать разрешающую способность и точность: хотя DS18B20 можно настроить таким образом, чтобы он отдавал 12-битные значения с разрешением 0,0625 градуса, его точность не станет лучше 0.5С. Но можно сделать "более живой" дисплей с отображением двух знаков после запятой ;)

Из характеристик видно невооруженным глазом, что DHT11 практически идеально подходит для жилых помещений и комнатных температур. Если датчик попадает в условия, выходящие за допустимые пределы, он начинает врать (попутно ускорится процесс старения аналогового сенсора), после чего требуется несложный процесс восстановления. Более подробно про это можно прочесть в описании: DHT11.pdf.

Как подключить DHT11 к Arduino? Начнем с расположения его пинов:


(третий пин не надо никуда подключать)

Рекомендуемая схема подключения содержит обязательный для однопроводных линий резистор-подтяжку к VCC и, в качестве опции, рекомендуется конденсатор (фильтр по питанию между VCC и GND):


На макетке это выглядит так (сенсор подключен к цифровому пину D8 платы Freeduino Nano):



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


Разберемся, как происходит обмен DHT11 с Arduino. Логически, это представляется такой последовательностью:
  1. Arduino запускает считывание показаний, переводя свой пин в режим выхода - как минимум на 18 миллисекунд переводит его в LOW, затем на 40 мкс в HIGH - и, после этого, переключает его в режим входа;
  2. Через 20..40 мкс DHT11 отвечает подтверждением, также сначала переводя шину в LOW на 80 мкс, а затем в HIGH на 80 мкс;
  3. DHT11 начинает побитную передачу информации, каждый бит начинается с уровня LOW в течение 50 мкс, и затем HIGH разной продолжительности: если 26-28 мкс, то это ноль, если же 70 мкс - единица;
  4. По окончании передачи 40 бит информации DHT11 "на прощание" еще раз переводит шину в LOW на 50 мкс и освобождает ее.
Полученная от DHT11 пачка из 40 бит представляется в виде последовательности из 5 байт следующего содержания:
  1. Целая часть значения влажности;
  2. Дробная часть значения влажности;
  3. Целая часть значения температуры;
  4. Дробная часть значения температуры;
  5. Контрольная сумма.
Как всегда, можно воспользоваться готовой библиотекой, которая считывает показания и вычисляет контрольную сумму для проверки. Что характерно, байты с дробной частью приходят всегда нулевые - пусть вас это не смущает, так и задумано ;)

Примеры использования DHT11 с Arduino: во-первых, данные можно выводить в последовательный порт и наблюдать на Serial Monitor:

#include <dht11.h>

dht11 sensor;

#define DHT11PIN 8

void setup()
{
  Serial.begin(115200);
  Serial.println("DHT11 TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();
}

void loop()
{
  Serial.println("\n");

  int chk = sensor.read(DHT11PIN);

  Serial.print("Read sensor: ");
  switch (chk)
  {
    case DHTLIB_OK: 
         Serial.println("OK"); 
         break;
    case DHTLIB_ERROR_CHECKSUM: 
         Serial.println("Checksum error"); 
         break;
    case DHTLIB_ERROR_TIMEOUT: 
         Serial.println("Time out error"); 
         break;
    default: 
         Serial.println("Unknown error"); 
         break;
  }

  Serial.print("Humidity (%): ");
  Serial.println(sensor.humidity);

  Serial.print("Temperature (oC): ");
  Serial.println(sensor.temperature);
  
  delay(2000);
}



Во-вторых, немного усложнив схему, можно выводить данные на LCD-дисплей:





#include <LiquidCrystalRus.h>
#include <dht11.h>

LiquidCrystalRus lcd(12, 11, 5, 4, 3, 2);
dht11 sensor;

#define DHT11PIN 8

void setup() {
  lcd.begin(16, 2);
  lcd.clear();
}

void loop() {
  switch (sensor.read(DHT11PIN)) {
    case DHTLIB_OK: 
                break;
    case DHTLIB_ERROR_CHECKSUM: 
                lcd.print("Checksum error");
                delay(2000);
                return;
    case DHTLIB_ERROR_TIMEOUT: 
                lcd.print("Time out error"); 
                delay(2000);
                return;
    default: 
                lcd.print("Unknown error"); 
                delay(2000);
                return;
  }
  lcd.setCursor(0, 0);
  lcd.print("Влажность,%:");
  lcd.print(sensor.humidity);
  lcd.setCursor(0, 1);
  lcd.print("Температура,C:");
  lcd.print(sensor.temperature);
  delay(2000);
  
}


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

Если стремиться к увеличению точности, можно найти достаточное количество датчиков, наиболее близкие по исполнению - DHT21/22. Они же, соответственно, и более дороги.

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

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

01.12.2012

ArduinoIDE 1.0.2

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

05.10.2012

Скоро Due!

Вот и прошел очередной Maker Faire в Нью-Йорке, и появились первые слухи по поводу даты входа Arduino Due. Вот что пишет Engadget:

The Due is roughly the size of the Mega 2560, but swaps the 16MHz, 8-bit processor found in your standard issue Arduino for a 96MHz Cortex-M3. Predictably, the Due is a much more capable development platform, and could easily replace multiple AVR-based Arduinos in products like DIY Drones' UAVs. The Due isn't expected ship till at least November in large quantities, but preview boards are currently being handed out to select developers.

То есть, в народ она пойдет где-то после ноября, есть и спецификации (взято отсюда):


02.07.2012

ADK 2012

Недавно в официальном блоге Arduino появилось сообщение о том, что на очередной конференции Google IO была представлена новая плата ADK 2012, уже базирующаяся на Arduino Due:


Официальный выход собственно Arduino Due запланирован на этот год, вместе с новой  ArduinoIDE, которая будет способна генерировать код под ARM. Пока что можно полюбоваться на фото ограниченного выпуска для разработчиков:

Фото в этом посте лицензированы под CC BY-NC-SA.

26.06.2012

Leonardo официальный

Вместе с выходом ArduinoIDE 1.0.1 нас посетила и "новая" плата Leonardo, выпуск которой был настолько основательно задержан, что она уже успела обзавестись массой клонов:



В официальном магазине Arduino ее можно приобрести за 18 EUR со всеми разъемами  или же, немного сэкономив, за 16 EUR, но уже без них:

Изучая схему, можно найти испытанный не одним поколением плат Arduino узел автоматического выбора питания на основе LM358 и полевого транзистора. Цепь питания +3.3В выполнена на отдельном регуляторе LP2985A-33, как и во всех платах, в которых нет USB-TTL моста FTDI232RL.

Есть и некоторые нововведения - впервые в этой серии видим разъем microUSB. Колодки выводов расположены согласно последнему стандарту arduino pinoout 1.0 - с фиксированной позицией SCL, SDA и IOREF. Скопированы и спорные с моей точки зрения "усовершенствования" в виде резистора 1М между ножками кварца, диода в цепи сброса и включенного в параллель внешнему источнику питания диода, лихо закорачивающего источник с неверной полярностью.

Таким образом, никаких сюрпризов в схеме нет - всё самое интересное происходит в программной части (напоминаю, что до момента выхода ArduinoIDE 1.0.1 код ATmega32u4 был практически неработоспособен из коробки - например, чтобы работать с Freeduino 32u4 надо было установить пропатченное ядро).

Бутлоадер

Изменен полностью - ранее он основывался на коде Peter Barrett-а и назывался DiskLoader, теперь же мы имеем модифицированный вариант CDC-бутлоадера из LUFA, под кодовым названием Caterina. Единственное предположение по поводу цели такого перехода - новый код лучше поддерживается - других внятных объяснений я пока не подыскал, особенно в свете удвоившегося размера bootloader-а. Звучит особенно грустно, если вспомнить, что поддержка USB неявно подключается к каждому компилируемому под Leonardo скетчу, для поддержания возможности программного сброса через USB. И вот уже blink занимает 4850 байт (против 1084 при компиляции под UNO!). Невольно вспоминается teensy с его закрытым от общественного взора кодом, но зато и с впечатляющим 512-байтным размером...

Как и раньше, процедура заливки скетча начинается со сброса, и сигналом к этому служит закрытие виртуального COM-порта Leonardo, до этого открытого на скорости 1200. Изменился, впрочем, сам подход к запуску бутлоадера - если раньше управление ему передавалось немедленно, то теперь это происходит через 120 мс, путем установки watchdog-а. Полагаю, авторы стремились дать корректно завершиться собственно процедуре закрытия порта, чтобы она не провоцировала ситуацию с таймаутом на хосте.

Таймаут ожидания заливки скетча в бутлоадере увеличили до 8 секунд! Практика показала, что это действительно правильно: время от времени получаю письма от пользователей Freeduino 32u4, что их плата перестала принимать скетчи по USB. Добиться этого нетрудно - достаточно залить в плату скетч, который ее полностью завешивает, и ArduinoIDE сбросить ее программно уже не сможет. Но когда пользователь нажимает кнопку сброса на плате, и лишь затем - Ctr+U в ArduinoIDE, процесс компиляции и ликновки не успевает уложиться в заданные 6 секунд, и плата вновь зависает. Я всегда рекомендую изменить последовательность - сначала нажимать Ctrl+U и только потом - сброс на плате (ну, или нажать и удерживать сброс, а потом отпустить его - надо просто прицелиться поточнее, и это всегда помогает :) 

Если раньше и бутлоадер, и ядро имели один и тот же PID комбинированного USB-устройства, новый бутлоадер представляется только CDC-устройством, зато имеющим свой собственный PID. Таким образом, Windows попросит установить драйвера дважды - сначала для бутлоадера, затем для скетча.

Ну и последнее изменение - протокол общения с бутлоадером сменился с  'arduino' на 'avr109'. В этом тоже не стоит искать скрытого смысла, поскольку именно avr109 поддерживает CDC-бутлоадер из LUFA.

Ядро

Arduino Leonardo по-прежнему уверенно изображает из себя комбинированное USB-устройство (CDC-модем, мышь и клавиатура - три в одном). 

С точки зрения API все осталось прежним - использовать это многообразие функциональности вы можете  через соответствующие классы Serial, Mouse, Keyboard. Причем интерфейс общения с клавиатурой обогатился функциями-членами press() и release(), которые великолепно понимают "непечатные" символы, и поэтому редактировать исходники ядра, чтобы сделать sendReport публичным (как это, например, потребовалось здесь) отныне не нужно.

Наконец-то пофикшена инициализация таймеров - аппаратный ШИМ одинаково корректно работает на всех выходах.

К сожалению, в ядре по-прежнему есть и недоделки:
  • попытка использовать встроенную функцию tone, скорее всего, вызовет повисание скетча, запущенного на ATmega32u4;
  • не работают назначаемые пользователем прерывания - через attachInterrupt, это Issue714. Справедливости ради стоит заметить, что работа в этом направлении все-таки ведется, но пока - увы, прерывания в для ATmega32u4 реализованы.

Freeduino 32u4 в ArduinoIDE 1.0.1

Для того, чтобы Freeduino32u4 можно было использовать с ArduinoIDE 1.0.1, потребуется замена бутлоадера - увы, подружить с ней старый вариант на базе DiskLoader мне пока не удалось.

С другой стороны, новый бутлоадер основан на Caterina и позволяет добиться максимальной совместимости с оригинальным Leonardo - изменения касаются только VID/PID и мигания встроенным светодиодом L. Ядро в этом случае тоже остается неизменным - добавляется лишь variant-файл для правильной трансляции номеров пинов.

Расплачиваемся за все это двумя килобайтами памяти программ... если решились - скачайте и распакуйте в каталог с ArduinoIDE 1.0.1 архив, в котором вы найдете:
  • готовый hex, для заливания в плату при помощи программатора;
  • файл-вариант Arduino-нумерации пинов Freeduino 32u4;
  • .inf-файл для Windows (новому бутлоадеру - новы PID :);
  • boards.txt.add: секция для добавления к boards.txt;
  • Makefile.freeduino32u4 для сборки hex-файла с правильными VID/PID.
Прошивать можно либо из ArduinoIDE, либо из командной строки (например, если у вас AVRDoper):

avrdude -c stk500v2 -P avrdoper -B 3 -p atmega32u4 -F -e -u -U lock:w:0x3f:m -U efuse:w:0xcb:m -U hfuse:w:0xd8:m -U lfuse:w:0xff:m
avrdude -c stk500v2 -P avrdoper -B 1.1 -p atmega32u4 -F -U flash:w:Caterina-Freeduino32u4.hex -U lock:w:0x2f:m


Саму плату можно купить здесь.

22.05.2012

ArduinoIDE 1.0.1


Несмотря на весьма скромное приращение версии, проделана значительная работа. Я бы картко выделил четыре момента:
  • интернационализация;
  • официальная поддержка Leonardo;
  • встроенный тулчейн (Linux);
  • багофиксы.
Теперь мы все, наконец, сможем общаться с ArduinoIDE на родном и могучем:



Пользователи Linux получили в составе дистрибутива avr-gcc тулчейн. Таким образом, все проблемы, которые я подробно описывал в статье ArduinoIDE в Ubuntu 11.10, благополучно решены.

Официально вышел Leonardo:

(этому событию будет посвящен отдельный, подробный пост)

Изменения в языке Wiring

  • механизм неявного управления подтягивающими резисторами, наконец-то стал более явным - если указать в функции pinMode новый режим INPUT_PULLUP, они будут подключены. А вот старый режим INPUT однозначно их отключает;
  • в класс Stream добавлены функции, возвращающие результаты в виде класса String - readString() и readStringUntil();
  • библиотека поддержки I2C теперь способна на работу в режиме "repeated start" - очень-очень давно это были первые же грабли, на которые я сам наступил при работе с ней. Теперь у endTransmission и requestFrom добавился параметр, управляющий этим режимом, но совместимость с прежним синтаксисом сохранена.  

Усовершенствования в ArduinoIDE

  • при компиляции скетча пересобираются только те исходники, которые менялись (реально ускоряет процесс компиляции);
  • можно отключить верификацию скетча после загрузки - раньше он в обязательном порядке прочитывался и сравнивался с оригинальным файлом, так что загрузка должна ускориться ровно в два раза;
  • шрифты в окне последовательного монитора теперь меняются (подобно окну редактирования); 
Самые важные, на мой взгляд, исправления касаются Ethernet (о них я как-то упоминал в этом посте) и работы скетча-программатора ArduinoISP.  В ядро Arduino добавлена поддержка для ATmega1284P.

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

Полный список изменений можно увидеть на Google Code.