Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: ConfigFile EthernetInterface mbed-rtos mbed
Fork of S05APP3 by
Diff: main.cpp
- Revision:
- 16:cede55e5b075
- Parent:
- 15:4c748df01e5b
- Child:
- 17:7ae8f91f46a2
--- a/main.cpp Mon Feb 13 20:14:12 2017 +0000 +++ b/main.cpp Tue Feb 14 02:35:07 2017 +0000 @@ -1,3 +1,7 @@ +// Titre: S05APP3 +// Auteurs: Benjamin Roy et Marc-Antoine Beaudoin +// Date: 14 février 2017 +// ======================================================= // ===================== COORDINATOR ===================== // ======================================================= #include "EthernetInterface.h" @@ -15,7 +19,7 @@ Ticker ticker1; Thread *t1; -/* Mail */ +/* Boîte aux lettres */ typedef struct { uint8_t type; char strAccelerationX[15]; @@ -32,8 +36,10 @@ char serverAddress[32]; char panIdChar[5]; char portNbr[5]; -bool led = false; +/* +* Imprime le buffer à l'écran pour des fins de déboguage: +*/ void printBuffer(uint8_t bufferSize, uint8_t* buffer) { for(uint8_t k = 0; k <= bufferSize; k++) { pc.printf("%X-", buffer[k]); @@ -41,12 +47,22 @@ printf("\n"); } -void toggleErrorLed() { - errorLed.write(3.3); - wait(1); - errorLed.write(0); +/* +* Envoyer et recevoir des données via le protocole Xbee: +*/ +void readDataFromXbee(uint8_t bufferSize) {} +void sendDataToXbee(uint8_t bufferSize, uint8_t* buffer) { + for (uint8_t i = 0; i < bufferSize;) { + if (xbee.writeable()) { + xbee.putc(buffer[i]); + i++; + } + } } +/* +* Lecture du fichier de configuration: +*/ void readConfigFile() { LocalFileSystem local("local"); ConfigFile cfg; @@ -55,7 +71,7 @@ char *panIdStr = "panID"; if (!cfg.read("/local/input.cfg")) { - error("Erreur dans la lecture du fichier de configuration.\n"); + error("Erreur dans la lecture du fichier de configuration...\n"); } else { cfg.getValue(panIdStr, &panIdChar[0], sizeof(panIdChar)); cfg.getValue(serverAddressStr, &serverAddress[0], sizeof(serverAddress)); @@ -63,122 +79,37 @@ portNumber = (uint16_t)strtol(portNbr, NULL, 10); panId = (uint16_t)strtol(panIdChar, NULL, 10); - // printf("The server address is %s\n", serverAddress); // printf("The port number is %i\n", portNumber); // printf("The PAN ID is %i\n", panId); } } -uint8_t calculateChecksum(uint8_t frameTypeIndex, uint8_t frameSize, uint8_t* buffer) { - char checksum = 0; - - for (int i = frameTypeIndex; i < frameSize - 1; i++) { - checksum += buffer[i]; - } - - return (0xFF - checksum); +/* +* Détection et gestion des erreurs (allumer une LED pendant 1 seconde lorsqu'une erreur est détectée): +*/ +void toggleErrorLed() { + errorLed.write(3.3); + wait(1); + errorLed.write(0); } - -void toggleLed() { - // uint8_t high[20] = {0x7E, 0x00, 0x10, 0x17, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x8B, 0x41, 0x6E, 0xFF, 0xFE, 0x02, 0x44, 0x34, 0x05, 0x3C}; - // uint8_t low[20] = {0x7E, 0x00, 0x10, 0x17, 0x02, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x8B, 0x41, 0x6E, 0xFF, 0xFE, 0x02, 0x44, 0x34, 0x04, 0x3C}; - Thread::signal_wait(0x2); - - while(1) { - Thread::signal_wait(0x1); - - uint8_t command[20] = {0}; - - command[0] = 0x7E; - command[1] = 0x00; - command[2] = 0x10; - command[3] = 0x17; - if (led) { - command[4] = 0x01; - } - else { - command[4] = 0x02; - } - command[5] = routerAddress[0]; - command[6] = routerAddress[1]; - command[7] = routerAddress[2]; - command[8] = routerAddress[3]; - command[9] = routerAddress[4]; - command[10] = routerAddress[5]; - command[11] = routerAddress[6]; - command[12] = routerAddress[7]; - command[13] = 0xFF; - command[14] = 0xFE; - command[15] = 0x02; - command[16] = 0x44; - command[17] = 0x34; - if (led) { - command[18] = 0x05; - } - else { - command[18] = 0x04; - } - command[19] = calculateChecksum(3, 20, command); - - for (uint8_t i = 0; i < 20;) { - if (xbee.writeable()) { - xbee.putc(command[i]); - i++; - } - } - led = !led; - led1 = !led1; - } -} - -void sendDataToServer() { - while(1) { - osEvent evt = mail_box.get(); - - if (evt.status == osEventMail) { - mail_t *mail = (mail_t*)evt.value.p; - - int responseSize = 0; - char buffer[50] = { 0 }; - - if (mail->type == 0) { - sprintf(buffer, "%s, %s, %s\0", mail->strAccelerationX, mail->strAccelerationY, mail->strAccelerationZ); - } else { - sprintf(buffer, "%s\0", mail->strDryContact); - } - - sock.send_all(buffer, sizeof(buffer)-1); - responseSize = sock.receive(buffer, sizeof(buffer)-1); - - if (responseSize <= 0) { - pc.printf("Error"); - } - - buffer[responseSize] = '\0'; - pc.printf("Received %d chars from server: %s\n", responseSize, buffer); - - mail_box.free(mail); - } - } +void printError(char* buffer) { + pc.printf(buffer); + toggleErrorLed(); } void readATCommandResponse(uint8_t* buffer) { - if (!buffer[4] == 0x00) toggleErrorLed(); - - if (buffer[4] == 0x01) pc.printf("AT Command Response: Error.\n"); - else if (buffer[4] == 0x02) pc.printf("AT Command Response: Invalid Command.\n"); - else if (buffer[4] == 0x03) pc.printf("AT Command Response: Invalid Parameter.\n"); - else if (buffer[4] == 0x04) pc.printf("AT Command Response: Tx Failure.\n"); + if (buffer[4] == 0x01) printError("AT Command Response: Error.\n"); + else if (buffer[4] == 0x02) printError("AT Command Response: Invalid Command.\n"); + else if (buffer[4] == 0x03) printError("AT Command Response: Invalid Parameter.\n"); + else if (buffer[4] == 0x04) printError("AT Command Response: Tx Failure.\n"); } void readRemoteATCommandResponse(uint8_t* buffer) { - if (!buffer[14] == 0x00) toggleErrorLed(); - - if (buffer[14] == 0x01) pc.printf("Remote AT Command Response: Error.\n"); - else if (buffer[14] == 0x02) pc.printf("Remote AT Command Response: Invalid Command.\n"); - else if (buffer[14] == 0x03) pc.printf("Remote AT Command Response: Invalid Parameter.\n"); - else if (buffer[14] == 0x04) pc.printf("Remote AT Command Response: Tx Failure.\n"); + if (buffer[14] == 0x01) printError("Remote AT Command Response: Error.\n"); + else if (buffer[14] == 0x02) printError("Remote AT Command Response: Invalid Command.\n"); + else if (buffer[14] == 0x03) printError("Remote AT Command Response: Invalid Parameter.\n"); + else if (buffer[14] == 0x04) printError("Remote AT Command Response: Tx Failure.\n"); } void readTransmitStatus(uint8_t* buffer) { @@ -202,72 +133,35 @@ } void readModemStatus(uint8_t* buffer) { - if (buffer[1] == 0x00) { - pc.printf("Modem status: Hardware reset.\n"); - } - else if (buffer[1] == 0x01) { - pc.printf("Modem status: Watchdog timer reset.\n"); - toggleErrorLed(); - } - else if (buffer[1] == 0x02) { - pc.printf("Modem status: Joined network.\n"); - toggleErrorLed(); - } - else if (buffer[1] == 0x03) { - pc.printf("Modem status: Disassociated.\n"); - toggleErrorLed(); - } - else if (buffer[1] == 0x04) { - pc.printf("Modem status: Configuration error/synchronization.\n"); - toggleErrorLed(); - } - else if (buffer[1] == 0x05) { - pc.printf("Modem status: Coordinator realignment.\n"); - toggleErrorLed(); - } - else if (buffer[1] == 0x06) { - pc.printf("Modem status: Coordinator started.\n"); - } - else if (buffer[1] == 0x07) { - pc.printf("Modem status: Network security key updated.\n"); - toggleErrorLed(); + if (buffer[1] == 0x00) pc.printf("Modem status: Hardware reset.\n"); + else if (buffer[1] == 0x01) printError("Modem status: Watchdog timer reset.\n"); + else if (buffer[1] == 0x02) printError("Modem status: Joined network.\n"); + else if (buffer[1] == 0x03) printError("Modem status: Disassociated.\n"); + else if (buffer[1] == 0x04) printError("Modem status: Configuration error/synchronization.\n"); + else if (buffer[1] == 0x05) printError("Modem status: Coordinator realignment.\n"); + else if (buffer[1] == 0x06) pc.printf("Modem status: Coordinator started.\n"); + else if (buffer[1] == 0x07) printError("Modem status: Network security key updated.\n"); + else if (buffer[1] == 0x08) printError("Modem status: Network woke up.\n"); + else if (buffer[1] == 0x0C) printError("Modem status: Network went to sleep.\n"); + else if (buffer[1] == 0x0E) printError("Modem status: Device cloud connected.\n"); + else if (buffer[1] == 0x0F) printError("Modem status: Device cloud disconnected.\n"); + else if (buffer[1] == 0x11) printError("Modem status: Modem configurationchanged while join in progress.\n"); + else if (buffer[1] == 0x80) printError("Modem status: Stack error (80+).\n"); + else if (buffer[1] == 0x82) printError("Modem status: Send/join command issuedwithout connecting from AP.\n"); + else if (buffer[1] == 0x83) printError("Modem status: Access point not found.\n"); + else if (buffer[1] == 0x84) printError("Modem status: PSK not configured.\n"); +} + +/* +* Calculer et vérifier le checksum des trames reçues: +*/ +uint8_t calculateChecksum(uint8_t frameTypeIndex, uint8_t frameSize, uint8_t* buffer) { + char checksum = 0; + + for (int i = frameTypeIndex; i < frameSize - 1; i++) { + checksum += buffer[i]; } - else if (buffer[1] == 0x08) { - pc.printf("Modem status: Network woke up.\n"); - toggleErrorLed(); - } - else if (buffer[1] == 0x0C) { - pc.printf("Modem status: Network went to sleep.\n"); - toggleErrorLed(); - } - else if (buffer[1] == 0x0E) { - pc.printf("Modem status: Device cloud connected.\n"); - toggleErrorLed(); - } - else if (buffer[1] == 0x0F) { - pc.printf("Modem status: Device cloud disconnected.\n"); - toggleErrorLed(); - } - else if (buffer[1] == 0x11) { - pc.printf("Modem status: Modem configurationchanged while join in progress.\n"); - toggleErrorLed(); - } - else if (buffer[1] == 0x80) { - pc.printf("Modem status: Stack error (80+).\n"); - toggleErrorLed(); - } - else if (buffer[1] == 0x82) { - pc.printf("Modem status: Send/join command issuedwithout connecting from AP.\n"); - toggleErrorLed(); - } - else if (buffer[1] == 0x83) { - pc.printf("Modem status: Access point not found.\n"); - toggleErrorLed(); - } - else if (buffer[1] == 0x84) { - pc.printf("Modem status: PSK not configured.\n"); - toggleErrorLed(); - } + return (0xFF - checksum); } bool checksumIsValid(uint8_t bufferSize, uint8_t* buffer) { @@ -277,12 +171,87 @@ checkSum += buffer[i]; } if ((0xFF - (checkSum & 0xFF)) != buffer[bufferSize]) { - pc.printf("Erreur dans la transmission de la trame. \n"); + pc.printf("Erreur dans la transmission de la trame... \n"); return false; } return true; } +/* +* Faire allumer une DEL, reliée à un des ports du XBEE (DIO) du Routeur, en utilisant une commande de configuration à distance provenant du Coordinateur +*/ +void toggleRouterLed() { + // HIGH: {0x7E, 0x00, 0x10, 0x17, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x8B, 0x41, 0x6E, 0xFF, 0xFE, 0x02, 0x44, 0x34, 0x05, 0x3C}; + // LOW: {0x7E, 0x00, 0x10, 0x17, 0x02, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x8B, 0x41, 0x6E, 0xFF, 0xFE, 0x02, 0x44, 0x34, 0x04, 0x3C}; + bool led = false; + uint8_t command[20] = {0}; + + Thread::signal_wait(0x2); // Attendre que l'adresse du noeud rooter soit connue + command[0] = 0x7E; + command[1] = 0x00; + command[2] = 0x10; + command[3] = 0x17; + command[5] = routerAddress[0]; + command[6] = routerAddress[1]; + command[7] = routerAddress[2]; + command[8] = routerAddress[3]; + command[9] = routerAddress[4]; + command[10] = routerAddress[5]; + command[11] = routerAddress[6]; + command[12] = routerAddress[7]; + command[13] = 0xFF; + command[14] = 0xFE; + command[15] = 0x02; + command[16] = 0x44; + command[17] = 0x34; + + while(1) { + Thread::signal_wait(0x1); // Période: 1 Hz + + if (led) { + command[4] = 0x01; + command[18] = 0x05; + } else { + command[4] = 0x02; + command[18] = 0x04; + } + command[19] = calculateChecksum(3, 20, command); + + sendDataToXbee(20, command); + led = !led; + led1 = !led1; + } +} + +void sendDataToServer() { + while(1) { + osEvent evt = mail_box.get(); + + if (evt.status == osEventMail) { + mail_t *mail = (mail_t*)evt.value.p; + + int responseSize = 0; + char buffer[50] = { 0 }; + + if (mail->type == 0) { + sprintf(buffer, "%s, %s, %s\0", mail->strAccelerationX, mail->strAccelerationY, mail->strAccelerationZ); + } else { + sprintf(buffer, "%s\0", mail->strDryContact); + } + + sock.send_all(buffer, sizeof(buffer)-1); + responseSize = sock.receive(buffer, sizeof(buffer)-1); + buffer[responseSize] = '\0'; + pc.printf("Received %d chars from server: %s\n", responseSize, buffer); + + mail_box.free(mail); + } + } +} + +/* +* Lire et décomposer les trames reçues: +*/ void readRouterAddress(uint8_t* buffer) { routerAddress[0] = buffer[1]; routerAddress[1] = buffer[2]; @@ -298,22 +267,19 @@ void readRouterData(uint8_t bufferSize, uint8_t* buffer) { uint16_t acc[3] = {0}; - if (buffer[0] == 0x90 && bufferSize == 18) { // Accelerations (X,Y,Z) + if (buffer[0] == 0x90 && bufferSize == 18) { // Ajouter les données reçues par l'accéléromètre à la boîte aux lettres: for (uint8_t i = 12; i < bufferSize; i += 2) { acc[(i/2)-6] = (buffer[i+1] << 8 ) | (buffer[i] & 0xff); } - // pc.printf("Acceleration X: %d\n", acc[0]); - // pc.printf("Acceleration Y: %d\n", acc[1]); - // pc.printf("Acceleration Z: %d\n", acc[2]); - + mail_t *mail = mail_box.alloc(); mail->type = 0; - sprintf(mail->strAccelerationX, "Acc. X: %i\0", acc[0]); - sprintf(mail->strAccelerationY, "Acc. Y: %i\0", acc[1]); - sprintf(mail->strAccelerationZ, "Acc. Z: %i\0", acc[2]); + sprintf(mail->strAccelerationX, "Acc.: X: %i\0", acc[0]); + sprintf(mail->strAccelerationY, "Acc.: Y: %i\0", acc[1]); + sprintf(mail->strAccelerationZ, "Acc.: Z: %i\0", acc[2]); mail_box.put(mail); - } else if (buffer[0] == 0x90 && bufferSize == 13) { // Dry contact + } else if (buffer[0] == 0x90 && bufferSize == 13) { // Ajouter les données reçues par le contact sec à la boîte aux lettres: mail_t *mail = mail_box.alloc(); mail->type = 1; sprintf(mail->strDryContact, "Dry Contact: %i\0", buffer[12]); @@ -323,11 +289,10 @@ void readDataFromRouter(){ while(1) { - uint8_t bufferSize = 0; uint8_t buffer[104] = { 0 }; if (xbee.readable() && xbee.getc() == 0x7E) { - bufferSize = (xbee.getc() << 8 ) | (xbee.getc() & 0xff); + uint8_t bufferSize = (xbee.getc() << 8 ) | (xbee.getc() & 0xff); for (uint8_t i = 0; i <= bufferSize;) { if (xbee.readable()) { @@ -336,68 +301,56 @@ } } - printBuffer(bufferSize, buffer); if (checksumIsValid(bufferSize, buffer)) { - if (buffer[0] == 0x90) { + if (buffer[0] == 0x90) { // Frame Type: + printBuffer(bufferSize, buffer); readRouterAddress(buffer); readRouterData(bufferSize, buffer); - - } else if (buffer[0] == 0x8A) { // Modem Status + } else if (buffer[0] == 0x8A) { // Frame Type: Modem Status readModemStatus(buffer); - } else if (buffer[0] == 0x8B) { // Transmit Status - // Should never occur... - } else if (buffer[0] == 0x97) { // Remote AT Command Response + } else if (buffer[0] == 0x8B) { // Frame Type: Transmit Status + + } else if (buffer[0] == 0x97) { // Frame Type: Remote AT Command Response readRemoteATCommandResponse(buffer); - } else if (buffer[0] == 0x09) { // AT Command Response - printf("AT COMMAND RESPONSE"); + } else if (buffer[0] == 0x09) { // Frame Type: AT Command Response } } else { - - // HERE: Try to resend the frame... + printf("Erreur dans la tranmission de la trame...\n"); } } } } +/* +* Poser le ID du réseau PAN à rejoindre: +*/ void setCoordinatorPanId(uint16_t panId) { char _8bitsPanId[2]; _8bitsPanId[0] = (panId >> 8) & 0xFF; _8bitsPanId[1] = panId & 0xFF; + uint8_t setPanIdBuffer[10] = {0x07, 0x00, 0x06, 0x09, 0x01, 0x49, 0x44, _8bitsPanId[0], _8bitsPanId[1], 0x00}; - setPanIdBuffer[10] = calculateChecksum(0, 10, setPanIdBuffer); - - for (uint8_t i = 0; i < 10;) { - if (xbee.writeable()) { - xbee.putc(setPanIdBuffer[i]); - i++; - } - } - uint8_t saveChangesBuffer[8] = {0x7E, 0x00, 0x04, 0x09, 0x02, 0x57, 0x52, 0x4B}; + uint8_t applyChangesBuffer[8] = {0x7E, 0x00, 0x04, 0x09, 0x03, 0x41, 0x43, 0x6F}; + setPanIdBuffer[9] = calculateChecksum(0, 10, setPanIdBuffer); // Calculate the checksum - for (uint8_t i = 0; i < 8;) { - if (xbee.writeable()) { - xbee.putc(saveChangesBuffer[i]); - i++; - } - } - - - uint8_t applyChangesBuffer[8] = {0x7E, 0x00, 0x04, 0x09, 0x03, 0x41, 0x43, 0x6F}; - - for (uint8_t i = 0; i < 8;) { - if (xbee.writeable()) { - xbee.putc(saveChangesBuffer[i]); - i++; - } - } + sendDataToXbee(10, setPanIdBuffer); // Set the 64-bit PAN ID + sendDataToXbee(8, saveChangesBuffer); // Save the changes + sendDataToXbee(8, applyChangesBuffer); // Apply changes by sending the CN command } +/* +* Envoyer un signal au thread qui fait clignoter la DEL du noeud routeur: +*/ void isr() { t1->signal_set(0x1); } +// -------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------- int main() { pc.printf("Starting a coordinator... \n"); @@ -406,12 +359,7 @@ reset = 1; wait_ms(1); - readConfigFile(); - - xbee.baud(9600); // Set baud rate - //xbee.printf("ATID %i\r",panId); // Set the 64-bit PAN ID - //xbee.printf("ATWR \r"); // Save the changes - //xbee.printf("ATCN \r"); // Apply changes by sending the CN command + readConfigFile(); setCoordinatorPanId(panId); if (eth.init() != 0) { // Use DHCP @@ -433,7 +381,7 @@ // Démarrage des tâches: Thread _readDataFromRouter(readDataFromRouter); //Thread _sendDataToServer(sendDataToServer); - Thread _toggleRouterLed(toggleLed); + Thread _toggleRouterLed(toggleRouterLed); t1 = &_toggleRouterLed; ticker1.attach(&isr, 1);