×

Arduino负电压表

消耗积分:0 | 格式:zip | 大小:0.08 MB | 2023-02-09

分享资料个

描述

介绍

坚持只有一个万用表/电压表?但是,有时您需要同时检查 2 或 3 个电压。那么您可能会考虑制作一个真正的直流电压表!

采用常用组件和易于理解的代码设计,可以同时测量单个威廉希尔官方网站 或 3 个独立威廉希尔官方网站 中 3 个节点的正电压和负电压。

示范

 

硬件

以下硬件用于构建此设备:-

  • Arduino Uno:在 ATmega328P 微控制器上上传代码
  • ATmega328P:带有 Arduino Bootloader 和内置 10 位 ADC 的 8 位微控制器
  • 带 I2C 接口的 128x32 1306 OLED 显示屏:显示电压
  • LM324 OpAmp:ADC 的模拟信号调理
  • 4cm x 6 cm FR4 原型板:构建威廉希尔官方网站 板
  • 10k 多圈电位器:调整零(半 AREF)电压
  • TP4056模块:锂聚合物电池充电
  • LiPo电池:300mAh可充电电池为设备供电
poYBAGPjUl-AFDxvAAMQY8fDxKA245.jpg
硬件
 

工作原理:AFE 解释

通常,ATmega328P (Arduino Uno) 可以测量 Gnd 和 AVCC 范围之间的电压(即 0 到 5V),无需任何分压电阻网络。如果启用内部 AREF,它可以测量 Gnd 和 AREF 范围之间的电压(即 0 到 1.1 V)。使用一些分压器,可以测量高于 5V 的电压。这些都是相对于 Gnd 的正电压。

但它无法测量低于 Gnd 的任何电压,这意味着它无法测量负电压。问题是,ATmega328P 有一个单端 ADC,默认情况下会根据Gnd 进行测量。

解决办法是,不要再对 Gnd 进行测量。

真正的电压表有 COM(黑色)和 V(红色)端子,您将 COM 连接到一个节点,V 连接到威廉希尔官方网站 上的另一个节点。相对于 COM 节点,V 节点上的电压读数。

您需要构建一个 (AFE)模拟前端,某种信号调节威廉希尔官方网站 来生成类似 COM 的行为。此 COM 节点的电压应介于 AVCC 和 Gnd 之间。理想情况下,AVCC 电压的一半,但对于本设计,它是 AREF 的一半。

当对 COM 进行外部电压测量时,您可以轻松测量正电压和负电压!

请仔细检查以下威廉希尔官方网站 :

pYYBAGPjUmGAOYaEAADXZdp-pys076.png
使用 2 个单端 ADC 通道进行差分测量
 

那么,这里发生了什么?内部参考 AREF 在 ATmega328P 上启用(来自无效设置中的固件/代码)。AREF 引脚为 1.1 V。现在,ADC 测量的有效范围为 0 至 1.1 伏。

接下来,使用 LM324 运算放大器缓冲这个 1.1 AREF 电压,这意味着我们仍然有来自第一个运算放大器输出的 1.1 电压。一个 10k 多圈微调电位器精确设置为 5k 以产生 550mV(半 AREF)伏特。这个 550 mV 信号由第二个运算放大器缓冲。550 mV 信号也连接到 ADC Ch - 0。它应该读取 512(10 位的一半)。

有一个分压器网络由 5 兆欧姆(两个 10M 并联)和 100 千欧姆电阻组成,连接到第二个运算放大器的输出。

我将此分压器网络上的电阻较低端 (100k) 定义为 COM,电阻较高端 (5M) 端定义为 V。此分压器的中点连接到 ADC Ch - 1。当没有外部电压施加到此分压器时,ADC Ch - 1 应读取 512(因为 550 mV)

当施加外部电压时,分压器中点电压将移动到 550 mV 以上或以下。如果 V 上的外部电压相对于 COM 较高(正电压),它将移动到 550 mV 以上,如果 V 上的外部电压相对于 COM 较低(负电压),它将移动到 550 mV 以下。ADC Ch-1 读数将相应改变。使用 ADC 读数的这种变化,我们可以计算外部电压。

为什么使用 AREF 而不是 AVCC ?

