1

I have a problem measuring a signal from ADC using I2S.

    // Initialization of I2S buffer
    uint16_t* i2sReadBuffer = (uint16_t*)calloc(DMA_BUFFER_LEN, sizeof(uint16_t));
    size_t bytesRead;

    while (1) {

        // Read data in the buffer till its not full
        i2s_read(ADC_I2S_NUM, (void*)i2sReadBuffer, DMA_BUFFER_LEN * sizeof(uint16_t), &bytesRead, portMAX_DELAY);

        for (size_t i = 0; i < DMA_BUFFER_LEN; i++) {
            uint16_t value = i2sReadBuffer[i];
            printf("%d\n", value);
        }
    }

I have successfully gotten a signal and filtered it, but the filter parameters are set, so that the sampling frequency is around 1kHz. ECG signal before and after filtering

It means that the actual sampling frequency is 1kHz, but not 10 kHz isn't it? If not, why filtering works only with such parameters?

Matlab processing code:

xlsFile = 'ecg_data.xlsx';

[num, txt, raw] = xlsread(xlsFile);

input = cell2mat(raw);

a = fir1(100, [0.06 0.14], 'stop');

in = input(:, 2);

filtered = filter(a, 1, in);

y = fft(filtered);

N = length(y);                   % Length of a vector

f = (0:N - 1 ) * 100 / N;        % Frequency vector

m = abs(y);                      % Magnitude
% y(m<1e-6) = 0;
p = unwrap(angle(y));            % Phase

X_vector = (1:3:N) / ((N - 1) * 1e-3);

title('Frequency spectrum')

subplot(2,2,1)
plot(f,m)
title('Magnitude')
ax = gca;
ax.XTick = X_vector;

subplot(2,2,2)
plot(f,p*180/pi)
title('Phase')
ax = gca;
ax.XTick = X_vector;

subplot(2,2,3)
plot(in)
title('Input singal')
xlabel('msec')
ax = gca;

subplot(2,2,4)
plot(filtered)
title('Filtered signal')
ax = gca;

I2S ADC configuration is below

#define SAMPLING_FREQ 10000
#define ADC_CHANNEL ADC1_CHANNEL_4
#define ADC_UNIT ADC_UNIT_1
#define DMA_BUFFER_LEN 1024
#define ADC_I2S_NUM I2S_NUM_0

static void init_i2s_adc(void) {
    i2s_config_t i2s_config = 
    {
        .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN),
        .sample_rate = SAMPLING_FREQ,                                            
        .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,                            
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,                              
        .communication_format = I2S_COMM_FORMAT_STAND_MSB, 
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,                                                 
        .dma_buf_count = 8,                                                    
        .dma_buf_len = DMA_BUFFER_LEN,
        .tx_desc_auto_clear = 1,                                            
        .use_apll = 0,                                                       
    };
    adc1_config_channel_atten(ADC_CHANNEL, ADC_ATTEN_11db);
    adc1_config_width(ADC_WIDTH_12Bit);
    i2s_driver_install(ADC_I2S_NUM, &i2s_config, 0, NULL);

    i2s_set_clk(ADC_I2S_NUM, SAMPLING_FREQ, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO);
    i2s_set_adc_mode(ADC_UNIT, ADC_CHANNEL);
    i2s_adc_enable(ADC_I2S_NUM);
}
  • The filtering works with an assumed sampled rate of 1kHz because it was designed that way through the `fir1(100, [0.06 0.14], 'stop')` call. The `0.06` and `0.14` values are normalized (by the sampling rate) frequencies. So the filter will attenuate frequency components in the 60-140Hz band. You could make it work at another sampling rate by updating those values according to the desired rate. Keep in mind however that if you increase the sampling rate, you'd also need to increase the filter order to keep similar filtering performance. – SleuthEye Dec 28 '20 at 03:49
  • @SleuthEye But the sampling rate, set by me, is 10 times higher... – Vitalii Vorobii Dec 28 '20 at 14:25
  • I'm not familiar with the esp32, so I can't provide an answer with respect to that part of your question. However you could presumably measure the actual sampling rate by counting the number of samples in the period of a sinusoidal tone with a known frequency and see if it matches what you configured it to. – SleuthEye Dec 28 '20 at 17:03
  • @SleuthEye Thank you, real sampling was lower in like 60 times. So it allowed MATLAB to filter 50-60 Hz noise and at the same time not to distort ECG. – Vitalii Vorobii Dec 29 '20 at 20:26

0 Answers0