This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to transmit and receive beacons using nRF51 DK?

I need to transmit and receive beacons using nRF51 DK. I saw a few examples in the SDK ble_beacons where we use the app, but I need code to transmit and receive both using the nRF51 Development kit. Also, can you give me steps for setting up GCC for the nRF51DK, how do I setup that IDE for using it with the DK, if there are any youtube videos for setting up the GCC for the nRF51DK please send me the links. Also while receiving the beacons, I need the RSSI value at the receiver and how do I get that value?  Thank you so much for your help. Also, I need to know while transmitting from one nRF51DK to another is it necessary to pair the boards etc?

Parents
  • Hi,

    I need code to transmit and receive both using the nRF51 Development kit.
    First of all I think there is a misunderstanding regarding beacons. A BLE beacon is per definition not receiving anything. It is just mindlessly broadcasting a handful of bytes. If you want bidirectional communication between two nRF51 devices I suggest that you start out with the UART/Serial Port Emulation over BLE and Nordic UART Service Client examples. 

    can you give me steps for setting up GCC for the nRF51DK
    Unfortunately, we only have this relatively old tutorial: Development with GCC and Eclipse

    I need the RSSI value at the receiver and how do I get that value? 
    Please have a look at these APIs: sd_ble_gap_rssi_start(), sd_ble_gap_rssi_stop(), and sd_ble_gap_rssi_get().

    I need to know while transmitting from one nRF51DK to another is it necessary to pair the boards etc?
    It depends. But I suspect that you might be confusing BLE pairing and bonding.

     

  • Hello MartinBL,

    First of all thank you so much for your help. I tried to execute the Nordic UART service Client on two dev boards, I programmed both the soft device and the hex file into both the boards ( I am not sure if I had to program both the boards with the same code but that's what I did) and both of those boards were advertising and not able to connect to each other. If you have any solution for that please let me know.

    Also, I executed the radio transmitter and receiver example in the SDK, Its path is <InstallFolder>\examples\peripheral\radio\receiver and <InstallFolder>\examples\peripheral\radio\transmitter. My question is is there some sort of API I can use to get the RSSI or the signal strength on the receiver side because I think the API's that you mentioned above are for BLE and this application does not use BLE. So if you had something that would be really helpful for my project.

  • Hi,

    BLE devices have various roles and you need both a Central and a Peripheral to make a link (See Ole Morten's comment here). This means that you cannot use the Nordic UART service Client example on both boards, but you need to use examples:

    <InstallFolder>\ble_peripheral\ble_app_uart

    on one board and

    <InstallFolder>\examples\ble_central\ble_app_uart_c

    on a different kits. The peripheral should then advertise and the central should scan. When the Central receives the advertising packets it will initiate the the connection. 

    To get the RSSI you can read the RADIO->RSSISAMPLE register (Reading this register directly will not work if you are using a softdevice since the softdevice is restricting your applications access to the radio peripheral).

  • Hello,

    First of all, while using the radio, I am not programming the soft device ( it was not there in the instructions on the infocenter page) and it is transmitting and receiving properly. How do I read the register as in what is the code for that? and if I cannot read it directly how should I go about it? 

Reply Children
  • Hi,

    If you are not using a Softdevice you can read the register directly. For example like this: uint32_t rssi = NRF_RADIO->RSSISAMPLE;

    To clarify, the Softdevice is Nordic's proprietary stack for BLE and ANT. If you use it, it will block and restrict access to certain peripherals as you can see in this list

  • /** @file
    *
    * @defgroup nrf_dev_radio_rx_example_main main.c
    * @{
    * @ingroup nrf_dev_radio_rx_example
    * @brief Radio Receiver example Application main file.
    *
    * This file contains the source code for a sample application using the NRF_RADIO peripheral.
    *
    */
    #include <stdint.h>
    #include <stdbool.h>
    #include <stdio.h>
    #include "radio_config.h"
    #include "nrf_gpio.h"
    #include "boards.h"
    #include "bsp.h"
    #include "app_timer.h"
    #include "nordic_common.h"
    #include "nrf_error.h"
    #include "app_error.h"
     #define NRF_LOG_MODULE_NAME "APP"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    
    #define APP_TIMER_PRESCALER      0                     /**< Value of the RTC1 PRESCALER register. */
    #define APP_TIMER_OP_QUEUE_SIZE  2                     /**< Size of timer operation queues. */
    
    static uint32_t                   packet;             /**< Packet to transmit. */
    
    
    /**@brief Function for initialization oscillators.
     */
    void clock_initialization()
    {
        /* Start 16 MHz crystal oscillator */
        NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_HFCLKSTART    = 1;
    
        /* Wait for the external oscillator to start up */
        while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
        {
            // Do nothing.
        }
    
        /* Start low frequency crystal oscillator for app_timer(used by bsp)*/
        NRF_CLOCK->LFCLKSRC            = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
        NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_LFCLKSTART    = 1;
    
        while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
        {
            // Do nothing.
        }
    }
    
    
    /**@brief Function for reading packet.
     */
    uint32_t read_packet()
    {
        uint32_t result = 0;
    
        NRF_RADIO->EVENTS_READY = 0U;
        // Enable radio and wait for ready
        NRF_RADIO->TASKS_RXEN = 1U;
    
        while (NRF_RADIO->EVENTS_READY == 0U)
        {
            // wait
        }
        NRF_RADIO->EVENTS_END = 0U;
        // Start listening and wait for address received event
        NRF_RADIO->TASKS_START = 1U;
    
        // Wait for end of packet or buttons state changed
        while (NRF_RADIO->EVENTS_END == 0U)
        {
            // wait
        }
    
        if (NRF_RADIO->CRCSTATUS == 1U)
        {
            result = packet;
        }
        NRF_RADIO->EVENTS_DISABLED = 0U;
        // Disable radio
        NRF_RADIO->TASKS_DISABLE = 1U;
    
        while (NRF_RADIO->EVENTS_DISABLED == 0U)
        {
            // wait
        }
        return result;
    }
    
    
    /**
     * @brief Function for application main entry.
     * @return 0. int return type required by ANSI/ISO standard.
     */
    int main(void)
    {
    	  
    	
        uint32_t err_code = NRF_SUCCESS;
    
        clock_initialization();
        APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, NULL);
    
        err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
        err_code = bsp_init(BSP_INIT_LED, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), NULL);
        APP_ERROR_CHECK(err_code);
    
        // Set radio configuration parameters
        radio_configure();
        NRF_RADIO->PACKETPTR = (uint32_t)&packet;
    
        err_code = bsp_indication_set(BSP_INDICATE_USER_STATE_OFF);
        NRF_LOG_INFO("Wait for first packet\r\n");
        APP_ERROR_CHECK(err_code);
        NRF_LOG_FLUSH();    
    
        while (true)
        {
            uint32_t received = read_packet();
    				
    				
            err_code = bsp_indication_set(BSP_INDICATE_RCV_OK);
    				uint32_t rssi = NRF_RADIO->RSSISAMPLE; //changes
            NRF_LOG_INFO("Packet was received\r\n");
            APP_ERROR_CHECK(err_code);
    
            NRF_LOG_INFO("The contents of the package is %u\r\n", (unsigned int)received);
    				NRF_LOG_INFO("The RSSI value is %u\r\n", (unsigned int)rssi); //changes
            NRF_LOG_FLUSH();
        }
    }
    

    Hello, Hope you are doing well. I made the changes in the code above in receiver. Only the lines with //changes have modified and I ran the transmitter and the receiver code. The problem I am facing is that in the serial port the RSSISAMPLE register is always showing me value 0. No matter the distance between the transmitter and receiver. I have attached a screenshot of the output. If you could tell me why I am getting the RSSI value as 0. It will be of great help.

    Also, If you have an example for the nRF51Dk using interrupts that I could work with for my project, it will really help me a lot.

    Thank You.

  • /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
     *
     * The information contained herein is property of Nordic Semiconductor ASA.
     * Terms and conditions of usage are described in detail in NORDIC
     * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
     *
     * Licensees are granted free, non-transferable use of the information. NO
     * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
     * the file.
     *
     */
    
    /** @file
    * @brief Radio Receiver example.
    *
    * @defgroup nrf_dev_radio_rx_example Radio Receiver example
    * @{
    * @ingroup nrf_examples_nrf6310
    *
    * @brief Example project on receiving data using the NRF_RADIO peripheral.
    *
    * The receiver is configured to continuously receive packets from the corresponding
    * transmitter project. The first payload byte of the packet is sent to P1 which can
    * be used, for example, to light up the LEDs on an nRFgo board.
    *
    * @image html example_board_setup_a.png "Use board setup A for this example."
    */
    #include <stdint.h>
    #include <stdbool.h>
    #include "nrf_delay.h"
    #include "radio_config.h"
    #include "nrf_gpio.h"
    
    #define MAX_PACKET_SIZE (50U)
    
    static uint8_t volatile packet[MAX_PACKET_SIZE];  ///< Received packet buffer
    
    /**
     * main() function
     * @return 0. int return type required by ANSI/ISO standard.
     */
    int main(void)
    {
        /* Start 16 MHz crystal oscillator */
        NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_HFCLKSTART = 1;
    
        /* Wait for the external oscillator to start up */
        while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
    
        // Set Port 1 as output
        nrf_gpio_range_cfg_output(8, 15);
    
        // Set radio configuration parameters
        radio_configure();
    
        // Enable the shortcut between getting an address match in the radio and starting the RSSI
        // This will enable the RSSI once on every received packet
        NRF_RADIO->SHORTS |= RADIO_SHORTS_ADDRESS_RSSISTART_Msk;
    
        nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, 0x55);
    
        NRF_RADIO->INTENSET = RADIO_INTENSET_READY_Msk | RADIO_INTENSET_END_Msk | RADIO_INTENSET_DISABLED_Msk;
    
        NVIC_EnableIRQ(RADIO_IRQn);
    
        nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, 0x55);
    
        // Set payload pointer
        NRF_RADIO->PACKETPTR = (uint32_t)packet;
        
        // Set the radio in RX once to start the receive procedure
        NRF_RADIO->TASKS_RXEN = 1;
      
        while(true)
        {
            // Nothing do be done in the main loop since everything is handled through interrupts
        }
    
    }
    
    void RADIO_IRQHandler()
    {
        // The very first time the radio is powered up we have to trigger the START task after getting the READY event
        // (note, this could also have been handled by a shortcut)
        if(NRF_RADIO->EVENTS_READY)
        {
            NRF_RADIO->EVENTS_READY = 0;
            
            // Start listening and wait for the END event
            NRF_RADIO->TASKS_START = 1;
        }
        
        // Every time the END event is triggered we have received a packet on the radio
        // Check the CRC status on the packet, do whatever we want with it, and trigger the START task again to enable the receiver for new data
        if(NRF_RADIO->EVENTS_END)
        {
            NRF_RADIO->EVENTS_END = 0;
            
            if(NRF_RADIO->CRCSTATUS == 1)
            {
                // Convert the RSSI data so that a single LED is lit depending on the signal strength
                // On low RSSI values LED 0 will be lit, higher RSSI values will light LED 1, LED 2 and so forth..
                nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, 1 << ((NRF_RADIO->RSSISAMPLE*10/128)-2));
    
                //nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, packet[2]);           
            }
            
            // Start listening and wait for the END event
            NRF_RADIO->TASKS_START = 1;
        }
    }
    
    /**
     *@}
     **/

    Hello MartinBL, 

    The above code is what I took from the zip file in the thread that you shared with me. When I try to run this code it gives me a lot of errors such as nrf_delay.h file missing etc. I copied the code and pasted it in place of the radio receiver code in the SDK keil file. I am getting the following errors.

    *** Using Compiler 'V5.06 update 6 (build 750)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin'
    Build target 'nrf51422_xxac'
    assembling arm_startup_nrf51.s...
    compiling main.c...
    ..\..\..\main.c(61): warning:  #223-D: function "nrf_gpio_port_write" declared implicitly
          nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, 0x55);
    ..\..\..\main.c(61): error:  #20: identifier "NRF_GPIO_PORT_SELECT_PORT1" is undefined
          nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, 0x55);
    ..\..\..\main.c(104): warning:  #223-D: function "nrf_gpio_port_write" declared implicitly
                  nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, 1 << ((NRF_RADIO->RSSISAMPLE*10/128)-2));
    ..\..\..\main.c(104): error:  #20: identifier "NRF_GPIO_PORT_SELECT_PORT1" is undefined
                  nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, 1 << ((NRF_RADIO->RSSISAMPLE*10/128)-2));
    ..\..\..\main.c(116): warning:  #1-D: last line of file ends without a newline
       **/
    ..\..\..\main.c: 3 warnings, 2 errors
    compiling system_nrf51.c...
    ".\_build\nrf51422_xxac.axf" - 2 Error(s), 3 Warning(s).
    Target not created.
    Build Time Elapsed:  00:00:04

    I was hoping you could help me debug them or give me an idea as to what needs to be done.

    Also if possible can you share with me a precompiled hex file of the above code. 

    That would be great.

    Thank You.

  • Hi,

    The code in the zip file is based on an old SDK and made for an old development kit. That is why you get the errors. You can try to just remove all calls to  nrf_gpio_port_write() and the line with nrf_delay.h. 

    You were probably already close to making it work with your own code, but you have forgotten to actually start the RSSI sampling and hence the RSSISAMPLE is always 0. As discussed in the thread in my link this line should do the trick: 

    NRF_RADIO->SHORTS |= RADIO_SHORTS_ADDRESS_RSSISTART_Msk;

    It will make the radio perform an RSSI measurement every time you receive a packet.

Related