Code APP3
Dependencies: mbed EthernetInterface WebSocketClient mbed-rtos BufferedSerial
Fork of APP3_Lab by
main.cpp
- Committer:
- Cheroukee
- Date:
- 2017-10-02
- Revision:
- 27:3baf4701a047
- Parent:
- 26:cbf539141bfe
File content as of revision 27:3baf4701a047:
#define IS_COORDINATOR 0 #include "mbed.h" #include "rtos.h" // Communication avec les Zigbee #include "xbee.h" // Lecture de fichier de config #include "parser.h" #if IS_COORDINATOR // Pour la connection ethernet du coordinateur #include "EthernetInterface.h" #include "Websocket.h" #else // Les capteurs des routeurs #include "sensors.h" #endif // Loop led qui permet de verifier l'opération correcte du module DigitalOut loop_led(LED4); // Pour les fonctionnalites de synchro Ticker ticker; // A la reception d'un message de transmission non reussie, on demarre un ticker qui ferme // la DEL3 apres une seconde, pour permettre d'indiquer la presence d'erreur Ticker error_ticker; DigitalOut error_led(LED3); void error_display(); // Thread du coordinateur qui permet l'envoi au serveur distant a l'aide de websocket Thread ws_send; void send_to_ws(); // Structure servant de message pour la mailbox typedef struct { char buffer[64]; } ws_message_t; Mail<ws_message_t, 32> messages_box; // Envoie un remote AT command vers le noeud a l'addresse fournie void set_remote_xbee_dio4(bool set, zigbee_addr_64_t addr); // Set le pan ID du reseau pour le noeud courant a l'aide de AT Command void set_pan_id(long pan_id); // Liste de noeuds decouvert a la reception de messages zigbee_addr_64_t addr_64[255]; // Index actuel dans la liste de devices volatile int last_addr_64_index = 0; // Analyse un frame de data int process_frame(frame_t* frame); // Envois a tout les devices connus dans la liste d'addresse void send_del_to_all(); // Prends les valeurs des capteurs et les envois au coordinateur void get_all_sensors(); #if IS_COORDINATOR void coordinator(); #else void routeur(); #endif int main() { xbee_init(); #if IS_COORDINATOR coordinator(); #else routeur(); #endif } #if IS_COORDINATOR void coordinator() { // Lecture de la configuration du coordinateur coordinator_config_t config = read_coordinator_config(); // On set le pan ID du device adequatement dans le fichier de configuration set_pan_id(config.pan_id); // Demarrage du thread qui s'occupe d'envoyer au web server ws_send.start(callback(send_to_ws)); // Ticker qui envoi a tout les noeuds une commande de clignotement ticker.attach(&send_del_to_all, 1.0); frame_t current_frame; while(1) { // Reception bool finished_packet = receive(¤t_frame); // Si un packet complet est recu, on le traite if (finished_packet) { process_frame(¤t_frame); } wait_ms(10); } } #else void routeur() { // Lecture de la configuration du routeur router_config_t config = read_router_config(); // On set le pan ID du device adequatement dans le fichier de configuration set_pan_id(config.pan_id); // Init les capteurs qui seront captures par le noeud initialize_sensors(); // Appel de la fonction de mesure des donnes de capteurs a tout les // temps donnes par config.refresh_freq ticker.attach(&get_all_sensors, config.refresh_freq); frame_t current_frame; while(1) { // Reception bool finished_packet = receive(¤t_frame); // Si un packet complet est recu, on le traite if (finished_packet) { process_frame(¤t_frame); } wait_ms(10); } } #endif // Cree un pan id a l'aide du long en parametre, et envoi la commande at de configuration du PAN ID void set_pan_id(long pan_id) { char pan_id_buffer[8] = {0}; for (int i = 0; i < 8; i++) { pan_id_buffer[i] = 0xFF & (pan_id >> 8 * (7 - i)); } at_command_set('I', 'D', pan_id_buffer, 8); } // Analyse du frame recu, et prise de decisions int process_frame(frame_t* frame) { Serial pc(USBTX, USBRX); // tx, rx if (frame->length <= 0) { return -1; } if (frame->buffer[0] == 0x8B) { if(frame->buffer[5] != 0x00) { error_led = 1; error_ticker.attach(&error_display, 1.0); } return 2; } else if (frame->buffer[0] == 0x90) { // Manage source address // Detect the source address and list it dynamically zigbee_addr_64_t temp_addr_64; bool already_exist = false; // Read 64 bit address that was in message temp_addr_64.addr_0 = frame->buffer[1]; temp_addr_64.addr_1 = frame->buffer[2]; temp_addr_64.addr_2 = frame->buffer[3]; temp_addr_64.addr_3 = frame->buffer[4]; temp_addr_64.addr_4 = frame->buffer[5]; temp_addr_64.addr_5 = frame->buffer[6]; temp_addr_64.addr_6 = frame->buffer[7]; temp_addr_64.addr_7 = frame->buffer[8]; // Verify if the received address is new for(int j = 0; j < last_addr_64_index; j++) { if(addr_64_equal(temp_addr_64,addr_64[j])) { already_exist = true; } } // If it is New and our array isn't full of devices add it to the array if(!already_exist && last_addr_64_index < 255) { last_addr_64_index++; addr_64[last_addr_64_index] = temp_addr_64; } ws_message_t* message = messages_box.alloc(); //Data starts at 12 for (int i = 12; i < frame->length; i++) { message->buffer[i - 12] = frame->buffer[i]; pc.putc(frame->buffer[i]); } message->buffer[frame->length - 12] = '\0'; messages_box.put(message); return 1; } return 0; } #if IS_COORDINATOR // Fonction du thread d'envoi au web server par websocket void send_to_ws() { coordinator_config_t config = read_coordinator_config(); // Interface Ethernet EthernetInterface eth; eth.init(/*"192.168.3.3", "255.255.255.0", "192.168.3.2"*/); //Use DHCP eth.connect(); // Creation du WebSocket Websocket ws(config.server_url); ws.connect(); osEvent evt; while(1) { if (!ws.is_connected()) { ws.connect(); } evt = messages_box.get(); if (evt.status == osEventMail) { ws_message_t* mail = (ws_message_t*)evt.value.p; ws.send(mail->buffer); Thread::wait(500); messages_box.free(mail); } else { Thread::wait(100); } } } #endif // Envoi a tout les noeuds la commande at remote pour changer l'etat de la DEL void send_del_to_all() { loop_led = !loop_led; static bool flip = false; flip = !flip; for (int i = 0; i < last_addr_64_index; i++) { set_remote_xbee_dio4(flip, addr_64[i]); } } // Envoi la commande remote at pour setter la sortie de DIO4 void set_remote_xbee_dio4(bool set, zigbee_addr_64_t addr) { if (set) { remote_at_command_set(AT_COMMAND_DIO4_MSB, AT_COMMAND_DIO4_LSB, AT_COMMAND_DIO_OUT_LOW, 0x02, addr); } else { remote_at_command_set(AT_COMMAND_DIO4_MSB, AT_COMMAND_DIO4_LSB, AT_COMMAND_DIO_OUT_HIGH, 0x02, addr); } } #if !IS_COORDINATOR // Effecture une mesure sur tout les capteurs connus dans le tableau de fct puis // envoi les resultats au coordinateur void get_all_sensors() { loop_led = !loop_led; char sensor_buffer[64] = {}; DECLARE_ADDR64_COORD DECLARE_ADDR16_UNKNOWN_OR_BCAST for (int i = 0; i < 2; i++) { sensor_t sensor = (*p[i])(); if (sensor.sensor_type == 1) { sprintf(sensor_buffer, "button::%u\n\r", sensor.sensor_result.Bouton.etat != 0 ? 1 : 0); transmit_request(sensor_buffer, 8 + 1 + 2, 0, USE_ADDR64_COORD, USE_ADDR16_UNKNOWN_OR_BCAST); } else if (sensor.sensor_type == 2) { sprintf(sensor_buffer, "accel::%3.2f%3.2f%3.2f\n\r", sensor.sensor_result.Accelerometre.x, sensor.sensor_result.Accelerometre.y, sensor.sensor_result.Accelerometre.z); transmit_request(sensor_buffer, 7 + 15 + 2, 0, USE_ADDR64_COORD, USE_ADDR16_UNKNOWN_OR_BCAST); } } } #endif // Ferme la DEL d'erreur et detach le ticker void error_display() { error_led = 0; error_ticker.detach(); }