desloges-libioulle / Mbed 2 deprecated app3_coordinator

Dependencies:   mbed-rtos mbed EthernetInterface

Files at this revision

API Documentation at this revision

Comitter:
libv2001
Date:
Mon Feb 13 02:17:10 2017 +0000
Parent:
2:ff0b74e5e62c
Commit message:
Ethernet connection added

Changed in this revision

EthernetInterface.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetInterface.lib	Mon Feb 13 02:17:10 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/EthernetInterface/#183490eb1b4a
--- a/main.cpp	Sun Feb 12 17:11:58 2017 +0000
+++ b/main.cpp	Mon Feb 13 02:17:10 2017 +0000
@@ -1,6 +1,7 @@
 #include "mbed.h"
 #include "rtos.h"
 #include "xbee.h"
+#include "EthernetInterface.h"
 
 #define nullptr 0
 
@@ -19,6 +20,7 @@
 Thread * XBeeConsumer;
 Thread * XBeeProducer;
 Thread * EventConsumer;
+Thread * EthernetConsumer;
 Ticker timer;
 
 int responseStatus;
@@ -41,11 +43,25 @@
 Queue<void, 64> event;
 
 struct Rooter{
-    long long int addr64;
-    short addr16;
+    char addr64[8];
+    char addr16[2];
     
     bool operator==(const Rooter & rhs){
-        return addr64 == rhs.addr64 && addr16 == rhs.addr16;
+        bool same = true;
+        
+        for (int i = 0; i < 8; ++i){
+            if (addr64[i] != rhs.addr64[i]){
+                return false;
+            }
+        }
+        
+        for (int i = 0; i < 2; ++i){
+            if (addr16[i] != rhs.addr16[i]){
+                return false;
+            }
+        }
+        
+        return same;
     }
 };
 
@@ -54,6 +70,9 @@
 int rooterCount = 0;
 
 Mutex rooterMutex;
+
+TCPSocketConnection socket;
+
 /*******************************************************/
 /**********************UTILITIES************************/
 /*******************************************************/
@@ -108,8 +127,7 @@
     memset(server, 0x00, 16);
     FILE * f = fopen("/local/coord.cfg", "r");
     fscanf(f,"%s %x", key, &panID);
-    pc.printf("Config started\r\n");
-    pc.printf("Lecture de la config %s : %04x\r\n", key, panID);
+   pc.printf("Lecture de la config %s : %04x\r\n", key, panID);
     fscanf(f,"%s %d %d %d", key, &xbeeTxPin, &xbeeRxPin, &xbeeRstPin);
     pc.printf("Lecture de la config %s : %d %d %d\r\n", key, xbeeTxPin, xbeeRxPin, xbeeRstPin);
     fscanf(f,"%s %s", key, server);
@@ -148,6 +166,7 @@
 void XBeeSend(char * buffer, int count){
     for ( int i = 0; i < count; ++i ){
         xbee->putc(buffer[i]);
+        wait_us(25);
     }
 }
 
@@ -198,15 +217,15 @@
     XBeeSendATCommand(true, "AC", nullptr, 0);
 }
 
