基于ESP32实现示波器的制作教程

发布时间:2023-03-28  

  示波器是任何电子工程师必备的测试仪器。它用于可视化和观察各种信号,通常作为一个二维图,其中一个或多个信号随时间绘制。它们用于电子设备的设计和调试,以查看和比较波形,并确定施加在其输入端的信号随时间变化的电压电平、频率、噪声和其他参数。这使得示波器成为电子工程师或制造商办公桌上非常重要的工具。然而,示波器相当昂贵。入门级型号的价格从 500 美元到 2,000 美元不等。而先进的示波器则要花费数千美元,这使得它们超出了基本用户的承受能力。但是如果我们能创造出一种更便宜、更紧凑、并且容易制作?这就是导致今天教程的问题。

  ESP32 示波器功能

  单通道

  1Msps

  50000 @ 16bits 缓冲区(50ms 数据,1Msps)

  在 1Msps 时从 10us/div 扩展到 5ms/div

  1X 模式下的最大 VPP 3.3V 和 10X 模式下的 33V

  使用触觉开关进行快速响应控制。

  频率计算(20hz min 由于缓冲区大小)

  简单均值滤波器开/关

  最大、最小、平均和峰峰值电压

  时间和电压偏移

  模拟、数字/数据模式

  单次触发

  自动缩放

  构建基于 ESP32 的示波器所需的组件

  ESP32 开发套件

  1.69” 240x280 圆角 TFT 显示器(ST7789s)

  触觉开关

  单刀双掷开关

  100K电阻

  10K电阻

  100nF电容

  覆铜板或穿孔板

  焊接工具

  ESP32示波器电路图

  下面给出了基于 ESP32 的示波器的完整电路图。

poYBAGLKM_uAND4QAAFh3txgaIQ478.png

  ESP32 用作数据采集的控制器。我们将利用内置的 I2S 缓冲区来存储和操作信号。这里使用 38 Pin 变体,但您也可以使用其他开发模块。

pYYBAGLKM_iALX7kAAEVz0dPU5Y011.png

  对于显示,我们使用的是 1.69” TFT 显示模块。它的分辨率为 240x280 像素。显示控制器是 ST7789S,为了驱动它,我们将使用 SPI 通信。

pYYBAGLKM_KAa9TsAAChLANxAWc802.png

  该模块还包含一个我们尚未使用的 SD 卡插槽。我们可以在未来的更新中将其用于波形捕获或类似应用。

poYBAGLKM_WABLhuAAPzJG4qDJ8575.png

  键盘非常简单。带有上拉电阻的触觉开关用于此目的。我们正在使用硬件中断来检测每个按键。这将为我们提供一个非常灵敏的键盘。您可以了解我们之前介绍的ESP32 中断。

pYYBAGLKM-uAM1SFAACG2trtwyk980.png

  模拟输入部分相当简单。它由两个 SPDT 开关组成,用于范围选择和 AC/DC 耦合选择。对于范围选择,我们添加了一个分压器,可用于馈送峰值电压高于 3.3V 的信号。分压器将信号转换为 10:1 的比率。

pYYBAGLKM-mAdw3JAACh89aUV4s072.png

  构建和测试电路

  您可以在 perfboard 中构建此项目,也可以使用页面底部链接中的文件制作 PCB。包括用于墨粉转移方法的 PDF 文件和用于制造的 Gerber 文件。这是示波器的 PCB 布局。

poYBAGLKM-2AWJ1EAANux9LScV4325.png

  这是相同的PCB视图。

poYBAGLKM-GAQZ-aAALeonXbYqQ009.png

  底部 PCB 视图。

poYBAGLKM_KAKZR5AAOTKM8ElG8659.png

  用于示波器的 Arduino 代码

  从本文底部给出的 Circuit Digest GitHub 存储库链接下载整个代码。在 GitHub 存储库中,您还可以找到一个名为TFT_eSPI的存档。这个修改后的库是驱动显示器所必需的。将其解压缩到 Arduino 库文件夹。如果您已经安装了TFT_eSPI 库,请确保在提取修改后的库之前将其删除。完成后,在板管理器中选择 esp32。然后编译代码并上传。就是这样,我们的 DIY 示波器就可以使用了。您可以使用底部的 Micro USB 端口为示波器供电。此端口仅用于供电。

  代码


  #include


 


#include

#include

#include 

#include 

#include 

#include “esp_adc_cal.h”

#include “过滤器.h”

