From ba7164f5cd3af330c6398ef9404e351678e06404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Grome=C5=A1?= Date: Tue, 24 Jul 2018 09:54:07 +0200 Subject: [PATCH] XBee - implemented API packet reception --- examples/XBee_Receive/XBee_Receive.ino | 56 ++++++++++++++++++++++ src/modules/XBee.cpp | 66 +++++++++++++++++++++++++- src/modules/XBee.h | 5 ++ 3 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 examples/XBee_Receive/XBee_Receive.ino diff --git a/examples/XBee_Receive/XBee_Receive.ino b/examples/XBee_Receive/XBee_Receive.ino new file mode 100644 index 00000000..342cd356 --- /dev/null +++ b/examples/XBee_Receive/XBee_Receive.ino @@ -0,0 +1,56 @@ +/* + KiteLib XBee API Receive Example + + This example receives packets using XBee API mode. + In API mode, many XBee modules can form a mesh network. + + IMPORTANT: Before uploading this example, make sure that the XBee module + is running API ROUTER/ENDPOINT firmware! +*/ + +// include the library +#include + +// XBee module is in slot A on the shield +XBee bee = Kite.ModuleA; + +void setup() { + Serial.begin(9600); + + // initialize XBee module with baudrate 9600 + Serial.print(F("[XBee] Initializing ... ")); + int state = bee.begin(9600); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // set PAN ID to 0x0123456789ABCDEF + Serial.print(F("[XBee] Setting PAN ID ... ")); + uint8_t panId[] = {0x01, 0x23, 0x45, 0x67, + 0x89, 0xAB, 0xCD, 0xEF}; + state = bee.setPanId(panId); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } +} + +void loop() { + // check if XBee received some data + if (bee.available() > 0) { + // print source address + Serial.print("[XBee] Packet source:\t"); + Serial.println(bee.getPacketSource()); + + // print data + Serial.print("[XBee] Packet data:\t"); + Serial.println(bee.getPacketData()); + } +} diff --git a/src/modules/XBee.cpp b/src/modules/XBee.cpp index 6414873e..82417068 100644 --- a/src/modules/XBee.cpp +++ b/src/modules/XBee.cpp @@ -3,9 +3,20 @@ XBee::XBee(Module* mod) { _mod = mod; _frameID = 0x01; + _frameLength = 0; + _frameHeaderProcessed = false; + _packetData = new char[0]; } int16_t XBee::begin(long speed) { + // set Arduino pins + pinMode(A4, OUTPUT); + pinMode(A5, OUTPUT); + pinMode(3, OUTPUT); + digitalWrite(A4, LOW); + digitalWrite(A5, LOW); + digitalWrite(3, HIGH); + // set module properties _mod->baudrate = speed; _mod->init(USE_UART, INT_NONE); @@ -52,15 +63,66 @@ int16_t XBee::transmit(uint8_t* dest, uint8_t* destNetwork, const char* payload, } size_t XBee::available() { + // check if there are data available in the buffer + size_t serialBytes = _mod->ModuleSerial->available(); + if(serialBytes < 3) { + return(0); + } + uint8_t header[3]; + if(!_frameHeaderProcessed) { + // read frame header + for(uint8_t i = 0; i < 3; i++) { + header[i] = _mod->ModuleSerial->read(); + } + + // check if we received API frame + if(header[0] != XBEE_API_START) { + return(0); + } + + // get expected frame length + _frameLength = ((header[1] << 8) | header[2]) + 1; + _frameHeaderProcessed = true; + } + + // check if the header is complete + if(serialBytes < _frameLength) { + return(0); + } + + uint8_t* frame = new uint8_t[_frameLength]; //24 + for(size_t i = 0; i < _frameLength; i++) { + frame[i] = _mod->ModuleSerial->read(); + } + + // save packet source and data + size_t payloadLength = _frameLength - 12; + delete[] _packetData; + _packetData = new char[payloadLength]; + memcpy(_packetData, frame + 12, payloadLength - 1); + _packetData[payloadLength - 1] = '\0'; + memcpy(_packetSource, frame + 1, 8); + + delete[] frame; + _frameLength = 0; + _frameHeaderProcessed = false; + + // return number of bytes in payload + return(payloadLength); } String XBee::getPacketSource() { - + char buff[17]; + sprintf(buff, "%02X%02X%02X%02X%02X%02X%02X%02X", _packetSource[0], _packetSource[1], _packetSource[2], _packetSource[3], + _packetSource[4], _packetSource[5], _packetSource[6], _packetSource[7]); + String str(buff); + return(str); } String XBee::getPacketData() { - + String str(_packetData); + return(str); } int16_t XBee::setPanId(uint8_t* panId) { diff --git a/src/modules/XBee.h b/src/modules/XBee.h index 559f8b85..8d96bc62 100644 --- a/src/modules/XBee.h +++ b/src/modules/XBee.h @@ -67,6 +67,11 @@ class XBee { private: Module* _mod; uint8_t _frameID; + size_t _frameLength; + bool _frameHeaderProcessed; + + char* _packetData; + uint8_t _packetSource[8]; void sendApiFrame(uint8_t type, uint8_t id, const char* data); void sendApiFrame(uint8_t type, uint8_t id, uint8_t* data, uint16_t length);