269 lines
6.5 KiB
C++
269 lines
6.5 KiB
C++
#include "XBee.h"
|
|
|
|
XBeeApiFrame::XBeeApiFrame(uint8_t apiId, uint8_t frameId) {
|
|
_apiId = apiId;
|
|
_frameId = frameId;
|
|
}
|
|
|
|
XBee::XBee(Module* module) {
|
|
_mod = module;
|
|
}
|
|
|
|
uint8_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->AtLineFeed = "\r";
|
|
_mod->baudrate = speed;
|
|
_mod->init(USE_UART, INT_NONE);
|
|
|
|
// empty UART buffer (garbage data)
|
|
_mod->ATemptyBuffer();
|
|
|
|
// enter command mode
|
|
DEBUG_PRINTLN_STR("Entering command mode ...");
|
|
if(!enterCmdMode()) {
|
|
return(ERR_CMD_MODE_FAILED);
|
|
}
|
|
|
|
// test AT setup
|
|
DEBUG_PRINTLN_STR("Sending test command ...");
|
|
if(!_mod->ATsendCommand("AT")) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
// exit command mode
|
|
DEBUG_PRINTLN_STR("Exiting command mode ...");
|
|
if(!_mod->ATsendCommand("ATCN")) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
delay(1000);
|
|
|
|
return(ERR_NONE);
|
|
}
|
|
|
|
uint8_t XBee::setDestinationAddress(const char* destinationAddressHigh, const char* destinationAddressLow) {
|
|
// enter command mode
|
|
DEBUG_PRINTLN_STR("Entering command mode ...");
|
|
if(!enterCmdMode()) {
|
|
return(ERR_CMD_MODE_FAILED);
|
|
}
|
|
|
|
// set higher address bytes
|
|
DEBUG_PRINTLN_STR("Setting address (high) ...");
|
|
char* addressHigh = new char[strlen(destinationAddressHigh) + 4];
|
|
strcpy(addressHigh, "ATDH");
|
|
strcat(addressHigh, destinationAddressHigh);
|
|
bool res = _mod->ATsendCommand(addressHigh);
|
|
delete[] addressHigh;
|
|
if(!res) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
// set lower address bytes
|
|
DEBUG_PRINTLN_STR("Setting address (low) ...");
|
|
char* addressLow = new char[strlen(destinationAddressLow) + 4];
|
|
strcpy(addressLow, "ATDL");
|
|
strcat(addressLow, destinationAddressLow);
|
|
res = _mod->ATsendCommand(addressLow);
|
|
delete[] addressLow;
|
|
if(!res) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
// exit command mode
|
|
DEBUG_PRINTLN_STR("Exiting command mode ...");
|
|
if(!_mod->ATsendCommand("ATCN")) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
return(ERR_NONE);
|
|
}
|
|
|
|
uint8_t XBee::setPanId(const char* panId) {
|
|
// enter command mode
|
|
DEBUG_PRINTLN_STR("Entering command mode ...");
|
|
if(!enterCmdMode()) {
|
|
return(ERR_CMD_MODE_FAILED);
|
|
}
|
|
|
|
// set PAN ID
|
|
DEBUG_PRINTLN_STR("Setting PAN ID ...");
|
|
char* cmd = new char[strlen(panId) + 4];
|
|
strcpy(cmd, "ATID");
|
|
strcat(cmd, panId);
|
|
bool res = _mod->ATsendCommand(cmd);
|
|
delete[] cmd;
|
|
if(!res) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
// exit command mode
|
|
DEBUG_PRINTLN_STR("Exiting command mode ...");
|
|
if(!_mod->ATsendCommand("ATCN")) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
return(ERR_NONE);
|
|
}
|
|
|
|
bool XBee::enterCmdMode() {
|
|
for(uint8_t i = 0; i < 10; i++) {
|
|
delay(1000);
|
|
|
|
_mod->ModuleSerial->write('+');
|
|
_mod->ModuleSerial->write('+');
|
|
_mod->ModuleSerial->write('+');
|
|
|
|
delay(1000);
|
|
|
|
if(_mod->ATgetResponse()) {
|
|
return(true);
|
|
} else {
|
|
DEBUG_PRINT_STR("Unable to enter command mode! (");
|
|
DEBUG_PRINT(i + 1);
|
|
DEBUG_PRINTLN_STR(" of 10 tries)");
|
|
|
|
pinMode(3, OUTPUT);
|
|
delay(10);
|
|
digitalWrite(3, HIGH);
|
|
delay(500);
|
|
digitalWrite(3, LOW);
|
|
delay(500);
|
|
pinMode(3, INPUT);
|
|
delay(500);
|
|
|
|
_mod->ATsendCommand("ATCN");
|
|
|
|
if(i == 9) {
|
|
DEBUG_PRINTLN_STR("Terminated, check your wiring. Is AT FW uploaded?");
|
|
return(false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*uint8_t XBee::transmit(uint32_t destinationAddressHigh, uint32_t destinationAddressLow, const char* data, uint8_t length) {
|
|
//build the API frame
|
|
uint8_t frameLength = length + 12;
|
|
uint8_t * frameData = new uint8_t[frameLength];
|
|
|
|
//set the destination address
|
|
frameData[0] = (destinationAddressHigh >> 24) & 0xFF;
|
|
frameData[1] = (destinationAddressHigh >> 16) & 0xFF;
|
|
frameData[2] = (destinationAddressHigh >> 8) & 0xFF;
|
|
frameData[3] = destinationAddressHigh & 0xFF;
|
|
|
|
frameData[4] = (destinationAddressLow >> 24) & 0xFF;
|
|
frameData[5] = (destinationAddressLow >> 16) & 0xFF;
|
|
frameData[6] = (destinationAddressLow >> 8) & 0xFF;
|
|
frameData[7] = destinationAddressLow & 0xFF;
|
|
|
|
//set the destination network address
|
|
frameData[8] = 0xFF;
|
|
frameData[9] = 0xFE;
|
|
|
|
//set broadcast radius (number of allowed hops, 0 - maximum)
|
|
frameData[10] = 0x00;
|
|
|
|
//set the options
|
|
frameData[11] = 0x00;
|
|
|
|
//copy payload data
|
|
for(uint8_t i = 0; i < length; i++) {
|
|
frameData[12 + i] = (uint8_t)data[i];
|
|
}
|
|
|
|
//send the frame to XBee
|
|
sendApiFrame(XBEE_API_FRAME_ZIGBEE_TRANSMIT_REQUEST, frameData, frameLength);
|
|
|
|
//deallocate memory
|
|
delete frameData;
|
|
|
|
//wait for status frame
|
|
readApiFrame(1000);
|
|
}*/
|
|
|
|
/*void XBee::sendApiFrame(uint8_t apiId, uint8_t* data, uint16_t length) {
|
|
//send frame start delimiter
|
|
_mod->ModuleSerial->write(XBEE_API_START);
|
|
|
|
//send frame length (API ID, frame ID and data length)
|
|
write(((length + 2) >> 8) & 0xFF);
|
|
write((length + 2) & 0xFF);
|
|
|
|
//send API ID
|
|
write(apiId);
|
|
|
|
//send default frame ID (value 0x00 would disable some feedback)
|
|
write(XBEE_API_DEFAULT_FRAME_ID);
|
|
|
|
//checksum is calculated from API ID, frame ID and data
|
|
uint8_t checksum = apiId;
|
|
checksum += XBEE_API_DEFAULT_FRAME_ID;
|
|
|
|
//send the data and calculate checksum
|
|
for(uint16_t i = 0; i < length; i++) {
|
|
write(data[i]);
|
|
checksum += data[i];
|
|
}
|
|
|
|
//send the checksum
|
|
checksum = 0xFF - checksum;
|
|
write(checksum);
|
|
}*/
|
|
|
|
/*uint8_t XBee::readApiFrame(uint16_t timeout) {
|
|
//start the timer
|
|
unsigned long start = millis();
|
|
|
|
Serial.println("reading");
|
|
|
|
|
|
//array to store frame length, type and ID
|
|
uint8_t header[4];
|
|
while(millis() - start < timeout) {
|
|
Serial.println(_mod->ModuleSerial->available());
|
|
//check buffer for new data
|
|
while(_mod->ModuleSerial->available()) {
|
|
uint8_t b = _mod->ModuleSerial->read();
|
|
|
|
Serial.write(b);
|
|
Serial.print('\t');
|
|
Serial.println(b, HEX);
|
|
|
|
if(b == XBEE_API_START) {
|
|
//received the start character
|
|
n = 0;
|
|
} else {
|
|
n++;
|
|
}
|
|
|
|
//check escaped characters
|
|
if(b == XBEE_API_ESCAPE) {
|
|
//wait for the next byte
|
|
while(!_mod->ModuleSerial->available());
|
|
|
|
//resolve the escaped character
|
|
b =_mod->ModuleSerial->read();
|
|
b = 0x20 ^ b;
|
|
}
|
|
}
|
|
}
|
|
}*/
|
|
|
|
/*void XBee::write(uint8_t b) {
|
|
if((b == XBEE_API_START) || (b == XBEE_API_ESCAPE) || (b == XBEE_API_XON) || (b == XBEE_API_XOFF)) {
|
|
_mod->ModuleSerial->write(XBEE_API_ESCAPE);
|
|
_mod->ModuleSerial->write(b ^ 0x20);
|
|
} else {
|
|
_mod->ModuleSerial->write(b);
|
|
}
|
|
}*/
|