ADC1 noise at low voltages

rkagerer
Posts: 4
Joined: Fri Jan 27, 2023 7:19 pm

ADC1 noise at low voltages

Postby rkagerer » Fri Jan 27, 2023 7:40 pm

I'm using ADC1 on the ESP32-S3 in Continuous mode, 10kHZ sample rate, 11dB attenuation, and I'm getting some weird noise or "ringing" in the troughs of the trace below:

Image

Here's an analog logic probe capture of the exact same signal (measured near the IO pin):

Image

The signal is generated by a current transformer measuring a 60Hz mains supply to a halogen lamp.

Has anyone seen this sort of thing before, and have any tips? I know averaging is possible but I'd like to clean up the raw input a bit more before I go there.

Here's another pair of traces (from when the lamp is first turned on):

Image

Image

My code is using ESP-IDF. I'm pretty sure the problem is a configuration or code issue, because when I reverted to an earlier version that uses CircuitPython and a series of one-shot samples (also at ~10kHz) I get a cleaner result:

Image

I'm guessing the CircuitPython libraries are doing some tricks my rudimentary ESP-IDF code (which was copied from the ADC continuous_read example) is not.

rkagerer
Posts: 4
Joined: Fri Jan 27, 2023 7:19 pm

Re: ADC1 noise at low voltages

Postby rkagerer » Wed Feb 01, 2023 8:38 am

I also tested some one-shot code under MicroPython and am getting clean results. I'm not clear why the continuous mode samples have the artifact.

I've been trying to set up the ADC registers by hand in MicroPython, using mem32(), but have found my writes to registers like APB_SARADC_CTRL_REG and APB_SARADC_CTRL2_REG are having no effect. Writes to the GPIO registers work as expected. Is there anything I need to do first in order to successfully write to the ADC registers?

rkagerer
Posts: 4
Joined: Fri Jan 27, 2023 7:19 pm

Re: ADC1 noise at low voltages

Postby rkagerer » Fri Feb 03, 2023 7:58 am

OK, I haven't solved the low-voltage noise problem, but I did make headway obtaining direct-register control of the ADC.

Turns out you need to de-assert the peripheral's RESET line (and probably enable it's clock) via the undocumented bit #28 of these two registers: SYSTEM_PERIP_RST_EN0_REG and SYSTEM_PERIP_CLK_EN0_REG.

The Technical Reference Manual (latest version 1.1) fails to mention this, and lists those bits as "(reserved)". But if you dive into the framework (v5.0) library code you can find #defines for them in system_reg.h. I reported the errata to EspressIf, hopefully someone there will bulk up their ADC documentation.

rkagerer
Posts: 4
Joined: Fri Jan 27, 2023 7:19 pm

Re: ADC1 noise at low voltages

Postby rkagerer » Sun Feb 26, 2023 2:02 pm

After a month of on-and-off work, I made some major breakthroughs. I started from scratch with a new Micropython project and manually configured DMA by hand via registers.

Here's a capture from it (using an 80Khz sample rate!):
Image

And the corresponding trace from my analog logic probe:
Image

The data is saved to one giant DMA buffer (via chained descriptors), so the CPU is free to do whatever it wants during the capture.

I'm starting to suspect there might be something buggered with the continuous_read example project from IspressIf, which caused the artifacts seen in my original post. Here's what it produced when I tried some quick and dirty changes to take a capture at ~80KHz:
Image

Craige Hales
Posts: 94
Joined: Tue Sep 07, 2021 12:07 pm

Re: ADC1 noise at low voltages

Postby Craige Hales » Sun Feb 26, 2023 5:35 pm

Interesting. I'm doing something very similar and continuous reading 4 channels interleaved on esp32. The interleave pattern was predictable up to about 270K total samples/sec. Above that the pattern gets scrambled, repeating, skipping. I take the raw 16 bit samples and split each sample into a 4-bit channel ID and a 12-bit value. You might be seeing something similar if your 80kHz is per channel for 4 or more channels (320K samples/sec). I'm using 264K at the moment. Fast enough for 60Hz power line monitoring.

