Arduino:Библиотеки/XBee

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.



Библиотека XBee[1][2]

Это библиотека для коммуникации с XBee-модулями в режиме API. Имеется поддержка и для модулей Series 1 (802.15.4), и для модулей Series 2 (ZB Pro/ZNet). Кроме того, библиотека XBee поддерживает большинство типов пакетов, включая TX/RX, AT Command, Remote AT, I/O Samples и Modem Status.

Новости

  • 18.11.15. Опубликована новая книга Мэттхиджса Куиджмана (Matthijs Kooijman) – «Building Wireless Sensor Networks Using Arduino» («Создание беспроводных сетей для датчиков при помощи Arduino»). Она описывает основы работы с XBee-устройствами в режиме API, а также затрагивает ряд более продвинутых тем (шифрование, безопасность, режим сна) и создание проектов при помощи библиотеки XBee.
  • 15.09.15. Мэттхиджс Куиджман добавил в библиотеку ряд улучшений, включая обратные вызовы, улучшенную отладку, новые функции и исправления багов. Все это можно найти в релизе 0.6.0.
  • 28.02.15. Код перенесен на GitHub. Впрочем, некоторая документация по-прежнему доступна на googlecodehttps://code.google.com/p/xbee-arduino.
  • 01.02.14. Выпущен релиз 0.5. В сущности, это релиз 0.4 с парой-другой исправлений багов. Если вы обновляетесь с версии, выпущенной до 0.4, то обратите внимание, что функция для указания последовательного порта была изменена (см. файл «SoftwareSerialReleaseNotes»). Также репозиторий был перенесен с Subversion на GitHub.
  • 15.10.12. Выпущен релиз 0.4 (бета). Пол Стоффреген (создатель Teensy) добавил патч, позволяющий использовать для XBee-коммуникации функционал SoftwareSerial. Это освобождает последовательный порт для отладки или для подключения к другим устройствам. Попробуйте и если обнаружите проблемы, сообщите о них в нашей странице в Группах Google. Чтобы включить поддержку этой функции, вам нужно поменять API (см. файл «SoftwareSerialReleaseNotes»).
  • 21.12.11. Выпущен релиз 0.3. Он включает поддержку Arduino 1.0, а также несколько исправлений багов и новую функцию setSerial() – для использования альтернативных последовательных портов (например, на Mega). Этот релиз также совместим с предыдущими релизами Arduino.
  • 03.04.11. В API XBee создана вики XBeeUseCases, которая описывает несколько примеров использования коммуникации при помощи XBee-модулей.
  • 14.11.09. Выпущен релиз 0.2.1. Он содержит исправление бага для Remote AT.
  • 26.10.09. Выпущен релиз 0.2. Он добавляет поддержку пакетов AT Command, Remote AT и I/O Sample (Series 1 и Series 2). Вместе с этим релизом выпущено несколько новых примеров.
  • 09.08.09. Эндрю Рапп (Andrew Rapp) выпустил Droplet – беспроводное устройство, совмещающее в себе функции пульта управления и LCD-экрана. Оно поддерживает Twitter, Google Calendar, погоду и т.д. Для отправления и получения пакетов XBee оно использует именно эту библиотеку.
  • 19.04.09. Выпущен релиз 0.1.2. Он привносит несколько конструкторов для создания базовых запросов, а также функции get/set для упрощения повторного использования запросов.
  • 29.03.09. Первоначальный релиз.

Документация

Документация Doxygen доступна на GitHub по этой ссылке. К сожалению, онлайн она больше не доступна, поскольку GitHub, в отличие от Subversion, не поддерживает MIME-тип HTML.

Также стоит упомянуть проект XBee API (Java). Хотя он является API для XBee на Java, в нем все же имеется несколько вики, относящихся и к библиотеке XBee для Arduino, включая настройку XBee и примеры использования.

Кроме того, у библиотеки XBee есть страница в Группах Google.

Пример

Создатель библиотеки Эндрю Рапп написал несколько скетчей, демонстрирующих отправку/получение пакетов при помощи XBee-модулей Series 1 и Series 2. Их можно найти в папке с примерами. Ниже – пример отправки пакета при помощи модуля Series 2:

// создаем объект XBee в самом верху скетча:
XBee xbee = XBee();

// запускаем последовательную коммуникацию:
Serial.begin(9600);
// приказываем XBee использовать аппаратный последовательный порт 
// (впрочем, его можно настроить и на использование программного порта):
SoftwareSerial
xbee.setSerial(Serial); 

