¿Alguna vez cargaste un PWM a un motor, viste que hacía algo raro y el multímetro te devolvió un número que no explicaba nada? El multímetro promedia; el osciloscopio te muestra la forma de la señal en el tiempo: el rebote de un botón, el rizado de una fuente o el flanco lento de un amplificador. Un equipo de banco no es barato, y además armar uno propio es la mejor manera de entender qué hace por dentro.
En esta guía vas a construir un osciloscopio digital de un canal con un STM32F411RE (placa NUCLEO-F411RE), un amplificador operacional MCP6002 como etapa de entrada y una pantalla TFT ILI9341 de 2,8 pulgadas. Al terminar vas a saber cómo se muestrea a una tasa exacta con un timer y DMA sin que la CPU intervenga, cómo funciona un disparo (trigger) con histéresis, cómo se mide frecuencia promediando varios ciclos y por qué el ancho de banda real lo fija el amplificador y no el ADC.
Qué hace este osciloscopio
Antes de soldar o cablear nada, conviene tener claro hasta dónde llega el equipo:
| Especificación | Valor |
|---|---|
| Canales | 1 |
| Rango de entrada | 0 a 3,3 V (acoplamiento DC) |
| Tasa de muestreo | 1,5 kS/s a 600 kS/s |
| Base de tiempo | 50 µs/div a 20 ms/div (nueve pasos) |
| Escala vertical | 0,1, 0,2, 0,5 y 1 V/div |
| Ancho de banda útil | unos 50 kHz |
| Resolución | 12 bits |
| Mediciones automáticas | máximo, pico a pico y frecuencia |
Tiene controles de panel frontal de verdad: un encoder rotatorio elige y cambia TIME/DIV, VOLTS/DIV, posición, nivel y flanco del disparo, y dos pulsadores dan RUN/STOP y captura SINGLE. Además genera su propia onda cuadrada de prueba, así que siempre tienes algo que medir aunque no tengas otro circuito a mano.
El concepto: tres bloques que trabajan solos
La idea central del proyecto es que la CPU casi no hace trabajo de tiempo real. Se reparte así:
- Etapa analógica de entrada. La señal entra a un MCP6002 configurado como seguidor de voltaje (ganancia 1). Tiene impedancia de entrada altísima, así que no "carga" al circuito que mides, y una impedancia de salida baja que llena rápido el condensador de muestreo del ADC. Una resistencia de 1 kΩ en serie protege el pin del STM32.
- Captura y análisis en el STM32. El TIM2 dispara cada conversión del ADC a una tasa exacta (30 muestras por división de pantalla) y el DMA guarda 600 muestras en RAM sin que la CPU toque nada. Recién cuando el búfer está lleno, el firmware busca el punto de disparo, calcula mínimo, máximo, pico a pico y frecuencia, y dibuja.
- Pantalla y controles. La ILI9341 de 320 × 240 va por SPI2 a 21 MHz. El encoder lo decodifica el TIM1 en hardware y los pulsadores usan las resistencias pull up internas.

