Ble-устройство с мэмс-датчиками? – легко, с программным пакетом bluemicrosystem1. Системные платы STM32 Nucleo

Где-то около года назад заказал на ali bluetooth module HC-05 . На тот момент ещё не знал для чего он мне может понадобиться, но беспроводные технологии манили меня своим таинством.
На момент заказа на рынке была представлена целая линейка bluetooth модулей от HC-03 до HC-09, но некоторые из них могут работать либо в режиме master (HC-04-M ), либо в режиме slave (HC-06-S ), а HC-05 может работать в обоих режимах, поэтому выбор пал на него.

Давайте кратко рассмотрим его характеристики:

  • чип Bluetooth – BC417143 производства CSR company;
  • протокол связи – Bluetooth Specification v2.0+EDR;
  • радиус действия – до 10 метров, у меня в квартире ловит через 2 бетонные стены;
  • совместимость со всеми Bluetooth-адаптерами, которые поддерживают SPP;
  • объем flash-памяти (для хранения прошивки и настроек) – 8 Мбит;
  • частота радиосигнала – 2.40 .. 2.48 ГГц;
  • хост-интерфейс – USB 1.1/2.0 или UART;
  • энергопотребление – ток в течение связи составляет 30–40 мА. Среднее значение тока около 25 мА. После установки связи потребляемый ток 8 мА. Режим сна отсутствует.
Обычно модули для DIY продаются в виде двух спаянных плат, меньшая из них - сам bluetooth модуль, большая - переходник, на котором расположен стабилизатор и прочая обвязка, позволяющая использовать модуль для DIY.

Распиновка DIY модуля:

  • VCC – питание +5В
  • GND – земля
  • TXD, RXD – выводы UART интерфейса для общения с МК.
  • KEY – вывод для входа в режим AT-команд
  • LED – можно подключить светодиод с токоограничивающим резистором, в случае установки соединения между модулями, светодиод загорится.
Сразу после того как модуль пришёл, попробовал его запустить, но попытка не увенчалась успехом. Поэтому было принято решение, снять термоусадку и пропаять его. После пропайки модуль заработал, но после того, как была одета термоусадка снова перестал работать. Думаю читатели уже догадались, что виной тому была термоусадка, одетая на антенну. Проблема была решена удалением термоусадки с антенны.

Для проверки модуля необходимо:

  • подать на него питание
  • соединить вывод tx с выводом rx переходника usb-uart
  • cкачать программку Terminal v1.9b by Bray
  • установить соединение с переходником usb-uart на скорости 9600. Эта скорость установлена по умолчанию в bluetooth модуле.

Если программа не видит переходник, то скорее всего ему присвоен номер com порта выше 10, изменить его можно в диспетчере устройств. После этих манипуляций, мы можем принимать и отправлять данные по bluetooth c компа.

Теперь надо сконфигурировать второе устройство для обмена данными, в качестве такого устройства может выступать телефон, ноутбук или планшет. Выбор пал на планшет, с ОС Android , далее опишу как конфигурировать его для обмена данными по bluetooth .
Для нашей задачи качаем с play market приложение bluetooth terminal от Qwerty и устанавливаем его. Включаем bluetooth и ищем среди устройств наш модуль.




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

Убедившись, что модуль работает подключил его к Atmega16 и написал программу, которая по приёму определённых символов будет выполнять какие-то действия, например включать светодиод.
#define F_CPU 8000000UL #include #include ISR(USART_RXC_vect) { switch(UDR) { case "f": //тут можно зажечь светодиод break; case "r": //а тут погасить break; } } int main(void) { DDRD &= ~(1<<0); //rx на вход DDRD |= (1<<1); //tx на выход //разрешаем прием, передачу, прерывание по приёму UCSRB = (1<Включив несколько раз светодиод понял, что гораздо удобнее было бы не клацать по клавиатуре в терминале, а создать на планшете примитивный интерфейс для отправки команд. Опыта в программировании под Android у меня практически нет, но создать интерфейс всё-таки получилось. Посмотреть на результат можно в

Сегодня помучаем получившие уже достаточно широкое распространение Bluetooth модули HC-04. Думаю, не ошибусь, если скажу, что широкое распространение они получили благодаря нашим китайским друзьям, низкой цене и бесплатной доставке с Dealextreme)))

