Takes in sensor readings from NRF24 connected nodes and publises the data over MQTT
Dependencies: EthernetInterface MQTT mbed-rtos mbed nRF24L01P
Revision 0:cec410958705, committed 2015-06-03
- 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
--- /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