Matthew Green / Mbed 2 deprecated IoT_NRF24

Dependencies:   EthernetInterface MQTT mbed-rtos mbed nRF24L01P

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "MQTTEthernet.h"
00003 #include "MQTTClient.h"
00004 #include "nRF24L01P.h"
00005 
00006 #define TRANSFER_SIZE 8 
00007 const uint8_t NodeID = 1;
00008 const uint8_t Nodes = 19;
00009 
00010 Serial pc(USBTX, USBRX); // tx, rx
00011 nRF24L01P my_nrf24l01p(p5, p6, p7, p8, p9, p10);    // mosi, miso, sck, csn, ce, irq
00012 DigitalOut myled1(LED1);
00013 DigitalOut myled2(LED2);
00014 DigitalOut myled3(LED3);
00015 DigitalOut myled4(LED4);   
00016 
00017 float brightness = 0.0f;
00018 char txData[TRANSFER_SIZE], rxData[TRANSFER_SIZE], oldRxData[TRANSFER_SIZE];
00019 int arrivedcount = 0;
00020 time_t seconds;
00021 
00022 struct MQTTmessage {
00023     char topic[50];
00024     char value[50];
00025     bool isNumeric;
00026 };
00027 
00028 struct lastHeard {
00029     uint8_t address;
00030     time_t seconds;
00031 };
00032 
00033 
00034 struct lastHeard lastHeardArray[Nodes];
00035 
00036 const struct MQTTtoNRF24map {
00037     uint8_t address;
00038     char topic[50];
00039 } maps[Nodes] = {
00040     {100, "temperature/study"},
00041     {101, "temperature/entrance"},
00042     {102, "temperature/hall"},
00043     {103, "temperature/lounge"},
00044     {104, "temperature/utility"},
00045     {105, "temperature/kitchen"},
00046     {106, "temperature/toilet"},
00047     {107, "temperature/landing"},
00048     {108, "temperature/mainBedroom"},
00049     {109, "temperature/samBedroom"},
00050     {110, "temperature/meganBedroom"},
00051     {111, "temperature/spareBedroom"},
00052     {112, "temperature/bathroom"},
00053     {113, "temperature/outside"},
00054     {114, "temperature/garage"},
00055     {120, "door/garage"},
00056     {121, "door/garageBig"},
00057     {122, "door/study"},
00058     {150, "power/house"},
00059     };
00060 
00061 struct MQTTmessage makeMessage(char topic[50], char value[50], bool isNumeric) {
00062     struct MQTTmessage returnMessage;
00063     strncpy(returnMessage.topic, topic, 50);
00064     strncpy(returnMessage.value, value, 50);
00065     returnMessage.isNumeric = isNumeric;
00066     return returnMessage;
00067 }
00068 
00069 int checkDuplicates(char inRx[TRANSFER_SIZE], char inOldRx[TRANSFER_SIZE]) {
00070     int i;
00071     for (i = 0; i < TRANSFER_SIZE; i++) {
00072         if (inRx[i] != inOldRx[i]) {return 1;}      // And if it's not the same as the last one recieved
00073     }
00074     return 0;
00075 }
00076 
00077 void sendMessage(MQTT::Client<MQTTEthernet, Countdown> client, struct MQTTmessage inMessage) {
00078     MQTT::Message message;
00079     message.qos = MQTT::QOS0;
00080     message.retained = false;
00081     message.dup = false;
00082     message.payload = (void*)inMessage.value;
00083     if (inMessage.isNumeric) {
00084         message.payloadlen = strlen(inMessage.value);
00085     } else {
00086         message.payloadlen = strlen(inMessage.value) + 1;
00087     }client.publish(inMessage.topic, message);
00088     while (arrivedcount < 1)
00089         client.yield(100);
00090     seconds = time(NULL);
00091     pc.printf("%d : Sent message to %s : %s\r\n", seconds, inMessage.topic, inMessage.value);
00092 }
00093 
00094 char* decodeTemperatures(uint8_t inTemp) {
00095     char tempStr[50];
00096     sprintf(tempStr, "%4.2f", ((float)inTemp - 20) / 2);
00097     return tempStr;
00098 }
00099 
00100 struct MQTTmessage useRadioData(){
00101     struct MQTTmessage returnMessage;   
00102     bool foundMap = false;
00103     for (int i=0; i<Nodes; i++) {
00104         if (maps[i].address == rxData[0]) {
00105             lastHeardArray[i].seconds = seconds;
00106             if (strncmp(maps[i].topic, "temp", 4) == 0) {
00107                 strncpy(returnMessage.topic, maps[i].topic, 50);
00108                 strncpy(returnMessage.value, decodeTemperatures(rxData[7]), 50);
00109                 returnMessage.isNumeric = true;
00110             } else if (strncmp(maps[i].topic, "door", 4) == 0) {
00111                 strncpy(returnMessage.topic, maps[i].topic, 50);
00112                 if (rxData[7] == 255) {
00113                     strncpy(returnMessage.value, "ON", 8);
00114                 } else if (rxData[7] == 0) {
00115                     strncpy(returnMessage.value, "OFF", 8);
00116                 } else {
00117                     strncpy(returnMessage.value, "Unknown", 8);
00118                 }
00119                 returnMessage.isNumeric = false;
00120             } else {
00121                 strncpy(returnMessage.topic, maps[i].topic, 50);
00122                 strncpy(returnMessage.value, decodeTemperatures(rxData[7]), 50);
00123                 returnMessage.isNumeric = false;
00124             }
00125             foundMap = true;
00126             break;
00127         }
00128     } 
00129     if (!foundMap){
00130         strncpy(returnMessage.topic, "mBed/UnknownMessage", 50);
00131         strncpy(returnMessage.value, rxData, 8);
00132     }
00133     return returnMessage;
00134 }
00135 
00136 void messageArrived(MQTT::MessageData& md) {
00137     MQTT::Message &message = md.message;
00138     pc.printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id);
00139     pc.printf("Payload %.*s\r\n", message.payloadlen, (char*)message.payload);
00140     ++arrivedcount;
00141     pc.puts((char*)message.payload);
00142 }
00143 
00144 int main() {
00145     set_time(0);
00146     seconds = time(NULL);
00147     pc.printf("%d : mBed started\r\n", seconds);
00148     
00149     for (int i=0; i<Nodes; i++) {
00150         lastHeardArray[i].address = maps[i].address;
00151     }
00152     
00153     //MQTT init
00154     MQTTEthernet ipstack = MQTTEthernet();
00155     MQTT::Client<MQTTEthernet, Countdown> client = MQTT::Client<MQTTEthernet, Countdown>(ipstack);
00156 
00157     char* hostname = "172.16.0.1";
00158     int port = 1883;
00159     char* topic = "mBed";
00160     seconds = time(NULL);
00161     pc.printf("%d : Connecting to %s:%d\r\n", seconds, hostname, port);
00162     int rc = ipstack.connect(hostname, port);
00163     if (rc != 0) {
00164         seconds = time(NULL);
00165         pc.printf("%d : rc from TCP connect is %d\r\n", seconds, rc);
00166     }
00167     MQTTPacket_connectData data = MQTTPacket_connectData_initializer;       
00168     data.MQTTVersion = 3;
00169     data.clientID.cstring = "mbed-sample";
00170     data.username.cstring = "testuser";
00171     data.password.cstring = "testpassword";
00172     if ((rc = client.connect(data)) != 0){
00173         seconds = time(NULL);
00174         pc.printf("%d : rc from MQTT connect is %d\r\n", seconds, rc);
00175     }
00176     if ((rc = client.subscribe(topic, MQTT::QOS1, messageArrived)) != 0) {
00177         seconds = time(NULL);    
00178         pc.printf("%d : rc from MQTT subscribe is %d\r\n", seconds, rc);    
00179     }
00180     sendMessage(client, makeMessage("mBed", "mBed powered up", false));
00181     //End MQTT init
00182     
00183     
00184     //Start NRF24 Init
00185     //int txDataCnt = 0;
00186     //int rxDataCnt = 0;
00187     
00188     my_nrf24l01p.powerUp();
00189     my_nrf24l01p.setRfFrequency(2525);
00190     my_nrf24l01p.setTransferSize( TRANSFER_SIZE );
00191     my_nrf24l01p.setCrcWidth(16);
00192     my_nrf24l01p.setAirDataRate(250);
00193     my_nrf24l01p.disableAutoAcknowledge();
00194     my_nrf24l01p.setRxAddress(0xe7e7e7e7e8);
00195     my_nrf24l01p.setTxAddress(0xe7e7e7e7e7);
00196     my_nrf24l01p.disableAutoRetransmit();
00197     
00198     pc.printf( "nRF24L01+ Frequency    : %d MHz\r\n",  my_nrf24l01p.getRfFrequency() );
00199     pc.printf( "nRF24L01+ Output power : %d dBm\r\n",  my_nrf24l01p.getRfOutputPower() );
00200     pc.printf( "nRF24L01+ Data Rate    : %d kbps\r\n", my_nrf24l01p.getAirDataRate() );
00201     pc.printf( "nRF24L01+ TX Address   : 0x%010llX\r\n", my_nrf24l01p.getTxAddress() );
00202     pc.printf( "nRF24L01+ RX Address   : 0x%010llX\r\n", my_nrf24l01p.getRxAddress() );
00203     pc.printf( "nRF24L01+ CRC Width    : %d bits\r\n", my_nrf24l01p.getCrcWidth() );
00204     pc.printf( "nRF24L01+ TransferSize : %d bytes\r\n", my_nrf24l01p.getTransferSize() );
00205     
00206     my_nrf24l01p.setReceiveMode();
00207     my_nrf24l01p.enable();
00208     //End NRF24 init
00209     
00210     while (1) {
00211         if ( my_nrf24l01p.readable() ) {
00212             //rxDataCnt = 
00213             my_nrf24l01p.read( NRF24L01P_PIPE_P0, rxData, TRANSFER_SIZE );
00214             myled1 = 1;
00215             int notDuplicate = checkDuplicates(rxData, oldRxData);
00216             if ( rxData[1]==NodeID ) {             // Addressed to this node, and not the same as the last one
00217                 seconds = time(NULL);
00218                 pc.printf("%d : New NRF Data: ", seconds);
00219 
00220                 //int i;
00221                 for (int i = 0; i < TRANSFER_SIZE; i++) {
00222                     oldRxData[i] = rxData[i];
00223                     if (i > 0) printf(":");
00224                     printf("%d", rxData[i]);
00225                 }
00226                 printf(" - ");
00227                 txData[0] = rxData[1];                      // Send response back to source
00228                 txData[1] = NodeID;                         // From this host
00229                 txData[2] = 2;                              // as an Ack...
00230                 txData[3] = rxData[3];                      // ...to the packet ID that was recieved
00231                 txData[4] = 0;                              // with an empty payload
00232                 txData[5] = 0;
00233                 txData[6] = 0;
00234                 txData[7] = 0;                              
00235                 
00236                 my_nrf24l01p.setTransmitMode();
00237                 for (int i = 0; i < 8; i++) {
00238                     //txDataCnt = 
00239                     my_nrf24l01p.write( NRF24L01P_PIPE_P1, txData, TRANSFER_SIZE );
00240                     wait_us(500);
00241                 }
00242                 my_nrf24l01p.setReceiveMode();
00243                                 
00244                 for (int i = 0; i < TRANSFER_SIZE; i++) {
00245                     if (i > 0) pc.printf(":");
00246                     pc.printf("%d", txData[i]);
00247                 }
00248                 printf("\r\n");
00249                 
00250                 seconds = time(NULL);
00251                 pc.printf("%d : Sending NRF data \r\n", seconds);            
00252                 if (notDuplicate) {
00253                     if(!client.isConnected()) {
00254                         myled4 = 1;
00255                         pc.printf("%d : Connecting to %s:%d\r\n", seconds, hostname, port);
00256                         rc = ipstack.connect(hostname, port);
00257                         if (rc != 0) {
00258                             seconds = time(NULL);
00259                             pc.printf("%d : rc from TCP connect is %d\r\n", seconds, rc);
00260                         }
00261                         /*
00262                         data = MQTTPacket_connectData_initializer;       
00263                         data.MQTTVersion = 3;
00264                         data.clientID.cstring = "mbed-sample";
00265                         data.username.cstring = "testuser";
00266                         data.password.cstring = "testpassword";
00267                         */
00268                         if ((rc = client.connect(data)) != 0){
00269                             seconds = time(NULL);
00270                             pc.printf("%d : rc from MQTT connect is %d\r\n", seconds, rc);
00271                         }
00272                         if ((rc = client.subscribe(topic, MQTT::QOS1, messageArrived)) != 0) {
00273                             seconds = time(NULL);    
00274                             pc.printf("%d : rc from MQTT subscribe is %d\r\n", seconds, rc);    
00275                         }
00276                         sendMessage(client, makeMessage("mBed", "session died, restarting", false));
00277                     }
00278                     sendMessage(client, useRadioData());
00279                 }    
00280             }
00281             myled1 = 0;
00282         }
00283         // insert mqtt poller here...
00284     }
00285 }