ESP32-S3 : Problem with ADC in continuous mode
Posted: Tue May 23, 2023 6:24 am
Good morning,
I am trying to use the ADC in continuous mode on an Esp32-S3 but I get a problem.
Can somebody help me please ?
Here is the explanation :
I am using an Esp32-S3-DevKitC-1 board for the development.
My goal is to sample an analog audio signal using the ADC1_7 pin of the board.
I would like to use a sampling frequency of 64000Hz and to record 4096 bytes (1024 32 bits samples) each time the ADC is started.
Before that, I just want to test the behaviour of the ADC with one 32 bits sample (4 bytes) recorded every 5 seconds.
So, I connect a Power Supply on the ADC1_7 so I canchange the value manualy and every 5 seconds, the ADC records one sample.
At the beginning, the Power Supply is set to 0v. So the ADC gives me 0v => Here everything is OK.
Unfortunately, after the first sample is recorded and displayed, if I set the Power Supply to 1,3V immediately,
the next sample is still 0v ( It should be 1,3V because I see using an oscilloscope that the value has changed), but the one after is 1,3V.
Maybe something is not configured correctly and I lose one sample.
Here is the configuration :
/* On efface le buffer qui contiendra les échantillons : */
memset(ptrSamples, 0x00, NBR_SAMPLES);
/* On initialise l'ADC : */
AdcHandle = NULL;
adc_continuous_handle_cfg_t AdcHandleConfig = {
.max_store_buf_size = NBR_SAMPLES,
.conv_frame_size = NBR_SAMPLES,
};
Err = adc_continuous_new_handle(&AdcHandleConfig, &AdcHandle);
if (Err != ESP_OK)
ESP_LOGI(TAG, "=====> AdMeasure : Adc Continuous Init Failed.");
else
{
/* On configure l'ADC : */
adc_continuous_config_t AdcConfig = { // @suppress("Invalid arguments")
.sample_freq_hz = 64000,
.conv_mode = ADC_CONV_SINGLE_UNIT_1, // On utilise uniquement l'ADC1.
.format = ADC_DIGI_OUTPUT_FORMAT_TYPE2, // On utilise le type 2. Pris dans l'exemple.
};
adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0};
AdcConfig.pattern_num = NBR_CHANNELS;
for (int ii = 0; ii < NBR_CHANNELS; ii++)
{
uint8_t unit = ADC_UNIT_1;
uint8_t ch = channel[ii] & 0x7;
adc_pattern[ii].atten = ADC_ATTEN_DB_11;
adc_pattern[ii].channel = ch;
adc_pattern[ii].unit = unit;
adc_pattern[ii].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH;
}
AdcConfig.adc_pattern = adc_pattern;
Err = adc_continuous_config(AdcHandle, &AdcConfig);
if (Err != ESP_OK)
ESP_LOGI(TAG, "=====> AdMeasure : Adc Continuous Configuration Failed.");
else
{
/* Mise en place de la calibration permettant d'avoir les résultats en mV directement :
* On utilise le schéma de calibration de type Courbe (Le seul proposé par la puce). */
adc_cali_curve_fitting_config_t Curve_Fitting;
Curve_Fitting.unit_id = ADC_UNIT_1;
Curve_Fitting.atten = ADC_ATTEN_DB_11;
Curve_Fitting.bitwidth = ADC_BITWIDTH_12;
Err = adc_cali_create_scheme_curve_fitting(&Curve_Fitting, &AdcCaliHandle);
if (Err != ESP_OK)
ESP_LOGI(TAG, "=====> AdMeasure : Fail to create the Curve Fitting Scheme.");
else
{
/* On démarre l'ADC : */
adc_continuous_start(AdcHandle);
}
}
}
Every 5 seconds, the sample is recorded this way :
int Voltage = 0;
memset(ptrSamples, 0x00, NBR_SAMPLES);
MeasureResult = adc_continuous_read(AdcHandle, ptrSamples, NBR_SAMPLES, &RealLen, 150);
if ((MeasureResult == ESP_OK) && (RealLen == NBR_SAMPLES))
{
adc_digi_output_data_t *Output = (adc_digi_output_data_t*)&ptrSamples[0];
MeasureResult = adc_cali_raw_to_voltage(AdcCaliHandle, Output->type2.data, &Voltage);
if (MeasureResult == ESP_OK)
ESP_LOGI(TAG, "=====> AdMeasure : Value %u.", Voltage);
}
I am trying to use the ADC in continuous mode on an Esp32-S3 but I get a problem.
Can somebody help me please ?
Here is the explanation :
I am using an Esp32-S3-DevKitC-1 board for the development.
My goal is to sample an analog audio signal using the ADC1_7 pin of the board.
I would like to use a sampling frequency of 64000Hz and to record 4096 bytes (1024 32 bits samples) each time the ADC is started.
Before that, I just want to test the behaviour of the ADC with one 32 bits sample (4 bytes) recorded every 5 seconds.
So, I connect a Power Supply on the ADC1_7 so I canchange the value manualy and every 5 seconds, the ADC records one sample.
At the beginning, the Power Supply is set to 0v. So the ADC gives me 0v => Here everything is OK.
Unfortunately, after the first sample is recorded and displayed, if I set the Power Supply to 1,3V immediately,
the next sample is still 0v ( It should be 1,3V because I see using an oscilloscope that the value has changed), but the one after is 1,3V.
Maybe something is not configured correctly and I lose one sample.
Here is the configuration :
/* On efface le buffer qui contiendra les échantillons : */
memset(ptrSamples, 0x00, NBR_SAMPLES);
/* On initialise l'ADC : */
AdcHandle = NULL;
adc_continuous_handle_cfg_t AdcHandleConfig = {
.max_store_buf_size = NBR_SAMPLES,
.conv_frame_size = NBR_SAMPLES,
};
Err = adc_continuous_new_handle(&AdcHandleConfig, &AdcHandle);
if (Err != ESP_OK)
ESP_LOGI(TAG, "=====> AdMeasure : Adc Continuous Init Failed.");
else
{
/* On configure l'ADC : */
adc_continuous_config_t AdcConfig = { // @suppress("Invalid arguments")
.sample_freq_hz = 64000,
.conv_mode = ADC_CONV_SINGLE_UNIT_1, // On utilise uniquement l'ADC1.
.format = ADC_DIGI_OUTPUT_FORMAT_TYPE2, // On utilise le type 2. Pris dans l'exemple.
};
adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0};
AdcConfig.pattern_num = NBR_CHANNELS;
for (int ii = 0; ii < NBR_CHANNELS; ii++)
{
uint8_t unit = ADC_UNIT_1;
uint8_t ch = channel[ii] & 0x7;
adc_pattern[ii].atten = ADC_ATTEN_DB_11;
adc_pattern[ii].channel = ch;
adc_pattern[ii].unit = unit;
adc_pattern[ii].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH;
}
AdcConfig.adc_pattern = adc_pattern;
Err = adc_continuous_config(AdcHandle, &AdcConfig);
if (Err != ESP_OK)
ESP_LOGI(TAG, "=====> AdMeasure : Adc Continuous Configuration Failed.");
else
{
/* Mise en place de la calibration permettant d'avoir les résultats en mV directement :
* On utilise le schéma de calibration de type Courbe (Le seul proposé par la puce). */
adc_cali_curve_fitting_config_t Curve_Fitting;
Curve_Fitting.unit_id = ADC_UNIT_1;
Curve_Fitting.atten = ADC_ATTEN_DB_11;
Curve_Fitting.bitwidth = ADC_BITWIDTH_12;
Err = adc_cali_create_scheme_curve_fitting(&Curve_Fitting, &AdcCaliHandle);
if (Err != ESP_OK)
ESP_LOGI(TAG, "=====> AdMeasure : Fail to create the Curve Fitting Scheme.");
else
{
/* On démarre l'ADC : */
adc_continuous_start(AdcHandle);
}
}
}
Every 5 seconds, the sample is recorded this way :
int Voltage = 0;
memset(ptrSamples, 0x00, NBR_SAMPLES);
MeasureResult = adc_continuous_read(AdcHandle, ptrSamples, NBR_SAMPLES, &RealLen, 150);
if ((MeasureResult == ESP_OK) && (RealLen == NBR_SAMPLES))
{
adc_digi_output_data_t *Output = (adc_digi_output_data_t*)&ptrSamples[0];
MeasureResult = adc_cali_raw_to_voltage(AdcCaliHandle, Output->type2.data, &Voltage);
if (MeasureResult == ESP_OK)
ESP_LOGI(TAG, "=====> AdMeasure : Value %u.", Voltage);
}