Projet s5 - sensors lib

Dependencies:   XBeeLib mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers xbeeutils.cpp Source File

xbeeutils.cpp

00001 /*  xbeeutils.cpp
00002  *  Guillaume Hivert, Marc-Olivier Lavoie, Gabriel Gibeau-Sanchez
00003  *  Université de Sherbrooke, S5 project
00004  *
00005  *  Provides high-level functions to initialize and control xbee communication.
00006  *  Inspired by https://os.mbed.com/teams/Digi-International-Inc/code/XBeeLib/wiki/Discovering-nodes-in-the-network
00007 */
00008 
00009 #include "xbeeutils.h"
00010 
00011 #define MAX_NODES                   10
00012 
00013 static XBeeZB *xbee = NULL;
00014 static RemoteXBeeZB remote_nodes_in_network[MAX_NODES];
00015 static unsigned int remote_nodes_count = 0;
00016 static Serial pc_(USBTX,USBRX);
00017 static Serial * pc=&pc_;
00018 
00019 static void handle_discover(const RemoteXBeeZB& remote, char const * const node_id);
00020 static void handle_receive_data(const RemoteXBeeZB& remote, bool broadcast, const uint8_t *const data, uint16_t len);
00021 static int isNewRemote(uint16_t addr_16);
00022 
00023 void xbee_init() {
00024     xbee = new XBeeZB(RADIO_TX, RADIO_RX, RADIO_RESET, NC, NC, 9600);
00025     RadioStatus radioStatus = xbee->init();
00026     radioStatus = xbee->set_panid((uint64_t) 0xABCD);                   // Don't forget to do this with config!
00027     xbee->register_receive_cb(handle_receive_data);
00028     
00029     // Wait for xbee to be ready
00030     while (!xbee->is_joined()) {
00031         wait_ms(1000);
00032         (*pc).printf(".");
00033     }
00034     (*pc).printf("OK\r\n");
00035 }
00036 
00037 /* This function is called when a node is discovered. It adds it to the known nodes list if it was a not previously discovered.
00038  *
00039  * remote: Node that was discovered
00040  * node_id: ID (NI) of the discovered node. Can be empty string "", so avoid using it.
00041 */
00042 static void handle_discover(const RemoteXBeeZB& remote, char const * const node_id) {
00043     uint16_t addr_16 = remote.get_addr16();
00044 
00045     (*pc).printf("Found device '%s' [%04X]\r\n", node_id, addr_16);
00046 
00047     if (remote_nodes_count < MAX_NODES) {
00048         if(isNewRemote(addr_16)) {
00049             (*pc).printf("in if\n");
00050             remote_nodes_in_network[remote_nodes_count] = remote;
00051             remote_nodes_count++;
00052             // get configs
00053         }
00054     } else {
00055         (*pc).printf("Found more nodes than maximum configured (%d)\r\n", MAX_NODES);
00056     }
00057 }
00058 
00059 /* Checks if a discovered node is already known
00060  *
00061  * addr_16: 16-bit network address of discovered node.
00062  * Returns 1 if the node is a new node, 0 if it was already known.
00063 */
00064 static int isNewRemote(uint16_t addr_16) {
00065     int i;
00066     for (i=0; i < remote_nodes_count; i++) {
00067         if (addr_16 == remote_nodes_in_network[i].get_addr16())
00068         return 0;
00069     }
00070     return 1;
00071 }
00072 
00073 /* This function is called when data is received from other nodes.
00074  *
00075  * remote: sender of the data.
00076  * broadcast: true if the message received was broadcasted, false if it was specifically sent to this module.
00077  * data: message received.
00078  * len: length of the message received.
00079 */
00080 static void handle_receive_data(const RemoteXBeeZB& remote, bool broadcast, const uint8_t *const data, uint16_t len) {
00081     (*pc).printf("Received message from remote %X\r\n", remote.get_addr16());
00082     (*pc).printf("%s\r\n", data);
00083     
00084     char *s = (char*) data;
00085     int c = 0;
00086     char **arr = NULL;
00087     
00088     c = split(s, ';', &arr);
00089     (*pc).printf("found %d tokens.\n", c);
00090     
00091     Config config;
00092     
00093     config.temperatureMax = atof(arr[0]);
00094     config.temperatureMin = atof(arr[1]);
00095     config.phMax = atof(arr[2]);
00096     config.phMin = atof(arr[3]);
00097     config.ec = atof(arr[4]);
00098     
00099     (*pc).printf("Tmax: %f\nTmin: %f\nPHmax: %f\nPHmin: %f\nEC: %f\n", config.temperatureMax, config.temperatureMin, config.phMax, config.phMin, config.ec);
00100     
00101     setConfig(config);
00102 }
00103 
00104 
00105 /* Tries to discover new nodes in the network. 
00106  *
00107  * If a node answers, handle_discover() will be called with information about the answering node.
00108 */
00109 void discover() {
00110     (*pc).printf("\r\nStarting Node Discovery\r\n\r\n");
00111     for(int i = 0; i < 3; i++) {
00112         xbee->start_node_discovery();
00113         
00114         do {
00115             xbee->process_rx_frames();
00116             wait_ms(10);
00117         } while(xbee->is_node_discovery_in_progress());
00118     }
00119     
00120     (*pc).printf("\r\nNode Discovery Finished\r\n\r\n");
00121     (*pc).printf("remote nodes count %i\n", remote_nodes_count);
00122 }
00123 
00124 /* Sends a message to a remote ZigBee node.
00125  *
00126  * message: message to send.
00127  * length: length of the message to send.
00128  * target_addr_16: 16-bit network address of the target node.
00129 */
00130 void send_data_to_coordinator(char *message, int length) {    
00131 
00132     const TxStatus txStatus = xbee->send_data_to_coordinator((const uint8_t *)message, length);
00133     if (txStatus != TxStatusSuccess) {
00134         (*pc).printf("An error happened while sending data to remote coordinator %d\r\n", txStatus);
00135     }
00136 }
00137 
00138 RemoteXBeeZB get_remote_node() {
00139     return xbee->get_remote_node_by_id("Router");
00140 }
00141 
00142 void xbee_send(const RemoteXBeeZB& xbzb, char * msg, int length){
00143     xbee->send_data(xbzb, (const uint8_t *)msg, length);
00144 }
00145 
00146 /* Sends a message to all remote ZigBee nodes.
00147  *
00148  * message: message to send.
00149  * length: length of the message to send.
00150 */
00151 // Change to xbee->send_data_broadcast
00152 void xbee_broadcast(char *message, int length) {
00153     
00154     const TxStatus txStatus = xbee->send_data_broadcast((const uint8_t *) message, length);
00155     if (txStatus != TxStatusSuccess) {
00156         //(*pc).printf("An error happened while sending data to remote %X, status: %d\r\n", remote_nodes_in_network[i].get_addr16(), txStatus);
00157         (*pc).printf("An error happened while sending data to remote X, status: %d\r\n", txStatus);
00158     }
00159 }
00160 /* Gives processor time to process frames held in the receive buffer
00161  * 
00162  * Depending on the the type of frame received, different functions will be called.
00163  * See handle_discover and handle_receive_data
00164 */
00165 void process_rx_frames() {
00166     xbee->process_rx_frames();
00167 }
00168 
00169 int split (char *str, char c, char ***arr)
00170 {
00171     int count = 1;
00172     int token_len = 1;
00173     int i = 0;
00174     char *p;
00175     char *t;
00176 
00177     p = str;
00178     while (*p != '\0')
00179     {
00180         if (*p == c)
00181             count++;
00182         p++;
00183     }
00184 
00185     *arr = (char**) malloc(sizeof(char*) * count);
00186     if (*arr == NULL)
00187         exit(1);
00188 
00189     p = str;
00190     while (*p != '\0')
00191     {
00192         if (*p == c)
00193         {
00194             (*arr)[i] = (char*) malloc( sizeof(char) * token_len );
00195             if ((*arr)[i] == NULL)
00196                 exit(1);
00197 
00198             token_len = 0;
00199             i++;
00200         }
00201         p++;
00202         token_len++;
00203     }
00204     (*arr)[i] = (char*) malloc( sizeof(char) * token_len );
00205     if ((*arr)[i] == NULL)
00206         exit(1);
00207 
00208     i = 0;
00209     p = str;
00210     t = ((*arr)[i]);
00211     while (*p != '\0')
00212     {
00213         if (*p != c && *p != '\0')
00214         {
00215             *t = *p;
00216             t++;
00217         }
00218         else
00219         {
00220             *t = '\0';
00221             i++;
00222             t = ((*arr)[i]);
00223         }
00224         p++;
00225     }
00226 
00227     return count;
00228 }
00229 
00230