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...
}
}