![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Takes in sensor readings from NRF24 connected nodes and publises the data over MQTT
Dependencies: EthernetInterface MQTT mbed-rtos mbed nRF24L01P
Diff: main.cpp
- Revision:
- 0:cec410958705
--- /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