Arduino:Примеры/Series2 Sleep

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

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


Введение и выведение XBee-модуля из режима ожидания[1]

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

Код

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

#include <XBee.h>
#include <SoftwareSerial.h>

/*
Этот пример – только для XBee-модуля типа Series 2 (ZigBee), но он 
также поддерживает режим ожидания XBee-модуля типа Series 1. Этот 
пример демонстрирует, как работать с контактом для режима ожидания, 
который есть у XBee-модуля. То есть, по сути, он позволяет плате 
Arduino вводить и выводить XBee-модуль из режима ожидания. В этом 
примере конечное устрйство подключено к Arduino.

Режим ожидания у конечного устройства должен быть выставлен на «1» 
(SM=1) – это активирует режим ожидания. На координаторе нужно задать 
SP=AF0 (28 секунд). Благодаря этому координатор будет буфферизировать 
все пакеты в течение 28 секунд – пока конечное устройство будет 
находиться в режиме ожидания. «Проснувшись», конечное устройство
опросит координатора и получит приготовленный для него пакет.

Примечание: Для коммуникации с Arduino я использую библиотеку 
SoftSerial, потому что библиотека Serial уже используется самим XBee. 

Как это работает:

Когда вы отправляете «1», Arduino включает у XBee-модуля режим 
ожидания. Когда вы отправляете «2», XBee-модуль выходит из режима ожидания. Когда вы отправляете «3», Arduino отправляет произвольный 
TX-пакет.

Разумеется, если XBee-модуль находится в режиме ожидания, TX-пакет 
доставлен не будет. Чтобы отправлять эти команды, подключите монитор
порта в IDE Arduino к конвертеру USB-Serial. 

Подключите светодиод к 13-ому контакту XB-модуля (он называется 
«Status»). Он будет загораться, когда XBee-модуль будет выходить из 
режима ожидания, и потухать, когда модуль будет входить в режим 
ожидания.

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

Не забудьте также подключить все устройства к общей «земле»: XBee, 
Arduino и конвертер USB-Serial.
*/

// Создаем объект XBee:
XBee xbee = XBee();

// Создаем произвольную полезную нагрузку (она особого смысла не несет):
uint8_t payload[] = { 0, 0 };

// Адрес (SH + SL) удаленного XBee-модуля:
XBeeAddress64 addr64 = XBeeAddress64(0x0013a200, 0x403e0f30);
ZBTxRequest zbTx = ZBTxRequest(addr64, payload, sizeof(payload));
ZBTxStatusResponse txStatus = ZBTxStatusResponse();
ZBRxResponse rx = ZBRxResponse();

// Примечание: Чтобы XBee-модуль вошел в режим ожидания, ему не 
// обязательно нужно 3,3 вольта. Для этого достаточно незамкнутой 
// цепи. Но, разумеется, ему нужно 0 вольт, чтобы выйти из режима 
// ожидания. Подключите 7-ой цифровой контакт Arduino к 9-ому контакту 
// на XBee-модуле (это контакт для режима ожидания) при помощи 
// делителя напряжения. Я использую для этого резистор на 10 кОм.
uint8_t sleepPin = 7;

// SoftSerial RX: Подключаем 8-ой цифровой контакт Arduino к 
// TX-контакту на конвертере USB-Serial. Примечание: Лично я использую 
// USB BUB от Modern Device (выставлен на 5 вольт). Вы можете 
// использовать 3,3-вольтовый конвертер USB-Serial с делителем 
// напряжения на RX (TX не требуется, потому что Arduino устойчива к 
// 3,3 вольтам).
uint8_t ssRX = 8;
// SoftSerial TX: Подключаем 9-ый цифровой контакт Arduino к RX на 
// конвертере USB-Serial: 
uint8_t ssTX = 9;

SoftwareSerial nss(ssRX, ssTX);

void setup() {
  pinMode(sleepPin, OUTPUT);
  // Переключаем на LOW (выход из режима ожидания):
  digitalWrite(sleepPin, LOW);
  
  // запускаем коммуникацию XBee:
  Serial.begin(9600);
  xbee.setSerial(Serial);
  // Запускаем коммуникацию SoftSerial:
  nss.begin(9600);
}

void sendPacket() {

    nss.println("Sending a packet");  //  "Отправка пакета"
      
    xbee.send(zbTx);
    
    // После отправки TX-запроса 5 секунд ждем ответа о статусе.
    if (xbee.readPacket(5000)) {
        // Получили ответ!

        // Должен быть статус «znet tx»:
    	if (xbee.getResponse().getApiId() == ZB_TX_STATUS_RESPONSE) {
    	   xbee.getResponse().getZBTxStatusResponse(txStatus);
    		
    	   // Получаем подтверждение о доставке пакета (пятый байт):
           if (txStatus.getDeliveryStatus() == SUCCESS) {
            // Успешно. Ура!
             	nss.println("packet was delivered");  //  "Пакет доставлен"
           } else {
            // Удаленный XBee-модуль не получил наш пакет. Он включен?
                nss.println("packet delivery failed");  //  "Пакет не доставлен"
           }
        } else if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
        	// Что-то получили!
            xbee.getResponse().getZBRxResponse(rx);
        	// Показываем полезную нагрузку. Допустим, это текст.
        	for (uint8_t i = 0; i < rx.getDataLength(); i++) {
        		nss.println(rx.getData(i));
        	}
        }      
    } else {
      // Локальный XBee-модуль в режиме ожидания:
       nss.println("no response -- is local xbee sleeping?");  //  "Ответа нет – локальный модуль в режиме ожидания?"
    }  
}

void loop() {   
  if (nss.available()) {
    int cmd = nss.read();
    
    // ASCII-код для «1» - это «49»:
    if (cmd == 49) {   // 1 (ASCII)
      // Вводим XBee-модуль в режим ожидания:
      digitalWrite(sleepPin, HIGH);
      nss.println("sleeping xbee");  //  "XBee-модуль переходит в режим ожидания"
    } else if (cmd == 50) {  // ASCII-код для «2» - это «50»:
      digitalWrite(sleepPin, LOW);
      nss.println("waking xbee");  //  "XBee-модуль выходит из режима ожидания"
    } else if (cmd == 51) {  // ASCII-код для «3» - это «51»:

      // Отправляем пакет:
      sendPacket();
    } else {
       nss.println("I didn't understand");  //  "Я не понимаю"
    }
  }
  
  readPacket();
}

// Включаясь, XBee-модуль отсылает модему статус «0» (аппаратный 
// сброс), а затем «2» (присоединение к сети) – при условии, что он 
// правильно настроен. Выходя из режима ожидания, XBee-модуль отсылает 
// модему статус «2» (присоединение к сети).

void readPacket() {
  xbee.readPacket();
  
    if (xbee.getResponse().isAvailable()) {
        // Что-то получили... Показываем пакет при помощи NSS:
        nss.print("API=");
        nss.print(xbee.getResponse().getApiId(), HEX);
        nss.print(",frame=");
        
        // Показываем данные, находящиеся в секции «frame data» API-фрейма:
        for (int i = 0; i < xbee.getResponse().getFrameDataLength(); i++) {
          nss.print(xbee.getResponse().getFrameData()[i], HEX);
          nss.print(" ");
        }
        
        nss.println("");
    } else if (xbee.getResponse().isError()) {
     nss.print("XBee error. error code is");   //  "Ошибка XBee-моодуля. Код ошибки: "
     nss.println(xbee.getResponse().getErrorCode(), DEC);
    }
}

См.также

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