此设计由 LiPo 电池供电,充满电的 LiPo 将从 4.2 伏开始,电压会逐渐下降。所以,AVCC也会发生变化。但内部参考 AREF 具有恒定的 1.1 伏特。这就是我选择 AREF 的原因。

如果使用其他没有AREF的单片机,​​可以使用TL431 IC来产生参考电压!

为什么使用 LM324 运算放大器?

LM324 IC 在一个封装中有 4 个运算放大器,应用广泛,它的输出可以(非常接近)Gnd。它还适用于 3 至 32 伏之间的任何电源电压。

您始终可以使用更好的运算放大器(精密、低噪声、轨到轨)

电压计算公式

使用 ADC 测量的电压将是实际施加电压的一小部分。这就是为什么在固件内部使用以下公式来计算实际电压的原因:-

pYYBAGPjUmSAJuocAACKgjbcZWM798.png
公式
 

分压电阻器:范围与分辨率

  • 选择正确的输入电阻 R_Low 和 R_High 很重要,因为电阻值将根据以下公式确定有效电压测量范围:

+/- V = (R_High / R_Low) / 2

  • R_High和 R_Low 必须具有可以处理测量电压的额定功率,应满足以下公式:

V < sqrt ((R_High + R_Low) * P)

  • 电压测量设备的输入阻抗必须在数百千欧到几兆欧的数量级,以最大限度地减少负载效应

R_High + R_Low > hundreds of kOhms to few MOhms

对于这个项目,这个电压表可以测量 +/- 25 伏特R_High = 5M(或 5000k)和 R_Low = 100K ,额定功率为 1/10 瓦满足以上 3 个条件

  • 接下来是测量分辨率,它受实际 ADC 分辨率和您要设置的有效测量范围的限制。ADC 分辨率是可以识别的最小增量电压。

Measurement Resolution = Measurement Range / ADC Resolution

  • 例如:如果使用 10 位 ADC 将测量范围设置为 +/- 5 V,您应该在该范围内获得大约 10 mV 的分辨率。但对于这个测量范围为 +/- 25 V(总计 50V)的设计,分辨率约为 49 mV。
  • 分辨率还取决于显示器中显示的位数。此设计仅显示小数点后一位数字,因此 49 mV 分辨率可高达 100 mV 或 0.1 伏特。

示例:假设新的 AA 电池用 Fluke 电压表读数为 1.627 伏,但该电压表可能读数仅为 1.5 或 1.6 或 1.7 伏

  • For better range or resolution select microcontroller with 12 bit ADC or more
  • Reduce measurement range to increase resolution
  • Reduce resolution to increase range or measure bigger voltages

准确性:硬件和软件设计如何提供帮助

准确性取决于很多因素。在这个项目中实现了以下一些技巧。

  • 首先,输入电阻(分压器 R_Low 和 R_High 上的电阻)必须具有更好的容差,大约为 1% 或更小这将确保电阻器的电阻非常接近其额定值。
  • AVCC 和 Gnd 引脚上带有去耦电容器的稳定电源(最好是电池,无 SMPS)将降低噪声。建议使用 10uF 电容
  • 稳定的AREF 或模拟参考电压对于精度非常重要,放置一个 100nF 的电容就可以做到这一点。
  • 使用低噪声电子设备将有助于提高准确性(更好的 Opamp)
  • 建议在模拟前端采用良好的布线做法和屏蔽

在固件中实施以下操作将提高准确性:-

  • 在切换模拟通道之前/之后添加轻微的延迟
  • 丢弃第一个模拟转换值
  • 几百个样本并取平均值以提高准确性
  • 使用偏移变量进行读数的软校正/调整

尽管可以使用以下代码将 Arduino UNO 或 Atmega328P 的 AREF 引脚设置为 1.1 伏

analogReference(INTERNAL);

不同芯片的实际 AREF 电压可能在 1.06 伏到 1.13 伏之间变化。建议使用高精度万用表测量 AREF 引脚,并找到实际电压。然后在代码中定义它以获得更高的准确性

#define AREF 1.097            // Aref pin voltage

不要只是复制粘贴 1.1 伏!

输入保护:安全问题!