В простейшем случае модуль представляет собой Bluetooth-RS232 мост: какие байтики на вход послали, такие по радиоканалу и передались – фактически радиоудлинитель порта, все очень просто и легко интегрируется в существующие системы с RS232.

Вообще, у этих модулей достаточно много названий (по крайней мере, в продаже их можно найти под разными именами): HC-04, HC-05, BC04, BC05, BC06, RF-BT0417C, BT0417 и ряд других. Однако общей для все остается основа, а именно – микроконтроллер BC417143B от Cambridge Silicon Radio (CSR). Это решение называется BlueCore4, и все модули на его основе даже внешне очень похожи, поскольку основаны, видимо, на каком-то одном reference-design. Я пересмотрел достаточно много фотографий модулей, отличия минимальны: чуть другое расположение кварца и 1-2 пассивных компонентов, другой типоразмер какого-либо элемента – не более.

BC417143B сам по себе обладает достаточно богатым набором интерфейсов и возможностей:

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

Мне с Dealextreme прислали десяток вот таких модулей без опознавательных знаков:

Размеры – 27х13мм, питается железячка от 3,3В, потребляет в процессе установки соединения до 30мА и около 8мА в условиях стабильного коннекта. Поддерживает Bluetooth 2.0. Умеет работать в двух режимах: АТ-команд (для настройки и управления) и передачи данных (просто тупо отдает в эфир все, что получает по последовательному интерфейсу), переключение между режимами – аппаратное (в зависимости от состояния определенной ноги модуля. Скорость UART’a из стандартного ряда 1200 – 115200, настраивается АТ-командами (по умолчанию – 9600 8N1).

Назначение выводов следующее:

Или есть вот такая красивая картинка:

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

В режим AT-команд модуль переводится подтягиванием вывода PIO11 к питанию с последующим сбросом, в режиме передачи данных этот вывод заземлен или болтается в воздухе.

Собственно, «из коробки» этот модуль не умеет практически ничего, команды ограничены минимальным набором (все команды заканчиваются посылкой символов 0x0D и 0x0A):

AT – ответ ОК

AT+BAUDx, где (х = 1..8, что соответствует скорости 1200..115200) – установка скорости интерфейса, ответ – OKxxx, где xxx – установленная скорость

AT+NAMEname – установить имя модуля name, ответ – OKname

AT+PINxxxx – установить пин-код для соединения хххх, ответ – OKхххх

На этом все. Причем в данном виде модуль не может выступать в качестве инициатора соединения, мастера, он может быть только ведомым. Конечно, применение можно найти, но как-то оно скучно получается.

Варианты? Перепрошивка, что же еще… Но сначала сделаем несколько плат для удобства работы с модулем.

Вариант №1

Схема платы на рисунке:

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

В собранном виде оно выглядит так:

Уже после (забегая вперед) перепрошивки модуля была изготовлена плата по второму варианту:

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

На обратной стороне платы расположены цепи питания и внешнего сброса, все остальное – сверху.

Практически по этой же схемы был изготовлен вариант № 3:

Здесь вся суть в том, что данная плата предназначена для замены модулей MaxStream Xbee и XbeePro (это ZigBee, их я иногда тоже использую) и совместима с ними по выводам:

Как потом оказалось, такие платки уже даже серийно выпускаются…

Теперь насчет перепрошивки модуля. Многие читатели, уверен, обратили внимание на то, что на всех платах я сохранил SPI-интерфейс модуля: именно через него и осуществляется прошивка. Нужно собрат несложный программатор на LPT-порт компьютера, практически 5 проводков для AVR:

По сути, это просто согласование уровней между 5В LPT и 3.3В модулем.

В сборе выглядит вот так:

Я установил ряд разъемов для удобства подключения. Для программирования на модуль требуется подать внешнее питание.

Все манипуляции производятся под управлением Casira BlueSuite или Casira BlueLab. Насколько я понимаю, это разработки непосредственно CSR, причем раньше они разрешали регистрироваться у себя на сайте, после чего можно было скачивать это программное обеспечение и всяческие примеры, готовые прошивки и т.п. решения для их продуктов. Однако на данный момент судя по всему это работать перестало (для России, по крайней мере, но если у кого получится – дайте знать). Однако многие вещи остались лежать в Сети, так что при некотором старании все ищется. BlueLab я раздобыл только недавно и еще не пробовал, но это целая среда для разработки собственных приложений плюс документация и примеры, так что при желании там есть, где развернуться. А вот после установки BlueSuite на компе появляется масса всяческих утилит, предназначенных для работы в том числе и с нашим пациентом. Поэтому цепляем модуль к программатору, программатор к компу, подаем питание на модуль, не забывая внимательно следить, чтобы земли были объединены… А то мало ли что;)

