Arduino:Примеры/Echo Callbacks

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

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


Прослушка входящих пакетов и отправка идентичных ответов[1]

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

Код

/**
 * Автор – Мэттхиджс Куиджман (Matthijs Kooijman). 2015 год, все права защищены.
 *
 * Этот файл – часть библиотеки XBee-Arduino.
 *
 * Библиотека XBee для Arduino – это бесплатное ПО: его можно 
 * распространять и/или модифицировать согласно условиям Универсальной 
 * общественной лицензии GNU, изданной Фондом свободного ПО – будь то 
 * 3-тья или более поздняя версия этой лицензии (на ваш выбор).
 *
 * Библиотека XBee-Arduino распространяется бесплатно в надежде на то, 
 * что окажется полезной, но БЕЗО ВСЯКОЙ ГАРАНТИИ; включая даже 
 * обязательную гарантию на КОММЕРЧЕСКОЕ КАЧЕСТВО и ПРИГОДНОСТЬ 
 * КОНКРЕТНОЙ ЦЕЛИ. Более подробно читайте в Универсальной 
 * общественной лицензии GNU.
 *
 * Вы должны получить копию Универсальной общественной лицензии GNU 
 * вместе с библиотекой XBee-Arduino. Если не получили, ее можно найти 
 * на http://www.gnu.org/licenses/.
 */

#include <XBee.h>
#include <Printers.h>

/*
 Этот пример – для XBee-модуля Series 1 или Series 2 (изменения в 
 прошивке не требуются). 

 Он прослушивает входящие пакеты, а затем отправляет всю полученную 
 информацию обратно. Этот пример демонстрирует, как при помощи объекта 
 XBeeWithCallbacks лаконично осуществить чтение ответных пакетов. 

 Кроме того, этот скетч рассчитан на то, что вы используете Arduino с 
 двумя последовательными портами (вроде Leonardo или Mega). Замените 
 Serial и Serial1 ниже на то, что соответствует вашей плате.
*/

// Создаем объект XBeeWithCallbacks:
XBeeWithCallbacks xbee;

void zbReceive(ZBRxResponse& rx, uintptr_t) {
  // Создаем ответный пакет, содержащий те же данные.
  // При этом напрямую используется массив RX-данных, что нормально,
  // поскольку TX-пакет отправляется перед получением какого-либо 
  // нового ответа.
  ZBTxRequest tx;
  tx.setAddress64(rx.getRemoteAddress64());
  tx.setAddress16(rx.getRemoteAddress16());
  tx.setPayload(rx.getFrameData() + rx.getDataOffset(), rx.getDataLength());

  // Шлем ответ, но не ждем TX-ответа о статусе. Если возникнет 
  // ошибка, глобальный обработчик onTxStatusResponse покажет 
  // сообщение об ошибке, но при успехе никакого сообщения показано 
  // не будет.
  xbee.send(tx);
  Serial.println(F("Sending ZBTxRequest"));  //  "Отправка ZBTxRequest"
}

void receive16(Rx16Response& rx, uintptr_t) {
  // Создаем ответный пакет, содержащий те же данные.
  // При этом напрямую используется массив RX-данных, что нормально,
  // поскольку TX-пакет отправляется перед получением какого-либо 
  // нового ответа.
  Tx16Request tx; 
  tx.setAddress16(rx.getRemoteAddress16());
  tx.setPayload(rx.getFrameData() + rx.getDataOffset(), rx.getDataLength());

  // Шлем ответ, но не ждем статусного TX-ответа. Если возникнет 
  // ошибка, глобальный обработчик onTxStatusResponse покажет 
  // сообщение об ошибке, но при успехе никакого сообщения показано 
  // не будет.
  xbee.send(tx);
  Serial.println(F("Sending Tx16Request"));  //  "Отправка Tx16Request"
}

void receive64(Rx64Response& rx, uintptr_t) {
  // Создаем ответный пакет, содержащий те же данные.
  // При этом напрямую используется массив RX-данных, что нормально,
  // поскольку TX-пакет отправляется перед получением какого-либо 
  // нового ответа.
  Tx64Request tx;
  tx.setAddress64(rx.getRemoteAddress64());
  tx.setPayload(rx.getFrameData() + rx.getDataOffset(), rx.getDataLength());

  // Шлем ответ, но не ждем статусного TX-ответа. Если возникнет 
  // ошибка, глобальный обработчик onTxStatusResponse покажет 
  // сообщение об ошибке, но при успехе никакого сообщения показано 
  // не будет.
  xbee.send(tx);
  Serial.println(F("Sending Tx64Request"));  //  "Отправка Tx64Request"
}
void setup() {
  Serial.begin(9600);

  Serial1.begin(9600);
  xbee.setSerial(Serial1);

  // Делаем так, чтобы все ошибки записывались в Serial. Адрес Serial 
  // сначала приводим к Print* (т.к. это то, чего ожидает 
  // функция внешнего вызова), а затем к uintptr_t (чтобы подогнать 
  // его к параметру данных):
  xbee.onPacketError(printErrorCb, (uintptr_t)(Print*)&Serial);
  xbee.onTxStatusResponse(printErrorCb, (uintptr_t)(Print*)&Serial);
  xbee.onZBTxStatusResponse(printErrorCb, (uintptr_t)(Print*)&Serial);

  // Эти функции вызываются при получении пакета:
  xbee.onZBRxResponse(zbReceive);
  xbee.onRx16Response(receive16);
  xbee.onRx64Response(receive64);

  // Показываем все необработанные ответы с правильным форматированием:
  xbee.onOtherResponse(printResponseCb, (uintptr_t)(Print*)&Serial);

  // Показываем «сырые» байты для всех ответов перед их обработкой: 
  //xbee.onResponse(printRawResponseCb, (uintptr_t)(Print*)&Serial);

  // Задаем AO=0, чтобы убедиться, что мы получили ZBRxResponses, а не
  // ZBExplicitRxResponses (поддерживается только на Series 2). 
  // Возможно, это не потребуется, но зато отлично показывает, как 
  // использовать sendAndWait(). 
  uint8_t value = 0;
  AtCommandRequest req((uint8_t*)"AO", &value, sizeof(value));
  req.setFrameId(xbee.getNextFrameId());
  // Отправляем команду и ждем ответа в течение 150 миллисекунд:
  uint8_t status = xbee.sendAndWait(req, 150);
  if (status == 0)
    Serial.println(F("Set AO=0"));  //  "Задаем AO=0"
  Else
    Serial.println(F("Failed to set AO (this is expected on series1)"));  //  "Не удалось задать AO=0" (такое происходит на Series 1" 
}

void loop() {
  // Приказываем XBee-модулю постоянно считывать пакеты и вызывать 
  // функции внешнего вызова:
  xbee.loop();
}

См.также

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