STM32F303 - Switching noise on ADC - Page 1
Forum section: electronics / general

author: ppTRN
author_rank: Regular Contributor
timestamp: May 09, 2025, 03:08:14 pm
content: Hi everyone,I made a custom PCB for a metal detector that produces two signals, called I and Q, that changes if some metal is present. They have a steady voltage of 1.65V and can go up or down depending on the type of metal. Their bandwith is less than 100Hz. They comes from various op amp stages, but the final one that interfaces with the ADC is a single supply rail to rail TS9121. See schematic attached.The signals have a noise of about 80mVpp, which I still think it is a lot but I think it is due to bad op amp quality on the previous stages.The problem is that as soon as I connect these two signals to the STM32F303 nucleo board, they start ti be affected with some switching noise. Before going on:1. I have two square wave that travels in the wires between the nucleo board and the PCB. The noise is not sincronous with any of the edges of said signals, so they are not the fault;2. Even if sure about pt1, I still used coax cable to connect the PCB output to the nucleo. Only one side of the cable sleeve is connected to GND. No changes whatsoever;3. The swithing noise seems to be dependent on the voltage: it is minimum at 1.65V and grows up to 1V as I get closer to 0V or 3.3V;4. If I disconnect the cables and measure the output from the pcb, the switching noise DISAPPEARS;5. If I remove supply to the PCB, noise is still present.6. Adding a small resistor (<10Omh) or an inductor in series with the signal does not affect the noise;7. All op amps are equipped with bypass capacitors on positive and negative rail;It is clear to me that it is the microcontroller that is generating such noise, at a timing that is asyncronous with any operation I am doing.I tought it was because I was putting the system asleep using WFI, turns out it was not.Allow me to share the ADC code. It is configured in conversion mode and uses DMA. It works just fine, nothing to do on main().Code:#include "channelAcquisition.h"#include <math.h>#define AVERAGE_COUNT 64 // Must be power of two (e.g., 2, 4, 8, 16, 32, 64...)#define AVERAGE_SHIFT 6 // log2(64) = 6extern int I;extern int Q;extern int dI;extern int dQ;int max = 0;int16_t I_prev = 0, Q_prev = 0;static uint16_t adc_buffer;static uint32_t I_accumulator = 0;static uint32_t Q_accumulator = 0;static uint16_t sample_count = 0;void channelAcquisitionInit(void) {// Enable clocksRCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_DMA1EN | RCC_AHBENR_ADC12EN;// Set PA1, PA3 to analogGPIOA->MODER |= (3 << (1 * 2)) | (3 << (3 * 2));// === CRITICAL: Set ADC clock mode BEFORE ADC operations ===ADC12_COMMON->CCR &= ~ADC12_CCR_CKMODE;ADC12_COMMON->CCR |= ADC12_CCR_CKMODE_0; // HCLK/1// Enable ADC voltage regulatorADC1->CR &= ~ADC_CR_ADEN;ADC1->CR |= ADC_CR_ADVREGEN_0;for (volatile int i = 0; i < 1000; i++); // ~10us delay// CalibrationADC1->CR |= ADC_CR_ADCAL;while (ADC1->CR & ADC_CR_ADCAL);// Sampling time: slow (239.5 cycles)ADC1->SMPR1 = (7 << ADC_SMPR1_SMP2_Pos) | (7 << ADC_SMPR1_SMP4_Pos);// Conversion sequence: CH2 (PA1), CH4 (PA3)ADC1->SQR1 = (1 << ADC_SQR1_L_Pos) | (2 << ADC_SQR1_SQ1_Pos) | (4 << ADC_SQR1_SQ2_Pos);// Continuous + DMA + scanADC1->CFGR |= ADC_CFGR_DMAEN | ADC_CFGR_DMACFG | ADC_CFGR_CONT;// Enable ADCADC1->CR |= ADC_CR_ADEN;while (!(ADC1->ISR & ADC_ISR_ADRDY));// DMA setupDMA1_Channel1->CCR = 0;DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR;DMA1_Channel1->CMAR = (uint32_t)adc_buffer;DMA1_Channel1->CNDTR = 2;DMA1_Channel1->CCR = DMA_CCR_MINC| DMA_CCR_CIRC| DMA_CCR_PSIZE_0| DMA_CCR_MSIZE_0| DMA_CCR_TCIE| DMA_CCR_EN;NVIC_EnableIRQ(DMA1_Channel1_IRQn);// START CONVERSIONSADC1->CR |= ADC_CR_ADSTART;}void DMA1_Channel1_IRQHandler(void) {if (DMA1->ISR & DMA_ISR_TCIF1) {DMA1->IFCR |= DMA_IFCR_CTCIF1;I_accumulator += adc_buffer;Q_accumulator += adc_buffer;sample_count++;if (sample_count >= AVERAGE_COUNT) {I = (I_accumulator >> AVERAGE_SHIFT) - 2048;Q = (Q_accumulator >> AVERAGE_SHIFT) - 2048;I_accumulator = 0;Q_accumulator = 0;sample_count = 0;}}}Any clues?