Непосредственно для прошивки предназначена Blue Flash:

После запуска выбираем способ подключения к модулю (LPT1) и указываем на файл прошивки. Как уже стало понятно, прошивать будем нечто под названием «HC-05».

После этого нажимаем «Stop Processor» (не волнуйтесь, это про модуль, а не про ваш любимый комп)), становятся активными остальные кнопки:

Я бы порекомендовал на всякий случай сохранить имеющуюся прошивку через «Dump», хотя это и не обязательно, в принципе… Ну а дальше жмем «Download» и через пару минут получаем совсем другое устройство. Конечно, можно еще «Verify» жмакнуть, чтоб убедиться, что все хорошо.

Теперь запускаем PSTool.

Первым делом требуется указать способ подключения модуля:

Открывается основное окно:

В левой части немеряно всяческих параметров, значения которых можно всячески изменять. Настроек реально очень много, так что простор для экспериментов имеется, я, честно говоря, особо не копался.

Стоит сразу изменить адрес устройства:

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

Теперь ради интереса можно запустить BlueTest3. Опять же, выбираем способ подключения:

И попадаем в основное окно:

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

Ради чего все это было. В результате мы получили сильно расширенный набор AT-команд. Теперь можно сканировать эфир, задавать доверенные устройства, изменять класс модуля и многое другое. Одно из самых полезных благоприобретенных качеств – возможность конфигурирования модуля в режим мастера. Т.е. теперь имея два таких модуля можно делать полноценный радиомост без участия третьей стороны. Полное описание команд можно посмотреть в даташите на модуль, доступном в конце статьи.

Один нюанс. На данный момент я перепрошил 4 модуля и после перепрошивки скорость последовательного интерфейса у них почему-то принимала случайное значение: у кого-то 9600, у другого – 115200. Причины явления мне не понятны, но после соответствующей настройки AT-командами все возвращается в нормальное русло. Да, в режиме команд скорость интерфейса – 38400.

Вобщем, собрали пару плат, научились устанавливать соединение, погоняли туда-сюда байтики по воздуху – вроде все работает, стабильно, дальность на воздухе метров до 20, бетонную стену пробивает, в пределах квартиры работает. Теперь хочется сделать что-то более-менее осмысленное.

У меня уже довольно давно была мысль сделать какую-нибудь систему синхронизации времени для нескольких домашних часов в разных помещениях (DS1307, конечно, достаточно точна сама по себе, да и другие микросхемы RTC тоже, но вот кварцы и прочие компоненты часов все же приводят к некоторому убеганию на уровне 10-15с/месяц: не критично, но неаккупратненько как-то). Это вполне себе реализуемо на таких модулях, так почему бы и нет? Итак, нам нужно установить по модулю в каждые часы, время на которых мы хотим изменять, а так же некий передатчик точного времени. В качестве такого передатчика вполне логично использовать компьютер с синхронизацией времени из Сети (конечно, не атомный эталон, ну дык ведь и не для точной промышленности стараемся в данном случае). В принципе, в качестве передатчика вполне подойдет какой-нибудь USB-донгл, но у меня такого не нашлось (да и кроме того хотелось лишний раз повозиться с новыми для меня STM32 и проверить некоторые другие решения), поэтому родилась такая вот схема:

Суть в чем: микроконтроллер STM32F100C4T6 одним своим UART смотрит через преобразователь интерфейсов в USB компа, а вторым – в Bluetooth-модуль. Кроме этого имеется кучка индикаторных светодиодов и несколько кнопок (не используются). Также имеется возможность принудительно сбрасывать модуль и переводить его в режим команд/данных – соответствующие выводы подключены к микроконтроллеру.

В качестве USB-RS232 преобразователя применена Atmega8 с софтовой реализацией USB. Честно говоря, не помню, откуда скатал это решение, но все исходники доступны в конце статьи (давно уже лежала на винте эта схема, все никак не доходили руки попробовать, как оно живет). Конечно, решение избыточно, но просто было интересно. Не обязательно использовать именно такой переходник, варианты рассмотрены . Скорости обмена между компом, микроконтроллером и модулем равны и составляют 38400кбит/с. Вот чем мне нравятся STM-ки, так это гибкостью системы тактирования: я поставил кварц на 4.433619 МГц (купил по случаю 1000шт задешево, теперь вот использую)), частота тактирования ядра при этом 26.601714 МГц, но совершенно спокойно получаются любые стандартные скорости обмена по UART.

