
电压电流表
简介
基于esp32s3设计的电压电流表,能够测量0~30V的电压,0~3A的电流,供电课输入5~12V电压,可以实现0~10KHz采样率,电压分为两档,一档为0~6v,另一档为0~30v。
简介:基于esp32s3设计的电压电流表,能够测量0~30V的电压,0~3A的电流,供电课输入5~12V电压,可以实现0~10KHz采样率,电压分为两档,一档为0~6v,另一档为0~30v。开源协议
:GPL 3.0
描述
电压电流表硬件设计
为了彩色丝印使用时的美观与整洁,我会尽可能使用贴片的元器件。同时为了方便焊接,元器件封装不小于0603。
(文档内容与附件中”电压电流表硬件设计.docx“相同,我是先用word整理然后上传的,所以内容一样,下载下来后可以离线看,有错误的地方也可以直接改掉,最好在来提醒咱一下错误的内容)
一、芯片选型
这个项目要求使用立创开发板,从开发难度和手头方便的角度考虑,我选择了立创开发板的esp32这块板子来做主控。以下分析基于这块板子。

1.1供电芯片选型
在供电方面,因为esp32这块板子已经有了自身的5V供电和3.3V转换用的LDO电路,所以我们可以直接选择使用板子上的供电。
同时,我也打算使用9V电池供电作为另一个供电方案,所以在供电方便也打算做一个输入用的稳压电路。
由于板子自带5V到3.3V的稳压电路,这里我们只需要使用一个芯片将输入电压稳压至5V即可。

图1-1 lckfb-esp32s3电源电路原理图
在这个需求下,我们常用的芯片分为两类,DC-DC和LDO。
其中,LDO中常用的芯片有1117、7805,这里我选择了和教程之中相同的SE8550K2。其中1117最高输入电压较低,盗版较多难以购买到正版,以及电路之中需要加入钽电容,增加了元器件购买的复杂性和价格,并不适合小量的购买和使用。
(LDO又称为串联线性稳压器,因为输入端和输出段电流相等,在输出电压差大的情况下,其余的能量都被稳压电路以电阻的形式进行消耗)
关于DC-DC的方案,由于外围电路更复杂,具有更大的输出纹波(准确的说是具有输出纹波的属性,但这么说更好理解),同时芯片价格也会更好,这里我们不选择。如果想要尝试,b站up主工科男孙老师的视频很不错,可以参考他进行制作。视频bv号:BV1Mb4y127e9。

图1-2 DC-DC电路设计参考
1.2电压采样
电压采样我们直接通过板子的ADC对外部输入电压进行读取。在采样率要求不高的情况下,可以直接使用板子上自带的ADC。基本上stm32,cw32,tm4c等的单片机的板子自带的ADC都是逐次逼近式的,所以在这个方案上不用挑,速度普遍也都不高。当然,对于声音信号的频谱分析还是能够满足的。(这里性能上来说是不如CW32的,大家根据需求自由选择)
以下是芯片的数据手册中ADC模块的电气特性,我们设计时选择0~1100mV的挡位作为设计参考,后续元器件参数根据这个数值进行计算。后面会根据具体调试得到的实际误差大小,来决定最终使用的挡位和实际的元器件参数。
(LSB(Least Significant Bit)是最低有效位的意思,那么它实际上对应的就是 ADC 的分辨率。一个基准为 5.12V 的 8 位 ADC,它的分辨率就是 0.02V,用它去测量一个电压信号,得到的结果是 100,就表示它测到的电压值是 100*0.02V=2V,假定它的 INL 是 1LSB,就表示这个电压信号真实的准确值是在1.98V~2.02V 之间的,按理想情况对应得到的数字应该是 99~101,测量误差是一个最低有效位,即 1LSB。----来自参考链接)

