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

Glitches in adc sampling

I am sampling 3 sensors using the ADC peripheral, clocking it once every 15us to sample the 3 sensors (3us acquisition time + 2us processing = 5us per channel).

I use the easy DMA in double buffer to sample 402 samples and interrupt me so i can process them and prepare the DMA next buffer (interrupt every 402*15/3=2100us).

In the interrupt context, I copy the buffer into a continuous big buffer and to excel and this is what i see:

when i stop the adc sampling and start it again (vertical spike above), i sometimes have a glitch that looks as if one sample is missed and i thus get channel 2 instead of 1 as shown in the above image. The vertical spike seen in the image is just a marker i add to the debug software buffer to mark where i re-enabled adc sampling.

The image above contains ~6 concatenated buffers (each buffer holds 402 samples = 134 samples from each of the 3).

Following is the code i use:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// this is double buffer hooked to the adc pointer. it is used to sample 3 channels
static nrf_saadc_value_t adc_3_channels_double_buffer[2][402];
static uint32_t adc_3_channels_double_buffer_index = 0;
//this is a debug buffer holding 50 adc buffers
static nrf_saadc_value_t adc_3_channels_debug_buffer[402*50];
static int adc_3_channels_debug_buffer_index = 0;
// tis function is called to start adc sampling
void start_adc_sampling(void)
{
// NRF_TIMER1 is a timer used to clock adc sampling of the 3 sensors we have - clock every 15us
NRF_TIMER1->MODE = (TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos);
NRF_TIMER1->PRESCALER = 4; // 1mhz --> 1us
NRF_TIMER1->CC[0] = 15;
NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk;
// ppi #6: connect adc timer to adc sampling
NRF_PPI->CH[5].EEP = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[0];
NRF_PPI->CH[5].TEP = (uint32_t) &NRF_SAADC->TASKS_SAMPLE;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

In the code i have '#if 0' in line 131 commenting out the bit of code that causes the glitch problem.

When i remove it i see no glitches.

In the blocked code shuts down the ADc in order to save power.

It blocked code is art of code within the ADC interrupt that is trigered when someone set 'flag_stop_sampling' to 1 in order to stop ADC sampling.

My point is - if i disable the ADC peripheral (as i do) in between samples and later on wake it up again and re configure the entire logic - how come i see glitches of channels in my buffer.

My target was to make my software implementation to do the sampling regardless of softdevice and other tasks interrupts.

Parents
  • Hello,

    Moving the typedef uint32_t ret_code_t somehow solved the issue. I was able to compile after changing ble_advertising_start_with_map() ble_advertising_start() on line 765 in ble.c. where did you declare ble_advertising_start_with_map()? I could not find it.

     

    I was never able to compile in IAR. I am sorry, but I have had some bad experience with IAR before, so I ported the project to Keil. However, after programming the slightly modified project to Keil, and programming it, I can't see any logging. I used the preprocessor defines from IAR, but with no luck.

     

    Can you try to unzip the project in a fresh unmodified version of the SDK and see whether you can make it run (in IAR)? If not, please try to find out what files you have to modify to make it run, and let me know.

     

    Best regards,

    Edvin

Reply
  • Hello,

    Moving the typedef uint32_t ret_code_t somehow solved the issue. I was able to compile after changing ble_advertising_start_with_map() ble_advertising_start() on line 765 in ble.c. where did you declare ble_advertising_start_with_map()? I could not find it.

     

    I was never able to compile in IAR. I am sorry, but I have had some bad experience with IAR before, so I ported the project to Keil. However, after programming the slightly modified project to Keil, and programming it, I can't see any logging. I used the preprocessor defines from IAR, but with no luck.

     

    Can you try to unzip the project in a fresh unmodified version of the SDK and see whether you can make it run (in IAR)? If not, please try to find out what files you have to modify to make it run, and let me know.

     

    Best regards,

    Edvin

Children
  • Hi Edvin, I gave up on trying to make this work and switched to another approach where i need to sample just one ADC channel instead of 3 and this seems to work for me. 

    However, in order to do that i need to disable all interrupts for a duration of 3us once every 500us on average. Will that cause any problem to the soft device proper functionality?

  • Hello,

    Ususally, we don't recommend disabling softdevice interrupts. If the softdevice misses a timing critical interrupt it may cause an application reset. I know that 3 µs is a very short amount of time, and it may not cause any harm, but I can't say that "it's fine".

     

    You will  have to do some testing. If it works for your application, and you don't run into any softdevice issues, then it will probably be fine.

     

    Best regards,

    Edvin