Project for MPOA 2015/2016. Communication link with nRF24L01+.
Fork of nRF24L01P_Hello_World by
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 }
Generated on Thu Jul 14 2022 17:56:10 by 1.7.2