图1-3 ADC芯片手册电气部分
项目案例之中使用了电位器连接电源电压模拟输入电压,这里我打算做的集成度高一些,所以就不在板子上留有这个电路了,直接在外部电路搭建。我选择的是一个dcdc的升压模块输入测量。
1.3电流采样与放大
原理:使用采样电阻串联于电路之中,测量其两端电压差对电流进行测算。
电流采样分为两种形式,一种称为高侧采样,一种称为底侧采样,我们这里把正负接口都引出,可以使用两种方案,样例之中使用的是底侧采样,采样电路的底侧需要和开发板共地。
参考样例之中使用了100mΩ的电阻,考虑到连接外部电路时也有接触电阻,所以也不需要太小,只要后面测试的时候选择大一些的电压和电阻即可。这里我打算使用小一些的电阻通过电流感应放大芯片进行放大,为对输入电阻敏感的电路做准备。
参考另一个样例(最后一个链接,相关内容可以通过链接查看),电流感应放大器我选择了INA199这款芯片,通过查找数据手册,可以看到这款芯片有三种放大规格,这里我们测量的电流没有那么小,同时对灵敏度的要求也没有那么高,所以选择50倍的即可,即INA199X1的系列。后续我们在对电路中元器件进行设计时也需要考虑到这个放大倍数。

图1-4 INA199芯片手册
1.4连接件相关
这里我们使用的连接件有:
普通的排母,用来连接开发板和屏幕。
一个dc母座用来输入电源。
二、原理图设计
2.1供电电路
底板上使用SE8550K2为芯片的9V~12V稳压至5V的稳压电路。

图2-1 DC 9-12V电源输入电路
以下是关于该电路的详细说明:
1、使用DC电源插座作为输入接口,输入9~12V电压,实际运行可以输入5~30V电压,但是需要调整后面电解电容的耐压和封装。
2、正向串联D1这个肖特基二极管,起防反接的作用,在反向输入电压时,D1电阻趋向无穷,可以防止后端电路损坏。
3、R1起到进行分压操作,一方面减少在高电压情况下LDO由于较大的压差导致发热严重的问题。另一方面,利用了串联的10欧姆小功率电阻过电流小的原理,充当低阻值保险丝,具有电路过流保护或者短路保护作用。
4、C1电解电容滤除DC输入后端低频纹波,C2电解电容滤除芯片输入端低频纹波,C3电解电容滤除芯片输出端低频纹波,在前端输入电压不够时为后端负载提供能量,这里的容值和前面使用的电解电容相同是为了减少购买的电解电容类型,C4,C5滤除相应的高频纹波。
(当电解电容和陶瓷电容并联使用时,电解电容首先过滤掉输入电压中的低频部分,为电路提供稳定的直流电压。随后,陶瓷电容进一步补偿高频波动,滤除高频噪声和脉冲危害。这种高低搭配的滤波方式能够更有效地滤除整个频段的噪声和波动,提高电路的整体性能。此外,陶瓷电容还可以消除电解电容在高频时产生的感性特性(电容的寄生电感),进一步提高滤波效果。)
5、R2和LED1组成指示led电路,可以直观了解该电路工作状态。
2.2电压采样电路
这里我们输入的电压范围为0~30V,而我们设定的最高采样电压是1.1V,所以需要经过的电阻比大约为1:27,为了方便购买,这里我们选择300K的电阻和10K的电阻串联分压。然后也有一个小电压的精细测量电路。

图2-2 电压采样电路
我们还需要注意引脚最大输入电压需要小于等于3.3V,所以我们这里使用钳位二极管将电源钳位到板子上输出的3.3V 。使用的二极管为开关二极管,可以足够快的打开来达到保护电路的效果。
同时,在芯片设计手册中,可以看到建议在ADC输入管脚边上增加一个100nF的电容来保持稳定,这里我们放在底板管脚边上,起到的作用可能一般,这个可以在后续实际测量之中观察。这里需要注意,0.1uF的电容要放在开发板管脚的边上。