Все это дело упаковалось в пластиковый корпус BOX-KC01:

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

USB разъем не устанавливал: miniUSB у меня маловато, а хвостов с USB-A папой на конце много и бесплатно – просто распаял на плату кабель длиной около метра.

Кнопки, как уже сказал, не пригодились, финально все выглядит вот таким образом:

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

Итак, контроллер тоже может работать в двух режимах – режиме команд и режиме передачи данных.

Вне зависимости от режима работы все, что появляется на выходе BT-модуля (я имею ввиду его последовательный интерфейс, конечно же), передается на комп. Очевидно, в режиме передачи данных контроллера все, что передается с компа на контроллер попадает на вход BT-модуля и далее в эфир. Переход из режима данных в режим команд происходит, если контроллер получает последовательность из трех символов «+» подряд.

В этом режиме поддерживаются следующие команды (все в символах латиницы):

«с0» - переключение контроллера в режим данных, возвращает «Data Mode OK»

«с1» - сброс ВТ-модуля, возвращает «ВТ Reset OK»

«с2» - переключение ВТ-модуля в режим команд, возвращает «BT Command Mode OK»

«с3» - переключение ВТ-модуля в режим данных, возвращает «BT Data Mode OK»

«с4» - сброс настроек ВТ-модуля, возвращает «BT Reinit Completed»

«с5хххххххххххх» - установка нового адреса ведомого (хххххххххххх – сам адрес), возвращает «Setting New Bind Address Completed»

«с6» - состояние соединения в соответствии с состоянием статусного светодиода ВТ-модуля, возвращает «Connection Passed» или «Connection Failed»

«с9» - сброс контроллера, возвращает «MCU Reset...»

Вот скриншот общения с контроллером:

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

После этого ВТ-модуль устанавливает соединение с тем устройством, с которым он работал в последний раз перед выключением.

Светодиоды отображают прохождение данных по последовательному интерфейсу BT-модуля и соединению с ПК (Rx и Tx), состояние BT-модуля (Stat, см. даташит), состояние соединения (Conn) и состояние контроллера (Contr. Mode: мигает в режиме команд и повторяет Conn в режиме данных)

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

Непосредственно для синхронизации времени на часах была «написана» небольшая программка на HiAsm:

Все предельно просто: выбираем ком-порт, на котором висит контроллер, далее соединяемся с целевым устройством (OrbitLED (пришлось поправить прошивку для работы по UART, ) или GreenClock (один мой уже довольно старый проект, делается по мере наличия времени уже несколько лет, надеюсь, скоро все же выложу его на Радиокоте)) и либо нажимаем «Sync Time» для синхронизации, либо «Set Time» для установки любого другого времени и даты, настроенного в полях «Time and Date Setup».

Назначение кнопок в нижней части окна понятно из их названий. Часть из них вряд ли когда-то понадобится и использовалась исключительно для тестовых целей. Вообще конечно эту программу нужно переделать так, чтобы синхронизация происходила по расписанию в автоматическом режиме. Тогда, поместив ее в автозагрузку на домашнем сервере 24/7, можно полностью решить вопрос одинаковости показаний часов по всей квартире. Именно так я в ближайшее время поступить и собираюсь.

Все вопросы в .

Как вам эта статья?

День добрый.
Сегодня я попытаюсь рассказать о своей попытке построить систему удаленного управления ПК в пределах одного помещения.

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

Предыстория

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

Один вариантов использовал привычный для пультов ДУ к современной бытовой технике способ передачи данных - IR он же ИК. Однако ввиду того что это не совсем удобно, да и с большими расстояниями проблема. На самом же деле всё проще чем вы можете подумать, тот модуль что я достал из одного и «трупиков» КПК был предназначен для работы именно как приёмопередатчик, то есть не было даже инвертора сигнала. Поэтому когда я подключил его напрямую к преобразователю USB<->UART на отладочной консоли я увидел непрекращающийся поток случайных символов.