//#define DEBUG_SERIAL

//#define DEBUG_BUFF

#define 延迟 1000

//精灵的宽度和高度

#定义宽度 240

#定义高度 280

#define ADC_CHANNEL ADC1_CHANNEL_5 // GPIO33

#define NUM_SAMPLES 1000 // 样本数

#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(); // 声明对象“tft”

TFT_eSprite spr = TFT_eSprite(&tft); // 使用指向“tft”对象的指针声明 Sprite 对象“spr”

esp_adc_cal_characteristics_t adc_chars;

TaskHandle_t 任务菜单;

TaskHandle_t task_adc;

浮动 v_div = 825;

浮动 s_div = 10;

浮动偏移量 = 0;

浮动toffset = 0;

uint8_t current_filter = 1;

//选项处理程序

枚举选项 {

  没有任何,

  自动缩放,

  分压,

  斯迪夫,

  抵消,

  偏移量,

  筛选,

  停止,

  模式,

  单身的,

  清除,

  重置,

  探测,

  更新F,

  光标1,

  光标2

};

int8_t volts_index = 0;

int8_t tscale_index = 0;

uint8_t opt = 无;

布尔菜单=假;

布尔信息=真;

布尔 set_value = false;

浮动率 = 1000;//以 ksps --> 1000 = 1Msps

bool auto_scale = false;

bool full_pix = true;

布尔停止=假;

bool stop_change = false;


uint16_t i2s_buff[BUFF_SIZE];


bool single_trigger = false;

布尔数据触发器 = 假;


布尔更新屏幕=假;

布尔新数据=假;

布尔菜单操作 = 假;

uint8_t digital_wave_option = 0;//0-自动 | 1-模拟 | 2 位数据 (SERIAL/SPI/I2C/etc)

int btnok,btnpl,btnmn,btnbk;

无效 IRAM_ATTR btok()

{

  btnok = 1;

}

无效 IRAM_ATTR btplus()

{

  btnpl = 1;

}

无效 IRAM_ATTR btminus()

{

  btnmn = 1;

}

无效 IRAM_ATTR btback()

{

  btnbk = 1;

}

无效设置(){

  序列号.开始(115200);


  configure_i2s(1000000);


  设置屏幕();


  pinMode(BUTTON_Ok,输入);

  pinMode(BUTTON_Plus,输入);

  pinMode(BUTTON_Minus,输入);

  pinMode(BUTTON_Back,输入);

  attachInterrupt(BUTTON_Ok, btok, RISING);

  attachInterrupt(BUTTON_Plus, btplus, RISING);

  attachInterrupt(BUTTON_Minus, btminus, RISING);

  attachInterrupt(BUTTON_Back, btback, RISING);


  特征ADC();

#ifdef DEBUG_BUF

  调试缓冲区();

#万一


  xTaskCreatePinnedToCore(

    core0_task,

    "menu_handle",

    10000, /* 以字为单位的堆栈大小 */

    NULL, /* 任务输入参数 */

    0, /* 任务的优先级 */

    &task_menu, /* 任务句柄。*/

    0); /* 任务应该运行的核心 */


  xTaskCreatePinnedToCore(

    core1_task,

    "adc_handle",

    10000, /* 以字为单位的堆栈大小 */

    NULL, /* 任务输入参数 */

    3、/*任务的优先级*/

    &task_adc, /* 任务句柄。*/

    1); /* 任务应该运行的核心 */

}



无效的core0_task(无效* pvParameters){


  (void) pvParameters;


  为了 (;;) {

    菜单处理程序();


    如果(新数据 || 菜单操作){

      新数据=假;

      菜单操作 = 假;


      更新屏幕=真;

      更新屏幕(i2s_buff,速率);

      更新屏幕=假;

      vTaskDelay(pdMS_TO_TICKS(10));

      Serial.println("CORE0");

    }


    vTaskDelay(pdMS_TO_TICKS(10));

  }


}