图2-3 硬件设计指南中的建议
2.3电流采样与放大电路
这里我们假设最高采样电压是1.1V的挡位,经过芯片放大前的最大可采样电压为22mV,除以最高输入的3A,我们可以得到对应的采样电阻为7.3mΩ,这里我们选用5mΩ的采样电阻,便于购买。
通过这里的采样电阻,我们可以通过得到的采样值计算出对应的电流。
即:采样值/4095 * 22(mV)/5(mΩ)=对应的电流值(A)
通过查询芯片手册,我们可以找到INA199的基础电路。(Typical Application of INA199)

图2-4 Typical Application of INA199
参考这个电路进行绘制的电流采样电路如下。
其中,R7为合金采样电阻,U5是电流感应放大芯片,C8是参考上面电路进行放置的,推测是电源输入滤波用的电容,所以会就近电源引脚放置,C9是ADC采样滤波用的电容,所以需要接近开发板引脚进行放置。

图2-5 电流采样电路
2.4测试用电路
左侧为输入信号,右侧为对应引脚和测试点,这样可以在运行的过程中测试,这里需要更改测试点的封装为后续使用的元器件的封装。

图2-6 测试点与引脚连接
这里使用的时淘宝上购买的铜只因脚,因为价格便宜且满足使用要求(这里我用了2元券,没有券的话实际购买会贵两块),购买的是2*3,所以我们需要更改封装的直径为2mm,然后整体直径可以根据实际需求进行设定,这里我设置了2.7mm。(这里实际使用之中我并没有使用,发现直接就可以插上电压表进行测试了)
淘宝链接:https://item.taobao.com/item.htm?id=522092049395

图2-7 铜鸡脚购买

图2-8 测试点封装属性
2.5 其他外设
第一版我放了四个按键,感觉其实不会很好用,所以第二版我放了两个旋转编码器,软件上打算写一个采样率较小的示波器模式,示波器果然还是旋钮更加顺手。
为了和后面的丝印配合好,将旋转编码器放置在如下两个位置:


同时预留一定空间,为后续增加其他功能做准备。

同时在第二版中,我将供电部分放到了左侧,单独铺铜,用以起到一定的隔离作用。
三、硬件焊接与测试
3.1焊接测试顺序
我在焊接过程之中,先焊接了供电部分,使用锡膏和热风枪一次性焊上去。注意,热风枪吹完之后记得测一下供电部分有没有短路(5V和GND以及二极管两端和GND),板子上的电容的容值不大,炸了没事,但是如果供电输入部分短路,而输入端并没有短路保护(大部分充电器都会有),有可能导致劣质的充电器损坏。
然后我焊接了电压采样电路,这个电路能够脱离电源直接进行测试。
之后焊接电流采样电路,这个电路需要接上核心板才能够运行,因为芯片使用的3v3供电只有核心板上才有对应的供电电路。
最后再将剩余部分按照rf接口、排座、旋转编码器的顺序焊接上去。
3.2焊接注意事项
在焊接电压采样电路之前,记得使用万用表测试以下元器件,方便后续根据具体的电阻阻值进行更准确的电压估算。
在电流采样电路焊接过程之中我们需要注意电流感应放大芯片的丝印的方向,因为它比较小,在软件之中自带的丝印形状和具体引脚定义如图:


图3-1 pcb设计中元器件形状
而芯片本身的丝印如图:

图3-2 芯片丝印
通过这些我们可以大致推断点状丝印的朝向与芯片那一横同向,但是并不准确,所以我们需要去找到芯片手册之中对应引脚定义的内容,将他与pcb上的引脚进行对比。

图3-2 芯片手册引脚定义
这里我们通过引脚的对比可以发现,横线确实与点同向。
同时在焊接该芯片时,由于其引脚间距较小,比较容易连锡,需要记得在焊接完成之后测试以下两个引脚间有没有连锡(只用万用表通断模式搭在两个引脚之前)。同时,由于1脚(REF)和2脚(GND)都是连地的,所以他们之间就是相连的。
3.3电路测试内容
1、供电电路,在按照焊接测试顺序中的描述测量过后,上电。如果LED1灯正常亮起,能够说明该电路能够正常运行。
2、电压采样电路,在焊接之前测量电阻大小,根据具体的电阻阻值比例计算测试点的电压值,将其与实际测量的电压值进行对比。
这里我测出来的四个电阻的阻值是:R3-300.4K,R4-9.96K,R5-100.1,R6-100.8K。
所以我们可以通过换算得到在0~30V的采样中,测试点的电压值=输入电压的电压值*9.96/(9.96+300.4)。在0~3V的采样中,测试点的电压值=输入电压的电压值*100.8/(100.8+100.1)。
这里测试电压使用的是这个升压模块,通过typec进行供电,我们可以方便的从输入两端引出5V用于测量电流采样电路,从输出端引出5~30V的电压,用于测量电压采样电路。

