Project for MPOA 2015/2016. Communication link with nRF24L01+.
Fork of nRF24L01P_Hello_World by
main.cpp
- Committer:
- petrsedlacek
- Date:
- 2016-01-17
- Revision:
- 2:f555c7caa707
- Parent:
- 1:5be2682710c6
File content as of revision 2:f555c7caa707:
//Autor: Petr Sedláček //Project for MPOA 2015/2016, Experimental Point-to-point link with nRF24L01+ in 2.4 GHz ISM band #include "mbed.h" #include "nRF24L01P.h" #include <string.h> #include <Timer.h> #include "menu.h" #define TRANSFER_SIZE 16 //Maximum data size Serial pc(USBTX, USBRX); // tx, rx nRF24L01P my_nrf24l01p(PTD2, PTD3, PTD1, PTD0, PTD5, PTA13); // mosi, miso, sck, csn, ce, irq DigitalOut rled(LED_RED, 1); DigitalOut gled(LED_GREEN, 1); Timer rtt_timer; //Timer to measure RTT Ticker rled_ticker; //Tickers for blinking LEDs Ticker gled_ticker; static uint16_t error_bits = 0; //static to be only visible in this file static uint16_t all_bits = 0; //static to be only visible in this file uint8_t interval; char txData[TRANSFER_SIZE]; int txDataCnt = 0; bool tx_mode; bool keyboard_mode; //Functions for LED blinks void led_red_flip() { rled = !rled; rled_ticker.detach(); } void led_green_flip() { gled = !gled; gled_ticker.detach(); } //Function for BER calculation void ber_calculate(char recData[]) { float ber = 0; char sent_string[] = "ACK\r"; //Compared string all_bits += (strlen(recData) *8); //Increase the size if incoming bits for (uint8_t i=0; i<= strlen(recData); i++) { recData[i] ^= sent_string[i]; //XOR received data with expected string //If there was no error, all bits must be zero while(recData[i] !=0) { //If there was an error, increase number of error bits and shift by one if (recData[i] & 1) { error_bits++; recData[i] >>= 1; } } } ber = (((float)error_bits)/all_bits) *100; //BER calculation pc.printf("BER: %3.4f %%\n", ber); } //Function to send data automatically void send() { //If the device is TX, send ping message if (tx_mode) { sprintf(txData, "ping\r"); rtt_timer.start(); } //If the device is RX, send ACK message else { sprintf(txData, "ACK\r"); } //Print sent data and send it via nrf24l01 pc.printf("\nSent: %s", txData); txDataCnt = 4; my_nrf24l01p.write( NRF24L01P_PIPE_P0, txData, txDataCnt ); //Small blocking delay for LED blink if (!tx_mode) { wait_ms(200); } rled = 0; rled_ticker.attach(&led_red_flip, 0.2); } int main() { Timer send_timer; //Timer for sending automatic messages uint16_t lost_num = 0; //Number of lost packets uint16_t ack_num = 0; //Number of ACKs uint16_t rec_messages = 0; //Number of received messages char rxData[TRANSFER_SIZE]; my_nrf24l01p.powerUp(); settings(); //Function for user menu // Display the (default) setup of the nRF24L01+ chip pc.printf( "nRF24L01 Frequency : %d MHz\n", my_nrf24l01p.getRfFrequency() ); pc.printf( "nRF24L01 Output power : %d dBm\n", my_nrf24l01p.getRfOutputPower() ); pc.printf( "nRF24L01 Data Rate : %d kbps\n", my_nrf24l01p.getAirDataRate() ); pc.printf( "nRF24L01 TX Address : 0x%010llX\n", my_nrf24l01p.getTxAddress() ); pc.printf( "nRF24L01 RX Address : 0x%010llX\n", my_nrf24l01p.getRxAddress() ); //If TX mode and automatic mode are chosen, print the set interval for messages if (tx_mode) { pc.printf( "Message Interval : %d seconds\n", interval); } //If keyboard mode is set, print this message if (keyboard_mode) { 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 ); } //Set registers for dynamic payload my_nrf24l01p.setRegister(_NRF24L01P_REG_FEATURE, 0x04); my_nrf24l01p.setRegister(_NRF24L01P_REG_DYNPD, 0x01); //Start up the nrf24L01 my_nrf24l01p.enable(); my_nrf24l01p.setReceiveMode(); //Start the timer for automatic transmissions if (!keyboard_mode && tx_mode) { send_timer.start(); } while (1) { //Send messages periodically if (!keyboard_mode && tx_mode) { if ((int) send_timer.read_ms() % (interval*1000) == 0) { send(); } } //If keyboard mode is activated, read user input if (keyboard_mode) { // If we've received anything over the host serial link... if ( pc.readable() ) { // ...add it to the transmit buffer txData[txDataCnt++] = pc.getc(); // If the transmit buffer is full or Enter is pressed if ( txDataCnt >= sizeof( txData ) || txData[txDataCnt-1] == '\r') { // Send the transmit buffer via the nRF24L01+ my_nrf24l01p.write( NRF24L01P_PIPE_P0, txData, txDataCnt ); pc.printf("\nSent: %s\n", txData); //Start the RTT timer in TX Mode if (tx_mode) { rtt_timer.start(); } // Blink Red LED to indicate message sent txDataCnt = 0; rled = 0; rled_ticker.attach(&led_red_flip, 0.2); } } } // If we've received anything in the nRF24L01+... if ( my_nrf24l01p.readable() ) { //Stop RTT timer if (tx_mode) { rtt_timer.stop(); wait_ms(200); } // ...read the data into the receive buffer my_nrf24l01p.read( NRF24L01P_PIPE_P0, rxData, sizeof( rxData ) ); pc.printf("Received: %s", rxData); //Blink green led to indicate message received gled = 0; gled_ticker.attach(led_green_flip, 0.2); //Send automatic response in RX mode if (!keyboard_mode && !tx_mode) { send(); } if (tx_mode) { //If a message wasn't received between automatic transmissions, increase BER and NACKs if ((int) rtt_timer.read() >= interval && !keyboard_mode) { lost_num = ((int) rtt_timer.read()/interval); error_bits += (strlen(rxData) * 8) * lost_num; all_bits += (strlen(rxData) * 8) * lost_num; } ack_num++; //If message was received between retransmissions, increase number of ACKs pc.printf("RTT: %3.4f\n", rtt_timer.read()); //Print RTT pc.printf("Number of ACKs: %d\n", ack_num); //Number of ACKs pc.printf("Number of NACKs: %d\n", lost_num); //Number of NACKs rtt_timer.reset(); //Reset the RTT timer //Calculate BER, but only in automatic mode if (!keyboard_mode) { ber_calculate(rxData); } //If RX mode is activated, diplay number of received messages } else { rec_messages++; pc.printf("Recieved message No.: %d\n\n", rec_messages); } } } }