Xbee

Revision:
0:fbed291691a6
--- /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;
+}