图3-3 升压模块
3、电流采样电路,在焊完后先对电流感应放大芯片进行引脚连锡与否的测试,通过测试后,再对GND和3v3、5v的网络之间的通断进行测试,防止短路损伤核心板。因为这里测试的时候芯片需要核心板上面的3v3供电。
然后测量升压模块输出供电(也可以直接使用其的输入供电),记录其大小。(比如测试时的9.241V),然后根据功率和电流计算出合适阻值的电阻(测试使用的是100欧姆,如果供电电压更小,那么使用的电阻也能够更小,通过的电流也能够更大,测试的电流范围也能够更大)
通过计算,我们可以得到输出的电压应该等于:输入电压/电路阻抗*采样电阻阻抗*感应放大倍数=9.241/100*0.005*50=0.231v
以下是实际测量的结果:

图3-4 电流采样模块测试结果
可以看到和计算中的结果相差了越0.02v,换算成测量的电流则是80mA。这不是测量的最大误差,但可以提供一定的参考。
3.4模块测试
1、tft屏幕测试
将开发板如图方向插入对应排母中,将tft屏幕如图插入对应排母之中,通过typec接口连接至电脑上。

图3-5 连接图
编译、烧录“TFT_TEST.ino”文件,观察tft屏幕是否正常显示(如下图)。

图3-6 测试结果图
四、软件相关
这里我选择使用Arduino对esp32进行开发。
ESP32大多的开发方式为idf、Arduino和micropython,idf和Arduino的编译速度比较慢,调试会消耗一定时间,而micropython虽然上传完成硬件就能够执行,但是代码运行时间更长,同时编译固件也较为麻烦。使用Arduino进行开发能够简单的调用别人写好的库,虽然编译时间较慢,但是整体耗时最短,同时也能够方便的使用底层的代码指令进行更加灵活的操作。
首先硬件连接上之后选择对应的端口设备:

图4-1 端口选择
4.1硬件引脚连接

图4-2 tft屏幕连接引脚

图4-3 旋转编码器连接引脚

图4-4 采样电路连接引脚
整理好后,tft屏幕的硬件引脚为:G09-BL,G10-CS,G11-DC,G12-RES,G13-SDA,G14-SCL。旋转编码器的硬件引脚为:G01-A1,G02-B1,G03-D1,G42-D2,G45-B2,G46-A2。采样部分引脚为:G06-ADC_V_3(0~3v电压采样),G05-ADC_V_30(0~30v电压采样),G07-ADC_I(电流采样)。
4.2 TFT屏幕控制
这里我使用的是Adafruit ST7735这个库,需要在Arduino中选择“库管理器”,搜索“Adafruit GFX Library”并安装,然后同样在库管理器中搜索“Adafruit ST7735 and ST7789 Library”并安装。以下是我安装完成之后显示的内容。

