Project for MPOA 2015/2016. Communication link with nRF24L01+.

Dependencies:   mbed

Fork of nRF24L01P_Hello_World by Owen Edwards

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //Autor: Petr Sedláček
00002 //Project for MPOA 2015/2016, Experimental Point-to-point link with nRF24L01+ in 2.4 GHz ISM band
00003 
00004 #include "mbed.h"
00005 #include "nRF24L01P.h"
00006 #include <string.h>
00007 #include <Timer.h>
00008 #include "menu.h"
00009 
00010 #define TRANSFER_SIZE 16 //Maximum data size
00011 
00012 
00013 Serial pc(USBTX, USBRX); // tx, rx
00014 
00015 nRF24L01P my_nrf24l01p(PTD2, PTD3, PTD1, PTD0, PTD5, PTA13);    // mosi, miso, sck, csn, ce, irq
00016 
00017 DigitalOut rled(LED_RED, 1);
00018 DigitalOut gled(LED_GREEN, 1);  
00019 
00020 Timer rtt_timer; //Timer to measure RTT
00021 Ticker rled_ticker; //Tickers for blinking LEDs
00022 Ticker gled_ticker;
00023 
00024 static uint16_t error_bits = 0; //static to be only visible in this file
00025 static uint16_t all_bits = 0;   //static to be only visible in this file
00026 uint8_t interval;
00027 char txData[TRANSFER_SIZE];
00028 int txDataCnt = 0;
00029 bool tx_mode;
00030 bool keyboard_mode;
00031 
00032 //Functions for LED blinks
00033 void led_red_flip() {
00034     rled = !rled;
00035     rled_ticker.detach();
00036         
00037 }
00038 
00039 void led_green_flip() {
00040     gled = !gled;
00041     gled_ticker.detach();    
00042 }
00043 
00044 //Function for BER calculation
00045 void ber_calculate(char recData[]) {
00046     float ber = 0;
00047     char sent_string[] = "ACK\r"; //Compared string
00048     
00049     all_bits += (strlen(recData) *8); //Increase the size if incoming bits
00050     
00051     for (uint8_t i=0; i<= strlen(recData); i++) {
00052         recData[i] ^= sent_string[i]; //XOR received data with expected string
00053         
00054         //If there was no error, all bits must be zero
00055         while(recData[i] !=0) {
00056             //If there was an error, increase number of error bits and shift by one
00057             if (recData[i] & 1) { 
00058                 error_bits++;
00059                 recData[i] >>= 1;
00060             }
00061         }
00062         
00063         
00064     }
00065     ber =  (((float)error_bits)/all_bits) *100; //BER calculation
00066     pc.printf("BER: %3.4f %%\n", ber);
00067     
00068 }
00069 //Function to send data automatically
00070 void send() {
00071     //If the device is TX, send ping message
00072     if (tx_mode) {
00073         sprintf(txData, "ping\r");
00074         rtt_timer.start();
00075     }
00076     //If the device is RX, send ACK message
00077     else {
00078         sprintf(txData, "ACK\r");
00079     }
00080     //Print sent data and send it via nrf24l01
00081     pc.printf("\nSent: %s", txData);
00082     txDataCnt = 4;
00083     my_nrf24l01p.write( NRF24L01P_PIPE_P0, txData, txDataCnt );
00084     //Small blocking delay for LED blink
00085     if (!tx_mode) {
00086         wait_ms(200);
00087     }
00088     rled = 0; 
00089     rled_ticker.attach(&led_red_flip, 0.2);
00090 }
00091 
00092 
00093 
00094 int main() {
00095     Timer send_timer; //Timer for sending automatic messages
00096     uint16_t lost_num = 0; //Number of lost packets
00097     uint16_t ack_num = 0; //Number of ACKs
00098     uint16_t rec_messages = 0;  //Number of received messages
00099     char rxData[TRANSFER_SIZE];
00100     
00101     my_nrf24l01p.powerUp();
00102     settings(); //Function for user menu 
00103     
00104     // Display the (default) setup of the nRF24L01+ chip
00105     pc.printf( "nRF24L01 Frequency    : %d MHz\n",  my_nrf24l01p.getRfFrequency() );
00106     pc.printf( "nRF24L01 Output power : %d dBm\n",  my_nrf24l01p.getRfOutputPower() );
00107     pc.printf( "nRF24L01 Data Rate    : %d kbps\n", my_nrf24l01p.getAirDataRate() );
00108     pc.printf( "nRF24L01 TX Address   : 0x%010llX\n", my_nrf24l01p.getTxAddress() );
00109     pc.printf( "nRF24L01 RX Address   : 0x%010llX\n", my_nrf24l01p.getRxAddress() );
00110     //If TX mode and automatic mode are chosen, print the set interval for messages 
00111     if (tx_mode) {
00112         pc.printf( "Message Interval      : %d seconds\n",  interval);
00113     }
00114     //If keyboard mode is set, print this message
00115     if (keyboard_mode) {
00116         pc.printf( "Type keys to test transfers:\r\n  (transfers are grouped into variable characters, maximum is a group of %d characters)\r\n", TRANSFER_SIZE );
00117     }
00118     //Set registers for dynamic payload
00119     my_nrf24l01p.setRegister(_NRF24L01P_REG_FEATURE, 0x04); 
00120     my_nrf24l01p.setRegister(_NRF24L01P_REG_DYNPD, 0x01);
00121     //Start up the nrf24L01
00122     my_nrf24l01p.enable();
00123     my_nrf24l01p.setReceiveMode();
00124     
00125     //Start the timer for automatic transmissions
00126     if (!keyboard_mode && tx_mode) {
00127         send_timer.start();
00128     }
00129 
00130 
00131     while (1) {
00132         //Send messages periodically
00133         if (!keyboard_mode && tx_mode) {
00134             if ((int) send_timer.read_ms() % (interval*1000) == 0) {
00135                 send();    
00136             }
00137         }
00138         //If keyboard mode is activated, read user input
00139         if (keyboard_mode) {
00140             // If we've received anything over the host serial link...
00141             if ( pc.readable() ) {
00142                 // ...add it to the transmit buffer
00143                 txData[txDataCnt++] = pc.getc();
00144                 // If the transmit buffer is full or Enter is pressed
00145                 if ( txDataCnt >= sizeof( txData ) || txData[txDataCnt-1] == '\r') {
00146                     // Send the transmit buffer via the nRF24L01+
00147                     my_nrf24l01p.write( NRF24L01P_PIPE_P0, txData, txDataCnt );
00148                     pc.printf("\nSent: %s\n", txData);
00149                     //Start the RTT timer in TX Mode
00150                     if (tx_mode) {
00151                         rtt_timer.start();
00152                     }   
00153                     // Blink Red LED to indicate message sent
00154                     txDataCnt = 0;
00155                     rled = 0; 
00156                     rled_ticker.attach(&led_red_flip, 0.2);
00157                 }
00158    
00159             }
00160         }
00161 
00162 
00163         // If we've received anything in the nRF24L01+...
00164         if ( my_nrf24l01p.readable() ) {
00165             //Stop RTT timer
00166             if (tx_mode) {
00167                 rtt_timer.stop();
00168                 wait_ms(200);
00169             }
00170             // ...read the data into the receive buffer
00171             my_nrf24l01p.read( NRF24L01P_PIPE_P0, rxData, sizeof( rxData ) );
00172             pc.printf("Received: %s", rxData);
00173             //Blink green led to indicate message received
00174             gled = 0;
00175             gled_ticker.attach(led_green_flip, 0.2);
00176             //Send automatic response in RX mode  
00177             if (!keyboard_mode && !tx_mode) {
00178                 send();
00179             }
00180                
00181             if (tx_mode) {
00182                 //If a message wasn't received between automatic transmissions, increase BER and NACKs 
00183                 if ((int) rtt_timer.read() >= interval && !keyboard_mode) {
00184                     lost_num = ((int) rtt_timer.read()/interval);
00185                     error_bits += (strlen(rxData) * 8) * lost_num;
00186                     all_bits += (strlen(rxData) * 8) * lost_num;
00187                 }
00188                 ack_num++; //If message was received between retransmissions, increase number of ACKs
00189                 pc.printf("RTT: %3.4f\n", rtt_timer.read()); //Print RTT
00190                 pc.printf("Number of ACKs: %d\n", ack_num); //Number of ACKs
00191                 pc.printf("Number of NACKs: %d\n", lost_num); //Number of NACKs
00192                 rtt_timer.reset(); //Reset the RTT timer
00193                 //Calculate BER, but only in automatic mode
00194                 if (!keyboard_mode) {
00195                     ber_calculate(rxData);
00196                 }
00197             //If RX mode is activated, diplay number of received messages
00198             } else {
00199                 rec_messages++;
00200                 pc.printf("Recieved message No.: %d\n\n", rec_messages);
00201             }
00202             
00203 
00204             
00205         }
00206 
00207     }
00208 }