Поэтому я решил использовать ставшим для меня привычным BT приёмопередатчик. Также нарыв в закромах оставшийся от одного из тестов модуль ESD-200 (не берите его, он реально неудобный и немного туповатый, а также дорогой модуль, плюс ко всему на больших расстояниях начинают пропадать пакеты). Чтобы не скучно было подцепил экран от Siemens M55. Также есть блок из шести кнопок на которые можно назначить произвольные команды. В качестве мозга выбрал отладочную плату STM32F4DISCOVERY - и отладчик на борту, и паять ничего не надо.

Общая схема

Внимание: то что здесь описано присутствует в основном в теории. На практике же некоторые моменты упрощены так как это макет и просто потому что так было быстрее сделать.
Со стороны ПК, на котором кстати Linux (у меня это Gentoo Linux, у вас это может быть любой другой дистрибутив) крутится программа - сервер. Она опрашивает список доступных устройств и найдя нужное устанавливает с ним соединение.
Со стороны устройства стоит триггер который контролирует статус соединения. При обнаружении подключения он вызывает модуль первичного опроса (своеобразный пинг). Который при удачном завершении переводит устройство в интерактивный режим.
Этот режим характерен тем что передачу инициирует любой из двух компонентов системы. Выбран такой принцип работы системы по двум причинам - малое время реакции на любые действия, отсутствие дополнительных таймеров (кроме таймера TIMEOUT со стороны демона на ПК) ну и конечно относительно простой протокол обмена. Хотя по идее нужен TIMEOUT со стороны устройства т.к. при работе с BT модулем иногда возникают проблемы.

Реализация

Теперь посмотрим что у нас получилось по выше расписанной схеме:
  • Демон который крутится на стороне ПК. Хотя какой там демон, в текущей реализации это скрипт на пару сотен строчек с минимальной обработкой ошибок. Один из самых интересных компонентов. Целиком написан на языке Python. Одной из особенностью данного модуля является то что для управления программами пользователя он использует систему сообщений DBUS. Кстати имплементация этого протокола для языка Python есть в любом современном дистрибутиве. Далее я подробно распишу как работает этот код.
  • Протокол для полностью асинхронного многопоточного обмена сообщения, реализован поверх последовательного порта с эмуляцией множества соединений используя систему адресации сообщений. Был придуман после прочтения описания сетевых протоколов и стандартов USB, а ещё я его написал т.к. мне было лениво курить MODBUS, а точнее грустно смотреть на его реализацию.
  • Устройство с прошивкой, которое используя модуль Bluetooth передаёт по последовательному порту команды при нажатии пользователем на кнопки устройства. Возможна также обратная связь в виде отображении информации на дисплее устройства. Но к сожалению сделано пока чисто для примера. Передаёт фиксированные команды и больше ничего.

Демон

После поиска устройства, мы подключаемся к нему и ожидаем поступления команд. На некоторые из запросов будет дан ответ, на другие же просто будет выполнено определённое действие.