-void XbeeSendRemoteAtCommand(long long int addr64, short addr16, char opt, char * type, char * data, int dataLength){
+void XbeeSendRemoteAtCommand(char * addr64, char * addr16, char opt, char * type, char * data, int dataLength){
     char buffer[128];
     buffer[START_IDX] = START;
     buffer[LENGTH_MSB_IDX] = (dataLength + REMOTE_AT_RQST_MIN_SIZE) >> 8;
     buffer[LENGTH_LSB_IDX] = (dataLength + REMOTE_AT_RQST_MIN_SIZE) & 0xff;
     buffer[API_ID_IDX] = API_ID_REMOTE_AT_RQST;
     buffer[FRAME_ID_IDX] = GetFrameID();
-    memcpy(&buffer[REMOTE_AT_RQST_64BIT_MSB_IDX], &addr64, ADDR_64BIT_SIZE);
-    memcpy(&buffer[REMOTE_AT_RQST_16BIT_MSB_IDX], &addr16, ADDR_16BIT_SIZE);
+    memcpy(&buffer[REMOTE_AT_RQST_64BIT_MSB_IDX], addr64, ADDR_64BIT_SIZE);
+    memcpy(&buffer[REMOTE_AT_RQST_16BIT_MSB_IDX], addr16, ADDR_16BIT_SIZE);
     buffer[REMOTE_AT_RQST_OPT_IDX] = opt;
     memcpy(&buffer[REMOTE_AT_RQST_AT_CMD1_IDX], type, AT_CMD_ID_SIZE);
     memcpy(&buffer[REMOTE_AT_RQST_AT_PARAM_IDX], data, dataLength);
@@ -215,9 +234,7 @@
     
     while(true){
         XBeeSend(buffer, dataLength + REMOTE_AT_RQST_MIN_SIZE + FRAME_MIN_SIZE);
-    
         Thread::signal_wait(RESPONSE_SIGNAL);
-        
         switch (responseStatus){
         case REMOTE_AT_CMD_RSP_STATUS_OK:
             return;
@@ -228,6 +245,11 @@
     }
 }
 
+inline void SendRemoteD0Command(char* addr64, char* addr16, bool on){
+    char data[1] = {on ? 0x05 : 0x04};
+    XbeeSendRemoteAtCommand(addr64, addr16, 0x02, "D0", data, 1);
+}
+
 /*******************************************************/
 /**********************XBEE READ************************/
 /*******************************************************/
@@ -256,8 +278,8 @@
 void HandleXbeeReceivedPacket(char * cmd){
     if (rooterCount < ROOTER_MAX){
         Rooter r;
-        r.addr64 = Get64Addr(cmd, RECEIVED_PACKET_64BIT_MSB_IDX);
-        r.addr16 = Get16Addr(cmd, RECEIVED_PACKET_16BIT_MSB_IDX);
+        memcpy(r.addr64, &cmd[RECEIVED_PACKET_64BIT_MSB_IDX], 8);
+        memcpy(r.addr16, &cmd[RECEIVED_PACKET_16BIT_MSB_IDX], 2);
         
         bool found = false;
         for (int i = 0; i < rooterCount; ++i){
@@ -322,10 +344,51 @@
         break;
     default:
         pc.printf("Unhandle XBee Command received : %02x\r\n", cmd[API_ID_IDX]);
+        break;
     }
 }
 
 /*******************************************************/
+/************************EVENT**************************/
+/*******************************************************/
+
+void HandleBtnEvent(ButtonEvent* data){
+     char out[24];
+     out[23] = 0x00;
+     sprintf(out, "Event BTN: %s", data->state ? "Pressed" : "Released");
+     
+     pc.printf("Sending to Server : %s\r\n", out);
+     socket.send_all(out, data->state ? 20 : 21);
+}
+
+#define NEGATIVE_PADDING 0xfffff000;
+int AccDataToInt(char* data)
+{
+    int x = ((int)data[0])<<4;
+    x |= data[1]>>4;
+    if ((data[0] & 0x80) != 0) {
+        x |= NEGATIVE_PADDING;
+    }
+    return x;
+}
+
+void HandleAccEvent(AccelerometerEvent* data){
+    char out[40];
+    out[39] = 0;
+    int x = AccDataToInt(data->x);
+    int y = AccDataToInt(data->y);
+    int z = AccDataToInt(data->z);
+    
+    float x_g = (float)x/1024.0f;
+    float y_g = (float)y/1024.0f;
+    float z_g = (float)z/1024.0f;
+    sprintf(out, "Event ACC: x=%01.02fg, y=%01.02fg, z=%01.02fg", x_g, y_g, z_g);  
+    
+    pc.printf("Sending to Server : %s\r\n", out);
+    socket.send_all(out, 40);
+}
+
+/*******************************************************/
 /************************INIT***************************/
 /*******************************************************/
 
@@ -347,26 +410,59 @@
     return true;
 }
 
+bool InitEthernet(){
+    EthernetInterface eth;
+    // No DHCP
+    eth.init("192.168.2.3", "255.255.255.0", server); 
+    // DHCP
+    //eth.init();
+    eth.connect();
+    printf("\nClient IP Address is %s\r\n", eth.getIPAddress());
+    
+    // Connect to Server
+    while (socket.connect(server, 7) < 0) {
+        printf("Unable to connect to (%s) on port (%d)\r\n", server, 7);
+        wait(1);
+    }
+    
+    printf("Connected to Server at %s\r\n", server);
+    
+    return true;
+}
+
+
+/*******************************************************/
+/************************MAIN***************************/
+/*******************************************************/
+
+inline char XbeeReadChar(){
+    while(!xbee->readable()){
+    }
+    return xbee->getc();
+}
+
 void ConsumerMain(){
     char buffer[128];
     while(true){
-        while(!xbee->readable()){
-            continue;
-        }
-        buffer[START_IDX] = xbee->getc();
+        buffer[START_IDX] = XbeeReadChar();
         if (buffer[START_IDX] != START){
             pc.printf("Wrong start byte received : %02x\r\n", buffer[START_IDX]);
             continue;
         }
-        buffer[LENGTH_MSB_IDX] = xbee->getc();
-        buffer[LENGTH_LSB_IDX] = xbee->getc();
+        buffer[LENGTH_MSB_IDX] = XbeeReadChar();
+        buffer[LENGTH_LSB_IDX] = XbeeReadChar();
         int length = GetFrameLength(buffer);
         
         for (int i = 0; i <= length; ++i){
-            buffer[i + API_ID_IDX] = xbee->getc();
+            buffer[i + API_ID_IDX] = XbeeReadChar();
         }
         if (!ValidateCheckSum(buffer)){
-            pc.printf("Bad CheckSum : %02x\r\n", buffer[length + FRAME_MIN_SIZE - 1]);
+            pc.printf("Bad CheckSum\r\n");
+            
+            for (int i = 0; i < length + FRAME_MIN_SIZE; ++i){
+                pc.printf("%02x ", buffer[i]);
+            }
+            pc.printf("\r\n");
             continue;
         }
         
@@ -374,15 +470,20 @@
     }
 }
 
-void ToggleRemoteRooters(){
+void ToggleRemoteRooters(bool on){
     rooterMutex.lock();
     for(int i = 0; i < rooterCount; ++i){
-        
+        SendRemoteD0Command(rooters[i].addr64, rooters[i].addr16, on);
     }
     rooterMutex.unlock();
 }
 
 bool ProducerInit(){
+    if (!InitEthernet()){
+        pc.printf("Connection problem with the Ethernet\r\n");
+        return false;
+    }
+    
     if (!InitXBee()){
         pc.printf("Connection problem with the XBee\r\n");
         return false;
@@ -395,17 +496,56 @@
     XBeeProducer->signal_set(TICKER_SIGNAL);
 }
 
+bool initDone = false;
+
 void ProducerMain(const void*){
     if (!ProducerInit()){
         pc.printf("Initialization problem\r\n");
         return;
+    } else {
+        initDone = true;
     }
     
     timer.attach(&Tick, 1);
-    
+    bool on = true;
     while(true){
         Thread::signal_wait(TICKER_SIGNAL);
-        ToggleRemoteRooters();
+        ToggleRemoteRooters(on);
+        on = !on;
+    }
+}
+
+void EventConsumerMain(const void*){
+    while(true){
+        void* ptr = event.get().value.p;
+        
+        char * id = (char*) ptr;
+        // Compare l'ID pour trouver le type d'évènement
+        if (id[0] == BTN_ID[0] && id[1] == BTN_ID[1] && id[2] == BTN_ID[2]){
+            ButtonEvent* BtnEvt = (ButtonEvent*)ptr;
+            HandleBtnEvent(BtnEvt);
+            btnPool.free(BtnEvt);
+        } else if (id[0] == ACC_ID[0] && id[1] == ACC_ID[1] && id[2] == ACC_ID[2]){
+            AccelerometerEvent* AccEvt = (AccelerometerEvent*)ptr;
+            HandleAccEvent(AccEvt);
+            accPool.free(AccEvt);
+        } else {
+            pc.printf("Unknown event : %c%c%c\r\n", id[0], id[1], id[2]);
+        }
+    }
+}
+
+void EthernetConsumerMain(const void *){
+    // Attend que l'initialisation soit terminée avant de commencer
+    while (!initDone){
+        Thread::yield();
+    }
+    // Receive message from server
+    char buf[256];
+    while(true){
+        int n = socket.receive(buf, 256);
+        buf[n] = 0x00;
+        printf("Received from Server : %s\r\n", buf);
     }
 }
 
@@ -421,6 +561,12 @@
     xbee = &mainXbee;
     xbeeRst = &mainXbeeRst;
     
+    Thread ethernet(EthernetConsumerMain);
+    EthernetConsumer = &ethernet;
+    
+    Thread event(EventConsumerMain);
+    EventConsumer = &event;
+    
     Thread consumer(ConsumerMain);
     XBeeConsumer = &consumer;