Oscilloscope de bricolage utilisant ESP32 – Aperçu rapide
Construire le temps: 6-8 heures | Coût: 30-50 $ | Difficulté: Intermédiaire
Ce que vous apprendrez: Échantillonnage ADC, communication SPI, interfaçage d’affichage TFT, manipulation d’interruption
Applications: Débogage du signal, analyse des formes d’onde, mesure de fréquence, surveillance de la tension
| Fonctionnalité | Spécification | Performance |
| Canaux | Canal unique | Est-ce que le travail pour l’analyse du signal de base |
| Taux d’échantillonnage | 1MSPS | Idéal pour l’analyse audio, capteur et à basse fréquence |
| Tampon | 50000 @ 16bits | Capture de données 50 ms à 1MSPS |
| Échelle de temps | 10us / div à 5ms / div | Options de synchronisation polyvalente |
| Tension d’entrée | 3,3 V (1x), 33V (10x) | Plage d’exploitation sûre |
| Temps de réponse | Contrôle tactile rapide | Surveillance du signal en temps réel |
| Gamme de fréquences | 20 Hz minimum | Limité par les contraintes de tampon |
»Il a une fonctionnalité de filtre moyenne sur / désactivée simple
»Mesures de tension max, min, moyenne et crête de pointe
»Ajustements de décalage de temps et de tension
»Fonctionnement du mode analogique et numérique / données
»Capacité de déclenchement unique
»Fonction à l’échelle automatique pour la configuration automatique
| Composant | Spécification | Quantité | But |
| ESP32 Devkit | Variante à 38 broches recommandée | 1 | Le microcontrôleur principal |
| Affichage TFT | 1,69 « 240×280 ST7789 | 1 | Visualisation du signal |
| Commutateurs tactiles | 6 mm standard | 6 | Contrôle de l’interface utilisateur |
| Commutateurs SPDT | Type à bascule | 2 | Sélection de plage / couplage |
| Résistances | 100k, 10k | 1 chacun | Conditionnement d’entrée |
| Condensateur | Céramique 100NF | 1 | Couplage AC |
| PCB / Perfboard | Cuivre vêtu de cuivre | 1 | Assemblage de circuit |

»Rendu de forme d’onde haute résolution
»Mises à jour du signal en temps réel
»Esclot de carte SD intégré pour la journalisation des données futures
»La conception maintient la consommation d’énergie au minimum
»Mesure de tension à double portée (3,3 V et 33 V)
»Sélection de couplage AC / DC
»Circuits de protection d’entrée
»Division de tension de précision
»Route de signal optimisé pour un bruit minimal
»Conception de facteur de forme compact
»Accessibilité des composants faciles
»Compatible pour la fabrication professionnelle
Processus d’assemblage:
»Vérification du placement des composants
»Optimisation de séquence de soudage
»Test de chemin de signal
»Procédures d’étalonnage
Étapes de programmation:
»Installation de la bibliothèque: Extraire le dossier de bibliothèque TFT_ESPI modifié à Arduino
»Sélection du conseil: Choisissez ESP32 dans Arduino Board Manager
»Compilation de code: Vérifiez la compilation de code sans erreurs
»Télécharger le processus: Flash firmware sur ESP32 via USB
»Configuration de l’alimentation: utilisez le port micro USB pour l’alimentation 5V
Caractéristiques du code:
»Gestion de tampon I2S optimisée
»Rendu de forme d’onde en temps réel
»Interface utilisateur axée sur l’interruption
»Routines d’étalonnage
»Algorithmes de traitement du signal
Référentiel GitHub
Questions courantes sur ce projet d’oscilloscope ESP32
Q1. Cela peut-il remplacer un véritable oscilloscope?
Pas vraiment. Un DSO commercial (Rigol, Siglent, etc.) peut goûter des centaines de fois plus rapidement et a une mémoire profonde, plusieurs canaux et des fins frontales précises. Cette version ESP32 est plus une «portée d’apprentissage», idéale pour l’audio, les capteurs et les signaux numériques lents, mais il ne captera pas des problèmes à grande vitesse ou une activité de bus MHZ.
Q2. Quelle est la plage d’entrée sûre?
Avec le diviseur de tension, vous pouvez regarder des signaux jusqu’à environ 33 V pic. Sans cela, l’ESP32 ne tolère que 3,3 V max. Ne connectez pas cela directement aux secteur (120/230 V AC) ou quoi que ce soit de haute énergie. Ce n’est pas isolé et vous frirez la planche (ou vous-même).
Q3. Pourquoi la forme d’onde a-t-elle l’air bruyante ou un peu «déchiquetée»?
C’est juste l’ADC de l’ESP32. Ce n’est pas de qualité en laboratoire. Il y a du bruit de quantification et de la non-linéarité. Le filtre moyen aide, mais vous devez vous attendre à des parcelles «assez bonnes», pas à des signaux de rasoir comme vous le verriez sur un tektronix.
Q4. Quel est le signal de fréquence le plus élevé que je peux mesurer?
Réfléchissez dans les dizaines de KHZ, peut-être des centaines basses si vous n’êtes pas pointilleux sur la précision. La fréquence d’échantillonnage 1 MSPS et la taille du tampon limitent la bande passante. C’est bien pour les données PWM, audio et capteurs. Pas pour RF ou des bus numériques rapides comme SPI ou USB.
Q5. Est-ce vraiment «en temps réel»?
Sorte de. L’affichage met à jour assez rapidement pour qu’il se sente en direct pour les signaux lents et à mi-vitesse. Mais par rapport à une portée commerciale, il y a un décalage notable et la profondeur de capture est peu profonde. C’est assez en temps réel pour le travail de passe-temps, pas pour déboguer un circuit complexe.
Projets ESP32 et Arduino connexes


