ESH10000560 - Tone Module
Overview
The ESH10000560 is a comprehensive audio tone generation and analysis module featuring dual-channel oscillators with programmable waveforms, precision frequency and amplitude control, and advanced audio measurement capabilities including THD analysis and high-speed waveform capture.
Description
The Tone Module provides sophisticated audio signal generation and analysis for acoustic testing, audio circuit characterization, and speaker/microphone testing. Built around an ESP32-S3 microcontroller running custom firmware, the module delivers stereo tone generation with multiple waveform types, precision voltage and frequency measurements, total harmonic distortion (THD) analysis, and high-speed sample acquisition up to 96 kSPS.
Key Features:
Dual-Channel Tone Generation: Independent stereo oscillators
- 5 waveform types: SINE, QUICKSINE, SQUARE, TRIANGLE, NOISE
- Frequency range: 100 Hz - 20 kHz
- Duty cycle control: 0-100% (square/triangle waves)
- Volume control: -127 dBFS to 0 dBFS per channel
Precision Audio Measurement: Comprehensive voltage and frequency analysis
- Peak-to-peak voltage (VPP)
- RMS voltage (VRMS)
- Average voltage (VAVG)
- Frequency measurement (Hz)
- Fundamental frequency extraction (FFREQ)
- Total harmonic distortion (THD) analysis
High-Speed Data Acquisition: Waveform capture with NumericResult support
- Sample rate: 96 kSPS per channel
- Sample depth: 1-10,000 samples per acquisition
- Multi-channel synchronized sampling
- Optional data reduction (min/max/avg/stddev)
- Base64-encoded transfer for efficient data handling
Programmable Input Gain: Configurable ADC gain per channel
- Range: -17.25 dB to +30 dB
- Precision audio signal conditioning
- Independent gain control per channel
Firmware Update Capability: Field-upgradeable ESP32-S3 firmware
- Bootloader control (BOOTn, CHIP_ENn signals)
- UART-based flashing (115200 baud bootloader, 921600 baud application)
- Merged binary image support via ByteStream channel
- Automatic reboot and reinitialization after flash
UART Communication: High-speed command interface
- Baudrate: 921600 bps (application mode)
- RS232 protocol
- Device: /dev/serial0
- CR-terminated commands (0x0D)
Hardware Details
Microcontroller:
- Chip: Espressif ESP32-S3
- Communication: UART @ 921600 baud (921600 application, 115200 bootloader)
- Firmware: Custom audio generation/analysis application
- Features:
- Dual DAC outputs (tone generation)
- Dual ADC inputs (audio measurement)
- Real-time DSP for THD and frequency analysis
- 96 kSPS sampling capability
GPIO Expander:
- Chip: NXP PI4IOE5V6416
- I²C Address: 0x20
- Channels: 16 digital I/O (2 ports × 8 pins)
- Communication: I²C bus
- Purpose: Bootloader control, UART enable, programming control
Bootloader/Programming Control:
- BOOTn: Boot mode select (user-accessible)
- CHIP_ENn: Enable/reset control (user-accessible)
- UART_EN: UART transceiver enable (hidden)
- NC1-NC13: Not connected pins (hidden)
Channel Naming Convention
All channels follow the naming pattern: {ModuleIndex}.ESH10000560.{ChannelName}
Where:
{ModuleIndex}is the position of the module in the system (e.g., 0, 1, 2...)ESH10000560is the module type identifier{ChannelName}is the specific channel name from the table below
Example: Module at position 0, frequency setpoint for channel 1 would be: 0.ESH10000560.FREQ1
User-Accessible Channels
Communication Channels (2):
| Channel Name | Type | Direction | Usage | Description |
|---|---|---|---|---|
| UART | UART | IN/OUT | UserAllocatable | UART communication (RS232, 921600 baud, /dev/serial0) |
| PROGRAM_FW | ByteStream | OUT | UserAllocatable | Firmware update channel (accepts Base64 merged binary) |
Channel 1 Tone Generation (6 channels):
| Channel Name | Type | Direction | Usage | Description |
|---|---|---|---|---|
| FREQ1 | Frequency | OUT | UserAllocatable | Set frequency on channel 1 (100-20000 Hz) |
| WAVE1 | Multiplexer | OUT | UserAllocatable | Set waveform on channel 1 (SINE, QUICKSINE, SQUARE, TRIANGLE, NOISE) |
| DUTY1 | Ratiometric | OUT | UserAllocatable | Set duty cycle on channel 1 (0.0-1.0 ratio, 0-100%) |
| VOLUME1 | Analog | OUT | UserAllocatable | Set volume on channel 1 (-127 to 0 dBFS) |
| GAIN1 | Analog | OUT | UserAllocatable | Set ADC input gain on channel 1 (-17.25 to 30 dB) |
Channel 2 Tone Generation (5 channels):
| Channel Name | Type | Direction | Usage | Description |
|---|---|---|---|---|
| FREQ2 | Frequency | OUT | UserAllocatable | Set frequency on channel 2 (100-20000 Hz) |
| WAVE2 | Multiplexer | OUT | UserAllocatable | Set waveform on channel 2 (SINE, QUICKSINE, SQUARE, TRIANGLE, NOISE) |
| DUTY2 | Ratiometric | OUT | UserAllocatable | Set duty cycle on channel 2 (0.0-1.0 ratio, 0-100%) |
| VOLUME2 | Analog | OUT | UserAllocatable | Set volume on channel 2 (-127 to 0 dBFS) |
| GAIN2 | Analog | OUT | UserAllocatable | Set ADC input gain on channel 2 (-17.25 to 30 dB) |
Channel 1 Measurement (7 channels):
| Channel Name | Type | Direction | Usage | Description |
|---|---|---|---|---|
| READ_FREQ1 | Frequency | IN | UserAllocatable | Measured frequency on channel 1 (Hz) |
| READ_VPP1 | Analog | IN | UserAllocatable | Measured peak-to-peak voltage on channel 1 (V) |
| READ_VRMS1 | Analog | IN | UserAllocatable | Measured RMS voltage on channel 1 (V) |
| READ_VAVG1 | Analog | IN | UserAllocatable | Measured average voltage on channel 1 (V) |
| READ_FFREQ1 | Analog | IN | UserAllocatable | Measured fundamental frequency on channel 1 (Hz) |
| READ_THD1 | Ratiometric | IN | UserAllocatable | Measured total harmonic distortion on channel 1 (ratio) |
Channel 2 Measurement (6 channels):
| Channel Name | Type | Direction | Usage | Description |
|---|---|---|---|---|
| READ_FREQ2 | Frequency | IN | UserAllocatable | Measured frequency on channel 2 (Hz) |
| READ_VPP2 | Analog | IN | UserAllocatable | Measured peak-to-peak voltage on channel 2 (V) |
| READ_VRMS2 | Analog | IN | UserAllocatable | Measured RMS voltage on channel 2 (V) |
| READ_VAVG2 | Analog | IN | UserAllocatable | Measured average voltage on channel 2 (V) |
| READ_FFREQ2 | Analog | IN | UserAllocatable | Measured fundamental frequency on channel 2 (Hz) |
| READ_THD2 | Ratiometric | IN | UserAllocatable | Measured total harmonic distortion on channel 2 (ratio) |
Bootloader/Programming Control (2 channels):
| Channel Name | Type | Direction | Usage | Description |
|---|---|---|---|---|
| BOOTn | Digital | OUT | UserAllocatable | Boot mode control (true=normal, false=bootloader) |
| CHIP_ENn | Digital | OUT | UserAllocatable | Chip enable/reset (true=enabled, false=reset) |
Data Acquisition (1 channel):
| Channel Name | Type | Direction | Usage | Description |
|---|---|---|---|---|
| NumericResult | NumericResult | IN | UserAllocatable | High-speed waveform acquisition (targets READ_VAVG1/2, 96 kSPS) |
Total User Channels: 29 (2 communication + 11 CH1 generation + 11 CH2 generation + 2 programming + 2 bootloader + 1 numeric result)
Internal Channels (Not User-Accessible)
The following channels are used for internal system control and are hidden from users (all HiddenSystemControl):
- UART_EN (OUT, default=false): UART transceiver enable
- NC1-NC13 (mixed directions): Not connected GPIO pins
Waveform Types
The module supports 5 waveform types:
| Waveform | Description | Use Cases |
|---|---|---|
| SINE | Standard sine wave | THD testing, frequency response, harmonic analysis |
| QUICKSINE | Optimized sine generation | Fast switching between frequencies |
| SQUARE | Square wave with duty cycle control | Digital signal simulation, PWM testing |
| TRIANGLE | Triangle wave with duty cycle control | Slew rate testing, ramp signals |
| NOISE | Pseudo-random noise | Noise immunity testing, bandwidth characterization |
Channel Configuration
Tone Generation Configuration
Set frequency, waveform, and amplitude for audio output:
// Configure channel 1 for 1 kHz sine wave at -10 dBFS
SetValues(
new[] {
"0.ESH10000560.FREQ1",
"0.ESH10000560.WAVE1",
"0.ESH10000560.VOLUME1"
},
new[] {
"1000", // 1000 Hz
"SINE", // Sine waveform
"-10" // -10 dBFS
}
);
Duty Cycle Control
Adjust duty cycle for square and triangle waveforms:
// Configure channel 2 for 50% duty cycle square wave
SetValues(
new[] {
"0.ESH10000560.FREQ2",
"0.ESH10000560.WAVE2",
"0.ESH10000560.DUTY2"
},
new[] {
"5000", // 5 kHz
"SQUARE", // Square waveform
"0.5" // 50% duty cycle
}
);
Input Gain Configuration
Set ADC input gain for measurement channels:
// Set channel 1 input gain to +20 dB
SetValues(
new[] { "0.ESH10000560.GAIN1" },
new[] { "20" } // +20 dB gain
);
Numeric Result Acquisition
Configure high-speed waveform capture:
ConfigureChannels(new[] {
new NumericResultChannel {
NetName = "0.ESH10000560.NumericResult",
Enabled = true,
NumberOfSamples = 1000,
SampleRate = 96000, // 96 kSPS (fixed by device)
TargetNetName = "0.ESH10000560.READ_VAVG1",
ReducedSet = true, // Get statistics
MultiChannel = false
}
});
// Acquire samples
string[] result = GetValues(new[] { "0.ESH10000560.NumericResult" });
List<NumericResult> data = NumericResult.FromBase64(result[0]);
Programming Interface
Generate Sine Wave:
// Generate 440 Hz sine wave (A4 note) at -20 dBFS
SetValues(
new[] {
"0.ESH10000560.FREQ1",
"0.ESH10000560.WAVE1",
"0.ESH10000560.VOLUME1"
},
new[] {
"440", // 440 Hz (A4)
"SINE", // Sine waveform
"-20" // -20 dBFS
}
);
Measure Audio Signal:
// Read comprehensive audio measurements
string[] measurements = GetValues(new[] {
"0.ESH10000560.READ_FREQ1",
"0.ESH10000560.READ_VPP1",
"0.ESH10000560.READ_VRMS1",
"0.ESH10000560.READ_THD1"
});
double frequency = double.Parse(measurements[0]);
double vpp = double.Parse(measurements[1]);
double vrms = double.Parse(measurements[2]);
double thd = double.Parse(measurements[3]);
Console.WriteLine($"Frequency: {frequency} Hz");
Console.WriteLine($"Vpp: {vpp} V");
Console.WriteLine($"Vrms: {vrms} V");
Console.WriteLine($"THD: {thd * 100:F2}%");
Generate Square Wave PWM:
// Generate 10 kHz square wave with 25% duty cycle
SetValues(
new[] {
"0.ESH10000560.FREQ2",
"0.ESH10000560.WAVE2",
"0.ESH10000560.DUTY2",
"0.ESH10000560.VOLUME2"
},
new[] {
"10000", // 10 kHz
"SQUARE", // Square waveform
"0.25", // 25% duty cycle
"0" // 0 dBFS (maximum)
}
);
Capture Waveform Samples:
// Acquire 5000 samples from channel 1 at 96 kSPS
ConfigureChannels(new[] {
new NumericResultChannel {
NetName = "0.ESH10000560.NumericResult",
Enabled = true,
NumberOfSamples = 5000,
SampleRate = 96000, // 96 kSPS (device fixed)
TargetNetName = "0.ESH10000560.READ_VAVG1",
ReducedSet = false, // Get all samples
MultiChannel = false
}
});
string[] result = GetValues(new[] { "0.ESH10000560.NumericResult" });
List<NumericResult> data = NumericResult.FromBase64(result[0]);
// Process samples
foreach (var sample in data[0].Samples)
{
Console.WriteLine($"Sample: {sample} V");
}
Update Firmware:
// Read firmware binary
byte[] firmwareBinary = File.ReadAllBytes("tone_module_v2.0.bin");
string base64Firmware = Convert.ToBase64String(firmwareBinary);
// Flash firmware (module will reboot automatically)
SetValues(
new[] { "0.ESH10000560.PROGRAM_FW" },
new[] { base64Firmware }
);
// Wait for reboot (5 seconds built-in + margin)
Thread.Sleep(7000);
// Module is now running new firmware
UART Command Protocol
The module communicates with the ESP32-S3 via UART using ASCII commands terminated with CR (0x0D):
Set Commands:
SET:WAVE CHANx,WAVE- Sets waveform type (x=1 or 2)SET:FREQ CHANx,FREQ- Sets frequency in Hz (100-20000)SET:DUTY CHANx,DUTY- Sets duty cycle ratio (0.0-1.0)SET:VOLUME CHANx,VOLUME- Sets volume in dBFS (-127.0 to 0.0)SET:GAIN CHANx,GAIN- Sets ADC gain in dB (-17.25 to 30.0)
Query Commands:
GET:FREQ CHANx- Returns measured frequency in HzGET:VRMS CHANx- Returns RMS voltage in VGET:VPP CHANx- Returns peak-to-peak voltage in VGET:VAVG CHANx- Returns average voltage in VGET:FUND CHANx- Returns fundamental frequency in HzGET:THD CHANx- Returns total harmonic distortion ratioGET:SAMPLES CHANx,SAMPLES- Returns requested samples (1-10000)
Example UART Transaction:
// Internal UART transaction (handled automatically by SetValues/GetValues)
Command: "SET:FREQ CHAN1,1000\r"
Response: None (set commands don't return data)
Command: "GET:VRMS CHAN1\r"
Response: "0.707\r" (parsed as double)
Firmware Update Process
The module supports field firmware updates via the ESP32-S3 bootloader:
Flashing Sequence:
Enter Bootloader Mode:
- Set BOOTn = false (GPIO low)
- Set CHIP_ENn = false (reset asserted)
- Set CHIP_ENn = true (release reset)
- ESP32 enters bootloader mode
Flash Firmware:
- Change UART baudrate to 115200 (bootloader speed)
- Send merged binary via esptool protocol
- Verify flash success
Exit Bootloader:
- Set BOOTn = true (GPIO high)
- Set CHIP_ENn = false (reset)
- Set CHIP_ENn = true (release reset)
- ESP32 boots into application at 921600 baud
Automatic Reset:
- Module sleeps 5 seconds for device reboot
- Calls Reset() to reinitialize channels
- UART communication restored at application baudrate
Note: The firmware update process is managed automatically when writing to the PROGRAM_FW channel. The module enters a "critical UART section" during flashing to prevent transaction interleaving.
Critical UART Section
The module implements a critical section mechanism for atomic multi-command sequences:
Purpose:
- Prevents other transactions from interleaving during sensitive operations (e.g., firmware flashing)
- Ensures UART stays enabled for the duration of the critical section
- Allows sequential command execution without bus contention
Behavior:
// Enter critical section (internal)
EnterCriticalUartSection();
// - UART_EN set to true
// - Parent UART channel enabled
// - Verification query sent to confirm bus ready
// Perform critical operations (e.g., flash firmware)
flasher.FlashMergedImage(bytes, changeBaud: true);
// Wait for completion
Thread.Sleep(5000); // ESP32 reboot time
// Exit critical section (internal)
ExitCriticalUartSection();
// - UART_EN set to false
// - Parent UART channel disabled
Error Handling
The module validates operations and provides error messages:
- Channel Not Found: Throws exception if channel does not exist
- Invalid Channel Type: Throws exception for unsupported channel types
- Parse Errors: Boolean, double, and enum values must be valid
- Waveform Type: Must be valid WAVETYPES enum (SINE, QUICKSINE, SQUARE, TRIANGLE, NOISE)
- Numeric Result Target: Must be valid analog channel (READ_VAVG1 or READ_VAVG2)
- Sample Count Mismatch: Warns if requested samples != received samples
- UART Communication Errors: Logged with command details and exception message
Best Practices
- Waveform selection: Use SINE for THD testing, SQUARE/TRIANGLE for timing tests
- Volume control: Start with low volumes (-20 dBFS) to avoid clipping or damage
- Duty cycle: Only applies to SQUARE and TRIANGLE waveforms
- Input gain: Adjust GAIN1/2 to optimize ADC dynamic range for signal amplitude
- THD measurement: Ensure clean sine wave generation for accurate distortion analysis
- Numeric results: Use high sample counts (>1000) for frequency domain analysis
- Firmware updates: Verify firmware compatibility before flashing
- UART timing: Allow processing time between commands (50-100ms typical)
- Sample rate: 96 kSPS is fixed by device, configure SampleRate to match
- Critical section: Firmware flashing automatically manages UART critical section
Module Initialization Sequence
On Reset(), the module performs:
- Clear existing channel list
- Setup GPIO expander (PI4IOE5V6416 at 0x20):
- Create 16 digital channels:
- Port 0: BOOTn (user), CHIP_ENn (user), UART_EN (hidden), NC1-5 (hidden)
- Port 1: NC6-13 (hidden)
- Reset and update GPIO expander
- Add channels to module collection
- Create 16 digital channels:
- Update GPIO hardware: Apply all settings
- Initialize ESP32 flasher:
- Create Esp32S3Flasher with bootloader control callbacks
- Set bootloader baudrate: 115200
- Set application baudrate: 921600
- Define BOOTn and CHIP_ENn control functions
- Exit bootloader mode (set to application mode)
- Add UART channel:
- NetName:
{ModuleIndex}.ESH10000560.UART - BusType: RS232
- Baudrate: 921600
- DeviceName: /dev/serial0
- Usage: UserAllocatable
- NetName:
- Add tone generation channels (Channel 1):
- FREQ1 (Frequency OUT, DeviceName: "SET:FREQ CHAN1,")
- WAVE1 (Multiplexer OUT, DeviceName: "SET:WAVE CHAN1,", values: SINE/QUICKSINE/SQUARE/TRIANGLE/NOISE)
- DUTY1 (Ratiometric OUT, DeviceName: "SET:DUTY CHAN1,")
- VOLUME1 (Analog OUT, DeviceName: "SET:VOLUME CHAN1,", units: dBFS)
- GAIN1 (Analog OUT, DeviceName: "SET:GAIN CHAN1,", units: dB)
- Add tone generation channels (Channel 2):
- FREQ2, WAVE2, DUTY2, VOLUME2, GAIN2 (same structure as CH1 with "CHAN2")
- Add measurement channels (Channel 1):
- READ_FREQ1 (Frequency IN, DeviceName: "GET:FREQ CHAN1")
- READ_VPP1 (Analog IN, DeviceName: "GET:VPP CHAN1")
- READ_VRMS1 (Analog IN, DeviceName: "GET:VRMS CHAN1")
- READ_VAVG1 (Analog IN, DeviceName: "GET:VAVG CHAN1")
- READ_FFREQ1 (Analog IN, DeviceName: "GET:FUND CHAN1")
- READ_THD1 (Ratiometric IN, DeviceName: "GET:THD CHAN1")
- Add measurement channels (Channel 2):
- READ_FREQ2, READ_VPP2, READ_VRMS2, READ_VAVG2, READ_FFREQ2, READ_THD2 (same structure with "CHAN2")
- Add NumericResult channel:
- NetName:
{ModuleIndex}.ESH10000560.NumericResult - PossibleTargetNames: [READ_VAVG1.NetName, READ_VAVG2.NetName]
- Units: V
- NetName:
- Add firmware update channel:
- PROGRAM_FW (ByteStream OUT, accepts Base64 merged binary)
- Trigger channel update event: Notify subscribers of channel additions
Typical Use Cases
1. Audio Frequency Response Test:
// Sweep frequency from 100 Hz to 10 kHz, measure response
for (int freq = 100; freq <= 10000; freq += 100)
{
// Generate tone
SetValues(
new[] { "0.ESH10000560.FREQ1", "0.ESH10000560.VOLUME1" },
new[] { freq.ToString(), "-10" }
);
Thread.Sleep(100); // Allow stabilization
// Measure response
string[] vrms = GetValues(new[] { "0.ESH10000560.READ_VRMS2" });
Console.WriteLine($"{freq} Hz: {vrms[0]} Vrms");
}
2. THD Characterization:
// Measure THD at various frequencies
var frequencies = new[] { 100, 500, 1000, 5000, 10000 };
foreach (var freq in frequencies)
{
SetValues(
new[] {
"0.ESH10000560.FREQ1",
"0.ESH10000560.WAVE1",
"0.ESH10000560.VOLUME1"
},
new[] { freq.ToString(), "SINE", "-10" }
);
Thread.Sleep(200); // Allow stabilization
string[] measurements = GetValues(new[] {
"0.ESH10000560.READ_VRMS2",
"0.ESH10000560.READ_THD2"
});
double vrms = double.Parse(measurements[0]);
double thd = double.Parse(measurements[1]);
Console.WriteLine($"{freq} Hz: Vrms={vrms:F4}V, THD={thd * 100:F3}%");
}
3. Noise Immunity Testing:
// Inject noise on channel 2, measure signal on channel 1
SetValues(
new[] {
"0.ESH10000560.WAVE2",
"0.ESH10000560.VOLUME2"
},
new[] {
"NOISE", // White noise
"-30" // -30 dBFS
}
);
// Monitor signal quality
string[] snr = GetValues(new[] {
"0.ESH10000560.READ_VRMS1", // Signal
"0.ESH10000560.READ_VRMS2" // Noise
});
4. PWM Signal Generation:
// Generate 50 kHz PWM with 33% duty cycle (not possible - max 20 kHz)
// Corrected to 20 kHz maximum
SetValues(
new[] {
"0.ESH10000560.FREQ1",
"0.ESH10000560.WAVE1",
"0.ESH10000560.DUTY1",
"0.ESH10000560.VOLUME1"
},
new[] {
"20000", // 20 kHz (maximum supported)
"SQUARE", // Square waveform
"0.33", // 33% duty cycle
"0" // 0 dBFS (maximum)
}
);
5. Stereo Tone Generation:
// Generate stereo test tones: 440 Hz left, 880 Hz right
SetValues(
new[] {
"0.ESH10000560.FREQ1",
"0.ESH10000560.WAVE1",
"0.ESH10000560.VOLUME1",
"0.ESH10000560.FREQ2",
"0.ESH10000560.WAVE2",
"0.ESH10000560.VOLUME2"
},
new[] {
"440", // A4 (left channel)
"SINE",
"-20",
"880", // A5 (right channel)
"SINE",
"-20"
}
);
6. Waveform Capture and Analysis:
// Capture 10000 samples at 96 kSPS
ConfigureChannels(new[] {
new NumericResultChannel {
NetName = "0.ESH10000560.NumericResult",
Enabled = true,
NumberOfSamples = 10000,
SampleRate = 96000,
TargetNetName = "0.ESH10000560.READ_VAVG1",
ReducedSet = true,
MultiChannel = false
}
});
string[] result = GetValues(new[] { "0.ESH10000560.NumericResult" });
List<NumericResult> data = NumericResult.FromBase64(result[0]);
Console.WriteLine($"Samples captured: {data[0].Samples.Count}");
Console.WriteLine($"Min: {data[0].Min} V");
Console.WriteLine($"Max: {data[0].Max} V");
Console.WriteLine($"Avg: {data[0].Average} V");
Console.WriteLine($"StdDev: {data[0].StdDev} V");
// Perform FFT or other analysis on data[0].Samples
Debugging and Troubleshooting
Problem: Tone not generating
- Check: FREQ1/2 is within 100-20000 Hz range
- Check: VOLUME1/2 is not at minimum (-127 dBFS)
- Check: WAVE1/2 is set to valid waveform type
- Action: Query device with "GET:FREQ CHAN1" to verify communication
Problem: Measurements return zero or invalid values
- Check: Input signal is present and within ADC range
- Check: GAIN1/2 is set appropriately for signal amplitude
- Check: UART communication is functional (921600 baud)
- Action: Verify UART_EN signal is controlled correctly
Problem: UART communication fails
- Check: Baudrate is 921600 for application mode, 115200 for bootloader
- Check: /dev/serial0 device exists and has proper permissions
- Check: UART_EN GPIO is managed correctly (hidden channel)
- Action: Reset module to reinitialize UART
Problem: Firmware update fails
- Check: Binary is valid ESP32-S3 merged image
- Check: BOOTn and CHIP_ENn control sequences are correct
- Check: UART communication is stable during flash process
- Action: Module automatically retries flash operations; check logs
Problem: THD measurements seem incorrect
- Check: Input signal is clean sine wave
- Check: Signal amplitude is within ADC dynamic range
- Check: GAIN is set to avoid clipping or excessive noise
- Action: Use QUICKSINE instead of SINE for cleaner generation
Problem: Sample acquisition incomplete
- Check: Requested samples <= 10000 (device limit)
- Check: SampleRate is set to 96000 (device fixed)
- Check: Target channel is READ_VAVG1 or READ_VAVG2
- Action: Check logs for sample count mismatch warnings
Problem: Cannot enter bootloader mode
- Check: BOOTn and CHIP_ENn signals are user-accessible
- Check: GPIO expander communication is functional
- Action: Manually control BOOTn/CHIP_ENn sequence before firmware update
Hardware Specifications
Audio Performance:
- Frequency accuracy: Limited by ESP32-S3 crystal tolerance (~±20 ppm typical)
- THD performance: Depends on DAC quality and filtering (typically <1% for SINE)
- Output level range: -127 dBFS to 0 dBFS (full scale depends on external circuits)
- Input gain range: -17.25 dB to +30 dB (extends ADC dynamic range)
Sampling Specifications:
- Maximum sample rate: 96 kSPS per channel
- Sample depth: 1-10,000 samples per acquisition
- Resolution: 12-bit (ESP32-S3 ADC/DAC typical)
- Measurement types: VPP, VRMS, VAVG, frequency, THD
Frequency Range:
- Generation: 100 Hz to 20 kHz
- Measurement: Depends on input signal bandwidth (ADC limited)
Waveforms:
- SINE: Standard sine wave (DDS or lookup table)
- QUICKSINE: Optimized sine generation (reduced computation)
- SQUARE: Variable duty cycle (0-100%)
- TRIANGLE: Variable duty cycle (0-100%)
- NOISE: Pseudo-random noise generation
Comparison with Standard Function Generators
| Feature | ESH10000560 (Tone Module) | Benchtop Function Generator |
|---|---|---|
| Channels | 2 (stereo) | 1-2 typical |
| Waveforms | 5 types | 10+ types typical |
| Frequency Range | 100 Hz - 20 kHz | DC - 100 MHz typical |
| Output Level | -127 to 0 dBFS | ±10V typical |
| Measurement | Integrated (VPP, VRMS, THD) | Separate DMM required |
| Sample Acquisition | 96 kSPS, 10k samples | Higher (scope-like) |
| THD Analysis | Built-in | Separate analyzer required |
| Firmware Update | Field-upgradeable | Typically fixed |
| Form Factor | Accordion module | Benchtop instrument |
| Integration | UART, embedded systems | GPIB, LAN, USB |
| Cost | Lower (integrated module) | Higher (standalone) |
Revision History
- ESH10000560: Current production version
- ESP32-S3 microcontroller (UART 921600 baud application, 115200 bootloader)
- PI4IOE5V6416 GPIO expander (16 channels, I²C 0x20)
- Dual-channel tone generation (FREQ, WAVE, DUTY, VOLUME per channel)
- 5 waveform types (SINE, QUICKSINE, SQUARE, TRIANGLE, NOISE)
- Comprehensive audio measurement (VPP, VRMS, VAVG, FREQ, FFREQ, THD)
- Programmable input gain (-17.25 to +30 dB per channel)
- High-speed sampling (96 kSPS, 10k samples max)
- NumericResult support (targets READ_VAVG1/2)
- Firmware update capability (ByteStream channel, ESP32 flasher)
- Critical UART section for atomic operations
- Bootloader control (BOOTn, CHIP_ENn user-accessible)