¿Por qué hace falta el amplificador si el ADC ya mide voltaje? El ADC del STM32 es de tipo SAR: en cada conversión conecta un condensador interno de unos pocos picofaradios a la entrada y espera a que se cargue durante el tiempo de muestreo (acá, 15 ciclos). Si la fuente tiene impedancia alta, por ejemplo un divisor con resistencias de 100 kΩ, ese condensador no alcanza a cargarse y la lectura sale baja y "arrastrada" de la muestra anterior. El seguidor resuelve eso: entrega la misma tensión, pero con capacidad de corriente de sobra.
Hardware: materiales y conexiones
El autor original compró todo en DigiKey. Esta es la lista completa:
- NUCLEO-F411RE (STM32F411RE con ST LINK integrado), 1 unidad
- MCP6002-I/P, amplificador operacional doble rail to rail de 1 MHz en DIP8, 1 unidad
- Pantalla TFT SPI de 2,8" 240 × 320 con controlador ILI9341, 1 unidad
- Módulo encoder rotatorio con pulsador, de 5 pines (CLK, DT, SW, +, GND), 1 unidad
- Pulsadores táctiles de 6 mm, 2 unidades
- Potenciómetro de 10 kΩ, 1 unidad
- Resistencia de 1 kΩ, 1 unidad
- Condensador cerámico de 100 nF, 1 unidad
- Opcional: sensor de luz LDR para la demostración final
- Protoboard, cables jumper y el cable USB de la NUCLEO
En software necesitas STM32CubeIDE y STM32CubeMX (gratuitos, de STMicroelectronics) con la librería HAL STM32Cube FW_F4.
Tabla de pines
El proyecto usa 13 pines del STM32, todos accesibles desde los conectores Arduino y Morpho de la NUCLEO:
| Función | Pin STM32 | Conector NUCLEO | Va a |
|---|---|---|---|
| Entrada ADC (ADC1_IN0) | PA0 | A0 (CN8 pin 1) | Salida del MCP6002 a través de 1 kΩ |
| Señal de prueba (TIM3_CH1 PWM) | PA6 | D12 (CN5 pin 5) | Extremo A del potenciómetro |
| TFT CS | PB12 | CN10 pin 16 | CS de la pantalla |
| TFT RESET | PB2 | CN10 pin 22 | RESET de la pantalla |
| TFT DC | PB1 | CN10 pin 24 | DC de la pantalla |
| SPI2 MOSI | PB15 | CN10 pin 26 | SDI (MOSI) |
| SPI2 SCK | PB13 | CN10 pin 30 | SCK |
| SPI2 MISO | PB14 | CN10 pin 28 | SDO (MISO) |
| Encoder CLK (TIM1_CH1) | PA8 | D7 (CN9 pin 8) | CLK del encoder |
| Encoder DT (TIM1_CH2) | PA9 | D8 (CN5 pin 1) | DT del encoder |
| Pulsador del encoder | PB10 | D6 (CN9 pin 7) | SW del encoder |
| Botón RUN/STOP | PB4 | D5 (CN9 pin 6) | Pulsador a GND |
| Botón SINGLE | PB5 | D4 (CN9 pin 5) | Pulsador a GND |
| Botón USER (en la placa) | PC13 | , | Frecuencia de la señal de prueba |
| LED LD2 (en la placa) | PA5 | , | Latido por cuadro |
Todo se alimenta del pin 3V3 de la NUCLEO: la TFT (VCC y LED), el MCP6002 (pin 8) y el encoder (+). Las tierras son comunes. Se usa SPI2 y no SPI1 porque el reloj de SPI1 sale por PA5, el mismo pin del LED de la placa.

Cómo se arma la etapa de entrada
La señal de prueba sale de D12 (PA6) como una onda cuadrada de 0 a 3,3 V y llega a un extremo del potenciómetro; el otro extremo va a GND. El cursor entrega entonces la misma onda con amplitud regulable y alimenta el pin 3 (entrada no inversora) del MCP6002. Los pines 1 y 2 van unidos, y eso convierte al amplificador A en seguidor. Su salida llega a PA0 a través de la resistencia de 1 kΩ, que limita la corriente si algo sale mal. El condensador de 100 nF va entre los pines 8 y 4, lo más cerca posible del chip, para desacoplar la alimentación.
El amplificador B, que no se usa, no se deja flotando: el pin 5 va a GND y el pin 6 se une al pin 7. Una entrada flotante puede hacer oscilar esa mitad del chip y meter ruido en la otra.

Pantalla y controles
La ILI9341 va a SPI2 (SCK en PB13, MOSI en PB15, MISO en PB14) con tres líneas de control: CS en PB12, DC en PB1 y RESET en PB2. Los pines del táctil y de la microSD del módulo no se usan.
El CLK y el DT del encoder van a PA8 y PA9, que son las entradas de los canales 1 y 2 del TIM1: por eso el timer puede decodificar la perilla en hardware. El pulsador del encoder y los dos botones conectan su pin a GND al apretarlos, y el firmware activa las pull up internas, así que no hacen falta resistencias externas.
Ojo con el encoder: aliméntalo con 3V3, nunca con 5V. Los módulos tipo KY-040 traen sus propias resistencias pull up hacia el pin +, así que el voltaje con que lo alimentes es el que verán PA8 y PA9 en reposo. Con 3V3, esas líneas quedan en un nivel seguro para el STM32.

