Xbee
Revision 0:fbed291691a6, committed 2018-10-14
- Comitter:
- renanbmx123
- Date:
- Sun Oct 14 02:01:07 2018 +0000
- Commit message:
- Xbee
Changed in this revision
XBEE.cpp | Show annotated file Show diff for this revision Revisions of this file |
XBEE.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r fbed291691a6 XBEE.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/XBEE.cpp Sun Oct 14 02:01:07 2018 +0000 @@ -0,0 +1,448 @@ +#include "XBEE.h" +#include <stdlib.h> + +/* Class constructor */ +XBEE::XBEE(Serial* serial, int baud):xbee(serial) +{ + xbee->baud(baud); + /* Enable the reception of bytes on the serial interface by providing a cb */ + xbee->attach(callback(this, &XBEE::recvAttach), Serial::RxIrq); +} + +/* Class destructor */ +XBEE::~XBEE() +{ + if (xbee != NULL) { + delete xbee; + } +} + +/* Chamada por Interrupcao, RX */ +void XBEE::recvAttach (void) +{ + if (int_ctrl == 1) + while(xbee->readable()) { + buf_rx[count_rx%sizeof(buf_rx)] = xbee->getc(); + //buf_rx.push(xbee->getc()); + count_rx++; + } +} + +/* Initialize the Device XBEE */ +void XBEE::init(void) +{ + // memset(&NI,0,sizeof(NI)); + ID = 0; + MY = 0; + SH = 0; + SL = 0; + PL = 0; + BD = 0; + AO = 0; + DB = 0; + TP = 0; + + wait(0.5); + + memset(&buf_rx,0,sizeof(buf_rx)); + + create_CMD("NI",0); // Pan ID da rede + sendBuffer(); + wait(0.5); + + recv_NI(); + read_cfg("ID", ID); + read_cfg("SH", SH); + read_cfg("SL", SL); + read_cfg("PL", PL); + read_cfg("BD", BD); + read_cfg("AO", AO); + read_cfg("DB", DB); + read_cfg("TP", TP); + + count_rx = 0; + memset(&buf_rx,0,sizeof(buf_rx)); +} + +/* Send message to the destination */ +int XBEE::send_msg(char * str, int dest) +{ + int n = strlen(str); + if(n > 92) { + return -1; + } + create_TX(str,dest); + sendBuffer(); + wait(0.2); + return 0; +} + +/* Sets a configuration value into the module device */ +int XBEE::set_cfg(char * cmd, int value) +{ + int n = strlen(cmd); + if(n != 2) { + return -1; + } + create_CMD(cmd,hex2dec(value)); + sendBuffer(); + wait(0.2); + + create_CMD("WR",0); + sendBuffer(); + wait(0.2); + + create_CMD("AC",0); + sendBuffer(); + wait(0.2); + return 0; +} + +/* Receives a message, writes in str */ +int XBEE::recv_msg(char * buf, int tam) +{ + pkt_tx *p; + int i; + int ptam = 0; + int j = 0; + + memset(buf,0,tam); + + for(i = 0; i < count_rx; i++) { + if(buf_rx[i] == 0x7E) { + + p = (pkt_tx *) &buf_rx[i]; + + if(p->frame_type == 0x90) { + ptam = p->length - 0x0C; + if(tam < ptam + j) { + return -1; + } + // posicao aonde comeca a msg em um pacote de Receive + memcpy(&buf[j], ((char *)(&p->broadcast_radius)), ptam); + j += ptam; + } + } + } + return j; +} + +/* Updates the command value, call a request from device configurations */ +int XBEE::read_cfg(char * cmd, int & var) +{ + int n = strlen(cmd); + if(n != 2) { + return -1; + } + count_rx = 0; + memset(&buf_rx,0,sizeof(buf_rx)); + + create_CMD(cmd,0); // Pan ID da rede + sendBuffer(); + wait(0.5); + recv_CMD(var); + return 0; +} + +/* Clear all the Receive buffer */ +void XBEE::clear_buf(void) +{ + count_rx = 0; + memset(buf_rx,0,sizeof(buf_rx)); +} + +/* Cria pacote de mensagem */ +int XBEE::create_TX(char * str, int dest) +{ + int i = 0; + int n = strlen(str); + + pkt_tx *p = (pkt_tx *) buf_tx; // ponteiro para buffer global + + uint8_t count = 0; + + if(n > 92) { + // Error: data nao pode exceder 92 bytes + return -1; + } + + count_tx = 0; + memset(&buf_tx,0,sizeof(buf_tx)); + + p->start_delimiter = 0x7E; + p->length = 0x0E + n; // pacote vazio + dados + p->frame_type = 0x10; // transmit request + p->frame_id = 1; + + if(dest == XBEE_COORD) { + p->dest_addr64[6] = 0x00; //SL_H + p->dest_addr64[7] = 0x00; //SL_L + } else if(dest == XBEE_BROAD) { + p->dest_addr64[6] = 0xFF; //SL_H + p->dest_addr64[7] = 0xFF; //SL_L + } else { + p->dest_addr64[0] = 0x00; + p->dest_addr64[1] = 0x13; + p->dest_addr64[2] = 0xA2; + p->dest_addr64[3] = 0x00; + + p->dest_addr64[4] = (dest >> 24); + p->dest_addr64[5] = (dest & 0x00FF0000) >> 16; + p->dest_addr64[6] = (dest & 0x0000FF00) >> 8; + p->dest_addr64[7] = (dest & 0x000000FF); + } + p->dest_addr16[0] = 0xFF; //MY_H + p->dest_addr16[1] = 0xFF; //MY_L + + memcpy(&p->rf_data, str, n); + + // Calcula Checksum + + // comeca 3 pra frente, tenq passar 3 adiante no final + // para ler o mesmo tamanho de pacote + for(i = 3; i < p->length + 3; i++) { + count += buf_tx[i]; + //printf("\n%d\n", count); + } + count = 0xFF - count; + + p->rf_data[n] = count; + + //p->length tem o tamanho soh do frame, + //pacote total eh o starter + length alto + length baixo + checksum + count_tx = p->length + 4; + return count_tx; +} + +/* Cria pacote de comando */ +int XBEE::create_CMD(char * cmd, int val) +{ + pkt_cmd *p = (pkt_cmd *) buf_tx; // ponteiro para buffer global + char str[4]; // string do val + int size_cmd = strlen(cmd); + //int value = dec2hex(val); + int value = val; + int n = 0; // tamanho em bytes do parametro do comando + int i; + uint8_t count = 0; + + if(size_cmd != 2) { + // Error: comando deve conter 2 chars + return -1; + } + + if(val != 0) { + if( (value >> 24) & 0xFF ) { + str[0] = (value >> 24) & 0xFF; + str[1] = (value >> 16) & 0xFF; + str[2] = (value >> 8) & 0xFF; + str[3] = value & 0xFF; + n = 4; + } else if( (value >> 16) & 0xFF ) { + str[0] = (value >> 16) & 0xFF; + str[1] = (value >> 8) & 0xFF; + str[2] = value & 0xFF; + n = 3; + } else if( (value >> 8) & 0xFF ) { + str[0] = (value >> 8) & 0xFF; + str[1] = value & 0xFF; + n = 2; + } else { + str[0] = value & 0xFF; + n = 1; + } + } + + count_tx = 0; + memset(&buf_tx,0,sizeof(buf_tx)); + + p->start_delimiter = 0x7E; + p->length = 0x04 + n; // pacote vazio + dados + p->frame_type = 0x09; // AT Command Queue + p->frame_id = 1; + + p->command[0] = cmd[0]; + p->command[1] = cmd[1]; + + if(val != 0) { + memcpy(&p->rf_data, str, n); + } + + // Calcula Checksum + + // comeca 3 pra frente, tenq passar 3 adiante no final + // para ler o mesmo tamanho de pacote + for(i = 3; i < p->length + 3; i++) { + count += buf_tx[i]; + //printf("\n%d\n", count); + } + count = 0xFF - count; + + p->rf_data[n] = count; + + //p->length tem o tamanho soh do frame, + //pacote total eh o starter + length alto + length baixo + checksum + count_tx = p->length + 4; + return count_tx; +} + +/* Envia pacote do buffer_tx */ +void XBEE::sendBuffer(void) +{ + if(xbee->writeable()) { + for(int i = 0; i < count_tx; i++) { + xbee->putc(buf_tx[i]); + } + //pode zerar pacote aqui + } +} + +/* Printa todo o buffer de Receive, e limpa */ +/* +void XBEE::printBuffer(void) +{ + char flag_msg = 0; + int size = sizeof(buf_rx); + if(count_rx < size) { + size = count_rx; + } + for(int i = 0; i < size; i++) { + printf("%c", buf_rx[i]); + flag_msg++; + } + if (flag_msg) { + printf("\n"); + } + + //Limpa buffer + count_rx = 0; + memset(&buf_rx,0,sizeof(buf_rx)); +} +*/ + +/* Receive and update NI variable */ +void XBEE::recv_NI(void) +{ + pkt_cmd *p; + int i; + for(i = 0; i < count_rx; i++) { + if(buf_rx[i] == 0x7E) { + p = (pkt_cmd *) &buf_rx[i]; + } + } + if(p->frame_type == 0x88) { + memcpy(NI, ((char *)(&p->rf_data))+2, 16); + // remove o checksum do nome + for(i = 15; i >= 0; i--) { + if(NI[i] != 0) { + NI[i] = '\0'; + break; + } + } + } +} + +/* Receive and update CMD variable */ +void XBEE::recv_CMD(int &cmd) +{ + char data[16]; + pkt_cmd *p; + int i; + int j = -1; + + for(i = 0; i < count_rx; i++) { + if(buf_rx[i] == 0x7E) { + p = (pkt_cmd *) &buf_rx[i]; + } + } + if(p->frame_type == 0x88) { + memcpy(data, &p->rf_data, 16); + for(i = 15; i > -1; i--) { + if(data[i] != 0 || j != -1) { + // pular o checksum + if(j==-1) { + j++; + } else { + //ID = (int)(dec2hex((data[i] << 8)) + dec2hex(data[i+1])); + cmd += data[i] << 8*j; + j++; + } + } + } + } +} + +/* Verify Packet Checksum return 0 if msg OK, just work with Transmit Package*/ +/* +char XBEE::validPackage(uint8_t * buf, int tam) +{ + int i = 0; + uint8_t count = 0; + + if(buf[0] != 0x7E) return 1; + if(buf[1] != 0) return 2; + if(buf[2] != tam-4) return 3; + + for(i = 3; i < tam; i++) { + count += buf[i]; + } + if(count != 0xFF) return 4; + + return 0; // OK +} +*/ + +/* Convert Dec to Hex, OBS: just for Hex number without Letter */ +int XBEE::dec2hex(int nbr) +{ + char hexa[8]; + int temp; + int result = 0; + int i = 0; + char hasLetter = 0; + + while(nbr != 0) + { + temp = nbr % 16; + hexa[i] = temp; + nbr = nbr / 16; + i++; + if(temp > 9) { + hasLetter++; + } + } + // concat number + for(i=i-1; i > -1; i--) { + result += hexa[i] * pow(10.0,(double)i); + } + + return result; +} + +/* Convert Hex to Dec */ +int XBEE::hex2dec(int nbr) +{ + char deci[8]; + int result = 0; + int i = 0; + int temp; + char hasLetter = 0; + + while(nbr != 0) { + temp = nbr % 10; + deci[i] = temp; + nbr = nbr / 10; + i++; + if(temp > 9) { + hasLetter++; + } + } + // concat number + for(i=i-1; i > -1; i--) { + result += (deci[i] * pow(16.0,(double)i) ); + } + return result; +} +void XBEE::int_mng(int value){ + int_ctrl = value; +}
diff -r 000000000000 -r fbed291691a6 XBEE.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/XBEE.h Sun Oct 14 02:01:07 2018 +0000 @@ -0,0 +1,98 @@ +#if !defined(__XBEE_H_) +#define __XBEE_H_ + +#include "mbed.h" +#include <string.h> +#include <stdint.h> // uint8_t +#include <stdlib.h> // itoa +#include <math.h> + +#define XB_SIZEBUF 64 +#define XB_PAYLOAD 16 + +#define XBEE_COORD 0 +#define XBEE_BROAD 1 + +// para poder declarar como typedef +typedef struct __attribute__ ((__packed__)) { + uint8_t start_delimiter; + uint8_t length_H; + uint8_t length; + // Frame do Pacote + uint8_t frame_type; // 10 + uint8_t frame_id; + uint8_t dest_addr64[8]; + uint8_t dest_addr16[2]; + uint8_t broadcast_radius; + uint8_t options; + uint8_t rf_data[100]; //NOTE: last byte MUST be checksum +}pkt_tx; + +// para poder declarar como typedef +typedef struct __attribute__ ((__packed__)) { + uint8_t start_delimiter; + uint8_t length_H; + uint8_t length; + // Frame do Pacote + uint8_t frame_type; // 8 + uint8_t frame_id; + uint8_t command[2]; // ASCII + uint8_t rf_data[16]; //NOTE: last byte MUST be checksum +}pkt_cmd; + + +/* Classe para controlar XBEE Zigbee usando API*/ +class XBEE { + public: + uint8_t buf_tx[XB_SIZEBUF]; // Serial TX + uint8_t buf_rx[XB_SIZEBUF]; // Serial RX + //CircularBuffer<uint8_t, XB_SIZEBUF> buf_rx; + int count_tx; + int count_rx; + // DEVICE DATA + char NI[16]; // Device Name + int ID; // Net ID + int MY; // Device Net Address + int SH; // Serial High + int SL; // Serial Low + int PL; // Power Level + int BD; // Baud Rate + int AO; // API option + int DB; // RSSI between messages + int TP; // Temperature inside module + + //XBEE(PinName tx, PinName rx, int baud = 9600); + XBEE(Serial* serial, int baud = 9600); + /** Class destructor */ + virtual ~XBEE(); + void recvAttach (void); + + // High Level Function + void init (void); + int send_msg(char * str, int dest); + int set_cfg(char * cmd, int value); + int recv_msg(char * buf, int tam); + int read_cfg(char * cmd, int & var); + void clear_buf(void); + + // Low Level Function + int create_TX(char * str, int dest); + int create_CMD(char * cmd, int val); + void sendBuffer(void); + //void printBuffer(void); + void recv_NI(void); + void recv_CMD(int & cmd); + void int_mng(int value); + + // Auxiliar Function + //char validPackage (uint8_t * buf, int tam); + int dec2hex(int nbr); + int hex2dec(int nbr); //ToDo + + protected: + //RawSerial *xbee; + Serial* xbee; + int int_ctrl; +}; + +#endif /* defined(__XBEE_H_) */ \ No newline at end of file