Page 1 of 1

every 256th sample is missing when I read ADC via I2S with DMA

Posted: Mon Dec 14, 2020 5:09 pm
by joges1987
Hello guys,

I want to use the ESP32s internal DAC and ADC with a very high sampling rate (200kHz), so I use the I2S with DMA.
When I connected the DAC to the ADC and I sent a 20 kHz sine wave (10 samples per period) to the DAC, I got an ALMOST correct result. I can see in my ADC data a period is repeated every 10 steps.
However, it happens that some samples are omitted. This happens every 255 sample.

Example Data:

Code: Untitled.txt Select all


Samp;  AdVolt;
87; 1.83;
88; 2.06;
89; 2.27;
90; 2.27;
91; 2.06;
92; 1.82;
93; 1.55;
94; 1.39;
95; 1.39;
96; 1.55;
97; 1.82;
98; 2.06;
99; 2.27;
100; 2.06; // ERROR: here should be the value 2.27 instead
101; 1.82;
102; 1.55;
103; 1.39;
104; 1.39;
105; 1.55;
106; 1.82;
107; 2.06;
108; 2.27;
109; 2.27;
110; 2.06;
And this error ocurres 255 samples later again:

Code: Untitled.txt Select all


337;     2.06;
338; 2.27;
339; 2.27;//period start
340; 2.06;
341; 1.82;
342; 1.55;
343; 1.39;
344; 1.38;
345; 1.55;
346; 1.82;
347; 2.06;
348; 2.27;//end (10 samples, correct period)
349; 2.27; //period starts
350; 2.06;
351; 1.82;
352; 1.55;
353; 1.39;
354; 1.55;// ERROR: here should be a value arround 1.38 instead
355; 1.82;
356; 2.06;
357; 2.27; //period has only 9 samples, 1 was omitted
358; 2.27;
359; 2.06;
The DAC seems not to be the problem because I deactivated it and used a DebugPin instead and still the same error ocurred.
I also changed the buffer size and the sampling rate, but without any success.
Anybody has an explanation for this problem or knows how to solve it?

Here the code of my configuration:

Code: Untitled.c Select all


#include <Arduino.h>
#include <driver/i2s.h>
#include "prj_FastDmaAdc.h"//module header

#define ADC_CHANNEL ADC1_CHANNEL_0 // GPIO36
#define NUM_SAMPLES 1000 // number of samples in buffer

void InitI2S (){
i2s_config_t i2s_config = {
//I2S with ADC and DAC
.mode = (i2s_mode_t) (I2S_MODE_MASTER
| I2S_MODE_RX
| I2S_MODE_TX
| I2S_MODE_DAC_BUILT_IN
| I2S_MODE_ADC_BUILT_IN),
.sample_rate = (200000),
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S_MSB,
.intr_alloc_flags = 0,
.dma_buf_count = 4,
.dma_buf_len = NUM_SAMPLES,
.use_apll = false,
};

adc1_config_channel_atten (ADC_CHANNEL, ADC_ATTEN_11db);

adc1_config_width (ADC_WIDTH_12Bit);

i2s_driver_install (I2S_NUM_0, &i2s_config, 0, NULL);

i2s_set_dac_mode (I2S_DAC_CHANNEL_BOTH_EN);

i2s_set_adc_mode (ADC_UNIT_1, ADC_CHANNEL);

i2s_adc_enable (I2S_NUM_0);

}

int GetAdcData(float* po_AdcValues)
{
uint16_t i2s_read_buff[NUM_SAMPLES*2];
size_t num_bytes_read =0;

i2s_read( I2S_NUM_0, (void*) i2s_read_buff, NUM_SAMPLES * 2* sizeof (uint16_t), &num_bytes_read, portMAX_DELAY);

int NumSamps = num_bytes_read/(2*sizeof (uint16_t));

for (int i=0; i< NumSamps; i++)
{ //convert 12 bits to voltage
po_AdcValues[i] = 3.3* ( (float) (i2s_read_buff[i*2]& 0x0FFF)) /0x0FFF;
}
return NumSamps; //return number of the read samples
}
Thank your very much for helping me!
Joseph