Générateur de fonctions basé sur AD9833 et Arduino
Dans cet article, nous allons construire un générateur de signaux simple avec un module de générateur de fonction ARDUINO et AD9833 qui peut produire des ondes sinusoïdales, carrées et triangulaires avec une fréquence maximale de 12 MHz à la sortie.

Lecteur audio basé sur DIY ESP32
Ici, nous utilisons LM386 et un haut-parleur avec ESP32 pour lire des fichiers musicaux. La sortie audio n’est peut-être pas bruyante, mais cette application montre la capacité de la carte ESP32 à lire des fichiers audio.
Code de projet complet
Copier de code
#include #include #include #include #include #include #include "esp_adc_cal.h" #include "filters.h" //#define DEBUG_SERIAL //#define DEBUG_BUFF #define DELAY 1000 // Width and height of sprite #define WIDTH 240 #define HEIGHT 280 #define ADC_CHANNEL ADC1_CHANNEL_5 // GPIO33 #define NUM_SAMPLES 1000 // number of samples #define I2S_NUM (0) #define BUFF_SIZE 50000 #define B_MULT BUFF_SIZE/NUM_SAMPLES #define BUTTON_Ok 32 #define BUTTON_Plus 15 #define BUTTON_Minus 35 #define BUTTON_Back 34 TFT_eSPI tft = TFT_eSPI(); // Declare object "tft" TFT_eSprite spr = TFT_eSprite(&tft); // Declare Sprite object "spr" with pointer to "tft" object esp_adc_cal_characteristics_t adc_chars; TaskHandle_t task_menu; TaskHandle_t task_adc; float v_div = 825; float s_div = 10; float offset = 0; float toffset = 0; uint8_t current_filter = 1; //options handler enum Option { None, Autoscale, Vdiv, Sdiv, Offset, TOffset, Filter, Stop, Mode, Single, Clear, Reset, Probe, UpdateF, Cursor1, Cursor2 }; int8_t volts_index = 0; int8_t tscale_index = 0; uint8_t opt = None; bool menu = false; bool info = true; bool set_value = false; float RATE = 1000; //in ksps --> 1000 = 1Msps bool auto_scale = false; bool full_pix = true; bool stop = false; bool stop_change = false; uint16_t i2s_buff[BUFF_SIZE]; bool single_trigger = false; bool data_trigger = false; bool updating_screen = false; bool new_data = false; bool menu_action = false; uint8_t digital_wave_option = 0; //0-auto | 1-analog | 2-digital data (SERIAL/SPI/I2C/etc) int btnok,btnpl,btnmn,btnbk; void IRAM_ATTR btok() { btnok = 1; } void IRAM_ATTR btplus() { btnpl = 1; } void IRAM_ATTR btminus() { btnmn = 1; } void IRAM_ATTR btback() { btnbk = 1; } void setup() { Serial.begin(115200); configure_i2s(1000000); setup_screen(); pinMode(BUTTON_Ok , INPUT); pinMode(BUTTON_Plus , INPUT); pinMode(BUTTON_Minus , INPUT); pinMode(BUTTON_Back , INPUT); attachInterrupt(BUTTON_Ok, btok, RISING); attachInterrupt(BUTTON_Plus, btplus, RISING); attachInterrupt(BUTTON_Minus, btminus, RISING); attachInterrupt(BUTTON_Back, btback, RISING); characterize_adc(); #ifdef DEBUG_BUF debug_buffer(); #endif xTaskCreatePinnedToCore( core0_task, "menu_handle", 10000, /* Stack size in words */ NULL, /* Task input parameter */ 0, /* Priority of the task */ &task_menu, /* Task handle. */ 0); /* Core where the task should run */ xTaskCreatePinnedToCore( core1_task, "adc_handle", 10000, /* Stack size in words */ NULL, /* Task input parameter */ 3, /* Priority of the task */ &task_adc, /* Task handle. */ 1); /* Core where the task should run */ } void core0_task( void * pvParameters ) { (void) pvParameters; for (;;) { menu_handler(); if (new_data || menu_action) { new_data = false; menu_action = false; updating_screen = true; update_screen(i2s_buff, RATE); updating_screen = false; vTaskDelay(pdMS_TO_TICKS(10)); Serial.println("CORE0"); } vTaskDelay(pdMS_TO_TICKS(10)); } } void core1_task( void * pvParameters ) { (void) pvParameters; for (;;) { if (!single_trigger) { while (updating_screen) { vTaskDelay(pdMS_TO_TICKS(1)); } if (!stop) { if (stop_change) { i2s_adc_enable(I2S_NUM_0); stop_change = false; } ADC_Sampling(i2s_buff); new_data = true; } else { if (!stop_change) { i2s_adc_disable(I2S_NUM_0); i2s_zero_dma_buffer(I2S_NUM_0); stop_change = true; } } Serial.println("CORE1"); vTaskDelay(pdMS_TO_TICKS(300)); } else { float old_mean = 0; while (single_trigger) { stop = true; ADC_Sampling(i2s_buff); float mean = 0; float max_v, min_v; peak_mean(i2s_buff, BUFF_SIZE, &max_v, &min_v, &mean); //signal captured (pp > 0.4V || changing mean > 0.2V) -> DATA ANALYSIS if ((old_mean != 0 && fabs(mean - old_mean) > 0.2) || to_voltage(max_v) - to_voltage(min_v) > 0.05) { float freq = 0; float period = 0; uint32_t trigger0 = 0; uint32_t trigger1 = 0; //if analog mode OR auto mode and wave recognized as analog bool digital_data = !false; if (digital_wave_option == 1) { trigger_freq_analog(i2s_buff, RATE, mean, max_v, min_v, &freq, &period, &trigger0, &trigger1); } else if (digital_wave_option == 0) { digital_data = digital_analog(i2s_buff, max_v, min_v); if (!digital_data) { trigger_freq_analog(i2s_buff, RATE, mean, max_v, min_v, &freq, &period, &trigger0, &trigger1); } else { trigger_freq_digital(i2s_buff, RATE, mean, max_v, min_v, &freq, &period, &trigger0); } } else { trigger_freq_digital(i2s_buff, RATE, mean, max_v, min_v, &freq, &period, &trigger0); } single_trigger = false; new_data = true; Serial.println("Single GOT"); //return to normal execution in stop mode } vTaskDelay(pdMS_TO_TICKS(1)); //time for the other task to start (low priorit) } vTaskDelay(pdMS_TO_TICKS(300)); } } } void loop() {}Retrouvez l’histoire de Raspberry Pi dans cette vidéo :
ESP32 4-Channel Relay Module Ulegqin ESP32-WROOM Relay Carte de développement avec WIFI Bluetooth BLE Alimentation AC/DC pour Projets de programmation DIY(LC-Relay-ESP32-4R-A2)
BSIDE OT5 Mini Oscilloscope Numérique Portable 50MHz Bande Passante 200MSa/s Échantillonnage Oscilloscope de Poche Rechargeable Ultra Mince avec Écran Couleur 3,2” pour Électronique Audio Automobile