// создаем массив для хранения данных, которые нужно отправить:
uint8_t payload[] = { 'H', 'i' };

// указываем адрес удаленного XBee-модуля (это SH + SL):
XBeeAddress64 addr64 = XBeeAddress64(0x0013a200, 0x403e0f30);

// создаем TX-запрос:
ZBTxRequest zbTx = ZBTxRequest(addr64, payload, sizeof(payload));

// отправляем запрос:
xbee.send(zbTx);

Полный код смотрите в примерах. Для коммуникации между Arduino и компьютером смотрите проект XBee API. Чтобы добавить в новый скетч поддержку XBee, добавьте в самый верх скетча

#include <XBee.h>

Это также можно сделать, кликнув в IDE Arduino на Скетч > Подключить библиотеку > XBee (Sketch > Include Library > XBee).

Книги

Чтобы побольше узнать об Arduino и XBee, имеет смысл обратить внимание на эти книги:

  • Building Wireless Sensor Networks Using Arduino («Создание беспроводных сетей для датчиков при помощи Arduino»; есть версия для Kindle)
  • Wireless Sensor Networks: with ZigBee, XBee, Arduino, and Processing («Беспроводные сети для датчиков: при помощи ZigBee, XBee, Arduino и Processing»; есть версия для Kindle)
  • Programming Arduino: Getting Started with Sketches («Программирование Arduino: Знакомство со скетчами»)
  • Making Things Talk («Как заставить вещи говорить»)
  • Getting Started with Arduino («Знакомство с Arduino»; есть версия на Kindle)
  • Arduino Cookbook («Книга рецептов Arduino»; есть версия для Kindle)

Устройства

Для XBee рекомендуется использовать Arduino с двумя последовательными портами – вроде Arduino Leonardo. Дело в том, что XBee требует доступа к последовательному порту, а второй последовательный порт пригодится для отладочных целей (через консоль Arduino).

  • Arduino Leonardo (рекомендуется)
  • Arduino UNO R3 (один последовательный порт)
  • Arduino Pro (один последовательный порт)

Модули XBee бывают двух видов – Series 1 (S1) и Series 2 (S2). Модель Series 1 настраивать проще, поэтому ее можно смело рекомендовать большинству пользователей. Модель Series 2 может работать через протокол ZigBee, и для его использования нужен апдейт прошивки. Модели Series 1 и Series 2 не совместимы друг с другом.

  • XBee Series 1
  • XBee Series 2 (ZigBee)

Самый простой способ подключить XBee к Arduino – это модуль Arduino XBee Shield. Такие модули можно купить напрямую у поставщиков и даже на eBay. Учтите, что если вы остановите свой выбор на SparkFun XBee Shield, то для подключения к плате Arduino к нему надо будет припаять гребешки (в комплекте не идут).

Если вы хотите обойтись без Shield-модуля, то вам понадобится 3,3-вольтовый регулятор и преобразователь логического уровня – чтобы конвертировать 5 вольт (Arduino) в 3,3 вольта (XBee). Arduino допускает использование логики 3,3 вольт.

Для обновления прошивки и настройки модулей XBee крайне рекомендуется адаптер XBee Explorer. Он также подойдет в качестве интерфейса между XBee и компьютером. Также XBee Explorer нужен для загрузки прошивки API в модуль Series 2 (при помощи X-CTU – эта программа поставляется с прошивкой AT).

Установка

Сначала расскажем о способе для IDE Arduino версии 1.5 и новее. Теперь в IDE Arduino встроен менеджер библиотек, упрощающий установку библиотек. Кликните на Скетч > Подключить библиотеку > Управлять библиотеками... (Sketch > Include Library > Manage Libraries…), затем впишите в поле справа вверху «xbee» и установите найденную библиотеку.

Для IDE Arduino версии ниже 1.5 установка выполняется вручную. Загрузите с GitHub архив формата «.zip» или «.tar.gz». Определите месторасположение папки со скетчами, кликнув на Файл > Настройки (File > Preferences) в IDE Arduino – нужный путь будет указан в самом верху, в поле «Размещение папки скетчей» («Sketchbook location»). Создайте там папку «libraries» (если ее еще нет), а затем распакуйте туда скачанный архив.

Загрузка скетчей

