Xbee
XBEE.cpp
- Committer:
- renanbmx123
- Date:
- 2018-10-14
- Revision:
- 0:fbed291691a6
File content as of revision 0:fbed291691a6:
#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; }