Code APP3

Dependencies:   mbed EthernetInterface WebSocketClient mbed-rtos BufferedSerial

Fork of APP3_Lab by Jean-Philippe Fournier

Committer:
JayMcGee
Date:
Mon Oct 02 21:54:52 2017 +0000
Revision:
29:56b6c15904e6
Parent:
27:3baf4701a047
Merge

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Cheroukee 27:3baf4701a047 1
Cheroukee 27:3baf4701a047 2 #define IS_COORDINATOR 0
Cheroukee 27:3baf4701a047 3
Cheroukee 0:f468a460723d 4 #include "mbed.h"
Cheroukee 2:a9bb12eefc08 5
Cheroukee 17:8abdbfa6019c 6 #include "rtos.h"
Cheroukee 27:3baf4701a047 7 // Communication avec les Zigbee
Cheroukee 1:ea1b52d0a8a3 8 #include "xbee.h"
Cheroukee 27:3baf4701a047 9 // Lecture de fichier de config
Cheroukee 5:9e6a09a38785 10 #include "parser.h"
Cheroukee 27:3baf4701a047 11
Cheroukee 27:3baf4701a047 12 #if IS_COORDINATOR
Cheroukee 27:3baf4701a047 13 // Pour la connection ethernet du coordinateur
Cheroukee 27:3baf4701a047 14 #include "EthernetInterface.h"
Cheroukee 27:3baf4701a047 15 #include "Websocket.h"
Cheroukee 27:3baf4701a047 16 #else
Cheroukee 27:3baf4701a047 17 // Les capteurs des routeurs
Cheroukee 27:3baf4701a047 18 #include "sensors.h"
Cheroukee 27:3baf4701a047 19 #endif
Cheroukee 2:a9bb12eefc08 20
Cheroukee 27:3baf4701a047 21 // Loop led qui permet de verifier l'opération correcte du module
Cheroukee 15:c4d17caf0709 22 DigitalOut loop_led(LED4);
Cheroukee 13:5f21dd134bd2 23
Cheroukee 27:3baf4701a047 24 // Pour les fonctionnalites de synchro
Cheroukee 27:3baf4701a047 25 Ticker ticker;
Cheroukee 27:3baf4701a047 26
Cheroukee 27:3baf4701a047 27 // A la reception d'un message de transmission non reussie, on demarre un ticker qui ferme
Cheroukee 27:3baf4701a047 28 // la DEL3 apres une seconde, pour permettre d'indiquer la presence d'erreur
Cheroukee 25:7b808fb9e025 29 Ticker error_ticker;
Cheroukee 25:7b808fb9e025 30 DigitalOut error_led(LED3);
Cheroukee 27:3baf4701a047 31 void error_display();
Cheroukee 25:7b808fb9e025 32
Cheroukee 27:3baf4701a047 33 // Thread du coordinateur qui permet l'envoi au serveur distant a l'aide de websocket
Cheroukee 26:cbf539141bfe 34 Thread ws_send;
Cheroukee 26:cbf539141bfe 35 void send_to_ws();
Cheroukee 27:3baf4701a047 36 // Structure servant de message pour la mailbox
Cheroukee 26:cbf539141bfe 37 typedef struct {
Cheroukee 26:cbf539141bfe 38 char buffer[64];
Cheroukee 26:cbf539141bfe 39 } ws_message_t;
Cheroukee 26:cbf539141bfe 40 Mail<ws_message_t, 32> messages_box;
Cheroukee 26:cbf539141bfe 41
Cheroukee 27:3baf4701a047 42 // Envoie un remote AT command vers le noeud a l'addresse fournie
Cheroukee 25:7b808fb9e025 43 void set_remote_xbee_dio4(bool set, zigbee_addr_64_t addr);
Cheroukee 0:f468a460723d 44
Cheroukee 27:3baf4701a047 45 // Set le pan ID du reseau pour le noeud courant a l'aide de AT Command
Cheroukee 14:cd488eba8bba 46 void set_pan_id(long pan_id);
Cheroukee 14:cd488eba8bba 47
Cheroukee 27:3baf4701a047 48 // Liste de noeuds decouvert a la reception de messages
JayMcGee 22:7edae38d0758 49 zigbee_addr_64_t addr_64[255];
Cheroukee 27:3baf4701a047 50 // Index actuel dans la liste de devices
Cheroukee 25:7b808fb9e025 51 volatile int last_addr_64_index = 0;
Cheroukee 27:3baf4701a047 52 // Analyse un frame de data
Cheroukee 19:75e600a40741 53 int process_frame(frame_t* frame);
Cheroukee 27:3baf4701a047 54 // Envois a tout les devices connus dans la liste d'addresse
Cheroukee 25:7b808fb9e025 55 void send_del_to_all();
Cheroukee 27:3baf4701a047 56 // Prends les valeurs des capteurs et les envois au coordinateur
Cheroukee 25:7b808fb9e025 57 void get_all_sensors();
Cheroukee 25:7b808fb9e025 58
Cheroukee 13:5f21dd134bd2 59 #if IS_COORDINATOR
Cheroukee 13:5f21dd134bd2 60 void coordinator();
Cheroukee 13:5f21dd134bd2 61 #else
Cheroukee 13:5f21dd134bd2 62 void routeur();
Cheroukee 13:5f21dd134bd2 63 #endif
Cheroukee 6:9ed8153f1328 64
Cheroukee 0:f468a460723d 65 int main() {
Cheroukee 2:a9bb12eefc08 66
Cheroukee 1:ea1b52d0a8a3 67 xbee_init();
Cheroukee 2:a9bb12eefc08 68
Cheroukee 13:5f21dd134bd2 69 #if IS_COORDINATOR
Cheroukee 13:5f21dd134bd2 70 coordinator();
Cheroukee 13:5f21dd134bd2 71 #else
Cheroukee 13:5f21dd134bd2 72 routeur();
Cheroukee 13:5f21dd134bd2 73 #endif
Cheroukee 13:5f21dd134bd2 74 }
Cheroukee 2:a9bb12eefc08 75
Cheroukee 2:a9bb12eefc08 76 #if IS_COORDINATOR
Cheroukee 13:5f21dd134bd2 77 void coordinator()
Cheroukee 16:0a5f3c449c95 78 {
Cheroukee 27:3baf4701a047 79 // Lecture de la configuration du coordinateur
Cheroukee 13:5f21dd134bd2 80 coordinator_config_t config = read_coordinator_config();
Cheroukee 16:0a5f3c449c95 81
Cheroukee 27:3baf4701a047 82 // On set le pan ID du device adequatement dans le fichier de configuration
Cheroukee 14:cd488eba8bba 83 set_pan_id(config.pan_id);
Cheroukee 27:3baf4701a047 84
Cheroukee 27:3baf4701a047 85 // Demarrage du thread qui s'occupe d'envoyer au web server
Cheroukee 27:3baf4701a047 86 ws_send.start(callback(send_to_ws));
Cheroukee 27:3baf4701a047 87 // Ticker qui envoi a tout les noeuds une commande de clignotement
Cheroukee 27:3baf4701a047 88 ticker.attach(&send_del_to_all, 1.0);
Cheroukee 27:3baf4701a047 89
Cheroukee 12:1286b80c68f7 90 frame_t current_frame;
Cheroukee 13:5f21dd134bd2 91 while(1)
Cheroukee 13:5f21dd134bd2 92 {
Cheroukee 27:3baf4701a047 93 // Reception
Cheroukee 27:3baf4701a047 94 bool finished_packet = receive(&current_frame);
Cheroukee 27:3baf4701a047 95 // Si un packet complet est recu, on le traite
Cheroukee 8:5955af1ee445 96 if (finished_packet)
Cheroukee 24:29ec42daa82e 97 {
Cheroukee 26:cbf539141bfe 98 process_frame(&current_frame);
Cheroukee 6:9ed8153f1328 99 }
Cheroukee 26:cbf539141bfe 100 wait_ms(10);
Cheroukee 13:5f21dd134bd2 101 }
Cheroukee 13:5f21dd134bd2 102 }
Cheroukee 12:1286b80c68f7 103 #else
Cheroukee 13:5f21dd134bd2 104 void routeur()
Cheroukee 13:5f21dd134bd2 105 {
Cheroukee 27:3baf4701a047 106 // Lecture de la configuration du routeur
Cheroukee 13:5f21dd134bd2 107 router_config_t config = read_router_config();
Cheroukee 25:7b808fb9e025 108
Cheroukee 27:3baf4701a047 109 // On set le pan ID du device adequatement dans le fichier de configuration
Cheroukee 14:cd488eba8bba 110 set_pan_id(config.pan_id);
Cheroukee 25:7b808fb9e025 111
Cheroukee 27:3baf4701a047 112 // Init les capteurs qui seront captures par le noeud
Cheroukee 13:5f21dd134bd2 113 initialize_sensors();
Cheroukee 13:5f21dd134bd2 114
Cheroukee 27:3baf4701a047 115 // Appel de la fonction de mesure des donnes de capteurs a tout les
Cheroukee 27:3baf4701a047 116 // temps donnes par config.refresh_freq
Cheroukee 27:3baf4701a047 117 ticker.attach(&get_all_sensors, config.refresh_freq);
Cheroukee 25:7b808fb9e025 118
Cheroukee 27:3baf4701a047 119 frame_t current_frame;
Cheroukee 13:5f21dd134bd2 120 while(1)
Cheroukee 25:7b808fb9e025 121 {
Cheroukee 27:3baf4701a047 122 // Reception
Cheroukee 27:3baf4701a047 123 bool finished_packet = receive(&current_frame);
Cheroukee 27:3baf4701a047 124 // Si un packet complet est recu, on le traite
Cheroukee 25:7b808fb9e025 125 if (finished_packet)
Cheroukee 25:7b808fb9e025 126 {
Cheroukee 25:7b808fb9e025 127 process_frame(&current_frame);
Cheroukee 25:7b808fb9e025 128 }
Cheroukee 27:3baf4701a047 129 wait_ms(10);
Cheroukee 0:f468a460723d 130 }
Cheroukee 0:f468a460723d 131 }
Cheroukee 14:cd488eba8bba 132 #endif
Cheroukee 14:cd488eba8bba 133
Cheroukee 27:3baf4701a047 134 // Cree un pan id a l'aide du long en parametre, et envoi la commande at de configuration du PAN ID
Cheroukee 14:cd488eba8bba 135 void set_pan_id(long pan_id)
Cheroukee 14:cd488eba8bba 136 {
Cheroukee 14:cd488eba8bba 137 char pan_id_buffer[8] = {0};
Cheroukee 14:cd488eba8bba 138 for (int i = 0; i < 8; i++)
Cheroukee 14:cd488eba8bba 139 {
Cheroukee 14:cd488eba8bba 140 pan_id_buffer[i] = 0xFF & (pan_id >> 8 * (7 - i));
Cheroukee 14:cd488eba8bba 141 }
Cheroukee 14:cd488eba8bba 142 at_command_set('I', 'D', pan_id_buffer, 8);
Cheroukee 14:cd488eba8bba 143 }
Cheroukee 19:75e600a40741 144
Cheroukee 27:3baf4701a047 145 // Analyse du frame recu, et prise de decisions
Cheroukee 19:75e600a40741 146 int process_frame(frame_t* frame)
Cheroukee 19:75e600a40741 147 {
Cheroukee 19:75e600a40741 148 Serial pc(USBTX, USBRX); // tx, rx
Cheroukee 19:75e600a40741 149 if (frame->length <= 0)
Cheroukee 19:75e600a40741 150 {
Cheroukee 19:75e600a40741 151 return -1;
Cheroukee 19:75e600a40741 152 }
Cheroukee 26:cbf539141bfe 153
Cheroukee 25:7b808fb9e025 154 if (frame->buffer[0] == 0x8B)
Cheroukee 25:7b808fb9e025 155 {
Cheroukee 25:7b808fb9e025 156 if(frame->buffer[5] != 0x00)
Cheroukee 25:7b808fb9e025 157 {
Cheroukee 25:7b808fb9e025 158 error_led = 1;
Cheroukee 27:3baf4701a047 159 error_ticker.attach(&error_display, 1.0);
Cheroukee 25:7b808fb9e025 160 }
Cheroukee 26:cbf539141bfe 161 return 2;
Cheroukee 25:7b808fb9e025 162 }
Cheroukee 25:7b808fb9e025 163 else if (frame->buffer[0] == 0x90)
Cheroukee 19:75e600a40741 164 {
Cheroukee 19:75e600a40741 165 // Manage source address
Cheroukee 19:75e600a40741 166 // Detect the source address and list it dynamically
JayMcGee 22:7edae38d0758 167 zigbee_addr_64_t temp_addr_64;
JayMcGee 22:7edae38d0758 168 bool already_exist = false;
JayMcGee 22:7edae38d0758 169 // Read 64 bit address that was in message
JayMcGee 22:7edae38d0758 170 temp_addr_64.addr_0 = frame->buffer[1];
JayMcGee 22:7edae38d0758 171 temp_addr_64.addr_1 = frame->buffer[2];
JayMcGee 22:7edae38d0758 172 temp_addr_64.addr_2 = frame->buffer[3];
JayMcGee 22:7edae38d0758 173 temp_addr_64.addr_3 = frame->buffer[4];
JayMcGee 22:7edae38d0758 174 temp_addr_64.addr_4 = frame->buffer[5];
JayMcGee 22:7edae38d0758 175 temp_addr_64.addr_5 = frame->buffer[6];
JayMcGee 22:7edae38d0758 176 temp_addr_64.addr_6 = frame->buffer[7];
JayMcGee 22:7edae38d0758 177 temp_addr_64.addr_7 = frame->buffer[8];
Cheroukee 19:75e600a40741 178
JayMcGee 22:7edae38d0758 179 // Verify if the received address is new
JayMcGee 22:7edae38d0758 180 for(int j = 0; j < last_addr_64_index; j++)
JayMcGee 22:7edae38d0758 181 {
JayMcGee 22:7edae38d0758 182 if(addr_64_equal(temp_addr_64,addr_64[j]))
JayMcGee 22:7edae38d0758 183 {
JayMcGee 22:7edae38d0758 184 already_exist = true;
JayMcGee 22:7edae38d0758 185 }
JayMcGee 22:7edae38d0758 186 }
JayMcGee 22:7edae38d0758 187
JayMcGee 22:7edae38d0758 188 // If it is New and our array isn't full of devices add it to the array
JayMcGee 22:7edae38d0758 189 if(!already_exist && last_addr_64_index < 255)
JayMcGee 22:7edae38d0758 190 {
JayMcGee 22:7edae38d0758 191 last_addr_64_index++;
JayMcGee 22:7edae38d0758 192 addr_64[last_addr_64_index] = temp_addr_64;
JayMcGee 22:7edae38d0758 193 }
JayMcGee 22:7edae38d0758 194
Cheroukee 26:cbf539141bfe 195 ws_message_t* message = messages_box.alloc();
Cheroukee 26:cbf539141bfe 196
Cheroukee 19:75e600a40741 197 //Data starts at 12
Cheroukee 19:75e600a40741 198 for (int i = 12; i < frame->length; i++)
Cheroukee 19:75e600a40741 199 {
Cheroukee 26:cbf539141bfe 200 message->buffer[i - 12] = frame->buffer[i];
Cheroukee 19:75e600a40741 201 pc.putc(frame->buffer[i]);
Cheroukee 26:cbf539141bfe 202 }
Cheroukee 26:cbf539141bfe 203 message->buffer[frame->length - 12] = '\0';
Cheroukee 26:cbf539141bfe 204 messages_box.put(message);
Cheroukee 26:cbf539141bfe 205 return 1;
Cheroukee 19:75e600a40741 206 }
Cheroukee 19:75e600a40741 207 return 0;
Cheroukee 25:7b808fb9e025 208 }
Cheroukee 25:7b808fb9e025 209
Cheroukee 27:3baf4701a047 210 #if IS_COORDINATOR
Cheroukee 27:3baf4701a047 211 // Fonction du thread d'envoi au web server par websocket
Cheroukee 26:cbf539141bfe 212 void send_to_ws()
Cheroukee 26:cbf539141bfe 213 {
Cheroukee 26:cbf539141bfe 214 coordinator_config_t config = read_coordinator_config();
Cheroukee 26:cbf539141bfe 215
Cheroukee 27:3baf4701a047 216 // Interface Ethernet
Cheroukee 26:cbf539141bfe 217 EthernetInterface eth;
Cheroukee 27:3baf4701a047 218 eth.init(/*"192.168.3.3", "255.255.255.0", "192.168.3.2"*/); //Use DHCP
Cheroukee 26:cbf539141bfe 219 eth.connect();
Cheroukee 26:cbf539141bfe 220
Cheroukee 27:3baf4701a047 221 // Creation du WebSocket
Cheroukee 26:cbf539141bfe 222 Websocket ws(config.server_url);
Cheroukee 26:cbf539141bfe 223 ws.connect();
Cheroukee 26:cbf539141bfe 224 osEvent evt;
Cheroukee 26:cbf539141bfe 225 while(1)
Cheroukee 26:cbf539141bfe 226 {
Cheroukee 26:cbf539141bfe 227 if (!ws.is_connected())
Cheroukee 26:cbf539141bfe 228 {
Cheroukee 26:cbf539141bfe 229 ws.connect();
Cheroukee 26:cbf539141bfe 230 }
Cheroukee 26:cbf539141bfe 231
Cheroukee 26:cbf539141bfe 232 evt = messages_box.get();
Cheroukee 26:cbf539141bfe 233 if (evt.status == osEventMail) {
Cheroukee 26:cbf539141bfe 234 ws_message_t* mail = (ws_message_t*)evt.value.p;
Cheroukee 27:3baf4701a047 235 ws.send(mail->buffer);
Cheroukee 26:cbf539141bfe 236 Thread::wait(500);
Cheroukee 26:cbf539141bfe 237 messages_box.free(mail);
Cheroukee 26:cbf539141bfe 238 }
Cheroukee 26:cbf539141bfe 239 else
Cheroukee 26:cbf539141bfe 240 {
Cheroukee 26:cbf539141bfe 241 Thread::wait(100);
Cheroukee 26:cbf539141bfe 242 }
Cheroukee 26:cbf539141bfe 243 }
Cheroukee 26:cbf539141bfe 244 }
Cheroukee 27:3baf4701a047 245 #endif
Cheroukee 26:cbf539141bfe 246
Cheroukee 27:3baf4701a047 247 // Envoi a tout les noeuds la commande at remote pour changer l'etat de la DEL
Cheroukee 25:7b808fb9e025 248 void send_del_to_all()
Cheroukee 25:7b808fb9e025 249 {
Cheroukee 25:7b808fb9e025 250 loop_led = !loop_led;
Cheroukee 25:7b808fb9e025 251 static bool flip = false;
Cheroukee 25:7b808fb9e025 252 flip = !flip;
Cheroukee 25:7b808fb9e025 253 for (int i = 0; i < last_addr_64_index; i++)
Cheroukee 25:7b808fb9e025 254 {
Cheroukee 25:7b808fb9e025 255 set_remote_xbee_dio4(flip, addr_64[i]);
Cheroukee 25:7b808fb9e025 256 }
Cheroukee 25:7b808fb9e025 257 }
Cheroukee 25:7b808fb9e025 258
Cheroukee 27:3baf4701a047 259 // Envoi la commande remote at pour setter la sortie de DIO4
Cheroukee 25:7b808fb9e025 260 void set_remote_xbee_dio4(bool set, zigbee_addr_64_t addr)
Cheroukee 25:7b808fb9e025 261 {
Cheroukee 25:7b808fb9e025 262 if (set)
Cheroukee 25:7b808fb9e025 263 {
Cheroukee 25:7b808fb9e025 264 remote_at_command_set(AT_COMMAND_DIO4_MSB, AT_COMMAND_DIO4_LSB,
Cheroukee 25:7b808fb9e025 265 AT_COMMAND_DIO_OUT_LOW, 0x02, addr);
Cheroukee 25:7b808fb9e025 266 }
Cheroukee 25:7b808fb9e025 267 else
Cheroukee 25:7b808fb9e025 268 {
Cheroukee 25:7b808fb9e025 269 remote_at_command_set(AT_COMMAND_DIO4_MSB, AT_COMMAND_DIO4_LSB,
Cheroukee 25:7b808fb9e025 270 AT_COMMAND_DIO_OUT_HIGH, 0x02, addr);
Cheroukee 25:7b808fb9e025 271 }
Cheroukee 25:7b808fb9e025 272 }
Cheroukee 25:7b808fb9e025 273
Cheroukee 27:3baf4701a047 274 #if !IS_COORDINATOR
Cheroukee 27:3baf4701a047 275 // Effecture une mesure sur tout les capteurs connus dans le tableau de fct puis
Cheroukee 27:3baf4701a047 276 // envoi les resultats au coordinateur
Cheroukee 25:7b808fb9e025 277 void get_all_sensors()
Cheroukee 25:7b808fb9e025 278 {
Cheroukee 25:7b808fb9e025 279 loop_led = !loop_led;
Cheroukee 25:7b808fb9e025 280 char sensor_buffer[64] = {};
Cheroukee 25:7b808fb9e025 281 DECLARE_ADDR64_COORD
Cheroukee 25:7b808fb9e025 282 DECLARE_ADDR16_UNKNOWN_OR_BCAST
Cheroukee 25:7b808fb9e025 283 for (int i = 0; i < 2; i++)
Cheroukee 25:7b808fb9e025 284 {
Cheroukee 25:7b808fb9e025 285 sensor_t sensor = (*p[i])();
Cheroukee 25:7b808fb9e025 286
Cheroukee 25:7b808fb9e025 287 if (sensor.sensor_type == 1)
Cheroukee 25:7b808fb9e025 288 {
Cheroukee 25:7b808fb9e025 289 sprintf(sensor_buffer, "button::%u\n\r", sensor.sensor_result.Bouton.etat != 0 ? 1 : 0);
Cheroukee 25:7b808fb9e025 290 transmit_request(sensor_buffer, 8 + 1 + 2, 0, USE_ADDR64_COORD, USE_ADDR16_UNKNOWN_OR_BCAST);
Cheroukee 25:7b808fb9e025 291 }
Cheroukee 25:7b808fb9e025 292 else if (sensor.sensor_type == 2)
Cheroukee 25:7b808fb9e025 293 {
Cheroukee 25:7b808fb9e025 294 sprintf(sensor_buffer, "accel::%3.2f%3.2f%3.2f\n\r", sensor.sensor_result.Accelerometre.x,
Cheroukee 25:7b808fb9e025 295 sensor.sensor_result.Accelerometre.y, sensor.sensor_result.Accelerometre.z);
Cheroukee 25:7b808fb9e025 296 transmit_request(sensor_buffer, 7 + 15 + 2, 0, USE_ADDR64_COORD, USE_ADDR16_UNKNOWN_OR_BCAST);
Cheroukee 25:7b808fb9e025 297 }
Cheroukee 25:7b808fb9e025 298 }
Cheroukee 25:7b808fb9e025 299 }
Cheroukee 27:3baf4701a047 300 #endif
Cheroukee 25:7b808fb9e025 301
Cheroukee 27:3baf4701a047 302 // Ferme la DEL d'erreur et detach le ticker
Cheroukee 27:3baf4701a047 303 void error_display()
Cheroukee 25:7b808fb9e025 304 {
Cheroukee 25:7b808fb9e025 305 error_led = 0;
Cheroukee 25:7b808fb9e025 306 error_ticker.detach();
Cheroukee 25:7b808fb9e025 307 }