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

SPI communication and BLE advertising data with nRF52 DK

Hi everyone!

I have already developed a couple projects in nRF52 DK and the result was quite messy. I want to make it right this time and that's why I am requesting your help.

I am using nRF52 DK and SDK 13.0.0. and Eclipse Mars 2 (C/C++) with the setup explained in this Devzone Tutorial.
My goal is to create a project starting from some examples, modifying and merging them. I intend to comunicate with a SPI peripheral and send the recieved data through BLE advertising mode (broadcast).

I have compiled and tested the SPI example and it works just fine. Now, I need to send that data over BLE advertising. The requirement is it to be sent at least 10 times every second.

I would be very grateful if you could guide me on this. Some pages that I should read, any example that broadcasts data over BLE, any question already answered on this topic (I have searched and I did not find that much), any help will be very welcome. I really want to learn how to use Nordic hardware but my previous experience has only been frustrating so far.

Thank you so much for your time!

AGB

Parents
  • I am almost done. I fully integrated both projects together and now the readings are being send properly. I just have a few matters that I would like to solve:

    The LOG is printing an ERROR:FATAL somewhere in my code. After debugging I found out that it is this:

    err_code = sd_ble_gap_adv_start(&m_adv_params, BLE_CONN_CFG_TAG_DEFAULT);

    In the debug I got err_code = 7, which according to the documentation is NRF_ERROR_INVALID_PARAM. My m_adv_params are:

    m_adv_params.type        = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;
    m_adv_params.p_peer_addr = NULL;
    m_adv_params.fp          = BLE_GAP_ADV_FP_ANY;
    m_adv_params.interval    = NON_CONNECTABLE_ADV_INTERVAL;
    m_adv_params.timeout     = APP_CFG_NON_CONN_ADV_TIMEOUT;

    They are the default ones of the ble_app_beacon example and they had no errors before.

    Any idea?

  • What do you mean by readings are send properly?? how you are sending your spi data??

    Are you advertising it into beacon?

  • ok so try this.

    1. make one function adv_update(). and call this function when ever you are getting spi data  or whenever you wish to advertise your spi data into beacon info.

    2. structure for this adv_update is

    uint8_t m_update[] =
    {
    APP_DEVICE_TYPE, // Manufacturer specific information. Specifies the device type in this // implementation.
    APP_ADV_DATA_LENGTH, // Manufacturer specific information. Specifies the length of the
    APP_BEACON_UUID, // 128 bit UUID value.
    APP_MAJOR_VALUE,
    APP_MINOR_VALUE, // Major arbitrary value that can be used to distinguish between Beacons.
    APP_MEASURED_RSSI // Manufacturer specific information. The Beacon's measured TX power in
    };

    3.  rest of the adv_update function is same as your advertising_init function. just replace  manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info; with  

    manuf_specific_data.data.p_data = (uint8_t *) m_update;

    where m_update parameters are listed below.

    m_update[16] = rx_buffer[0];
    m_update[17] = rx_buffer[1];

    m_update[18] = rx_buffer[2];

    m_update[19] = rx_buffer[3];

    4. Set these vales as 0x00 initially 

    #define APP_MAJOR_VALUE 0x00,0x00 
    #define APP_MINOR_VALUE 0x00, 0x00  

    5. After changes you will be able to get your spi data(4 bytes) stored in rx_buffer as mjor and minor number field.

  • I added the function and structure and changed the main() like this:

    int main(void)
    {
        // Initialize.
        log_init();
        timers_init();
        leds_init();
        ble_stack_init();
        advertising_init();
    
        bsp_board_leds_init();
    
    	nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    	spi_config.ss_pin   = SPI_SS_PIN;
    	spi_config.miso_pin = SPI_MISO_PIN;
    	spi_config.mosi_pin = SPI_MOSI_PIN;
    	spi_config.sck_pin  = SPI_SCK_PIN;
    	APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    
    	while (1)
    	{
    		// Reset rx buffer and transfer done flag
    		memset(m_rx_buf, 0, m_length);
    		spi_xfer_done = false;
    
    		APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, NULL, 0, m_rx_buf, m_length));
    
    		NRF_LOG_FLUSH();
    
    		bsp_board_led_invert(BSP_BOARD_LED_0);
    
    		nrf_delay_ms(10);
    
            adv_update();
            advertising_start();
    
            if (NRF_LOG_PROCESS() == false)
            {
                //power_manage();
    
                NRF_LOG_INFO("Something sent.\r\n");
    
            }
        }
    }

    Sadly, I keep getting the same ERROR:FATAL in the LOG.

Reply
  • I added the function and structure and changed the main() like this:

    int main(void)
    {
        // Initialize.
        log_init();
        timers_init();
        leds_init();
        ble_stack_init();
        advertising_init();
    
        bsp_board_leds_init();
    
    	nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    	spi_config.ss_pin   = SPI_SS_PIN;
    	spi_config.miso_pin = SPI_MISO_PIN;
    	spi_config.mosi_pin = SPI_MOSI_PIN;
    	spi_config.sck_pin  = SPI_SCK_PIN;
    	APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    
    	while (1)
    	{
    		// Reset rx buffer and transfer done flag
    		memset(m_rx_buf, 0, m_length);
    		spi_xfer_done = false;
    
    		APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, NULL, 0, m_rx_buf, m_length));
    
    		NRF_LOG_FLUSH();
    
    		bsp_board_led_invert(BSP_BOARD_LED_0);
    
    		nrf_delay_ms(10);
    
            adv_update();
            advertising_start();
    
            if (NRF_LOG_PROCESS() == false)
            {
                //power_manage();
    
                NRF_LOG_INFO("Something sent.\r\n");
    
            }
        }
    }

    Sadly, I keep getting the same ERROR:FATAL in the LOG.

Children
  • Any other idea? I found a nasty solution that solves that and the only remaining issue: deleting the APP_ERROR_CHECK() function that throws the error... I know, I know, that is not a solution, but for some reason the BLE advertising beacon is working and sending the data that I need it to send, so it can be a temporary solution.

    The other one was that I needed it to send at least 10 samples/second, for some reason, after erasing de error check now it works at full speed. Before, it was like stuck, it would be sending 3 readings per second and I could do nothing to change that.

    So, what are your feelings about this? Do you thing that the error could cause a corruption of the MCU or something worse?

  • yes it could be. If you have some special need to do error checking then only do that.. 

Related