Takes in sensor readings from NRF24 connected nodes and publises the data over MQTT

Dependencies:   EthernetInterface MQTT mbed-rtos mbed nRF24L01P

Files at this revision

API Documentation at this revision

Comitter:
Mephi
Date:
Wed Jun 03 18:46:47 2015 +0000
Commit message:
v0.1 Initial Commit. Works fine for a little while...

Changed in this revision

EthernetInterface.lib Show annotated file Show diff for this revision Revisions of this file
MQTT.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
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
nRF24L01P.lib 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	Wed Jun 03 18:46:47 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/mbed_official/code/EthernetInterface/#2fc406e2553f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MQTT.lib	Wed Jun 03 18:46:47 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/mqtt/code/MQTT/#c299463ae853
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Jun 03 18:46:47 2015 +0000
@@ -0,0 +1,285 @@
+#include "mbed.h"
+#include "MQTTEthernet.h"
+#include "MQTTClient.h"
+#include "nRF24L01P.h"
+
+#define TRANSFER_SIZE 8 
+const uint8_t NodeID = 1;
+const uint8_t Nodes = 19;
+
+Serial pc(USBTX, USBRX); // tx, rx
+nRF24L01P my_nrf24l01p(p5, p6, p7, p8, p9, p10);    // mosi, miso, sck, csn, ce, irq
+DigitalOut myled1(LED1);
+DigitalOut myled2(LED2);
+DigitalOut myled3(LED3);
+DigitalOut myled4(LED4);   
+
+float brightness = 0.0f;
+char txData[TRANSFER_SIZE], rxData[TRANSFER_SIZE], oldRxData[TRANSFER_SIZE];
+int arrivedcount = 0;
+time_t seconds;
+
+struct MQTTmessage {
+    char topic[50];
+    char value[50];
+    bool isNumeric;
+};
+
+struct lastHeard {
+    uint8_t address;
+    time_t seconds;
+};
+
+
+struct lastHeard lastHeardArray[Nodes];
+
+const struct MQTTtoNRF24map {
+    uint8_t address;
+    char topic[50];
+} maps[Nodes] = {
+    {100, "temperature/study"},
+    {101, "temperature/entrance"},
+    {102, "temperature/hall"},
+    {103, "temperature/lounge"},
+    {104, "temperature/utility"},
+    {105, "temperature/kitchen"},
+    {106, "temperature/toilet"},
+    {107, "temperature/landing"},
+    {108, "temperature/mainBedroom"},
+    {109, "temperature/samBedroom"},
+    {110, "temperature/meganBedroom"},
+    {111, "temperature/spareBedroom"},
+    {112, "temperature/bathroom"},
+    {113, "temperature/outside"},
+    {114, "temperature/garage"},
+    {120, "door/garage"},
+    {121, "door/garageBig"},
+    {122, "door/study"},
+    {150, "power/house"},
+    };
+
+struct MQTTmessage makeMessage(char topic[50], char value[50], bool isNumeric) {
+    struct MQTTmessage returnMessage;
+    strncpy(returnMessage.topic, topic, 50);
+    strncpy(returnMessage.value, value, 50);
+    returnMessage.isNumeric = isNumeric;
+    return returnMessage;
+}
+
+int checkDuplicates(char inRx[TRANSFER_SIZE], char inOldRx[TRANSFER_SIZE]) {
+    int i;
+    for (i = 0; i < TRANSFER_SIZE; i++) {
+        if (inRx[i] != inOldRx[i]) {return 1;}      // And if it's not the same as the last one recieved
+    }
+    return 0;
+}
+
+void sendMessage(MQTT::Client<MQTTEthernet, Countdown> client, struct MQTTmessage inMessage) {
+    MQTT::Message message;
+    message.qos = MQTT::QOS0;
+    message.retained = false;
+    message.dup = false;
+    message.payload = (void*)inMessage.value;
+    if (inMessage.isNumeric) {
+        message.payloadlen = strlen(inMessage.value);
+    } else {
+        message.payloadlen = strlen(inMessage.value) + 1;
+    }client.publish(inMessage.topic, message);
+    while (arrivedcount < 1)
+        client.yield(100);
+    seconds = time(NULL);
+    pc.printf("%d : Sent message to %s : %s\r\n", seconds, inMessage.topic, inMessage.value);
+}
+
+char* decodeTemperatures(uint8_t inTemp) {
+    char tempStr[50];
+    sprintf(tempStr, "%4.2f", ((float)inTemp - 20) / 2);
+    return tempStr;
+}
+
+struct MQTTmessage useRadioData(){
+    struct MQTTmessage returnMessage;   
+    bool foundMap = false;
+    for (int i=0; i<Nodes; i++) {
+        if (maps[i].address == rxData[0]) {
+            lastHeardArray[i].seconds = seconds;
+            if (strncmp(maps[i].topic, "temp", 4) == 0) {
+                strncpy(returnMessage.topic, maps[i].topic, 50);
+                strncpy(returnMessage.value, decodeTemperatures(rxData[7]), 50);
+                returnMessage.isNumeric = true;
+            } else if (strncmp(maps[i].topic, "door", 4) == 0) {
+                strncpy(returnMessage.topic, maps[i].topic, 50);
+                if (rxData[7] == 255) {
+                    strncpy(returnMessage.value, "ON", 8);
+                } else if (rxData[7] == 0) {
+                    strncpy(returnMessage.value, "OFF", 8);
+                } else {
+                    strncpy(returnMessage.value, "Unknown", 8);
+                }
+                returnMessage.isNumeric = false;
+            } else {
+                strncpy(returnMessage.topic, maps[i].topic, 50);
+                strncpy(returnMessage.value, decodeTemperatures(rxData[7]), 50);
+                returnMessage.isNumeric = false;
+            }
+            foundMap = true;
+            break;
+        }
+    } 
+    if (!foundMap){
+        strncpy(returnMessage.topic, "mBed/UnknownMessage", 50);
+        strncpy(returnMessage.value, rxData, 8);
+    }
+    return returnMessage;
+}
+
+void messageArrived(MQTT::MessageData& md) {
+    MQTT::Message &message = md.message;
+    pc.printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id);
+    pc.printf("Payload %.*s\r\n", message.payloadlen, (char*)message.payload);
+    ++arrivedcount;
+    pc.puts((char*)message.payload);
+}
+
+int main() {
+    set_time(0);
+    seconds = time(NULL);
+    pc.printf("%d : mBed started\r\n", seconds);
+    
+    for (int i=0; i<Nodes; i++) {
+        lastHeardArray[i].address = maps[i].address;
+    }
+    
+    //MQTT init
+    MQTTEthernet ipstack = MQTTEthernet();
+    MQTT::Client<MQTTEthernet, Countdown> client = MQTT::Client<MQTTEthernet, Countdown>(ipstack);
+
+    char* hostname = "172.16.0.1";
+    int port = 1883;
+    char* topic = "mBed";
+    seconds = time(NULL);
+    pc.printf("%d : Connecting to %s:%d\r\n", seconds, hostname, port);
+    int rc = ipstack.connect(hostname, port);
+    if (rc != 0) {
+        seconds = time(NULL);
+        pc.printf("%d : rc from TCP connect is %d\r\n", seconds, rc);
+    }
+    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;       
+    data.MQTTVersion = 3;
+    data.clientID.cstring = "mbed-sample";
+    data.username.cstring = "testuser";
+    data.password.cstring = "testpassword";
+    if ((rc = client.connect(data)) != 0){
+        seconds = time(NULL);
+        pc.printf("%d : rc from MQTT connect is %d\r\n", seconds, rc);
+    }
+    if ((rc = client.subscribe(topic, MQTT::QOS1, messageArrived)) != 0) {
+        seconds = time(NULL);    
+        pc.printf("%d : rc from MQTT subscribe is %d\r\n", seconds, rc);    
+    }
+    sendMessage(client, makeMessage("mBed", "mBed powered up", false));
+    //End MQTT init
+    
+    
+    //Start NRF24 Init
+    //int txDataCnt = 0;
+    //int rxDataCnt = 0;
+    
+    my_nrf24l01p.powerUp();
+    my_nrf24l01p.setRfFrequency(2525);
+    my_nrf24l01p.setTransferSize( TRANSFER_SIZE );
+    my_nrf24l01p.setCrcWidth(16);
+    my_nrf24l01p.setAirDataRate(250);
+    my_nrf24l01p.disableAutoAcknowledge();
+    my_nrf24l01p.setRxAddress(0xe7e7e7e7e8);
+    my_nrf24l01p.setTxAddress(0xe7e7e7e7e7);
+    my_nrf24l01p.disableAutoRetransmit();
+    
+    pc.printf( "nRF24L01+ Frequency    : %d MHz\r\n",  my_nrf24l01p.getRfFrequency() );
+    pc.printf( "nRF24L01+ Output power : %d dBm\r\n",  my_nrf24l01p.getRfOutputPower() );
+    pc.printf( "nRF24L01+ Data Rate    : %d kbps\r\n", my_nrf24l01p.getAirDataRate() );
+    pc.printf( "nRF24L01+ TX Address   : 0x%010llX\r\n", my_nrf24l01p.getTxAddress() );
+    pc.printf( "nRF24L01+ RX Address   : 0x%010llX\r\n", my_nrf24l01p.getRxAddress() );
+    pc.printf( "nRF24L01+ CRC Width    : %d bits\r\n", my_nrf24l01p.getCrcWidth() );
+    pc.printf( "nRF24L01+ TransferSize : %d bytes\r\n", my_nrf24l01p.getTransferSize() );
+    
+    my_nrf24l01p.setReceiveMode();
+    my_nrf24l01p.enable();
+    //End NRF24 init
+    
+    while (1) {
+        if ( my_nrf24l01p.readable() ) {
+            //rxDataCnt = 
+            my_nrf24l01p.read( NRF24L01P_PIPE_P0, rxData, TRANSFER_SIZE );
+            myled1 = 1;
+            int notDuplicate = checkDuplicates(rxData, oldRxData);
+            if ( rxData[1]==NodeID ) {             // Addressed to this node, and not the same as the last one
+                seconds = time(NULL);
+                pc.printf("%d : New NRF Data: ", seconds);
+
+                //int i;
+                for (int i = 0; i < TRANSFER_SIZE; i++) {
+                    oldRxData[i] = rxData[i];
+                    if (i > 0) printf(":");
+                    printf("%d", rxData[i]);
+                }
+                printf(" - ");
+                txData[0] = rxData[1];                      // Send response back to source
+                txData[1] = NodeID;                         // From this host
+                txData[2] = 2;                              // as an Ack...
+                txData[3] = rxData[3];                      // ...to the packet ID that was recieved
+                txData[4] = 0;                              // with an empty payload
+                txData[5] = 0;
+                txData[6] = 0;
+                txData[7] = 0;                              
+                
+                my_nrf24l01p.setTransmitMode();
+                for (int i = 0; i < 8; i++) {
+                    //txDataCnt = 
+                    my_nrf24l01p.write( NRF24L01P_PIPE_P1, txData, TRANSFER_SIZE );
+                    wait_us(500);
+                }
+                my_nrf24l01p.setReceiveMode();
+                                
+                for (int i = 0; i < TRANSFER_SIZE; i++) {
+                    if (i > 0) pc.printf(":");
+                    pc.printf("%d", txData[i]);
+                }
+                printf("\r\n");
+                
+                seconds = time(NULL);
+                pc.printf("%d : Sending NRF data \r\n", seconds);            
+                if (notDuplicate) {
+                    if(!client.isConnected()) {
+                        myled4 = 1;
+                        pc.printf("%d : Connecting to %s:%d\r\n", seconds, hostname, port);
+                        rc = ipstack.connect(hostname, port);
+                        if (rc != 0) {
+                            seconds = time(NULL);
+                            pc.printf("%d : rc from TCP connect is %d\r\n", seconds, rc);
+                        }
+                        /*
+                        data = MQTTPacket_connectData_initializer;       
+                        data.MQTTVersion = 3;
+                        data.clientID.cstring = "mbed-sample";
+                        data.username.cstring = "testuser";
+                        data.password.cstring = "testpassword";
+                        */
+                        if ((rc = client.connect(data)) != 0){
+                            seconds = time(NULL);
+                            pc.printf("%d : rc from MQTT connect is %d\r\n", seconds, rc);
+                        }
+                        if ((rc = client.subscribe(topic, MQTT::QOS1, messageArrived)) != 0) {
+                            seconds = time(NULL);    
+                            pc.printf("%d : rc from MQTT subscribe is %d\r\n", seconds, rc);    
+                        }
+                        sendMessage(client, makeMessage("mBed", "session died, restarting", false));
+                    }
+                    sendMessage(client, useRadioData());
+                }    
+            }
+            myled1 = 0;
+        }
+        // insert mqtt poller here...
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Wed Jun 03 18:46:47 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/mbed_official/code/mbed-rtos/#d3d0e710b443
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Jun 03 18:46:47 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/487b796308b0
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF24L01P.lib	Wed Jun 03 18:46:47 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/Owen/code/nRF24L01P/#8ae48233b4e4