Skip to content

Commit 8fbfefb

Browse files
authored
ESP32 onboard ADC for more than 2 channels. (#1633)
* Reapply previous changes * Updating ESP32 continuous ADC driver work in progress * ESP32 onboard ADC, multichannel sorted 1-6 channels tested on ESP32 module other modules not tested yet
1 parent 494aaa8 commit 8fbfefb

File tree

6 files changed

+900
-518
lines changed

6 files changed

+900
-518
lines changed

examples/README_ESP32.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
# ESP32 Configuration
22

33
If you are using ESP32 by Espressif Systems version 3.0.0 and later, audio tools will use the new adc_continuous API.
4-
This board option is under development and changing.
54

65
For the adc_continuous API, audio tools provides the following options:
76

87
- **sample_rate** (per channel), the effective ADC sampling rate is the number of channels x sample rate and can be:
98
- ESP32: 20kHz to 2MHz
10-
- other ESP32 eg. ESP32S3 611Hz to 83kHz
9+
- ESP32 S2, S3, H2, C6, C3: 611Hz to 83.333kHz
1110

1211
for example:
1312

@@ -55,6 +54,12 @@ for example:
5554
- D5 on Adafruit ESP32-S3 is ADC_CHANNEL_4
5655
- D6 on Adafruit ESP32-S3 is ADC_CHANNEL_5
5756

57+
- **buffer_size**
58+
- maximum is 2048
59+
- minimum is number of channels
60+
- number needs to be devisible by number of channels
61+
- care must be taken because some streams in audio tools can not exceed 1024 bytes
62+
5863
## Example Configuration
5964
```
6065
auto adcConfig = adc.defaultConfig(RX_MODE);
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
* @file read-esp32-multi-channel-csv.ino
3+
* @author Urs Utzinger
4+
* @copyright GPLv3
5+
*/
6+
7+
// | attenuation | range | accurate range |
8+
// | ------------ | --------| -------------- |
9+
// | ADC_ATTEN_DB_0 | 0..1.1V | 100-950mV |
10+
// | ADC_ATTEN_DB_2_5| 0..1.5V | 100-1250mV |
11+
// | ADC_ATTEN_DB_6 | 0..2.2V | 150-1750mV |
12+
// | ADC_ATTEN_DB_12 | 0..3.9V | 150-2450mV |
13+
14+
#include "Arduino.h"
15+
#include "AudioTools.h"
16+
17+
#define NUM_CHANNELS 6 // number of channels
18+
#define DEC_FACTOR 48 // decimating
19+
#define ADC_ATTENUATION ADC_ATTEN_DB_11 // ADC attenuation, see above
20+
#define ADC_BIT_WIDTH 12 // the ADC bit width 9..12, values will be stored in 16 bit integers
21+
#define BIT_DEPTH 16 // default bit width of data returned from analgo_in. Do not change.
22+
23+
// It looks like Buffer larger than 1024 is capped by stream copy for decimater or csvoutput
24+
#define BUFFER_SIZE_FACTOR (1024/ (NUM_CHANNELS*DEC_FACTOR*BIT_DEPTH/8)) // 3.5
25+
#define ADC_BUFFER_SIZE (NUM_CHANNELS*DEC_FACTOR*BUFFER_SIZE_FACTOR) // Total number of samples (not bytes), needs to be divisible by 4 // 3*3*96 = 864
26+
#define BUFFER_SIZE ADC_BUFFER_SIZE*BIT_DEPTH/8 // Number of bytes for processing buffer
27+
#define SERIAL_BUFFER_SIZE BUFFER_SIZE/DEC_FACTOR // There will be factor times less data after decimating
28+
29+
// Sampling rates
30+
#define SERIAL_SAMPLE_RATE 300 // samples per channel per second
31+
#define SAMPLE_RATE SERIAL_SAMPLE_RATE*DEC_FACTOR // number of samples per channel before decimating
32+
#define ADC_SAMPLE_RATE SAMPLE_RATE*NUM_CHANNELS // actual sampling rate of ADC
33+
// BAUD rate required: SERIAL_SAMPLE_RATE * (NUM_CHANNELS * approx 6 chars + 2 EOL) * 10 approx 40,000 baud
34+
35+
#define ADC0 ADC_CHANNEL_7 // ADC channel 0
36+
#define ADC1 ADC_CHANNEL_0 // ADC channel 1
37+
#define ADC2 ADC_CHANNEL_3 // ADC channel 2
38+
#define ADC3 ADC_CHANNEL_6 // ADC channel 3
39+
#define ADC4 ADC_CHANNEL_4 // ADC channel 4
40+
#define ADC5 ADC_CHANNEL_5 // ADC channel 5
41+
#define ADC6 ADC_CHANNEL_1 // ADC channel 6, not routed on the ESP32 WROOM module
42+
#define ADC7 ADC_CHANNEL_2 // ADC channel 7, not routed on ESP32 WROOM module
43+
#define ADC8 ADC_CHANNEL_8 // ADC channel 8, only ESP32S3,S2
44+
#define ADC9 ADC_CHANNEL_9 // ADC channel 9, only ESP32S3,S2
45+
46+
AudioInfo info_serial(SERIAL_SAMPLE_RATE, NUM_CHANNELS, BIT_DEPTH);
47+
48+
AnalogAudioStream analog_in; // on board analog to digital converter
49+
Decimate decimater(DEC_FACTOR, NUM_CHANNELS, BIT_DEPTH); // skip samples
50+
ConverterStream<int16_t> decimated_stream(analog_in, decimater); // pipe the sound to the decimater
51+
CsvOutput<int16_t> serial_out(Serial, NUM_CHANNELS, SERIAL_BUFFER_SIZE); // serial output
52+
StreamCopy copier(serial_out, decimated_stream, BUFFER_SIZE); // stream the decimated output to serial port
53+
54+
// Arduino Setup
55+
void setup(void) {
56+
57+
Serial.begin(115200);
58+
while (!Serial);
59+
60+
// Include logging to serial, If you want no logging comment this line
61+
AudioLogger::instance().begin(Serial, AudioLogger::Warning); // Error, Warning, Info, Debug
62+
63+
auto adcConfig = analog_in.defaultConfig(RX_MODE);
64+
65+
// For ESP32 by Espressif Systems version 3.0.0 and later:
66+
// see examples/README_ESP32.md
67+
adcConfig.sample_rate = SAMPLE_RATE; // sample rate per channel
68+
adcConfig.channels = NUM_CHANNELS; // up to 6 channels
69+
adcConfig.adc_bit_width = ADC_BIT_WIDTH; // Supports only 12
70+
adcConfig.buffer_size = ADC_BUFFER_SIZE; // in total number of samples
71+
adcConfig.adc_calibration_active = true; // use and apply the calibration settings of ADC stored in ESP32
72+
adcConfig.is_auto_center_read = false; // do not engage auto-centering of signal (would subtract average of signal)
73+
adcConfig.adc_attenuation = ADC_ATTENUATION; // set analog input range
74+
adcConfig.adc_channels[0] = ADC0; // ensure configuration for each channel
75+
adcConfig.adc_channels[1] = ADC1;
76+
adcConfig.adc_channels[2] = ADC2;
77+
adcConfig.adc_channels[3] = ADC3;
78+
adcConfig.adc_channels[4] = ADC4;
79+
adcConfig.adc_channels[5] = ADC5;
80+
81+
analog_in.begin(adcConfig);
82+
serial_out.begin(info_serial);
83+
84+
}
85+
86+
// Arduino loop
87+
void loop() {
88+
copier.copy();
89+
}

examples/tests/conversion/channel-converter-decimate/channel-converter-decimate.ino

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010

1111
AudioInfo info1(44100, 1, 16);
1212
AudioInfo info2(44100, 2, 16);
13-
AudioInfo infoO(44100/FACTOR, 2, 16);
14-
SineWaveGenerator<int16_t> sineWave1(16000); // subclass of SoundGenerator with max amplitude of 32000
15-
SineWaveGenerator<int16_t> sineWave2(16000); // subclass of SoundGenerator with max amplitude of 32000
16-
GeneratedSoundStream<int16_t> sound1(sineWave1); // stream generated from sine wave
17-
GeneratedSoundStream<int16_t> sound2(sineWave2); // stream generated from sine wave
18-
InputMerge<int16_t> imerge;
19-
Decimate decimater; // decimate by 4 on 1 channel
20-
ConverterStream<int16_t> decimated_stream(imerge, decimater); // pipe the sound to the binner
21-
CsvOutput<int16_t> serial_out(Serial); // serial output
22-
StreamCopy copier(serial_out, decimated_stream); // stream the binner output to serial port
13+
AudioInfo info_out(44100/FACTOR, 2, 16);
14+
SineWaveGenerator<int16_t> sineWave1(16000); // subclass of SoundGenerator with max amplitude of 16000
15+
SineWaveGenerator<int16_t> sineWave2(16000); // subclass of SoundGenerator with max amplitude of 16000
16+
GeneratedSoundStream<int16_t> sound1(sineWave1); // stream generated from sine wave
17+
GeneratedSoundStream<int16_t> sound2(sineWave2); // stream generated from sine wave
18+
InputMerge<int16_t> imerge(sound1,sound2);
19+
Decimate decimater(FACTOR, 2, 16); // decimate by FACTOR on each channel
20+
ConverterStream<int16_t> decimated_stream(imerge, decimater); // pipe the sounds to the decimater
21+
CsvOutput<int16_t> serial_out(Serial); // serial output
22+
StreamCopy copier(serial_out, decimated_stream); // stream the decimater output to serial port
2323

2424
// Arduino Setup
2525
void setup(void) {
@@ -30,25 +30,19 @@ void setup(void) {
3030

3131
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
3232

33-
//
34-
decimater.setChannels(2);
35-
decimater.setFactor(FACTOR);
36-
37-
// Merge input to stereo
38-
imerge.add(sound1);
39-
imerge.add(sound2);
40-
imerge.begin(info2);
41-
4233
// Setup sine wave
4334
sineWave1.begin(info1, N_B4);
4435
sineWave2.begin(info1, N_B5);
4536

37+
// Merge input to stereo
38+
imerge.begin(info2);
39+
4640
// Define CSV Output
47-
serial_out.begin(infoO);
41+
serial_out.begin(info_out);
4842

4943
}
5044

5145
// Arduino loop - copy sound to out with conversion
5246
void loop() {
5347
copier.copy();
54-
}
48+
}

src/AudioAnalog/AnalogConfigESP32V1.h

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,44 +12,72 @@
1212
#if CONFIG_IDF_TARGET_ESP32
1313
# define ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1
1414
# define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE1
15-
# define ADC_CHANNELS {ADC_CHANNEL_7, ADC_CHANNEL_0, ADC_CHANNEL_3, ADC_CHANNEL_6, ADC_CHANNEL_4, ADC_CHANNEL_5}
15+
# define ADC_CHANNELS {ADC_CHANNEL_0, ADC_CHANNEL_3, ADC_CHANNEL_4, ADC_CHANNEL_5, ADC_CHANNEL_6, ADC_CHANNEL_7}
16+
# define NUM_ADC_CHANNELS 6
1617
# define AUDIO_ADC_GET_CHANNEL(p_data) ((p_data)->type1.channel)
1718
# define AUDIO_ADC_GET_DATA(p_data) ((p_data)->type1.data)
1819
# define HAS_ESP32_DAC
20+
# define ADC_CHANNEL_TYPE uint16_t
21+
# define ADC_DATA_TYPE uint16_t
1922
#elif CONFIG_IDF_TARGET_ESP32S2
2023
# define ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1
2124
# define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
2225
# define AUDIO_ADC_GET_CHANNEL(p_data) ((p_data)->type2.channel)
2326
# define AUDIO_ADC_GET_DATA(p_data) ((p_data)->type2.data)
24-
# define ADC_CHANNELS {ADC_CHANNEL_7, ADC_CHANNEL_0, ADC_CHANNEL_3, ADC_CHANNEL_6, ADC_CHANNEL_4, ADC_CHANNEL_5}
27+
# define ADC_CHANNELS {ADC_CHANNEL_0, ADC_CHANNEL_1, ADC_CHANNEL_2, ADC_CHANNEL_3, ADC_CHANNEL_4, ADC_CHANNEL_5, ADC_CHANNEL_6, ADC_CHANNEL_7, ADC_CHANNEL_8, ADC_CHANNEL_9}
28+
# define NUM_ADC_CHANNELS 10
2529
# define HAS_ESP32_DAC
30+
# define ADC_CHANNEL_TYPE uint16_t
31+
# define ADC_DATA_TYPE uint16_t
2632
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6
2733
# define ADC_CONV_MODE ADC_CONV_ALTER_UNIT //ESP32C3 only supports alter mode
2834
# define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
2935
# define AUDIO_ADC_GET_CHANNEL(p_data) ((p_data)->type2.channel)
3036
# define AUDIO_ADC_GET_DATA(p_data) ((p_data)->type2.data)
31-
# define ADC_CHANNELS {ADC_CHANNEL_7, ADC_CHANNEL_0, ADC_CHANNEL_3, ADC_CHANNEL_6, ADC_CHANNEL_4, ADC_CHANNEL_5}
37+
# define ADC_CHANNELS {ADC_CHANNEL_0, ADC_CHANNEL_1, ADC_CHANNEL_2, ADC_CHANNEL_3, ADC_CHANNEL_4}
38+
# define NUM_ADC_CHANNELS 5
39+
# define ADC_CHANNEL_TYPE uint32_t
40+
# define ADC_DATA_TYPE uint32_t
41+
#elif CONFIG_IDF_TARGET_ESP32C6
42+
# define ADC_CONV_MODE ADC_CONV_ALTER_UNIT
43+
# define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
44+
# define AUDIO_ADC_GET_CHANNEL(p_data) ((p_data)->type2.channel)
45+
# define AUDIO_ADC_GET_DATA(p_data) ((p_data)->type2.data)
46+
# define ADC_CHANNELS {ADC_CHANNEL_0, ADC_CHANNEL_1, ADC_CHANNEL_2, ADC_CHANNEL_3, ADC_CHANNEL_4, ADC_CHANNEL_5, ADC_CHANNEL_6}
47+
# define NUM_ADC_CHANNELS 7
48+
# define ADC_CHANNEL_TYPE uint32_t
49+
# define ADC_DATA_TYPE uint32_t
3250
#elif CONFIG_IDF_TARGET_ESP32S3
3351
# define ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1
3452
# define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
3553
# define AUDIO_ADC_GET_CHANNEL(p_data) ((p_data)->type2.channel)
3654
# define AUDIO_ADC_GET_DATA(p_data) ((p_data)->type2.data)
37-
# define ADC_CHANNELS {ADC_CHANNEL_8, ADC_CHANNEL_9, ADC_CHANNEL_4, ADC_CHANNEL_5, ADC_CHANNEL_4, ADC_CHANNEL_5}
55+
# define ADC_CHANNELS {ADC_CHANNEL_0, ADC_CHANNEL_1, ADC_CHANNEL_2, ADC_CHANNEL_3, ADC_CHANNEL_4, ADC_CHANNEL_5, ADC_CHANNEL_6, ADC_CHANNEL_7, ADC_CHANNEL_8, ADC_CHANNEL_9}
56+
# define NUM_ADC_CHANNELS 10
57+
# define ADC_CHANNEL_TYPE uint32_t
58+
# define ADC_DATA_TYPE uint32_t
59+
#elif CONFIG_IDF_TARGET_ESP32P4
60+
# define ADC_CONV_MODE ADC_CONV_SINGLE_UNIT_1
61+
# define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
62+
# define AUDIO_ADC_GET_CHANNEL(p_data) ((p_data)->type2.channel)
63+
# define AUDIO_ADC_GET_DATA(p_data) ((p_data)->type2.data)
64+
# define ADC_CHANNELS {ADC_CHANNEL_0, ADC_CHANNEL_1, ADC_CHANNEL_2, ADC_CHANNEL_3, ADC_CHANNEL_4, ADC_CHANNEL_5, ADC_CHANNEL_6, ADC_CHANNEL_7}
65+
# define NUM_ADC_CHANNELS 8
66+
# define ADC_CHANNEL_TYPE uint32_t
67+
# define ADC_DATA_TYPE uint32_t
3868
#endif
3969

40-
// #define GET_ADC_UNIT_FROM_CHANNEL(x) ((x >> 3) & 0x1)
41-
# define ADC_UNIT ADC_UNIT_1 // continuous ADC API only supports ADC1
70+
// continuous ADC API should run on ADC1
4271

72+
# define ADC_UNIT ADC_UNIT_1
4373
#ifdef HAS_ESP32_DAC
4474
# include "driver/dac_continuous.h"
4575
#endif
4676

4777
namespace audio_tools {
4878

4979
/**
50-
* @brief ESP32 specific configuration for i2s input via adc using the
51-
* adc_continuous API
52-
*
80+
* @brief ESP32 specific configuration for i2s input via adc using the adc_continuous API
5381
* @author Phil Schatzmann
5482
* @ingroup platform
5583
* @copyright GPLv3
@@ -63,12 +91,12 @@ class AnalogConfigESP32V1 : public AudioInfo {
6391
RxTxMode rx_tx_mode;
6492
TickType_t timeout = portMAX_DELAY;
6593

66-
#ifdef HAS_ESP32_DAC
67-
bool is_blocking_write = true;
68-
bool use_apll = false;
69-
/// ESP32: DAC_CHANNEL_MASK_CH0 or DAC_CHANNEL_MASK_CH1
70-
dac_channel_mask_t dac_mono_channel = DAC_CHANNEL_MASK_CH0;
71-
#endif
94+
#ifdef HAS_ESP32_DAC
95+
bool is_blocking_write = true;
96+
bool use_apll = false;
97+
/// ESP32: DAC_CHANNEL_MASK_CH0 or DAC_CHANNEL_MASK_CH1
98+
dac_channel_mask_t dac_mono_channel = DAC_CHANNEL_MASK_CH0;
99+
#endif
72100

73101
// ADC config parameters
74102
bool adc_calibration_active = false;
@@ -77,7 +105,8 @@ class AnalogConfigESP32V1 : public AudioInfo {
77105
adc_digi_output_format_t adc_output_type = ADC_OUTPUT_TYPE;
78106
uint8_t adc_attenuation = ADC_ATTEN_DB_12; // full voltage range of 3.9V
79107
uint8_t adc_bit_width = SOC_ADC_DIGI_MAX_BITWIDTH;
80-
adc_channel_t adc_channels[6] = ADC_CHANNELS;
108+
109+
adc_channel_t adc_channels[NUM_ADC_CHANNELS] = ADC_CHANNELS;
81110

82111
/// Default constructor
83112
AnalogConfigESP32V1(RxTxMode rxtxMode=TX_MODE) {
@@ -113,5 +142,6 @@ class AnalogConfigESP32V1 : public AudioInfo {
113142
using AnalogConfig = AnalogConfigESP32V1;
114143
#endif
115144

116-
} // ns
145+
} // namespace audio_tools
146+
117147
#endif

0 commit comments

Comments
 (0)