Takes in sensor readings from NRF24 connected nodes and publises the data over MQTT
Dependencies: EthernetInterface MQTT mbed-rtos mbed nRF24L01P
main.cpp
- Committer:
- Mephi
- Date:
- 2015-06-03
- Revision:
- 0:cec410958705
File content as of revision 0:cec410958705:
#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... } }