Загрузить скетч на Leonardo при помощи XBee также просто, как и с помощью компьютера. Если вы используете Arduino с одним последовательным портом (вроде UNO), перемычка на XBee Shield должна стоять на USB.

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

Настройка

Чтобы использовать эту библиотеку, ваш XBee должен быть выставлен в режим API (AP = 2). Подробнее о настройке читайте тут.

Руководство для разработчиков

Перед тем, как приступить к работе, вам нужно понимать разницу между прозрачным (AT) и пакетным (API) режимами. В режиме AT вы, как правило, ограничены коммуникацией только между двумя модулями XBee, а в режиме API можно настроить коммуникацию между координатором и несколькими модулями XBee. Кроме того, в режиме API в каждый пакет можно зашифровать дополнительную информацию. Библиотека XBee поддерживает только режим API.

Это руководство подразумевает, что вы уже настроили хотя бы два модуля XBee и подключили один из них к Arduino.

Создаем новый скетч. В самом верху скетча подключаем библиотеку XBee.

#include <XBee.h>

Затем, пока не переходя к блокам setup() и loop(), создаем объект XBee. С его помощью будут вызываться функции для отправки и получения пакетов.

XBee xbee = XBee();

В блоке setup() вызываем функцию begin(), указывая в ней скорость коммуникации:

void setup() {
  xbee.begin(9600);
}

Модули XBee – это устройства двусторонней радиосвязи, т.е. они одновременно могут и передавать, и получать данные.

Передача пакетов

Библиотека XBee поддерживает разные типы пакетов передачи данных (TX). Список всех поддерживаемых TX-пакетов можно найти по этой ссылке. Все классы, которые заканчиваются на «Request» – это TX-пакеты.

В этом разделе мы опишем, как отправить другому модулю XBee пакет с данными (полезной нагрузкой). Во-первых, нам нужно создать массив с данными, которые мы хотим отправить:

uint8_t payload[] = { 0, 0 };

Тип данных – это uint8_t, и это просто беззнаковый байт. Размер массива в строчке выше составляет «2», но вообще размер массива должен соответствовать количеству данных, которые вы хотите отправить. Важно помнить, что нельзя превышать максимальный размер полезной нагрузки. Этот размер зависит от типа модуля/прошивки: для Series 1 он составляет 100 байтов, для Series 2 зависит от прошивки и настроек, но составляет, как правило, не менее 80 байтов.

Теперь нам нужно создать TX-пакет. Он содержит полезную нагрузку, адрес модуля XBee, которому предназначены эти данные, и другая информация. TX-пакеты для Series 1 и Series 2 отличаются друг от друга. В этом примере мы будем использовать TX-пакет для Series 1. Обратиться к модулю Series 1 можно при помощи 16-битного или 64-битного адреса. Для 16-битных адресов мы рекомендуем использовать следующее:

Tx16Request tx = Tx16Request(0x1874, payload, sizeof(payload));

Здесь мы указываем полезную нагрузку (payload) и 16-битный адрес модуля XBee, которому будет отправлен пакет. Этот адрес должен соответствовать значению MY у принимающего модуля.

Полезная нагрузка

В блоке loop() мы считываем аналоговые данные и сохраняем их в payload.

pin5 = analogRead(5);
payload[0] = pin5 >> 8 & 0xff;
payload[1] = pin5 & 0xff;

Считанные данные получились 10-битными, но XBee может отправлять только однобайтные (т.е. 8-битные) данные, поэтому нам нужно разбить 10-битные данные на два байта.

К примеру, считанные данные могут выглядеть так: «10 10001000». В этом случае нам нужно привязать нижние 8 бит (10001000) к первому индексу массива с полезной нагрузкой. Далее мы сдвигаем 9-ый и 10-ый биты на позиции 0-ого и 1-ого битов во втором байте (00000010). При получении пакета нам нужно будет пересобрать эти данные, чтобы вновь получить 10-битное значение.

Теперь можно отсылать пакет принимающему модулю XBee.

xbee.send(tx);

После отправки XBee возвращает пакет TX Status, показывающий, что передача была выполнена успешно.

Полный код смотрите в соответствующих скетчах-примерах.

Получение пакетов

По умолчанию библиотека XBee выделяет для получения пакета массив размером в 110 байт. Это делается по той причине, что мы не используем динамическую память и не знаем размер получаемого пакета. Размер массива для пакета указывается в XBee.h:

#define MAX_FRAME_DATA_SIZE 110

Это позволяет работать с самой большой полезной нагрузкой (100 байт), при этом оставляя место для служебной информации.

Важно: Если вы используете маленькие пакеты, то это значение имеет смысл снизить и тем самым сэкономить немного памяти.

Как и с TX-пакетами, тип RX-пакетов зависит от модуля XBee: Series 1 или Series 2. Для получения XBee-данных нужно создать объект RX. Этот пример использует RX-пакет для Series 1:

Rx16Response rx16 = Rx16Response();

Считывание пакета

В блоке loop() вызываем функцию readPacket():

xbee.readPacket();

Она прочитает все доступные данные и должна сделать это очень быстро. Другой вариант – это вызвать readPacket() и указать таймаут:

xbee.readPacket(100) ;

Эта строчка будет ждать прибытия пакета 100 миллисекунд перед возвращением данных.

Важно: Для получения последовательных данных Arduino использует прерывания. Это позволяет скетчу получать данные и одновременно с этим делать другие вещи (например, считывать данные с датчиков, активировать устройства вывода данных и т.д.), при этом не теряя данные. Arduino использует 100-байтный буфер для получения данных. Очень важно, чтобы скорость извлечения данных из буфера была быстрее скорости передачи данных, иначе вы рискуете потерять пакеты. Это значит, что функцию readPacket() нужно вызывать быстрее, чем XBee получает пакеты. К примеру, если скетч TX (т.е. скетч, отправляющий пакеты) отправляет пакеты каждые 100 миллисекунд, то скетч RX (т.е. скетч, принимающий пакеты) должен считывать эти пакеты несколько быстрее (например, каждые 80 миллисекунд). Это позволит не терять данные.

Теперь проверяем, был ли получен пакет:

if (xbee.getResponse().isAvailable()) {
        if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
                xbee.getResponse().getRx16Response(rx16);
        }
}

Очень важно проверить тип полученного пакета, поскольку есть пакеты, которые требуют специальной обработки. Эта функция проверяет, соответствует ли идентификатор API значению в RX_16_RESPONSE. Если да, то это RX-пакет с 16-битным адресом, после чего этот пакет заполняется при помощи вызова функции getRx16Response() с объектом rx16.

Теперь проверяем адрес источника (модуль, от которого пришел пакет)...

rx16.getRemoteAddress16();

...считываем информацию о RSSI (т.е. о мощности сигнала, определенной при передаче пакета)...

rx16.getRssi()

...и получаем доступ к полезной нагрузке. Если у вас настроен New Soft Serial (NSS), то вы можете отобразить содержимое полезной нагрузки:

for (int i = 0; i < rx.getDataLength(); i++) { 
  nss.print(rx.getData(i), BYTE); 
}

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

processPayload(rx.getData(), rx.getDataLength());

Устранение ошибок

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

if (xbee.getResponse().isError()) {
// считываем код ошибки:
xbee.getResponse().getErrorCode()
}

Затем смотрим на код ошибки:

1 - CHECKSUM_FAILURE 
2 - PACKET_EXCEEDS_BYTE_ARRAY_LENGTH 
3 - UNEXPECTED_START_BYTE

Это определяется в XBee.h.

Вопросы и обратная связь

Вопросы об этом проекте можно задать тут. Задавая вопрос, пожалуйста, сообщите как можно больше подробностей (например, это S1 или S2, версию прошивки, настройки и код).

Примеры

  • AtCommand - Отправка AT-запросов к XBee-модулю
  • Echo Callbacks - Прослушка входящих пакетов и отправка идентичных ответов
  • RemoteAtCommand - Отправка AT-команд на удаленный XBee-модуль
  • Series1 IoSamples - Получение данных от удаленного XBee-модуля
  • Series1 Rx - Получение пакетов и преобразование в ШИМ-сигнал
  • Series1 Tx - Отправка пакетов
  • Series2 IoSamples - Получение данных от удаленного XBee-модуля (Series 2)
  • Series2 Rx - Получение пакетов и преобразование в ШИМ-сигнал (Series 2)
  • Series2 Rx Nss - Получение и отображение пакетов (Series 2)
  • Series2 Sleep - Введение и выведение XBee-модуля из режима ожидания
  • Series2 Tx - Отправка пакетов (Series 2)
  • ZdpScan - Поиск узлов в XBee-сети

См.также

Внешние ссылки