Límites de la entrada. El MCP6002 es rail to rail: funciona con los mismos 3,3 V del STM32 y su salida llega casi a 0 y a 3,3 V. Su hoja de datos limita las entradas a poco más allá de los rieles de alimentación, así que a esta etapa solo se le conectan señales de 0 a 3,3 V. Nada de medir directo los 12 V de una fuente o la red eléctrica.
Software: el firmware por partes
El firmware es un solo bucle que captura, analiza y dibuja un cuadro, mientras tres timers y el DMA hacen todo lo que depende del tiempo. Este es el reparto de periféricos:
| Periférico | Trabajo |
|---|---|
| TIM2 | Reloj de muestreo: cada desborde dispara una conversión del ADC |
| ADC1 + DMA2 Stream 0 | Convierte PA0 y guarda 600 muestras en RAM |
| TIM3 CH1 | Señal de prueba con ciclo de trabajo de 50 % en PA6 |
| TIM1 (modo encoder) | Cuenta los clics del encoder en hardware |
| SPI2 | Manda los píxeles a la ILI9341 a 21 MHz |
Primero, la pantalla
La recomendación del autor, y la mejor costumbre en cualquier proyecto con varios subsistemas, es avanzar por etapas y comprobar cada una antes de sumar la siguiente. El driver de la ILI9341 está escrito desde cero (reset, salida de sueño, formato de píxel, orientación, ventana de dirección y escritura de píxeles), justamente para que se vea cada paso de la conversación con la pantalla. El primer programa solo llena la pantalla y escribe un texto; si funciona, el cableado, la configuración SPI y el driver están bien:
#include "main.h"
#include "ili9341.h"
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI2_Init();
ILI9341_Init(); // hardware + software reset, sleep out, RGB565
ILI9341_SetRotation(1); // landscape, 320 x 240
ILI9341_FillScreen(ILI9341_BLACK);
ILI9341_DrawStringSize(60, 100, "HELLO STM32", ILI9341_YELLOW, ILI9341_BLACK, 2);
ILI9341_DrawGraphGrid(10, 28, 300, 160, ILI9341_GRAY);
while (1)
{
}
}
El orden completo de pruebas fue este: pantalla; ADC con un voltaje continuo conocido (el potenciómetro entre 3,3 V y GND, pasando por el MCP6002, dio lecturas de 3 a 4.089 cuentas y unos 3.295 mV en el extremo alto, lo que valida todo el camino analógico); forma de onda en vivo sobre una grilla; base de tiempo exacta con disparo; y al final la señal de prueba y los controles.
Muestreo disparado por timer, con DMA
Para que el eje de tiempo sea correcto, las muestras se tienen que tomar a una tasa exacta. El TIM2 corre con el reloj de 84 MHz y su evento de actualización (TRGO) arranca una conversión del ADC. Como la pantalla usa 30 muestras por división, el período del timer sale directo del TIME/DIV elegido:
static uint32_t Scope_Acquire(void)
{
uint32_t us = timebases[settings.timebase].us_per_div;
uint32_t ticks = (TIMER_CLOCK_MHZ * us) / DIV_PIXELS_X; // 84 x us / 30
acquisition_done = 0;
TIM2->CR1 &= ~TIM_CR1_CEN; // stop timer
TIM2->CNT = 0;
TIM2->ARR = ticks - 1; // time between samples
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_buffer, SAMPLE_COUNT);
TIM2->CR1 |= TIM_CR1_CEN; // start sampling
...
}
Ejemplo: con 500 µs/div quedan 84 × 500 / 30 = 1.400 ticks entre muestras, o sea 60.000 muestras por segundo. El ADC se configura sin modo continuo y con el disparo externo puesto en TIM2 TRGO:
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_TRGO;
hadc1.Init.DMAContinuousRequests = DISABLE;
sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
El DMA va en modo normal (una sola pasada): llena el búfer de 600 muestras una vez y genera una interrupción. El callback detiene el timer y el búfer queda como una foto limpia que nadie sobrescribe mientras se dibuja:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
if (hadc->Instance == ADC1)
{
TIM2->CR1 &= ~TIM_CR1_CEN; // no more conversions
acquisition_done = 1;
}
}
Por qué no basta con el modo continuo. La primera versión del autor leía el ADC en modo continuo y mostraba lo que llegara. Se veía como una onda, pero el eje de tiempo estaba mal: el ADC corría a unas 219.000 muestras por segundo, así que la pantalla que decía "1 ms/div" en realidad mostraba unos 46 µs por división. En modo continuo la tasa depende del reloj del ADC, del tiempo de muestreo y de los 12 ciclos de conversión, no de lo que tú quieras. Con el timer marcando el paso, cada TIME/DIV queda exacto.
Detección del disparo
Sin disparo, cada cuadro empezaría en un punto al azar y la onda se correría por la pantalla. El código busca en el búfer el primer cruce del nivel de disparo en la dirección elegida. Una histéresis de un octavo de la altura de la señal evita disparos falsos por ruido: la señal primero tiene que bajar de level - hyst ("armarse") para que llegar al nivel cuente como flanco de subida:
for (int32_t i = 0; i <= latest; i++)
{
int32_t s = buf[i];
if (!settings.falling_edge)
{
if (s < level - hyst) armed = 1;
else if (armed && s >= level && i >= TRIGGER_X)
{
r->trigger_index = i; // rising edge found
return;
}
}
...
}
La pantalla muestra entonces 300 muestras desde 30 antes del punto de disparo, así que el disparo siempre queda sobre la primera línea vertical de la grilla. Como el búfer tiene 600 muestras (dos pantallas), siempre hay margen para encontrar el flanco y mostrar una pantalla completa después de él.
Medición de frecuencia
El código cuenta los cruces de subida por el nivel del 50 % en todo el búfer de 600 muestras. Con n cruces entre las posiciones first y last, la frecuencia es 84 MHz × (n, 1) dividido por ticks × (last, first). Promediar varios ciclos da una lectura más estable que medir un solo período, porque el error de una muestra de más o de menos en cada cruce se reparte entre todos los ciclos. El cálculo usa enteros de 64 bits y devuelve milihertz, así que no hace falta punto flotante (el F411 tiene FPU, pero en un Cortex-M3 como el de una Blue Pill esto sí importa).
Dibujo sin parpadeo
Borrar la traza vieja y dibujar la nueva píxel por píxel es lento y además va rompiendo la grilla. En vez de eso, el área de 300 × 160 píxeles se repinta fila por fila, como el barrido de un televisor. Para cada píxel el código decide si es fondo, grilla, marcador o traza, arma una fila de 600 bytes en RAM y la manda en una sola transferencia SPI:
ILI9341_StartPixels(GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT);
for (int y = 0; y < GRAPH_HEIGHT; y++)
{
for (int x = 0; x < GRAPH_WIDTH; x++)
{
uint16_t color = COLOR_BG;
if (on_grid(x, y)) color = COLOR_GRID;
if (y >= trace_top[x] && y <= trace_bottom[x]) color = COLOR_TRACE;
row_pixels[x * 2] = color >> 8; // RGB565, high byte first
row_pixels[x * 2 + 1] = color & 0xFF;
}
ILI9341_PushPixels(row_pixels, sizeof(row_pixels));
}
ILI9341_EndPixels();
trace_top[x] y trace_bottom[x] guardan el tramo vertical entre muestras vecinas, así que un flanco empinado se ve como una línea vertical sólida y no como puntos sueltos.
Los números explican por qué esto importa: la pantalla completa son 320 × 240 × 2 bytes, unos 153 KB. A 21 MHz, el SPI mueve como máximo unos 2,6 MB/s, así que solo el área del gráfico (96 KB) ya toma cerca de 37 ms. Con este método el autor midió un refresco completo del gráfico de unos 43 ms; mandar un píxel por llamada, con su propia ventana de dirección, multiplicaba ese tiempo varias veces.
Encoder y pulsadores
El CLK y el DT del encoder son dos ondas cuadradas desfasadas 90°. El TIM1 en modo encoder 3 cuenta hacia arriba o hacia abajo en cada flanco de ambas señales por sí solo, así que no se pierden clics aunque la CPU esté dibujando:
TIM1->SMCR = TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1; // encoder mode 3
TIM1->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0 // TI1, TI2 inputs
| (0xFU << TIM_CCMR1_IC1F_Pos) // input filtering
| (0xFU << TIM_CCMR1_IC2F_Pos);
TIM1->ARR = 0xFFFF;
TIM1->CR1 = TIM_CR1_CEN;
El firmware lee TIM1->CNT y cada 4 cuentas equivalen a un clic de la perilla. Si tu encoder cambia dos pasos por clic, sube ENCODER_COUNTS_PER_CLICK a 8; si necesitas dos clics para un paso, bájalo a 2; si gira al revés, pon ENCODER_REVERSE en 1. Los pulsadores se leen con un antirrebote de 30 ms, así que cada apretón cuenta una sola vez.
Señal de prueba
El TIM3 canal 1 genera una onda cuadrada en PA6 en modo PWM 1. El timer va preescalado a 1 MHz y el período fija la frecuencia:
uint32_t period = 1000000UL / hz; // 1 MHz timer ticks
TIM3->ARR = period - 1;
TIM3->CCR1 = period / 2; // 50 % duty cycle
Cómo armar el proyecto en STM32CubeIDE
El proyecto completo está en GitHub (enlace en "Recursos"). Crea un proyecto CubeMX para la NUCLEO-F411RE con ADC1 IN0 + DMA2 Stream 0, SPI2 como maestro full duplex y las salidas GPIO PB12 TFT_CS, PB1 TFT_DC y PB2 TFT_RESET. Genera el código y después reemplaza o agrega los cuatro archivos fuente del repositorio (main.c, ili9341.c, ili9341.h y stm32f4xx_hal_msp.c, este último con el DMA del ADC en modo normal). No vuelvas a generar código después de reemplazar main.c: ese archivo no tiene las secciones de código de usuario de CubeMX y lo perderías.
Pruebas: qué deberías ver
Al encenderlo, el osciloscopio muestra una pantalla de bienvenida dos segundos y después la señal de prueba de 1 kHz. Girar la perilla cambia el ajuste elegido, apretarla pasa al siguiente (TIME → VOLT → POS → LEVL → EDGE → MODE), RUN/STOP congela o reanuda la imagen, SINGLE captura un evento disparado y se detiene, y el botón azul USER cambia la señal de prueba entre 100 Hz, 1 kHz y 5 kHz.
En la pantalla, arriba a la izquierda está el ajuste que mueve la perilla y arriba a la derecha el estado (TRIG, AUTO, WAIT, ARM o STOP). El marcador amarillo del borde izquierdo indica 0 V, el cian del borde derecho el nivel de disparo y la flecha cian de arriba el punto y el flanco del disparo. Abajo quedan la base de tiempo, los voltios por división, la frecuencia, el máximo y el pico a pico.