author: radiolistener
author_rank: Super Contributor
timestamp: May 12, 2025, 01:22:25 am
content: Analog signals are highly sensitive to interference and noise, particularly in high-impedance circuits where susceptibility increases significantly. Using a breadboard with loose wiring near digital circuitry is a poor choice for analog signal handling. Instead, analog circuits should be routed on a dedicated shielded PCB with proper ground layout, power supply filtering, and carefully designed signal paths. This is very important for analog signals.Without a solid theoretical background and practical experience in analog and RF electronics, it can be challenging to fully understand or explain how these systems behave and why certain configurations lead to interference. To the uninitiated, their behavior may seem almost like magic - and in practice, it will indeed appear to work that way, even if you are familiar with some basic electronics.The difficulty in understanding these phenomena stems from the need to grasp the physics of electromagnetic wave propagation - an area that is far from intuitive for those without a background in RF theory and practical experience in high-frequency electronics.You're right that microcontrollers generate noise, especially from internal clock sources, switching regulators, and I/O activity. However, in your setup, there's also a WiFi module involved, which is an even more significant source of interference. The transmitter in a WiFi module can emit at power levels up to 2-3 Watts, generating extreme high electromagnetic fields near the module that can induce noise on nearby conductors. This effect is particularly pronounced with unshielded and disorganized wiring, such as what's commonly found on breadboards. The result is a high level of EMI coupling into analog or sensitive digital circuits, often causing unexpected behavior even when the MCU appears to be idle or complete powered off.Attempting to measure millivolt-level signal variations in the presence of an active nearby transmitter is akin to trying to detect subtle ripples in the ocean during a violent storm - the surrounding electromagnetic "noise" can easily overwhelm and obscure any small-signal behavior you're trying to observe.For example, I have observed low-frequency transients with amplitudes of up to several millivolts at the output of an operational amplifier powered via loosely connected wires from a bench power supply. These disturbances consistently coincide with WiFi beacon transmissions from a nearby router located about one meter from the circuit. Notably, the operational amplifier is equipped with some level of power supply filtering, including ferrite beads and ceramic capacitors, yet the interference is still clearly present.

author: Doctorandus_P
author_rank: Super Contributor
timestamp: May 20, 2025, 11:05:30 am
content: Noise caused by interference is one of the biggest limitations for the use of breadboards. Origins of noise:Any wire which has a changing voltage has capacitive coupling to the stuff around it.Any wire with a changing current generates an electromagnetic field around it, that's coupled into nearby stuff.Any wire with a current though it has a voltage drop. This includes the GND wire, and then the GND level of different parts (ie. uC board and analog board) change, you will also see this as noise on your signal.Wires also have inductance, and this makes voltage differences due to changing currents even more noisier.I once built a circuit with an ATMEGA328 that used both the ADC, and did keyboard multiplexing, and built the circuit on matrix board. That did not fare well. The keyboard multiplexing caused so much noise that I lost quite a few bits of the ADC.Breadboards are nice for quick tests, but for anything more you really want to go into the direction of a PCB with a full GND plane. A full GND plane looks simple, but does a lot of nice things to your circuit. It has a very low impedance, improves signal integrity (reduces loop area) mitigates EMI. Due to the lower cost of 4 layer PCB's it's quite common to use both inner layers for a GND plane (and even use extra stitching via's near to where signals go though the PCB with via's.) Reason is that even the thickness difference of 0.1mm for prepreg compared to 1.4mm for the PCB core is significant for signal integrity. Nearly all uC's (and other digital circuits) have multiple GND pins, on quad packages usually on all 4 sides of the package, just to be able to connect it with lower parasitic impedances to the GND plane. First time I saw the RP2040 I was quite surprised it did not have GND pins at all. Instead it relies on the whole bottom tab to be soldered to GND. You can't create a GND connecction better then that.Rick Hartley (from altium) made an excellent video of "how to achieve a proper ground plane" It's over two hours in length, but worth watching.Combining both digital and analog in the same IC is also always a point of concern. One thing that can help is to manage the timing in such a way that the noise during ADC sampling and conversion is as low as possible. In my example above for example, I can interleave the ADC sampling with the keyboard sampling, as keyboard matrix scanning is not timing sensitive.

author: iMo
author_rank: Super Contributor
timestamp: May 20, 2025, 11:26:29 am
content: FYI - I've been just messing with the notorious BluePill board with stm32f303cc on it (replaced the original F103) and the ADC noise I see is, say, <7-8LSB peak-peak.In past (like 5+y back) there where discussions even at the stm forum, where a guy claimed a buggy ADC (with a larger stm32F in a complex design and an external Vref, afaik, claimed too noisy ADC almost unusable), while the others incl. the stm-guy answered to him a 1LSB p-p noise is even possible (and the DS is ok) with 4 or 6 layers pcb and a careful design. The unhappy guy finally redone the pcb to 4 or 6 layers and confirmed it helped significantly. You may perhaps find the posts somewhere.

author: Simmed
author_rank: Frequent Contributor
timestamp: May 20, 2025, 01:06:14 pm
content: too many variablesincomplete schemadont know the answer

author: DavidAlfa
author_rank: Super Contributor
timestamp: May 29, 2025, 06:25:48 pm
content: Show the adc channel schematic, there'e infinite possible culprits.Bad power (USB power is VERY noisy), ground loop, high adc source impedance, insufficient adq. time, bad wiring (Flying wire taking noise or trace too close to noisy signal)...

author: mtwieg
author_rank: Frequent Contributor
timestamp: May 30, 2025, 12:32:01 pm
content: Need the following:1. Schematic showing how the signals are sent from the opamps on one board to the ADC on the other.2. Scope captures of the signals with and without this excess noise.