STM32 DIY Oscilloscoop
Een eenvoudige USB-oscilloscoop gebouwd rond een STM32F207 Nucleo-board. Het maakt gebruik van de interne ADC, DMA en een hardwaretimer om een stabiele sampling rate van 2 MSPS te bereiken met edge-triggering. Een Python-front-end ontvangt de vastgelegde golfvorm via UART en plot deze in realtime.
Dit project is onderdeel van een videoserie; dit eerste deel behandelt één werkend kanaal: ADC + DMA-acquisitie, hardware-timed sampling, een softwarematige trigger met pre-trigger capture en een minimale Python-omgeving. In toekomstige video's zal de sampling rate verder worden verhoogd en zullen er meerdere kanalen worden toegevoegd.
Kenmerken
- Tot 2 MSPS, 12-bit resolutie.
- Hardware-timed sampling via TIM2 → ADC externe trigger (geen CPU-betrokkenheid bij de timing).
- Circulaire DMA-buffer, double-buffered via half/full transfer complete callbacks.
- Rising-edge trigger met hysteresis en pre-trigger capture.
- Non-blocking UART-transmissie via DMA (921600 baud).
- Eenvoudige Python/matplotlib GUI met interactieve zoom- en panfuncties.
Hardware
- Board: NUCLEO-F207ZG
- Analoge ingang: PA6 (ADC1, kanaal 6)
- Verbinding met PC: Virtuele COM-poort van de ST-LINK (USART3), er is geen externe USB-naar-serieel adapter nodig.
⚠️ Waarschuwing: Een ingangsbeschermingscircuit is verplicht om het ingangssignaal binnen 0 - 3,3V te houden. Negatieve voltages of signalen boven de 3,3V kunnen de MCU beschadigen. Een analoog front-end (offset + clamping) wordt behandeld in de bovengenoemde video.
Structuur van de repository
.
├── firmware/ # STM32CubeIDE project
│ └── Core/
│ ├── Inc/
│ └── Src/
│ ├── main.c
│ └── stm32f2xx_hal_msp.c
└── software/ # PC-side Python GUI
├── oscilloscope1_ch.py
└── requirements.txt
Aan de slag
Firmware
- Open de map
firmware/als project in STM32CubeIDE. - Bouw het project en flash het naar een NUCLEO-F207ZG board.
- Sluit een signaal aan op PA6 (houd rekening met de bovengenoemde voltage-limieten).
PC-zijde
- Ga naar de softwaremap:
cd software - Installeer de benodigdheden:
pip install -r requirements.txt - Start de applicatie:
python oscilloscope1_ch.py - Pas de variabele
PORTinoscilloscope1_ch.pyaan om deze te laten overeenkomen met de seriële poort van je board (bijv./dev/cu.usbmodemXXXXop macOS,COMxop Windows).
Hoe het werkt
- TIM2 triggert een ADC-conversie met een vast interval.
- Elk geconverteerd sample wordt geschreven in een circulaire DMA-buffer — de CPU is hierbij niet betrokken.
- Zodra de helft van de buffer is gevuld, scant de firmware deze op een stijgende flank (rising edge) die een configureerbare drempelwaarde overschrijdt (met hysteresis om ruis te onderdrukken).
- Wanneer een trigger wordt gevonden, wordt een vast venster van samples — sommige vóór het triggerpunt, de rest erna — gekopieerd en als één pakket via UART naar de PC verzonden. Hierbij wordt DMA gebruikt, zodat de overdracht de acquisitie niet blokkeert.
- Het Python-script ontvangt het pakket, pakt het uit en werkt de plot bij.
Bekende beperkingen
- Bandbreedte: Ongeveer 200 kHz is de praktische bovengrens voor het nauwkeurig reproduceren van de vorm van een signaal bij 2 MSPS (gebaseerd op een vuistregel van circa 10 samples per periode).
- Triggerstabiliteit: De trigger kan onstabiel zijn bij langzaam bewegende signalen met merkbare ruis (bijv. een sinusgolf onder de ~12 kHz tijdens tests). Dit komt omdat het signaal vele samples nodig heeft om langzaam de drempelwaarde te overschrijden, waardoor ruis meerdere kansen krijgt om de hysteresisband te passeren. Blokgolven zijn grotendeels ongevoelig hiervoor, aangezien hun flanken snel genoeg zijn. Het is gepland om de sample rate en hysteresis aanpasbaar te maken per frequentiebereik.
- Hardware: Er is nog geen ingangsbescherming of offset-circuitage aanwezig — een analoog front-end volgt in een toekomstige video.
Toekomstplannen (Roadmap)
- Variabele tijdbasis / sample rate bereiken.
- Analoog front-end (AC-koppeling, offset, ingangsbescherming).
- Hogere effectieve sampling rate via verminderde resolutie en/of interleaved gebruik van alle 3 de ADC's.
- Ondersteuning voor meerdere kanalen (tot 4 kanalen, waarbij de 3e ADC wordt gedeeld tussen twee ingangen).
Licentie
Dit project is gelicenseerd onder de MIT-licentie — zie het bestand LICENSE voor details. Firmware-bestanden die zijn gegenereerd door STM32CubeMX behouden hun oorspronkelijke STMicroelectronics copyright-headers, zoals vereist door hun licentie.
Groetjes,