У меня есть 2 модуля XBee S1, настроенных в режиме API 1. Модуль 1 XBee — это передатчик сигнала, а модуль 2 XBee — это приемник сигнала. И проблема в том, что приемник не получает ничего от передатчика (или так кажется).
Конфигурация передатчика такова:
AP 1
MY 1
ID 1984
DL 2
CH C
Все остальное оставлено по умолчанию.
Передатчик подключен к XBee Explorer. XBee Explorer подключен к ПК через USB.
Следующий фрагмент кода отправляет сигнал каждую 1 секунду:
public class Main {
private Main() {
XBee xbee = new XBee();
try {
xbee.open("/dev/ttyUSB0", 9600);
final XBeeRequest request = new TxRequest16(new XBeeAddress16(0, 2), new int[] { 1 });
//noinspection InfiniteLoopStatement
while (true) {
xbee.sendSynchronous(request);
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
xbee.close();
}
}
public static void main(String[] args) {
new Main();
}
}
Использовалась библиотека Java XBee API: https://code.google.com/p/xbee-api/
И я вижу, что светодиод TX мигает каждую секунду.
Конфигурация приемника такая:
AP 1
MY 2
ID 1984
DL 1
CH C
Все остальное оставлено по умолчанию.
Используется следующая проводка для приемника:
Приемник подключается к макету через XBee Explorer. Проверка непрерывности показывает, что ток течет нормально между XBee RX и mbed P27, а также между XBee TX и mbed P28.
И следующий код на mbed (LPC1768) работает для получения пакетов:
Serial terminal(USBTX, USBRX);
while(1) {
terminal.puts("Reading packet...\r\n");
xbee.readPacketUntilAvailable();
terminal.puts("Packet available\r\n");
XBeeResponse response = xbee.getResponse();
if (response.isAvailable()) {
char tmp[20];
sprintf(tmp, "0x%02X", response.getApiId());
terminal.puts("Response available at API: ");
terminal.puts(tmp);
terminal.puts("\r\n");
uint8_t api = response.getApiId();
if (api == RX_16_RESPONSE) {
Rx16Response rx16 = Rx16Response();
response.getRx16Response(rx16);
uint8_t len = rx16.getDataLength();
char l[20];
sprintf(l, "%d", len);
terminal.puts("We have data: ");
terminal.puts(l);
terminal.puts("\r\n");
}
}
wait(1);
}
Использовалась популярная библиотека Arduino / mbed для режима XBee API. Источники расположены здесь: http://mbed.org/users/okini3939/code/XBee/
И вывод консоли: Reading packet...
на все времена.
И светодиод RX не мигает на приемнике.
Вопрос был сложным (состоял из нескольких небольших вопросов). Вывод кадров запроса и ответа с обоих концов, как предложил @tomlogic, оказался весьма полезным.
Для решения этих проблем я сначала убедился, что аппаратная часть работает.
XBee Explorer имеет 4 светодиода. Одним из них является мощность и всегда должен светиться красным при питании. И еще 3, в зависимости от того, какой у вас исследователь, могут называться rx, tx, rssi
или же din, dout, rssi
,
Когда выполняется передача кода, мы должны сначала убедиться, что rx
а также tx
мигают одновременно каждую секунду. То есть сигнал отправляется каждую секунду.
При получении кода запускается и звонки readPacketUntilAvailable
Индикаторы на принимающем проводнике XBee должны светиться следующим образом: rssi
светится постоянно, tx
или же dout
должен мигать.
Теперь, когда мы знаем, что с оборудованием все в порядке, мы можем отлаживать программную часть.
Моя проблема была с получением кода. Когда мы настраиваем прием XBee, нам нужно убедиться, что мы делаем две вещи. Сначала мы называем xbee.begin(baudRate)
, И во-вторых, мы должны перезагрузить модуль.
reset = 0;
wait_ms(100);
reset = 1;
wait_ms(100);
И последнее, но не менее важное, readPacketUntilAvailable
метод будет не сбросить ответ. Мы называем эту функцию в цикле. Какой бы первый ответ мы не получили, он будет повторен независимо от того, какие другие данные отправлены передатчиком.
Первый ответ, который получатель получил в моем случае, был MODEM_STATUS_RESPONSE
(0x8A в HEX). И последующие пакеты не были прочитаны. readPacket
должен быть вызван вместо этого, так как этот метод будет сбрасывать предыдущий ответ.
Мой код получения теперь выглядит так:
XBee xbee(p28, p27);
DigitalOut reset(p11);
DigitalOut mbed_led1(LED1);
int main() {
Serial terminal(USBTX, USBRX);
while(!terminal.readable()) {
wait_ms(10);
}
terminal.getc();
mbed_led1 = 1;
xbee.begin(9600);
reset = 0;
wait_ms(100);
reset = 1;
wait_ms(100);
while(1) {
terminal.puts("Reading packet...\r\n");
xbee.readPacket(500);
XBeeResponse response = xbee.getResponse();
if (response.isAvailable()) {
terminal.puts("Packet available\r\n");
XBeeResponse response = xbee.getResponse();
char tmp[20];
sprintf(tmp, "0x%02X", response.getApiId());
terminal.puts("Response available at API: ");
terminal.puts(tmp);
terminal.puts("\r\n");
uint8_t api = response.getApiId();
if (api == RX_16_RESPONSE) {
Rx16Response rx16 = Rx16Response();
response.getRx16Response(rx16);
uint8_t len = rx16.getDataLength();
char l[20];
sprintf(l, "%d", len);
terminal.puts("We have data of length ");
terminal.puts(l);
terminal.puts("\r\n");
}
}
wait(1);
}
}
Обратите внимание, что, поскольку вы работаете в режиме API, ATDL
не используется, поэтому вам не нужно устанавливать его.
Библиотека Java, с которой вы связаны, задокументирована как работающая только с ATAP=2
, Попробуйте изменить этот параметр на передающем узле.
Вы должны сбрасывать любые пакеты, поступающие на передатчик. Модуль XBee должен сгенерировать кадр «Transmit Status» (0x89), который может помочь в отладке.
Я думаю, что самый простой способ прочитать данные с Xbee — это просто открыть последовательный порт в отдельном потоке и постоянно зацикливаться на 0x7E (начальный разделитель). Это то, что я делаю с моим кодом, и он отлично работает. Для начала я использовал библиотеку RxTxSerial и этот учебник:
http://embeddedfreak.wordpress.com/java-serial-port-trail/
У меня нет кода сброса xbee или необходимости ждать, чтобы получить данные должным образом. Если вы хотите взглянуть на мой код, я с удовольствием поделюсь им и объясню.