[SOLVED] Esp32 I2S DMA ADC Reading strange signals.

zekageri
Posts: 17
Joined: Mon Sep 03, 2018 11:04 am

[SOLVED] Esp32 I2S DMA ADC Reading strange signals.

Postby zekageri » Mon Sep 16, 2019 2:04 pm

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.)
Attachments
Képernyőfelvétel (9).png
Signal using analogRead() with a for loop.
Képernyőfelvétel (9).png (187.58 KiB) Viewed 204 times
Képernyőfelvétel (13).png
Signal using i2s DMGA
Képernyőfelvétel (13).png (196.34 KiB) Viewed 204 times
Képernyőfelvétel (12).png
Signal using i2s DMGA
Képernyőfelvétel (12).png (194.8 KiB) Viewed 204 times
Last edited by zekageri on Wed Sep 25, 2019 6:36 am, edited 1 time in total.

zekageri
Posts: 17
Joined: Mon Sep 03, 2018 11:04 am

Re: Esp32 I2S DMA ADC Reading strange signals.

Postby zekageri » Wed Sep 18, 2019 7:32 am

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".

zekageri
Posts: 17
Joined: Mon Sep 03, 2018 11:04 am

Re: Esp32 I2S DMA ADC Reading strange signals.

Postby zekageri » Thu Sep 19, 2019 7:06 am

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);
  }
}

Who is online

Users browsing this forum: DrSegatron and 9 guests