Устроен в прототипе достаточно просто:
#!/usr/bin/python2 # -*- coding: utf-8 -*- import serial import dbus import subprocess import time import os # Здесь я убрал никому не нужную инициализацию BT модуля, тем же кому интересно могут взять её из моего полного кода этого модуля, ниже я опишу где взять исходные коды. Также я убрал этот код ещё и потому, что он сделан криво и так делать не стоит в рабочем модуле. # Обычное подключение к последовательному порту ser = serial.Serial("/dev/rfcomm0", 115200, timeout=1) # Подключение к сессии шины DBUS, откуда мы подключимся к плееру медиапрограммы Amarok. bus = dbus.SessionBus() am = bus.get_object("org.kde.amarok", "/Player") # Словарь ключами которого выступают команды которые мы получаем из последовательного порта, а в итоге вызываем соответствующие методы объекта плеера. commands = { "p": , ">": , "<": , "m": , "+": ], "-": ] } print "Connected" # бесконечный цикл в котором мы и будем работать. try: while 1: try: # принимаем первый байт нашего сообщения, при этом ждём его не более секунды, если ничего не пришло за этот промежуток значит нам ничего и не присылали. line = ser.read(1) # в этой части мы ловим специфичное исключение по которому судим что последовательный порт у нас отвалился except serial.serialutil.SerialException: # а так как нам надо работать, то мы закрываем этот порт, и ждём пол секунды пока завершится это действие. ser.close() time.sleep(0.5) while 1: try: # позже пытаемся установить соединение вновь ser = serial.Serial("/dev/rfcomm0", 115200, timeout=1) break # если же опять всё плохо, т.е. нам так и не удалось подключится к последовательному порту, то мы ожидаем 2 секунды и повторяем снова наш круг. except serial.serialutil.SerialException: time.sleep(2) # если мы действительно считали байт (а это может быть и не так, потому, что у нас стоит время ожидания этого байта) то, if len(line) == 1: # проверяем что это за байт, пока реализован только приём команд if line == "C": print "Command" # дочитываем оставшиеся 2 байта заголовка - адрес и размер сообщения line += ser.read(2) # не забываем проверить что мы считали именно 2 байта - т.е. размер заголовка должен быть равен 3 байтам. if len(line) == 3: print "0x%02x 0x%02x 0x%02x" % (ord(line), ord(line), ord(line)) # это захадкоженный ответ на ping, в реальном модуле он должен быть стандартным для любого адреса, т.к. этот ответ определяет готовность "ящика" к работе с ним. if ord(line) == 0x00 and ord(line) == 0x00: print "Device ping" ser.write("A") ser.write(chr(0x00)) ser.write(chr(0x02)) ser.write(chr(ord("O"))) ser.write(chr(ord("K"))) print "Ansver to device" # если мы обратились ко второму узлу, то это сообщения общего уровня. if ord(line) == 0x02: # получаем длину и считываем сообщение. mlen = ord(line) message = ser.read(mlen) # если сообщение есть в словаре команд то выполняем команду которая соответствует полученному сообщению if message in commands: current = commands current(*current) # при получении исключения - прерывание от клавиатуры выходим. except KeyboardInterrupt: ser.close() del am print "Exiting" # не забывая закрыть соединение с BT модулем. # cleaning cmd = "sudo rfcomm unbind all" runner(cmd)

Протокол

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

Устройство

Вот собственно вид устройства которое у меня получилось, также как и модуль со стороны ПК это устройство делалось как прототип, учитывая горький опыт неудач при постройке первой версии системы:

