Code APP3
Dependencies: mbed EthernetInterface WebSocketClient mbed-rtos BufferedSerial
Fork of APP3_Lab by
main.cpp
00001 00002 #define IS_COORDINATOR 0 00003 00004 #include "mbed.h" 00005 00006 #include "rtos.h" 00007 // Communication avec les Zigbee 00008 #include "xbee.h" 00009 // Lecture de fichier de config 00010 #include "parser.h" 00011 00012 #if IS_COORDINATOR 00013 // Pour la connection ethernet du coordinateur 00014 #include "EthernetInterface.h" 00015 #include "Websocket.h" 00016 #else 00017 // Les capteurs des routeurs 00018 #include "sensors.h" 00019 #endif 00020 00021 // Loop led qui permet de verifier l'opération correcte du module 00022 DigitalOut loop_led(LED4); 00023 00024 // Pour les fonctionnalites de synchro 00025 Ticker ticker; 00026 00027 // A la reception d'un message de transmission non reussie, on demarre un ticker qui ferme 00028 // la DEL3 apres une seconde, pour permettre d'indiquer la presence d'erreur 00029 Ticker error_ticker; 00030 DigitalOut error_led(LED3); 00031 void error_display(); 00032 00033 // Thread du coordinateur qui permet l'envoi au serveur distant a l'aide de websocket 00034 Thread ws_send; 00035 void send_to_ws(); 00036 // Structure servant de message pour la mailbox 00037 typedef struct { 00038 char buffer[64]; 00039 } ws_message_t; 00040 Mail<ws_message_t, 32> messages_box; 00041 00042 // Envoie un remote AT command vers le noeud a l'addresse fournie 00043 void set_remote_xbee_dio4(bool set, zigbee_addr_64_t addr); 00044 00045 // Set le pan ID du reseau pour le noeud courant a l'aide de AT Command 00046 void set_pan_id(long pan_id); 00047 00048 // Liste de noeuds decouvert a la reception de messages 00049 zigbee_addr_64_t addr_64[255]; 00050 // Index actuel dans la liste de devices 00051 volatile int last_addr_64_index = 0; 00052 // Analyse un frame de data 00053 int process_frame(frame_t* frame); 00054 // Envois a tout les devices connus dans la liste d'addresse 00055 void send_del_to_all(); 00056 // Prends les valeurs des capteurs et les envois au coordinateur 00057 void get_all_sensors(); 00058 00059 #if IS_COORDINATOR 00060 void coordinator(); 00061 #else 00062 void routeur(); 00063 #endif 00064 00065 int main() { 00066 00067 xbee_init(); 00068 00069 #if IS_COORDINATOR 00070 coordinator(); 00071 #else 00072 routeur(); 00073 #endif 00074 } 00075 00076 #if IS_COORDINATOR 00077 void coordinator() 00078 { 00079 // Lecture de la configuration du coordinateur 00080 coordinator_config_t config = read_coordinator_config(); 00081 00082 // On set le pan ID du device adequatement dans le fichier de configuration 00083 set_pan_id(config.pan_id); 00084 00085 // Demarrage du thread qui s'occupe d'envoyer au web server 00086 ws_send.start(callback(send_to_ws)); 00087 // Ticker qui envoi a tout les noeuds une commande de clignotement 00088 ticker.attach(&send_del_to_all, 1.0); 00089 00090 frame_t current_frame; 00091 while(1) 00092 { 00093 // Reception 00094 bool finished_packet = receive(¤t_frame); 00095 // Si un packet complet est recu, on le traite 00096 if (finished_packet) 00097 { 00098 process_frame(¤t_frame); 00099 } 00100 wait_ms(10); 00101 } 00102 } 00103 #else 00104 void routeur() 00105 { 00106 // Lecture de la configuration du routeur 00107 router_config_t config = read_router_config(); 00108 00109 // On set le pan ID du device adequatement dans le fichier de configuration 00110 set_pan_id(config.pan_id); 00111 00112 // Init les capteurs qui seront captures par le noeud 00113 initialize_sensors(); 00114 00115 // Appel de la fonction de mesure des donnes de capteurs a tout les 00116 // temps donnes par config.refresh_freq 00117 ticker.attach(&get_all_sensors, config.refresh_freq); 00118 00119 frame_t current_frame; 00120 while(1) 00121 { 00122 // Reception 00123 bool finished_packet = receive(¤t_frame); 00124 // Si un packet complet est recu, on le traite 00125 if (finished_packet) 00126 { 00127 process_frame(¤t_frame); 00128 } 00129 wait_ms(10); 00130 } 00131 } 00132 #endif 00133 00134 // Cree un pan id a l'aide du long en parametre, et envoi la commande at de configuration du PAN ID 00135 void set_pan_id(long pan_id) 00136 { 00137 char pan_id_buffer[8] = {0}; 00138 for (int i = 0; i < 8; i++) 00139 { 00140 pan_id_buffer[i] = 0xFF & (pan_id >> 8 * (7 - i)); 00141 } 00142 at_command_set('I', 'D', pan_id_buffer, 8); 00143 } 00144 00145 // Analyse du frame recu, et prise de decisions 00146 int process_frame(frame_t* frame) 00147 { 00148 Serial pc(USBTX, USBRX); // tx, rx 00149 if (frame->length <= 0) 00150 { 00151 return -1; 00152 } 00153 00154 if (frame->buffer[0] == 0x8B) 00155 { 00156 if(frame->buffer[5] != 0x00) 00157 { 00158 error_led = 1; 00159 error_ticker.attach(&error_display, 1.0); 00160 } 00161 return 2; 00162 } 00163 else if (frame->buffer[0] == 0x90) 00164 { 00165 // Manage source address 00166 // Detect the source address and list it dynamically 00167 zigbee_addr_64_t temp_addr_64; 00168 bool already_exist = false; 00169 // Read 64 bit address that was in message 00170 temp_addr_64.addr_0 = frame->buffer[1]; 00171 temp_addr_64.addr_1 = frame->buffer[2]; 00172 temp_addr_64.addr_2 = frame->buffer[3]; 00173 temp_addr_64.addr_3 = frame->buffer[4]; 00174 temp_addr_64.addr_4 = frame->buffer[5]; 00175 temp_addr_64.addr_5 = frame->buffer[6]; 00176 temp_addr_64.addr_6 = frame->buffer[7]; 00177 temp_addr_64.addr_7 = frame->buffer[8]; 00178 00179 // Verify if the received address is new 00180 for(int j = 0; j < last_addr_64_index; j++) 00181 { 00182 if(addr_64_equal(temp_addr_64,addr_64[j])) 00183 { 00184 already_exist = true; 00185 } 00186 } 00187 00188 // If it is New and our array isn't full of devices add it to the array 00189 if(!already_exist && last_addr_64_index < 255) 00190 { 00191 last_addr_64_index++; 00192 addr_64[last_addr_64_index] = temp_addr_64; 00193 } 00194 00195 ws_message_t* message = messages_box.alloc(); 00196 00197 //Data starts at 12 00198 for (int i = 12; i < frame->length; i++) 00199 { 00200 message->buffer[i - 12] = frame->buffer[i]; 00201 pc.putc(frame->buffer[i]); 00202 } 00203 message->buffer[frame->length - 12] = '\0'; 00204 messages_box.put(message); 00205 return 1; 00206 } 00207 return 0; 00208 } 00209 00210 #if IS_COORDINATOR 00211 // Fonction du thread d'envoi au web server par websocket 00212 void send_to_ws() 00213 { 00214 coordinator_config_t config = read_coordinator_config(); 00215 00216 // Interface Ethernet 00217 EthernetInterface eth; 00218 eth.init(/*"192.168.3.3", "255.255.255.0", "192.168.3.2"*/); //Use DHCP 00219 eth.connect(); 00220 00221 // Creation du WebSocket 00222 Websocket ws(config.server_url); 00223 ws.connect(); 00224 osEvent evt; 00225 while(1) 00226 { 00227 if (!ws.is_connected()) 00228 { 00229 ws.connect(); 00230 } 00231 00232 evt = messages_box.get(); 00233 if (evt.status == osEventMail) { 00234 ws_message_t* mail = (ws_message_t*)evt.value.p; 00235 ws.send(mail->buffer); 00236 Thread::wait(500); 00237 messages_box.free(mail); 00238 } 00239 else 00240 { 00241 Thread::wait(100); 00242 } 00243 } 00244 } 00245 #endif 00246 00247 // Envoi a tout les noeuds la commande at remote pour changer l'etat de la DEL 00248 void send_del_to_all() 00249 { 00250 loop_led = !loop_led; 00251 static bool flip = false; 00252 flip = !flip; 00253 for (int i = 0; i < last_addr_64_index; i++) 00254 { 00255 set_remote_xbee_dio4(flip, addr_64[i]); 00256 } 00257 } 00258 00259 // Envoi la commande remote at pour setter la sortie de DIO4 00260 void set_remote_xbee_dio4(bool set, zigbee_addr_64_t addr) 00261 { 00262 if (set) 00263 { 00264 remote_at_command_set(AT_COMMAND_DIO4_MSB, AT_COMMAND_DIO4_LSB, 00265 AT_COMMAND_DIO_OUT_LOW, 0x02, addr); 00266 } 00267 else 00268 { 00269 remote_at_command_set(AT_COMMAND_DIO4_MSB, AT_COMMAND_DIO4_LSB, 00270 AT_COMMAND_DIO_OUT_HIGH, 0x02, addr); 00271 } 00272 } 00273 00274 #if !IS_COORDINATOR 00275 // Effecture une mesure sur tout les capteurs connus dans le tableau de fct puis 00276 // envoi les resultats au coordinateur 00277 void get_all_sensors() 00278 { 00279 loop_led = !loop_led; 00280 char sensor_buffer[64] = {}; 00281 DECLARE_ADDR64_COORD 00282 DECLARE_ADDR16_UNKNOWN_OR_BCAST 00283 for (int i = 0; i < 2; i++) 00284 { 00285 sensor_t sensor = (*p[i])(); 00286 00287 if (sensor.sensor_type == 1) 00288 { 00289 sprintf(sensor_buffer, "button::%u\n\r", sensor.sensor_result.Bouton.etat != 0 ? 1 : 0); 00290 transmit_request(sensor_buffer, 8 + 1 + 2, 0, USE_ADDR64_COORD, USE_ADDR16_UNKNOWN_OR_BCAST); 00291 } 00292 else if (sensor.sensor_type == 2) 00293 { 00294 sprintf(sensor_buffer, "accel::%3.2f%3.2f%3.2f\n\r", sensor.sensor_result.Accelerometre.x, 00295 sensor.sensor_result.Accelerometre.y, sensor.sensor_result.Accelerometre.z); 00296 transmit_request(sensor_buffer, 7 + 15 + 2, 0, USE_ADDR64_COORD, USE_ADDR16_UNKNOWN_OR_BCAST); 00297 } 00298 } 00299 } 00300 #endif 00301 00302 // Ferme la DEL d'erreur et detach le ticker 00303 void error_display() 00304 { 00305 error_led = 0; 00306 error_ticker.detach(); 00307 }
Generated on Sat Jul 30 2022 02:06:50 by 1.7.2