Page 1 of 1

[SOLVED] Esp32 I2S DMA ADC Reading strange signals.

Posted: Mon Sep 16, 2019 2:04 pm
by zekageri
Hello guys!
I experiencing some strange signals with i2s dma.
I'am using esp32 with PlatformIO in vscode IDE and using Arduino framework.


The esp is measuring a 4khz signal at 80.000hz right now.
And the signals that i'am getting are strange. ( The signal is coming from a signal generator ).

Code to reproduce:

Code: Select all

#include <Arduino.h>
#include <driver/i2s.h>
#include <driver/adc.h>
#include <soc/syscon_reg.h>
#include <WebSocketsServer.h>
#include <WiFi.h>
#include <Ethernet.h>
#include <WebAuthentication.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
/** SPIFFS LIBRARIES **/
#define FS_NO_GLOBALS
#include <FS.h>
#include "SPIFFS.h"

#define ADC_CHANNEL   ADC1_CHANNEL_6 // GPIO34
#define NUM_SAMPLES   100                       // number of samples
#define DUMP_INTERVAL 5000                     // dump samples at this interval
int32_t  last_millis = -DUMP_INTERVAL;
uint32_t collected_samples = 0;
uint32_t last_sample_count = 0;


void configure_i2s() {
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_ADC_BUILT_IN),  // I2S receive mode with ADC
    .sample_rate = 160000,                                                        // sample rate
    .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,                                 // 16 bit I2S
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,                                 // only the right channel
    .communication_format = I2S_COMM_FORMAT_I2S,                                  // I2S format
    .intr_alloc_flags = 0,                                                        // none
    .dma_buf_count = 8,                                                           // number of DMA buffers
    .dma_buf_len = NUM_SAMPLES,                                                   // number of samples
    .use_apll = 0,                                                                // no Audio PLL
  };
  // ADC channel 0 with 11db (divide by input 3.6)
  adc1_config_channel_atten(ADC_CHANNEL, ADC_ATTEN_11db);
  // 12 bit ADC
  adc1_config_width(ADC_WIDTH_12Bit);
  // install I2S 0 driver, using event queue
  i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
  // ADC should use ADC_CHANNEL
  i2s_set_adc_mode(ADC_UNIT_1, ADC_CHANNEL);
  // The raw ADC data is written in DMA in inverted form. This add aninversion:
  SET_PERI_REG_MASK(SYSCON_SARADC_CTRL2_REG, SYSCON_SARADC_SAR1_INV);
  // enable I2S ADC
  i2s_adc_enable(I2S_NUM_0);
  Serial.println("I2S started");
}

static void loop0(void * pvParameters){
  for( ;; ){
    Got_Ip_Handle();
    webSocket.loop();
    delay(1);
  }
}

void Web_Setup(){
    SPIFFS.begin() ? Serial.println("SPIFFS.OK") : Serial.println("SPIFFS.FAIL");
    WiFi.onEvent(WiFiEvent);
    ETH_begin();
    ethernet.config(ip1, nm1, gw1);
    server.begin();
    serverons();
    xTaskCreatePinnedToCore ( loop0, "v_getIMU0", 5000, NULL, 10, &TaskHandle_2, 0 );
    ws.onEvent(onWsEvent);
    server.addHandler(&ws);
    webSocket.begin();
}

void setup() {
  Serial.begin(115200);
  configure_i2s();
  Web_Setup();
}

static const inline void ADC_Sampling(){
  uint16_t i2s_read_buff[NUM_SAMPLES];
  int num = i2s_read_bytes(I2S_NUM_0, (char*)i2s_read_buff,  NUM_SAMPLES * sizeof(uint16_t), portMAX_DELAY);
  collected_samples += num / sizeof(uint16_t);
  if( (millis() - last_millis) >= DUMP_INTERVAL )
  {
    last_millis += DUMP_INTERVAL;
    last_sample_count = collected_samples;
    for (int i=0;i<NUM_SAMPLES;i++) {
      String json = "";
      json += String(i2s_read_buff[i] & 0xFFF);
      json += "}";
      webSocket.broadcastTXT(json.c_str(), json.length());
    }
  }
}

void loop() {
  ADC_Sampling();
}
The signals that iam getting:
(Last two pictures.)
The signals that iam expecting:
(First picture. This is using simple analog-read with a for loop.)

Re: Esp32 I2S DMA ADC Reading strange signals.

Posted: Wed Sep 18, 2019 7:32 am
by zekageri
The strange thing is, that if i use an other ADC1 PIN on the esp32
and read the i2s data from the first PIN, the signal is there with some more "noise".

Re: Esp32 I2S DMA ADC Reading strange signals.

Posted: Thu Sep 19, 2019 7:06 am
by zekageri
My problem is solved.
I just had to switch the channel format in the i2s config to "all left"
My i2S config is looks like this now:

Code: Select all

#define I2S_NUM         (0)
void configure_i2s(){
  i2s_config_t i2s_config = 
    {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN),  // I2S receive mode with ADC
    .sample_rate = samplingFrequency,                                             // sample rate
    .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,                                 // 16 bit I2S
    .channel_format = I2S_CHANNEL_FMT_ALL_LEFT,                                   // only the left channel
    .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),   // I2S format
    .intr_alloc_flags = 1,                                                        // none
    .dma_buf_count = 2,                                                           // number of DMA buffers
    .dma_buf_len = NUM_SAMPLES,                                                   // number of samples
    .use_apll = 0,                                                                // no Audio PLL
  };
  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_adc_mode(ADC_UNIT_1, ADC_CHANNEL);
  SET_PERI_REG_MASK(SYSCON_SARADC_CTRL2_REG, SYSCON_SARADC_SAR1_INV);
  i2s_adc_enable(I2S_NUM_0);
}
And the "Sampling and Plotting" function:

Code: Select all

#define DUMP_INTERVAL 2000
int32_t  last_millis = DUMP_INTERVAL;

static const inline void ADC_Sampling(){
  uint16_t i2s_read_buff[NUM_SAMPLES];
  String data;
  i2s_read_bytes(I2S_NUM_0, (char*)i2s_read_buff,  NUM_SAMPLES * sizeof(uint16_t), portMAX_DELAY);
  long Millis_Now = millis();
  if (((Millis_Now - Start_Sending_Millis) >= DUMP_INTERVAL)&& Chart_is_ok_to_Send_Data && olvasunk_e)
  {
    Start_Sending_Millis = Millis_Now;
    i2s_adc_disable(I2S_NUM_0);
    for (int i=0;i<NUM_SAMPLES;i++) {
      data = String((i2s_read_buff[i])/(float)40.95);
      data += "}";
      webSocket.broadcastTXT(data.c_str(), data.length());
    }
    i2s_zero_dma_buffer(I2S_NUM_0);
    i2s_adc_enable(I2S_NUM_0);
  }
}

Re: [SOLVED] Esp32 I2S DMA ADC Reading strange signals.

Posted: Thu Jun 10, 2021 7:47 am
by Samit Hasan
What we need to do for it if we just want to send multiple channel data at the same time ?