Управляется устройство прошивкой, написанной на С, для сборки используется собственная структура проекта которую вы можете увидеть пройдя по ссылке на проект ниже.
/* main work function */ void work(void) { unsigned short i, j; unsigned char mailbox_num = 0; volatile ProtoIOMBox * mbox; /* Убрал из примера инициализацию периферии и протокола, а также вывод на дисплей картинок - логотипа. */ // Провека статуса порта перед запуском. /* check status */ check_status(); // Здесь происходит подготовка "ящиков" сообщений для приём и передачи, а также установка флагов о готовности. после осуществляется вывод сообщения на экран и в случае удачного ответа от сервера переход в режим отправки команд. /* send ping */ mbox->outbox->header = "C"; /* Command */ mbox->outbox->size = 0x00; /* 0 for ping request */ mbox->outbox_s = PROTO_IO_MBOX_READY; /* Box ready */ mbox->inbox->size = 64; /* buffer len for control */ mbox->inbox_s = PROTO_IO_MBOX_READY; /* Box ready */ /* wait connection estabilished */ while (status == 0); /* send ping message */ proto_send_msg(mailbox_num); /* wait to send message */ while (mbox->outbox_s <= PROTO_IO_MBOX_SEND); if (mbox->outbox_s == PROTO_IO_MBOX_COMPLETE) LCD_String("Con", 36, 6, 1, WHITE, GLASSY); else LCD_String("Un", 36, 6, 1, RED, GLASSY); /* get ping message */ /* FIXME wtf? this not work or work parity */ //proto_get_msg(mailbox_num); /* wait to get message */ while (mbox->inbox_s <= PROTO_IO_MBOX_SEND); if (mbox->inbox_s == PROTO_IO_MBOX_COMPLETE) { LCD_String("OK", 36 + 3 * 7, 6, 1, GREEN, GLASSY); for (i = 0; i < mbox->inbox->size; i++) LCD_Char(mbox->inbox->message[i], 70 + i * 6, 6, 1, WHITE, GLASSY); } else LCD_String("ERR", 36 + 3 * 7, 6, 1, RED, GLASSY); // Бесконечный цикл в котором мы опрашиваем кнопки и посылаем команды если одна из них нажата. Допускается множественное нажатие кнопок, в этом случае будут отосланы все те команды которые соответствуют нажатым кнопкам. /* infinity loop */ while (1) { if (button_state.state == B_CLICK) { sender("+"); button_state.state = B_RELEASE; } /* код аналогичен и для остальных кнопок */ } }

Также отдельно хочу упомянуть модуль отправки и приёма сообщений - в проекте это модуль proto.o - исходный код proto.c и заголовочный файл proto.h. Код приводить не буду так как он большой. А вот в целом расскажу как он работает.
Модуль рассчитан целиком на работу от прерываний, однако передача данных корректно не реализована сейчас поэтому требует предварительного вызова инициализации. Приём и отправка сообщения осуществляется с помощью 2 конечных автоматов, которые по мере пересылки байтов меняют своё состояние. Реализована проверка сообщения на валидность и обработка ошибок.

Также прикладываю видео работы системы в целом:

Bluetooth — это пожалуй самый распространенный тип связи для коротких дистанций, которым пользуются большинство современных электронных устройств. Телефонные гарнитуры, наушники, клавиатуры и мышки, принтеры и бог знает какие еще гаджеты. Некоторое время назад bluetooth был распространен как средство передачи файлов между телефонами.

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

Лично я использую BT для управления роботами со смартфона. В Google play уже есть несколько приложений с удобным интерфейсом именно для этих целей. Участники нашего хакспейса MakeItLab с помощью Bluetooth управляют удаленно светом и собирают телеметрию с борта квадрокоптеров.

Самыми доступными на сегодня Bluetooth модулями можно назвать HC-05 и HC-06. Они в изобилии присутствуют в Китайских онлайн-магазинах и на ebay. Отличия между ними в том, что первый может работать как в режиме ведущего (slave), так и в режиме ведомого (master). Второй же является чисто ведомым устройством (но это поправимо!). Другими словами, HC-06 не может сам обнаружить парное устройство и наладить с ним связь, он может лишь подчиниться ведущему.

Оба устройства базируются на чипе CSR BC417 , который поддерживает Bluetooth версии 2.0 со скоростью до 3 Мбит/сек. Именно об этих модулях далее и пойдет речь.

1. Варианты исполнения

Обычно модули продаются в виде двух спаянных вместе плат. Меньшая из них — заводской модуль, широко используемый в разных электронных устройствах. Большая — специальная макетная платка для DIY. Так выглядит меньшая плата с чипом BC417:

А так сами DIY модули HC-05 и HC-06:

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

Очень распространен и другой вариант макетной платки. В отличие от показанных выше, в них нет ноги EN, но есть нога KEY, что немного удобнее.

Распиновка

Итак, за что отвечают ноги у всех вариантов модулей.

  • EN — включение/выключение модуля;
  • VCC — питание +5В;
  • GND — земля;
  • TXD, RXD — UART интерфейс для общения с контроллером;
  • STATE — индикатор состояния;
  • KEY — нога для входа в режим AT-команд.

Настройка модуля осуществляется в режиме AT-команд, который включается с помощью ноги KEY. Отсюда, у многих счастливых обладателей модуля может возникнуть вопрос: что делать, если мне попался модуль без KEY?

На самом деле, на малой плате эта нога конечно есть, просто она не разведена на большой плате. Черт знает зачем китайцы так сделали, но проблема решается легко. KEY-нога растет отсюда:

2. Подключение к Ардуино Уно

Ног не так много, так что запутаться не получится. Подключаем к bluetooth к Arduino Uno по следующей схеме:

Bluetooth GND VCC TXD RXD KEY
Ардуино Уно GND +5V 10 11

TX и RX подключаем к GPIO ногам 10 и 11, так как аппаратный UART на ногах 0 и 1 будет занят общением с компьютером.

В рабочем режиме KEY никуда не подключается, так что в таблице я его не стал соединять с GPIO ногами Arduino.

3. Сопряжение уровней напряжения

Малая платка Bluetooth модуля имеет напряжение логики 3.3 Вольта. А это значит, что Ардуино Уно может либо сжечь у нее порты, либо просто неправильно передавать сигналы. К счастью, в большинстве случаев большая плата имеет на своем борту все необходимое, чтобы этого избежать. Указанные выше модули легко подключаются к Arduino, без лишних заморочек. Даже не смотря на то, что сами изготовители написали на платке предупреждение об уровне сигналов 3.3 Вольта.

Однако, в некоторых ситуациях может потребоваться поставить на линию Ардуино TX — BT RX делитель напряжения для понижения логических уровней. На самом деле, даже если все работает и без делителя, лучше его все-таки поставить, для порядка. Схема делителя ниже:

4. Подготовка Arduino

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

#include #include int gLedPin = 13; int gRxPin = 10; int gTxPin = 11; SoftwareSerial BTSerial(gRxPin, gTxPin); void setup() { # 38400 - для метода №1, 9600 - для метода №2 BTSerial.begin(38400); Serial.begin(9600); delay(500); } void loop() { if (BTSerial.available()) { Serial.write(BTSerial.read()); } if (Serial.available()) { BTSerial.write(Serial.read()); } }

Загружаем скетч на Ардуино и переходим к следующему шагу.

5. Подготовка терминала

В качестве терминала можно использовать встроенный в Arduino IDE монитор порта, а можно любой другой. Я использовал сторонний терминал TeraTerm. Перед соединением необходимо сделать две важные настройки:

  • скорость обмена: 9600;
  • символа перевода строки: CR+LF.

Вот как настройки выглядят в TeraTerm:

Когда все правильно настроено, подключаемся к COM-порту и проверяем соединение. Все дальнейшие манипуляции рационально поделить на две части: для ведомого модуля HC-06 и для ведущего HC-05.

6. Настройка HC-06

Проверка соединения

После подачи питания на модуль, светодиод начнет бодро мигать:

Теперь заходим в терминал и пишем команду: AT

В ответ, модуль нам должен сказать: OK

Следующая наша команда запросит у модуля его версию: AT+VERSION?

Получаем что-то вроде такого: OKLinvor1.5

Получилось? Если нет, то проверяем:

  1. Скорость соединения с модулем, которая задается в программе-трансляторе: для связи с ведомым скорость должна быть 9600.
  2. Настройки символа перевода строки: не забываем про CR+LF!
  3. Нажимаем ли после каждой команды Enter? Мало ли…

Полезные команды

У ведомого Bluetooth модуля есть всего три параметра для настройки:

  • команда смены пароля на устройстве: AT+PIN<пароль>
  • смена скорости: AT+BAUD<скорость>
  • смена имени устройства: AT+NAME<имя>

Например, для смены пароля пишем: AT+PIN4321

В общем-то готово! Теперь можно соединиться с модулем, например, со смартфона. Об этом речь пойдет во второй части моего повествования.

7. Настройка HC-05

Переход в режим AT-команд

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

Первый метод:

  1. Отключаем модуль от питания.
  2. Подаем на ногу KEY сигнал +3.3V.
  3. Включаем модуль.

В это варианте скорость обмена с модулем устанавливается в 38400.

Второй метод

  1. Включаем модуль.
  2. Подаем на ногу KEY сигнал +3.3V;

В этом случае скорость обмена с модулем будет равна стандартной, установленной настройками. По-умолчанию 9600.

После успешного перехода в режим AT-команд светодиод на модуле начнет мигать раз в две секунды.

Проверка соединения HC

Проверим командный режим HC-05 так же как и в случае ведомого модуля:

>>: AT
<<: OK
>>: AT+VERSION?
<<: +VERSION:2.0-20100601

Настройка HC-05 как ведомого (slave)

Для превращения модуля в ведомого потребуется выполнить несколько команд:

Сброс предыдущих настроек: AT+ORGL

Сброс спаренных устройств: AT+RMAAD

Установка пароля: AT+PSWD=1234

Включение режима ведомого: AT+ROLE=0

Дополнительно можно узнать адрес устройства (понадобится для настройки спаренного модуля): AT+ADDR?

В ответ получим сам адрес: ADDR=12:6:143117

После настройки, отключаем ногу KEY от +3.3В, и перезапускаем модуль. Готово!

Настройка HC-05 как ведущего (master)

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

Сброс предыдущих настроек: AT+ORGL

Сброс спаренных устройств: AT+RMAAD

Включение режима ведущего: AT+ROLE=1

Рестарт после смены роли: AT+RESET

Если мы хотим связать ведомого и ведущего, пишем такие команды:

Установка пароля ведомого: AT+PSWD=1234

Указываем парное устройство: AT+PAIR=<адрес>,<таймаут> (пример: AT+PAIR=12,6,143117, 5 )

Связываем с конкретным адресом: AT+BIND=<адрес> (пример: AT+BIND=12,6,143117 )

Запрещаем соединяться с другими адресами: AT+CMODE=0

Готово! Теперь модуль связан с ведомым, и при каждом включении будет пытаться с ним соединиться.