I have an Adafruit KB2040 μcontroller, which is based on the RP2040 chip from the rPi PICO.

The Adafruit max9814 microphone hooked up to the ADC0 channel gave me a very noisy signal.

So instead, I thought I would test it with a more steady input.

I tried to create that by creating a 1.6V level as shown below. Did I do that correctly?


simulate this circuit – Schematic created using CircuitLab

Feeding this point into the ADC still gave me a noisy signal, see below:

enter image description here

This is a 12b DAC, so values are from 0..4095, with the noise swinging up/dn at least 10% of that range.

(As an side, if I touch that 1.6V point with my hands, I can even pick up a radio station, which I hear when I play the samples on a speaker.)

Is this noise level as good as I can expect, or is there something else wrong?

I read the samples via DMA at 8000Hz, and the whole thing is powered via USB from my computer.

I tried adding capacitors, electrolytic and ceramic, between GND and VCC to try to stabilize the power source, which did not help.


The time between top-to-top spikes is roughly 200 samples, which at 8000Hz is 40 Hz, 25ms.

The time between top-to-dip is roughly 100 samples, which at 8000Hz is 80 Hz, 12.5ms.

I do the DMA reads in batches of 1024 samples, roughly 8 Hz.

Samples are sent via Serial.println() and printed in Arduino IDE serial plotter tool.

The hardware ADC FIFO is merely 4 samples deep, btw.

enter image description here

  • \$\begingroup\$ How often do the spikes happen? Like in ms/us. It's not clear from the graph. \$\endgroup\$
    – Ilya
    Apr 9, 2022 at 19:02
  • \$\begingroup\$ I have a feeling it could be sampling capacitor charging? Maybe? If the timing matches. \$\endgroup\$
    – Ilya
    Apr 9, 2022 at 19:06
  • \$\begingroup\$ @Ilya Thanks, those spikes happen without a capacitor between GND/VCC too. \$\endgroup\$
    – Bram
    Apr 9, 2022 at 19:11
  • 1
    \$\begingroup\$ Is it a coincidence that they happen almost every 100 samples? What is your DMA buffer size and how do you send them somewhere to be plotted? \$\endgroup\$
    – Justme
    Apr 9, 2022 at 19:16
  • 1
    \$\begingroup\$ Can you show us some of the actual numbers (ascii characters) sent over the serial port during one of the glitches? What happens to the glitch frequency if you change the sample rate? \$\endgroup\$ Apr 9, 2022 at 20:31

2 Answers 2


I think I approached the stabilization using capacitors incorrectly.

My original thought was to stabilize my VCC by adding capacitors between GND and VCC. This did not remove any noise.

Then I tried to catch the noise at the input:

I put a 0.01μF ceramic capacitor between the ADC0 input pin, and VCC. (The blue capacitor shown in the picture that I added to my post.)

This removed the bulk of the noise. When I sample my 1.6V point, I now get fewer spikes, and lower spikes:

enter image description here

Rerouting the sampling pin back to the microphone gave me a voice signal that no longer had the loud hum in the background, and the voice was reasonably clear too. So I think I may have to add that 0.01μF to my PCB design.


When testing one thing, without a clear idea on what may influence the results, it really helps to focus on that one thing and remove everything else. Disconnect everything but the circuit you use to drive the ADC input. Just a single breadboard with the KB2040, two resistors, a capacitor, and a USB cable plugged in. Nothing else.

Only once you get results that you're satisfied with, you can methodically begin to add other stuff, and re-verify the results at each step.

The KB2040 board is a two-layer board, very dense, and I'm skeptical that it's very electrically quiet. It's very hard to get such designs to perform well when the ground planes are just cut to shreds, and there's no power plane, etc. I appreciate their effort to keep it cheap to make, but the performance you get may have something to do with the trade-offs made during the design.

I'd suggest at least trying with the Raspberry Pico board as a reference design, get things working with it well enough, and only then transition to other boards, so that you can see the difference - if any - just due to the change of the board. The Pico is also cheaper :)

For testing the ADC performance, it helps to base the inputs on the same reference the ADC is using. On KB2040, the ADC's reference voltage is connected directly to 3V3. Due to trade-offs in the ground plane layout, it helps to take the GND and 3V3 reference directly from the chip, bypassing the ground/power planes. Just allocate two GPIO pins to output HI and LO as your references. Those will bypass any voltage drops on the PCB, and should be fairly close to the voltages the ADC is using - since they come from within the chip. At least GND will be much quieter from ADC's perspective that way.


simulate this circuit – Schematic created using CircuitLab

For the MAX9814, use the same approach:


simulate this circuit

Note that the only connections are between I/O pins and the analog circuits. That's the best way to minimize interference from noisy ground plane etc.

Once you've verified that those circuits work satisfactorily, you can then start modifying them to free up I/O pins if needed.

Note that the ADC FIFO depth is more than adequate: all it needs to cover is worst-case latency in servicing the ADC either by DMA or by an interrupt handler. This is a blazing-fast controller. Servicing interrupts at 8kHz rates is well handled even by a single-core 16MHz ARM M0. You can service ADC at 8kHz with an interrupt handler written in Python on RP2040. It's fast enough for it.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.