ESB "Hiccup"

I am currently working on a project in which I want to transmit audio wirelessly from one nRF chip to another. Currently I am using the nRF Dongle to act as the transmitter and a nRF-DK board as the receiver. I have finally gotten them to talk to each other through ESB, and the transmitter is currently sending a digital sine wave table out to the receiver which is then using SPI to interface with an external DAC. The problem lies in these "hiccups" that occur periodically, and while the frequency of the wave is something I can control, I can't seem to get rid of these hiccups. I am new to the Nordic development environment and I don't have much experience in the ESB protocol, and so I'm not sure if it's a hardware limitation, an acknowledgement issue, or something that I've overlooked in my code. At some point, the transmission will live in an SAADC callback function. That version works in terms of the signal path, but is experiencing the same problem that is outlined here. The problem is shown below, and here is my initialization of ESB, along with the transmission. Any help is greatly appreciated!

uint32_t esb_init( void )
{
    uint32_t err_code;
    uint8_t base_addr_0[4] = {0xE7, 0xE7, 0xE7, 0xE7};
    uint8_t base_addr_1[4] = {0xC2, 0xC2, 0xC2, 0xC2};
    uint8_t addr_prefix[8] = {0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8 };

    nrf_esb_config_t nrf_esb_config         = NRF_ESB_DEFAULT_CONFIG;
    nrf_esb_config.protocol                 = NRF_ESB_PROTOCOL_ESB_DPL;
    nrf_esb_config.retransmit_delay         = 100;
    nrf_esb_config.bitrate                  = NRF_ESB_BITRATE_2MBPS;
    nrf_esb_config.event_handler            = nrf_esb_event_handler;
    nrf_esb_config.mode                     = NRF_ESB_MODE_PTX;
    nrf_esb_config.selective_auto_ack       = true;
    nrf_esb_config.payload_length           = 2;
    nrf_esb_config.retransmit_count         = 1;

    err_code = nrf_esb_init(&nrf_esb_config);

    VERIFY_SUCCESS(err_code);

    err_code = nrf_esb_set_base_address_0(base_addr_0);
    VERIFY_SUCCESS(err_code);

    err_code = nrf_esb_set_base_address_1(base_addr_1);
    VERIFY_SUCCESS(err_code);

    err_code = nrf_esb_set_prefixes(addr_prefix, NRF_ESB_PIPE_COUNT);
    VERIFY_SUCCESS(err_code);

    return err_code;
}

int i = 0;

    while (true)
    {
        tx_payload.data[0] = SineWave[i] & 0xFF;
        tx_payload.data[1] = SineWave[i] >> 8;
        tx_payload.noack = true;
        nrf_esb_write_payload(&tx_payload);

        i++;

        if (i >= 80)
        {
            i = 0;
        }

        nrf_delay_ms(50);
    }

 

  • Hi

    I assume you have tested that this noise has nothing to do with the radio transmission, and is actually present on the sampled signal before it is transmitted over the air?

    Have you tried to measure the analog signal with an oscilloscope to see if the noise is present on the input, or if it is somehow added by the sampling process itself? 

    There are various external and internal factors that could affect noise on the input. Since this is more of a hardware question I would recommend opening a new ticket, explain the problem, and include the schematic design of your board so we can check if it looks good. 

    The complete ADC configuration could also be helpful. One way to check if the noise is caused by the ADC itself is to enable oversampling on the ADC, and see if the noise is reduced. 

    Best regards
    Torbjørn

  • So the noise is not being injected at the input, as this is also happening with a function generated wave going through the ADC. I can post the ADC config here however, to see if there is something I can change in that. 

    void saadc_init(void)
    {
        ret_code_t err_code;
        nrf_saadc_channel_config_t channel_config =
            NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
    
        err_code = nrf_drv_saadc_init(NULL, saadc_callback);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_init(0, &channel_config);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
    
    }
    
    void saadc_sampling_event_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_drv_ppi_init();
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
        timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
        err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, timer_handler);
        APP_ERROR_CHECK(err_code);
    
        /* setup m_timer for compare event every 20us */
        uint32_t ticks = nrf_drv_timer_us_to_ticks(&m_timer, 40);
        nrf_drv_timer_extended_compare(&m_timer,
                                       NRF_TIMER_CC_CHANNEL0,
                                       ticks,
                                       NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                       false);
        nrf_drv_timer_enable(&m_timer);
    
        uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,
                                                                                    NRF_TIMER_CC_CHANNEL0);
        uint32_t saadc_sample_task_addr   = nrf_drv_saadc_sample_task_get();
    
        /* setup ppi channel so that timer compare event is triggering sample task in SAADC */
        err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_ppi_channel_assign(m_ppi_channel,
                                              timer_compare_event_addr,
                                              saadc_sample_task_addr);
        APP_ERROR_CHECK(err_code);
    }
    
    void saadc_sampling_event_enable(void)
    {
        ret_code_t err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);
    
        APP_ERROR_CHECK(err_code);
    }

  • Hi 

    Sorry for the slow response, I have been out of office for the last couple of weeks. 

    In order to check if the noise is caused by the ADC itself you could try to enable oversampling, and see if the noise is reduced?

    Theoretically every doubling of the oversampling (corresponding to increasing the oversampling setting by 1) should reduce the ADC noise by half a LSB. 

    You can change the oversampling setting through the NRFX_SAADC_CONFIG_OVERSAMPLE parameter in sdk_config.h. Try a value of 4 for instance, and you should see a reduction of noise of about 2 LSB compared to an oversample setting of 0. 

    Best regards
    Torbjørn

Related