Cuatro pruebas que valen la pena hacer, porque cada una enseña algo:
- Amplitud y frecuencia. Gira el potenciómetro: la altura de la onda y la lectura VPP cambian, pero la frecuencia se queda en 1,00 kHz. Aprieta USER y la lectura sigue a los 5 kHz.
- Slew rate del amplificador. A 50 µs/div, el flanco de subida de la cuadrada se ve inclinado y no vertical. Es el slew rate de 0,6 V/µs del MCP6002: subir 3,3 V le toma unos 5,5 µs. Eso mismo fija el ancho de banda práctico en unos 50 kHz, aunque el ADC muestree a 600 kS/s.
- Aliasing. A 20 ms/div el equipo muestrea solo 1.500 veces por segundo, menos del doble de la señal de 1 kHz. La imagen se vuelve confusa y la frecuencia marca unos 500 Hz: es el teorema de Nyquist en vivo. Un osciloscopio comercial pone un filtro antialiasing antes del ADC justamente para que esto no te engañe.
- Sensor de luz. Con un LDR conectado a la entrada del amplificador, tapar el sensor o alumbrarlo con una linterna mueve la traza. Con SINGLE y un nivel de disparo justo bajo la línea normal, capturas el instante en que una mano pasa sobre el sensor.

Errores comunes y cómo resolverlos
Varios de estos los encontró el autor en el camino, y te van a pasar igual:
- El refresco es lentísimo: estás mandando 2 bytes por llamada SPI. Arma filas completas en RAM y mándalas de una vez. Revisa también el preescalador de SPI2: bajarlo de 8 a 2 sube el reloj de unos 5,25 MHz a 21 MHz.
- Las ondas viejas se acumulan: nada borra la traza anterior. Repinta el área del gráfico completa en cada cuadro.
- La grilla parpadea o la traza la borra: las estás dibujando por separado. Dibuja grilla, traza y marcadores juntos, fila por fila.
- El TIME/DIV no calza con la realidad: el ADC está en modo continuo. Haz que el TIM2 dispare cada conversión.
- La onda salta de un lado a otro: no hay disparo, o el DMA sobrescribe el búfer mientras dibujas. Usa una captura de 600 muestras en una sola pasada más el disparo por flanco.
- La lectura queda pegada en 0 o en 4.095: revisa que el seguidor tenga los pines 1 y 2 unidos y que el MCP6002 tenga 3,3 V en el pin 8 y GND en el 4.
- El encoder cuenta solo en una dirección o salta: CLK y DT tienen que ir exactamente a PA8 y PA9; si los cambias de pin, el TIM1 ya no los ve como sus canales.
Variantes y mejoras
- Pásalo a una Blue Pill. La STM32F103C8T6 tiene un ADC de 12 bits que se acerca a 1 MS/s, DMA1 canal 1 para el ADC1, SPI2 en los mismos PB13, PB14 y PB15 y el TIM1 en PA8 y PA9, así que buena parte del cableado se mantiene. Hay tres diferencias que sí obligan a tocar el código: el F103 no acepta TIM2 TRGO como disparo del ADC (usa TIM3 TRGO, y mueve la señal de prueba a otro timer, por ejemplo el TIM4), el reloj de los timers baja a 72 MHz (
TIMER_CLOCK_MHZ) y los tiempos de muestreo tienen otros nombres en la HAL F1 (por ejemploADC_SAMPLETIME_13CYCLES_5). Se programa con un ST LINK externo por SWD. - Una entrada protegida de verdad. Para medir señales del mundo real, agrega un conector BNC con atenuación ×1/×10 (un divisor de 9 MΩ y 1 MΩ con su condensador de compensación), un condensador serie conmutable para acoplamiento AC y diodos de protección hacia los rieles. Con un divisor resistivo y un offset de 1,65 V también puedes ver señales negativas.
- Segundo canal y vista FFT. El amplificador B del MCP6002 ya está en el chip: úsalo como seguidor de un segundo canal hacia PA1 y escanea los dos canales con el ADC en modo scan. Con la librería CMSIS DSP puedes sumar una vista de espectro (FFT de 512 puntos) y, mandando el SPI por DMA, ganar cuadros por segundo para mostrarla fluida.
Personalización para Chile
En Chile consigues buena parte del montaje en MechatronicStore:
- Placa de Desarrollo STM32F103C8T6 (SKU N-314): la Blue Pill, alternativa a la NUCLEO-F411RE para la variante descrita arriba. No es la misma placa: corre a 72 MHz, no trae ST LINK integrado y pide portar el firmware a la HAL F1.
- Encoder rotatorio EC11 KY-040 360 (SKU GR2-3): el módulo de 5 pines (CLK, DT, SW, +, GND) que pide el tutorial, con su pulsador incluido.
- Botón Pulsador switch 2 pines 6x6x7mm (SKU GG4-6): los botones RUN/STOP y SINGLE.
- Potenciómetro rotacional lineal por unidad 10K (SKU GB1-5): regula la amplitud de la señal de prueba.
- Resistencias 1/4W 1 unidad 1kΩ (SKU GK3-17): la resistencia de protección entre el amplificador y PA0.
- Condensadores cerámicos 100N (SKU GF17V24): el desacople de la alimentación del MCP6002.
- LDR fotoresistencia resistencia fotosensible sensor de luz 5mm (SKU GC1-3) con una Resistencias 1/4W 1 unidad 10kΩ (SKU GK2-15): para la demostración del sensor de luz arma un divisor entre 3V3 y GND y lleva el punto medio al pin 3 del MCP6002. Cumple la función del módulo LDR del original.
- Breadboard / Protoboard 830 puntos MB102 (SKU C-302) y Cables macho macho 40 piezas 20cm (SKU C-411): para todo el montaje.
- Cable USB a Mini USB 1 metro (SKU N-112): el conector de la NUCLEO-F411RE.
Dos piezas no están en el catálogo: el MCP6002 y la TFT ILI9341 de 2,8". Para el amplificador no uses un TL072 ni un LM358 como reemplazo directo: el TL072 necesita fuente doble y no llega a los rieles, y el LM358 no sube su salida hasta 3,3 V con 3,3 V de alimentación, así que perderías el tramo alto de la escala. Busca un rail to rail equivalente (MCP6002, MCP6022 u otro de entrada y salida rail to rail que funcione a 3,3 V). Para la pantalla, cualquier módulo SPI de 240 × 320 con controlador ILI9341 sirve con el driver del repositorio; una pantalla con otro controlador obliga a reescribir la inicialización.
Recursos
- Tutorial original (inglés): STM32 Digital Oscilloscope: 600kS/s DIY Build with ADC DMA, de Yogesh Bawane en Circuit Digest. Esta versión está basada en él.
- Repositorio GitHub: ImpulseTechy/DIY OSCILLOSCOPE, con el proyecto completo de STM32CubeIDE, el driver de la ILI9341, el diagrama del circuito en alta resolución y un README con los pasos de configuración.
- Herramientas: STM32CubeIDE y la librería HAL STM32Cube FW_F4.
- Documentación adicional: la hoja de datos del MCP6002 de Microchip (slew rate y límites de entrada) y la de la ILI9341 (comandos de la pantalla).
Versión chilena con componentes en stock local en MechatronicStore.












