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

Issues in reading analog mic data over SAADC pin of nRF52810.

I have an expansion board by ST mounting an analog mic (MP23ABS1). The mic out pin (via a diff. amplifier) is given on a connector. I take that signal and feed it to the AIN5 (P0.29) on nrf52810. I want to continuously sample the analog mic data at 8000Hz and store the data in a buffer and transmit that over BLE. I've implemented a solution but I'm not getting the right values (already tested analog signal independently over oscilloscope). What I have done is, I initialized the ADC and the configured the channel with default values in single ended mode. Created an application timer with repeat mode and period of timer as 0.125ms(1/8000Hz) and in the timer callback function I sample the ADC(nrf_drv_saadc_sample()). After buffer (96 bytes of int16_t) is full, I check for NRFX_SAADC_EVT_DONE  and convert the buffer, in the saadc handler. And this process repeats after every 0.125ms.

The issue is that the buffer is filled with starting 4-5 bytes as 0x0000 and some random values in between as 0x0000 which get filled gradually. Also the digital values don't change much with changes in the sound I make (while I check in the buffer in the debug mode). Can you help me identify where I am going wrong with the implementation ?

Init Routine:

bool SDL_Mic_Init(void)
{
  uint32_t ret_code=false;
  
  
  ret_code=nrf_drv_saadc_init(NULL, mic_callback);  //ADC Initialization
  
  if(ret_code==NRFX_SUCCESS)
  { 
    nrf_saadc_channel_config_t adc_channel=NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(MIC_INPUT_DATA_PIN);
    
    ret_code=nrf_drv_saadc_channel_init(MIC_ADC_CHANNEL,&adc_channel);
    if(ret_code==NRFX_SUCCESS)
      ret_code=true;
    
   app_timer_create(&test_timer,APP_TIMER_MODE_REPEATED,sampling_callback);
    
    nrf_saadc_continuous_mode_enable(2000); //for 8K sample rate (16000000/2000=8000Hz)
  }
  
  return ret_code;
}

When I send a start streaming command from app

bool Mic_DataAcq_Start(void)
{
  uint32_t ret_code=false;
  //Set the buffer in RAM that will acquire adc data(raw datamic)
    ret_code=nrf_drv_saadc_buffer_convert(mic_handler.audio_sample , AUDIO_SAMPLES_BUFFER_SIZE);
        if(ret_code==NRFX_SUCCESS)
    {
        ret_code=true;
    }
    
    app_timer_start(test_timer, ticks, NULL); //ticks=APP_TIMER_TICKS(0.125)

  return ret_code;
}

After 0.125ms, timer handler will call nrf_drv_saadc_sample() and after buffer is full the following will be called

void mic_callback(const nrf_drv_saadc_evt_t  * p_event)
{
  if(p_event->type==NRFX_SAADC_EVT_DONE)
  {
    //copy mic_handler.audio_samples buffer into a copy buffer
   // memcpy(SRV_DATA_state.txLogFrame3.txStreamFrame.mic_rawaudio.audio_raw_val, mic_handler.audio_sample, AUDIO_SAMPLES_BUFFER_SIZE);
    //Set a flag to indicate FSM process that data is ready to be sent over BLE
    //MSG_SetFlag(MSG_TYPE_SRV_DATA, DATA_FLAG_AMIC_DATA);
    
    nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer , AUDIO_SAMPLES_BUFFER_SIZE);
  }
  
}

Related