这是用于过压或浪涌保护的双向二极管钳位,您可以与 R_Low 并联使用。由于空间不足,我将这部分留在了我的构建中!

pYYBAGPjUmeAKG-OAAAc2YPQkdA414.bmp
双向电压钳
 

安全永远不能掉以轻心!当 R_Low 两端的电压超过 +/- 800 mV 时,这些二极管将开始钳位。这只是一个例子,根据需要使用不同类型的二极管以获得合适的钳位电压。

编程和焊接

pYYBAGPjUm2AfKTLAAKXIZyj-d0130.png
下载IDE
 
  • 第 2 步:打开 IDE。转到工具 > 库管理器并键入“u8g”
poYBAGPjUoGAdYPTAAQcI2gMRWw813.png
安装 u8g 库
 

为 1306 OLED 显示器安装u8glib(由 Oliver 设计)库。

  • 第 3 步:将 Arduino Uno 连接到 USB,复制并粘贴下面附带的代码。然后编译并上传代码。
  • 第 4 步:从 Uno 板上取下 Atmega328P 芯片
poYBAGPjUoWAEsSXAADpuwArWqA226.jpg
上传代码后删除Atmega328
 
  • 第 5 步:根据此原理图构建威廉希尔官方网站 。将所有组件焊接到原型板上。
 
 
 
poYBAGPjUo-AC_PjAAK_iSQIJkg402.png
 
1 / 3电压表示意图
 

执行电压校准和测量

校准

为获得最佳效果,您需要使用常规万用表/电压表校准该电压表。您将需要任何电池 AA 或 LiPo。用普通万用​​表测量电池电压。然后用这个电压表测量电池。看到读数有一些差异,现在稍微调整/调整 10K 电位器(参见示意图)以进行校准。

通过反转电池的负电压来执行相同的步骤。

您还可以通过使用电阻器定义的值添加/减去一些偏移值来从代码进行软校准。

测量

共有 3 个 Commons COM1、COM2、COM3 和 3 个对应的 V1、V2、V3 探头,用于 3 个不同通道的电压测量。

对于通道 1,电压是在 V1 上相对于 COM1 测量的。如果用 V1 探测的威廉希尔官方网站 节点的电位高于用 COM1 探测的节点,则电压读数将为正。如果 V1 和 COM1 在这两个威廉希尔官方网站 节点上交换,则电压读数将为负。

同样适用于带 V2 和 COM2 的通道 2 以及带 V3 和 COM3 的通道 3。

在不共享任何电气连接的 3 个不同威廉希尔官方网站 上测量三个不同电压时,对 3 个威廉希尔官方网站 使用 V1/COM1、V2/COM2、V3/COM3 对。

pYYBAGPjdYKAc61aAABvJzV0KzQ253.png
3 个不同威廉希尔官方网站 上的 3 个不同电压测量
 

在单个威廉希尔官方网站 上测量三个不同的电压时,请勿使用多个 COM 只需将一个 COM (例如 COM3,任何 COM 都可以!)连接到 Gnd 或该威廉希尔官方网站 的任何节点。然后使用 V1、V2、V3 测量 3 个不同节点上相对于 Gnd 或连接 COM 的节点的 3 个不同电压。

pYYBAGPjdYmAIk0KAABcC86EksA086.png
单个威廉希尔官方网站 上的 3 种不同电压测量
 

在同一威廉希尔官方网站 上连接多个 COM 会搞砸读数!

结论和未来的工作

我忘了添加一些重要的东西,当电压范围超过测量范围时显示 OL(过载)。希望我会用额外的功能更新代码。

内部 EEPROM 上的一些电压记录可能很方便,我也会尝试这样做。我想为 REL(归零幻影电压)和 HOLD(冻结屏幕)添加几个按钮。我已经在顶部焊接了一个母接头以供将来扩展,敬请期待。

该设计可用于测量缓慢变化的交流电压/信号(假设为正弦波),而无需更改硬件。它还可用于设计分流电流表(提示:用非常低的 R 值替换分压器)。但是您需要为此编写不同的代码。

这个概念适用于任何微控制器,请随意构建您自己的设计,祝您好运。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'Arduino负电压表',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);