无效core1_task(无效* pvParameters){


  (void) pvParameters;


  为了 (;;) {

    如果(!single_trigger){

      而(更新屏幕){

        vTaskDelay(pdMS_TO_TICKS(1));

      }

      如果(!停止){

        如果(停止更改){

          i2s_adc_enable(I2S_NUM_0);

          stop_change = 假;

        }

        ADC_Sampling(i2s_buff);

        新数据=真;

      }

      别的 {

        如果(!stop_change){

          i2s_adc_disable(I2S_NUM_0);

          i2s_zero_dma_buffer(I2S_NUM_0);

          stop_change = 真;

        }

      }

      Serial.println("CORE1");

      vTaskDelay(pdMS_TO_TICKS(300));

    }

    别的 {

      浮动 old_mean = 0;

      而(single_trigger){

        停止=真;

        ADC_Sampling(i2s_buff);

        浮动平均值 = 0;

        浮动 max_v, min_v;

        peak_mean(i2s_buff, BUFF_SIZE, &max_v, &min_v, &mean);


        //信号捕获(pp > 0.4V || 变化平均值 > 0.2V)-> 数据分析

        if ((old_mean != 0 && fabs(mean - old_mean) > 0.2) || to_voltage(max_v) - to_voltage(min_v) > 0.05) {

          浮动频率 = 0;

          浮动周期 = 0;

          uint32_t 触发器0 = 0;

          uint32_t 触发器1 = 0;


          //如果模拟模式或自动模式和波形识别为模拟

          布尔数字数据=!假;

          if (digital_wave_option == 1) {

            trigger_freq_analog(i2s_buff, RATE, mean, max_v, min_v, &freq, &period, &trigger0, &trigger1);

          }

          否则如果(digital_wave_option == 0){

            数字数据=数字模拟(i2s_buff,max_v,min_v);

            如果(!数字数据){

              trigger_freq_analog(i2s_buff, RATE, mean, max_v, min_v, &freq, &period, &trigger0, &trigger1);

            }

            别的 {

              trigger_freq_digital(i2s_buff, RATE, mean, max_v, min_v, &freq, &period, &trigger0);

            }

          }

          别的 {

            trigger_freq_digital(i2s_buff, RATE, mean, max_v, min_v, &freq, &period, &trigger0);

          }


          单触发器 = 假;

          新数据=真;

          Serial.println("单机");

          //在停止模式下返回正常执行

        }


        vTaskDelay(pdMS_TO_TICKS(1)); //其他任务开始的时间(低优先级)


      }

      vTaskDelay(pdMS_TO_TICKS(300));

    }

  }

}

无效循环(){}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    stm32单片机用什么软件编程;  今天要和大家分享的是stm32单片机用什么软件编程相关信息。   想学单片机开发,最主要是熟悉stm32的软件开发环境,目前stm32的开发环境,主流是KEIL和......
    stm32用什么软件写程序;  stm32用什么软件写程序?STM32单片机在编程时可以使用库函数和使用配置寄存器的方式来进行程序的实现。   在学习stm32的过程中我们会用到编程环境:Keil......
    单片机编程用什么软件?单片机开发软件有哪些?;单片机编程需要的软件其实不多,网上看了很一大堆,什么protues仿真、Labview、Pycharm等等,其实完全没必要一下装这么多。 我从......
    形式为DIP40,相信大家在大学里学单片机的时候老师都是用这一款教的吧。 3 硬件原理设计 芯片选型完毕之后,又有了设计思路,那就赶快把电路图画出来吧。画电路图用什么软件呢?这样的EDA工具很多,像......
    stm32系列简介与stm32 esp32性能比较;STM32应该是比较熟悉的一个系列的单片机,而ESP32相对陌生一些。但是从名字看,两者应该都是32位单片机。那么两者之间到底有什么关联,或者......
    物联网开发用什么单片机?单片机在物联网系统中的作用是什么?;物联网基本能涵盖全行业,如果没涵盖,那一定是痛点和需求没被挖掘出来。 我算是比较早那一批接触物联网产品开发的,记得......
     (16 KB 专用于 cache) 和 576 KB ROM,具有 14 个可编程 GPIO 管脚,支持 SPI、UART、I2C、GDMA 和 PWM。  广告 ESP32-C2......
    某些情况下精度仍然受限,如在复杂的背景下,图像分析和处理的精度受到影响。   做机器视觉用什么软件好   做机器视觉需要使用一些专业的软件,以下是几个比较好的机器视觉软件:   OpenCV:OpenCV是一......
    、Dual SPI、Quad SPI、QPI flash。ESP32-C6具有22个可编程GPIO管脚,支持ADC、SPI、UART、I2C、I2S、RMT、TWAI和PWM。 ESP32-C6功能......
    -IDF 软件环境的 v5.1。 “对于希望将 ESP32-C6 用作带外部主机的通信协处理器的客户,还可以使用 ESP-Hosted 和 ESP-AT 固件。 ESP32-C6 也将通过 ESP......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>