图4-5 Adafruit ST7735库安装完成图
使用这个库需要提前引用“Adafruit_GFX.h”和“Adafruit_ST7735.h”,代码如下:
#include
#include
以下是对于引脚的定义,如果你使用了别的引脚连接tft屏幕,那么只需要修改这里的定义就行。(背光引脚,即BL可以自己设置一个pwm进行亮度控制,不进行控制也可以)
#define TFT_CS 10
#define TFT_RST 12
#define TFT_DC 11
// 为ESP32自定义SPI引脚
#define TFT_MOSI 13
#define TFT_SCLK 14
这个库的一些函数使用方式如下:
//初始化tft对象
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// 初始化显示屏
tft.initR(INITR_BLACKTAB);
//屏幕铺色
tft.fillScreen(ST7735_BLACK);
// 设置屏幕为横屏模式
tft.setRotation(3); // 0: 默认,1: 90度,2: 180度,3: 270度
// 设置文本大小
tft.setTextSize(2.5);
//设置文本位置
tft.setCursor(0, 0);
//设置文本颜色
tft.setTextColor(ST77XX_BLUE); tft.setTextWrap(true);
//显示文本内容
tft.print("Voltmeter");
绘制图形函数:
// 绘制线条
// tft.drawLine(0, 0, 127, 159, ST7735_RED);
// // 绘制矩形
// tft.drawRect(10, 10, 50, 30, ST7735_GREEN);
// tft.fillRect(70, 10, 50, 30, ST7735_BLUE);
// // 绘制圆形
// tft.drawCircle(30, 90, 20, ST7735_YELLOW);
// tft.fillCircle(90, 90, 20, ST7735_CYAN);
// // 绘制三角形
// tft.drawTriangle(30, 130, 50, 160, 10, 160, ST7735_MAGENTA);
// tft.fillTriangle(90, 130, 110, 160, 70, 160, ST7735_ORANGE);
TFT屏幕的用法本质上和串口区别不大,所以以上内容足够简单的控制TFT屏幕以实现本项目了。
4.3 编码器控制
第二版(v1.0)中,我将1、2号引脚用于编码器模块,没有注意到这两个引脚主要用于uart0,这里我打算不让编码器占用uart0,同时由于出了示波器以外,只需要一个旋转编码器就能够完成交互,所以我在编写程序之中,旋转编码器模块只使用了45和46两个引脚的旋转编码器。而旋转编码器模块自带的两个按键则都使能了,根据具体情况使用。
我是用的是Encoder库,这个库可以方便地处理旋转编码器的信号,并计算旋转的方向和位置。在Arduino IDE中,选择库管理器(Sketch -> Include Library -> Manage Libraries)。搜索“Encoder”并安装Encoder by Paul Stoffregen。
在这个库中,我们需要在每一次电平变化的时候使用其自身的read函数来读取变化后的电平,用以确定当前状态。所以这里我们使用硬件中断进行状态的读取。
以下是45和46两个引脚硬件中断的配置函数:
attachInterrupt(digitalPinToInterrupt(46),handleEncoder2,CHANGE);//编码器2A相
attachInterrupt(digitalPinToInterrupt(45),handleEncoder2,CHANGE);//编码器2B相
以下是硬件中断函数(handleEncoder2)的定义:
void IRAM_ATTR handleEncoder2() {
// 中断服务程序的代码
myEnc2.read();
}
其中,IRAM_ATTR是一个特定于ESP32(以及ESP8266)的编译器指令,用于将函数或变量放置在ESP32的内部RAM(IRAM)中。它的作用主要在于优化中断处理函数的执行速度和响应时间。
需要注意这个ram的大小有限,尽量只将硬件中断放入其中,同时注意代码的大小。
4.4模数转换(ADC)
这里推荐直接看官方文档,官方文档讲的很全面,而我们使用的功能也并不复杂,所以可以直接照着写。地址是:https://wiki.lckfb.com/zh-hans/esp32s3r8n8/arduino-beginner/adc.html
如果想要使用高采样率进行采样,建议换成ESP-IDF使用DMA进行开发,这个项目中使用定时器中断进行中等速度(1-10k)的采样。
使用定时器中断之前,我们需要先测试执行adc读取的代码(analogRead)的时间,编译并烧录附录之中“ESP32_ADC_Time.ino”文件,我们可以通过重复执行这段代码一万次,计算平均执行时间以得到这个代码执行一次所需要多少微秒(microseconds)。文件之中也有注释,你可以根据自己的需求更改测试的方式,比如执行多次这个函数,或者执行该函数的同时执行其他函数。

