# ESP32: I2S ADC read. Two inputs possible?

**URL:** <https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963>\
**Category:** Programming\
**Created:** [September 18, 2022, 5:12am UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963 "2022-09-18T05:12:39Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Matt\_TYGA](https://avatars.discourse-cdn.com/v4/letter/m/6bbea6/32.png) [@Matt\_TYGA](https://forum.arduino.cc/u/Matt_TYGA)\
**Post date:** [September 18, 2022, 5:12am UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963/1 "2022-09-18T05:12:39Z")

</div>

Hi Guys,

I need to read an analog input quickly.

`analogRead()` was way too slow and was messing the rest of my code up.

`adc1_get_raw(ADC1_CHANNEL_3)` was somewhat faster, but still not exactly what I was looking for.

I started looking at I2S, and although I don't understand it fully yet, I managed to whittle away at some code I found online and came up with this:

```cpp
#include <driver/i2s.h>

// I2S
#define I2S_SAMPLE_RATE (3000)
#define ADC_INPUT (ADC1_CHANNEL_4) //pin 32
#define I2S_DMA_BUF_LEN (8)

// The 4 high bits are the channel, and the data is inverted
size_t bytes_read;
uint16_t buffer[I2S_DMA_BUF_LEN] = {0};

unsigned long lastTimePrinted;
unsigned long loopTime = 0;

void i2sInit() {
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN),
    .sample_rate = I2S_SAMPLE_RATE, // The format of the signal using ADC_BUILT_IN
    .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // is fixed at 12bit, stereo, MSB
    .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
    .communication_format = I2S_COMM_FORMAT_I2S_MSB,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 2,
    .dma_buf_len = I2S_DMA_BUF_LEN,
    .use_apll = false,
    .tx_desc_auto_clear = false,
    .fixed_mclk = 0
  };

  i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
  i2s_set_adc_mode(ADC_UNIT_1, ADC_INPUT);
  i2s_adc_enable(I2S_NUM_0);
  adc1_config_channel_atten(ADC_INPUT, ADC_ATTEN_DB_11);
}

void setup() {
  Serial.begin(115200);

  i2sInit();
}

void loop() {

  unsigned long startMicros = ESP.getCycleCount();

  i2s_read(I2S_NUM_0, &buffer, sizeof(buffer), &bytes_read, 0);

  unsigned long stopMicros = ESP.getCycleCount();

  loopTime = stopMicros - startMicros;

  if (millis() - lastTimePrinted >= 100) {
    Serial.println("------------------");
    Serial.println(buffer[0] & 0x0FFF);
    Serial.println(loopTime);
    lastTimePrinted = millis();
  }
}

```

This works really well, and I'm happy. Need to study I2S some more to get a better grasp of it.

However, I'd like to read another analog input but I'm not sure how it can be done (if at all) using I2S.

I tried fiddling a bit but not really understanding it 100%. With any changes it either doesn't compile, or has no output.

Any ideas? Any snippets of code doing something similar?

Cheers,

Matt

---

<div class="post-metadata">

**Author:** ![johnerrington](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/johnerrington/32/340106_2.png) [@johnerrington](https://forum.arduino.cc/u/johnerrington)\
**Post date:** [September 18, 2022, 6:47am UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963/2 "2022-09-18T06:47:04Z")

</div>

Hi Matt, can you tell us what hardware you are using please?

---

<div class="post-metadata">

**Author:** ![Matt\_TYGA](https://avatars.discourse-cdn.com/v4/letter/m/6bbea6/32.png) [@Matt\_TYGA](https://forum.arduino.cc/u/Matt_TYGA)\
**Post date:** [September 18, 2022, 8:02am UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963/3 "2022-09-18T08:02:32Z")

</div>

@johnerrington  
Apologies for the vagueness.

ESP32 dev kit.

The analog value I am reading is from a 5k potentiometer. 3.3v on one side and ground on the other. The pot is limited in movement so the output values are 700 ~ 3200.

The pot is connected to a motor. The motor is driven by a TB6612FNG driver. The position of the motor is relative to rpm. The motor will control the movement of an exhaust valve in a motorcycle engine.

It's a small part of a bigger project, which is a capacitive discharge ignition system.

It all works well, so at tis point the hardware and code works well. I'd just like to know if I can add another pot and read it with I2S.

So that would be two 5k pots. Both 3.3V.

Hope that's enough info.

Cheers

Matt

---

<div class="post-metadata">

**Author:** ![Matt\_TYGA](https://avatars.discourse-cdn.com/v4/letter/m/6bbea6/32.png) [@Matt\_TYGA](https://forum.arduino.cc/u/Matt_TYGA)\
**Post date:** [September 18, 2022, 8:04am UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963/4 "2022-09-18T08:04:00Z")

</div>

The pot provides feedback on the motor position.

---

<div class="post-metadata">

**Author:** ![Matt\_TYGA](https://avatars.discourse-cdn.com/v4/letter/m/6bbea6/32.png) [@Matt\_TYGA](https://forum.arduino.cc/u/Matt_TYGA)\
**Post date:** [September 18, 2022, 8:48am UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963/5 "2022-09-18T08:48:40Z")

</div>

Hi,

Have now stumbled across another issue. While the I2S is doing it's thing, I can't read another analog input.

Tried a couple of things like `i2s_adc_disable(I2S_NUM_0);` and `i2s_stop(I2S_NUM_0);` but not having any joy.

A bit out of my depth.

Any clues?

Cheers,

Matt

---

<div class="post-metadata">

**Author:** ![johnerrington](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/johnerrington/32/340106_2.png) [@johnerrington](https://forum.arduino.cc/u/johnerrington)\
**Post date:** [September 19, 2022, 7:18am UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963/6 "2022-09-19T07:18:30Z")

</div>

> [@Matt\_TYGA](#):
>
> I'd just like to know if I can add another pot and read it with I2S.

Matt, I'm not understanding. What is the device you are connecting to the ESP32 via I2S?

> [@Matt\_TYGA](#):
>
> `analogRead()` was way too slow and was messing the rest of my code up.

2 pots should not be moving quickly enough that the time taken for an analog read would be an issue. Perhaps you are reading them too frequently?

---

<div class="post-metadata">

**Author:** ![Matt\_TYGA](https://avatars.discourse-cdn.com/v4/letter/m/6bbea6/32.png) [@Matt\_TYGA](https://forum.arduino.cc/u/Matt_TYGA)\
**Post date:** [September 19, 2022, 10:40am UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963/7 "2022-09-19T10:40:20Z")

</div>

@johnerrington  
I've just got the wiper from a potentiometer hooked up to pin 32. The potentiometer gives feedback from a motor so that I can monitor the position and turn it CW or CCW as necessary.

No, the pots don't move fast enough, but an `analogRead()` takes forever.

I times my loop() and it's running start to finish in 25us using the I2S to read the pot.

As to reading it too frequently....good point. Probably only need to read it every 100~200ms, so let me give that a try using the `adc1_get_raw(ADC1_CHANNEL_4)` function and see what happens.

Will report back on that.

However, regardless of the above, is it possible to set the I2S up to read two channels? I found the following in the Espressif docs:

`i2s_channel_disable` and `i2s_channel_enable`

I suspect that I have to use these somehow, and then change the config to a different pin while disabled, and then re-enable. Or something like that.

Cheers for your assistance.

Matt

---

<div class="post-metadata">

**Author:** ![gfvalvo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gfvalvo/32/1013044_2.png) [@gfvalvo](https://forum.arduino.cc/u/gfvalvo)\
**Post date:** [September 19, 2022, 11:13am UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963/8 "2022-09-19T11:13:17Z")

</div>

> [@Matt\_TYGA](#):
>
> I've just got the wiper from a potentiometer hooked up to pin 32.

That's not how I2S works. I2S is a digital interface, it doesn't read analog pot values. You need to connect an external ADC with an I2S interface to the ESP32.

There is a variant of I2S called TDM that allows connecting multiple devices. However, both the processor and external devices must support it. The Teensy 3.2 and above boards support TDM. Here's an example interface board: [https://oshpark.com/shared\_projects/2Yj6rFaW](https://oshpark.com/shared_projects/2Yj6rFaW)

PS - I'd probably go with a digital means of determining motor position. Perhaps a rotary encoder.

---

<div class="post-metadata">

**Author:** ![Idahowalker](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/idahowalker/32/238858_2.png) [@Idahowalker](https://forum.arduino.cc/u/Idahowalker)\
**Post date:** [September 19, 2022, 11:44am UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963/9 "2022-09-19T11:44:31Z")

</div>

[Inter-IC Sound (I2S) - ESP32 - — ESP-IDF Programming Guide latest documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/i2s.html) \<\<the docs

Some words from the docs,

ADC and DAC modes only exist on ESP32 and are only supported on I2S0. Actually, they are two sub-modes of LCD/Camera mode. I2S0 can be routed directly to the internal analog-to-digital converter(ADC) and digital-to-analog converter(DAC). In other words, ADC and DAC peripherals can read or write continuously via I2S0 DMA. As they are not an actual communication mode, the I2S driver does not implement them.

---

<div class="post-metadata">

**Author:** ![Matt\_TYGA](https://avatars.discourse-cdn.com/v4/letter/m/6bbea6/32.png) [@Matt\_TYGA](https://forum.arduino.cc/u/Matt_TYGA)\
**Post date:** [September 19, 2022, 11:56am UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963/10 "2022-09-19T11:56:53Z")

</div>

@gfvalvo  
Thanks. With my pot wiper as the input I am getting very fast reading of the input value and the value is exactly as expected, so using I2S for this "analog read" is working perfectly as far as I see it.

@Idahowalker  
Been through that doc a few times. Will need to go through a few more times to fully 'get it'. But thanks for the link.

I've since found some code that disables the I2S, does a regular `analogRead()` and then enables the I2S once more. Not just the disable and then enable as I tried. Here's the code required, although I haven't tested it yet:

```cpp
  i2s_adc_disable(I2S_NUM_0);
  i2s_driver_uninstall(I2S_NUM_0);
  analogRead(34);
  i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
  i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_0);
  i2s_adc_enable(I2S_NUM_0);

```

I'll give it a bash and see what happens.

Cheers,

Matt

---

<div class="post-metadata">

**Author:** ![a442509097](https://avatars.discourse-cdn.com/v4/letter/a/3da27b/32.png) [@a442509097](https://forum.arduino.cc/u/a442509097)\
**Post date:** [November 23, 2022, 5:21am UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963/11 "2022-11-23T05:21:10Z")

</div>

```cpp
  size_t bytesRead = 0;
  i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_6);
  i2s_read(I2S_NUM_0, (void*)samples, sizeof(samples), &bytesRead, portMAX_DELAY); 
FFT01 handle

-------------------------------------------------------

   bytesRead = 0;
  i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_7);
  i2s_read(I2S_NUM_0, (void*)samples02, sizeof(samples02), &bytesRead, portMAX_DELAY);
FFT02 handle

```

The difference is 3us, but two FFT processing will take a lot of time.

---

<div class="post-metadata">

**Author:** ![hazo](https://avatars.discourse-cdn.com/v4/letter/h/6a8cbe/32.png) [@hazo](https://forum.arduino.cc/u/hazo)\
**Post date:** [December 30, 2022, 3:04pm UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963/13 "2022-12-30T15:04:51Z")

</div>

I'm trying to read two channels from the internal esp32 adc. Dispite all the tips I didn't manage to get result. One channel works fine. Is it possible the post an example reading two adc channels via i2s?

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [June 28, 2023, 3:05pm UTC](https://forum.arduino.cc/t/esp32-i2s-adc-read-two-inputs-possible/1032963/14 "2023-06-28T15:05:46Z")

</div>

Closed on June 28, 2023, 3:05pm UTC

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.