Experiment, using esp-idf/examples/peripherals/adc/dma_read/main/adc_dma_example_main.c

mod for esp32 to read 4 channels in sequence, original low freq, works fine

Code: Select all

static adc_channel_t channel[4] = {ADC1_CHANNEL_7,ADC1_CHANNEL_6,ADC1_CHANNEL_5,ADC1_CHANNEL_4};
I (8651) ADC DMA: Unit: 1, Channel: 7, Value: 0
I (8651) ADC DMA: Unit: 1, Channel: 4, Value: 0
I (8661) ADC DMA: Unit: 1, Channel: 5, Value: 0
I (8661) ADC DMA: Unit: 1, Channel: 6, Value: 0
I (8671) ADC DMA: Unit: 1, Channel: 7, Value: 0
I (8681) ADC DMA: Unit: 1, Channel: 4, Value: 0
I (8681) ADC DMA: Unit: 1, Channel: 5, Value: 0
I (8691) ADC DMA: Unit: 1, Channel: 6, Value: 0
I (8691) ADC DMA: Unit: 1, Channel: 7, Value: 0
I (8701) ADC DMA: Unit: 1, Channel: 4, Value: 0
I (8701) ADC DMA: Unit: 1, Channel: 5, Value: 0
I (8711) ADC DMA: Unit: 1, Channel: 6, Value: 0
I (8711) ADC DMA: Unit: 1, Channel: 7, Value: 0


mod for 280K, this is too high, the channel ordering is puzzling

Code: Select all

.sample_freq_hz = 280 * 1000,
I (4481) ADC DMA: Unit: 1, Channel: 7, Value: 0
I (4491) ADC DMA: Unit: 1, Channel: 4, Value: 0
I (4491) ADC DMA: Unit: 1, Channel: 6, Value: 0
I (4501) ADC DMA: Unit: 1, Channel: 7, Value: 0
I (4501) ADC DMA: Unit: 1, Channel: 5, Value: 0
I (4511) ADC DMA: Unit: 1, Channel: 5, Value: 0
I (4511) ADC DMA: Unit: 1, Channel: 4, Value: 0
I (4521) ADC DMA: Unit: 1, Channel: 4, Value: 0
I (4521) ADC DMA: Unit: 1, Channel: 7, Value: 0
I (4531) ADC DMA: Unit: 1, Channel: 7, Value: 0
I (4541) ADC DMA: Unit: 1, Channel: 5, Value: 0
I (4541) ADC DMA: Unit: 1, Channel: 6, Value: 0


mod down to 270K, the channel ordering makes sense again

Code: Select all

.sample_freq_hz = 270 * 1000,
I (3341) ADC DMA: Unit: 1, Channel: 7, Value: 0
I (3341) ADC DMA: Unit: 1, Channel: 4, Value: 0
I (3351) ADC DMA: Unit: 1, Channel: 5, Value: 0
I (3351) ADC DMA: Unit: 1, Channel: 6, Value: 0
I (3361) ADC DMA: Unit: 1, Channel: 7, Value: 0
I (3361) ADC DMA: Unit: 1, Channel: 4, Value: 0
I (3371) ADC DMA: Unit: 1, Channel: 5, Value: 0
I (3371) ADC DMA: Unit: 1, Channel: 6, Value: 0
I (3381) ADC DMA: Unit: 1, Channel: 7, Value: 0
I (3381) ADC DMA: Unit: 1, Channel: 4, Value: 0
I (3391) ADC DMA: Unit: 1, Channel: 5, Value: 0
I (3401) ADC DMA: Unit: 1, Channel: 6, Value: 0
I (3401) ADC DMA: Unit: 1, Channel: 7, Value: 0


My original working prototype at a lower frequency assumed the channel order would be stable. Ver 2 ran at a higher frequency and the unexpected scrambled channel ordering meant sometimes I'd get a volt reading when I thought I was reading amps.

https://community.jmp.com/t5/Uncharted/ ... a-p/562554
Craige

Who is online

Users browsing this forum: No registered users and 55 guests