图4-6 “ESP32_ADC_Time.ino”文件执行结果
可以看出,执行一万次花费了301485微秒,执行一次大约需要30微秒,10k的采样率要求中断代码执行时间小于100微秒,说明单纯的read代码能够满足10k的采样率,不过还需要再实际测量之中验证,因为中断传递等内容也需要时间执行。
不过,在使用定时器时,定时器配置的函数报错了,经过排查过后,发现是sdk版本的问题,这里直接跟着教程之中将sdk版本设置成一样即可。
之前的版本是3.0.3,卸载之后将左侧版本号更改为2.0.14就能够正常编译函数,推测是SDK中的库函数进行了更改,本身选择Arduino进行开发就是为了简化、加速开发,所以相比于查看底层寻找问题,不如直接更换SDK的版本进行编译。

图4-7 esp32SDK版本
实际项目中,使用了两个定时器,其中一个用于采样,另一个用于定时触发采样。以下是输入幅值为3.3V的1khz方波,进行10khz采样得到的数据,一个周期为10个数据,可以证明编写的定时器中断函数执行的频率正确。(即函数内容能够在100微秒之内完成)

图4-8 方波测试结果
更改“SAMPLE_SIZE”的数值能够更改采样率,存储用的数组的大小也会随之改变。
对应的程序存储在“ESP32ADC_TEST.ino”之中,可以自行下载测试。
4.5整体程序
由于时间关系,加上是第一次写esp32Arduino的代码,示波器模式、频谱仪模式等难以在时限内完成,所以我先写了一个简单的显示界面。
后续会更新示波器、频谱仪等模式,通过编码器进行调节,同时会更改编码器引脚使得右侧编码器也能够被使用。(底层已经能够实现,主要是编写界面比较耗时,如果看到本项目感兴趣的,可以来帮忙编写一下呀)
程序存储在“VoltmeterAndAmmeter.ino”之中,使用的教程见演示视频。
3D外壳顶层层厚较薄,建议增厚,否则打印效果较差,加上面板之后层厚的影响倒不大。(就像手机壳背壳,有的做工差有的做工好,套个手机壳都一样了)
面板完善中,你可以在文件中增加别的面板避免浪费。
最后,十分感谢老师详细的文档和详尽的视频讲解。让我学到了很多的东西。
文档地址:
https://wiki.lckfb.com/zh-hans/dwx-cw32f030c8t6/training/voltammeter-bootcamp/voltammeter.html
视频地址:https://www.bilibili.com/video/BV1Hw4m1k7PK/
还有参考的文章
Esp官方:
https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_cn.pdf(芯片手册)
Mpy软件开发:
http://t.csdnimg.cn/npC93(屏幕驱动)
ADC部分:
http://t.csdnimg.cn/OaQyu(对于LSB的理解(位的LSB、模数转换的LSB))
电流采样部分:
http://t.csdnimg.cn/uZ7rP(电流感应放大器之指南-TI高精度实验室)
http://t.csdnimg.cn/ckecA(运放-电阻式电流采样-高压侧和低压侧电流采样方案)
https://oshwhub.com/limengmeng12345/ji-chu-ying-usb-dian-ya-biao(开源工程)
设计图
未生成预览图,请在编辑器重新保存一次BOM
暂无BOM
克隆工程工程成员
知识产权声明&复刻说明
本项目为开源硬件项目,其相关的知识产权归创作者所有。创作者在本平台上传该硬件项目仅仅供平台用户用于学习交流及研究,不包括任何商业性使用,请勿用于商业售卖或其他盈利性的用途;如您认为本项目涉嫌侵犯了您的相关权益,请点击上方“侵权投诉”按钮,我们将按照嘉立创《侵权投诉与申诉规则》进行处理。
请在进行项目复刻时自行验证电路的可行性,并自行辨别该项目是否对您适用。您对复刻项目的任何后果负责,无论何种情况,本平台将不对您在复刻项目时,遇到的任何因开源项目电路设计问题所导致的直接、间接等损害负责。


评论