Arduino Mega 2560测量电压与ADC精度

栏目: 服务器 · 发布时间: 6年前

内容简介:如上图,若分辨率为

Arduino Mega 2560 能够读取 0 ~ 5V 的电压,并转换为 10bit0~1023 级的数字信号。这怎么理解呢?

Arduino Mega 2560测量电压与ADC精度

如上图,若分辨率为 2bit (即 ) ,意味着将 5V 分为 0~3 级的数字信号,每级精度是 5V /4 = 1250mV 。如果分辨率为 10bit ,即 0~1023 ,每级是 5V / 1024 = 4.88mV ;如果是 12bit ,即 0~4096 ,每级是 5V / 4096 = 1.22mV 。分辨率越高,每级分得越小,精度就越高。

得到 0~1023 级测量结果后,在程序内简单转化一下(没有复杂函数,只用乘除法),就能直观读出电压。接线图如下:

Arduino Mega 2560测量电压与ADC精度

问题来了,怎样显示电压呢?这里使用最简单的 IDE 串口监视器,连着开发板,直接在电脑屏幕上显示,但我们先要使用 Serial.begin() 启动串口通信,然后通过 Serial.print() 将电压在屏幕打印出来:

/*
 作者:Ardui.Co
 效果:串口显示模拟端口的电压值
 版本:1.0
 更新时间:2017年1月8日
*/
void setup()
{
  Serial.begin(9600); //指定串口通讯比特率为9600
}
void loop()
{
  int v = analogRead(A0);  //从A0口读取电压,模拟端口电压测量范围为0-5V,返回的值为0-1024
  float volt = v * (5.0 / 1024.0); //将返回值换算成电压
  Serial.print(volt);  //串口输出电压值
  Serial.println(" V");  //输出单位,并且换行
  delay(1000);  //输出后等待1s,降低刷新速度
}

通过 A0 读取电压范围不能超过 5V ,否则会损坏开发板,但要测量更高的电压怎么办?其实,我们可以通过分压电路来实现:

Arduino Mega 2560测量电压与ADC精度

根据欧姆定律, Va0 = V *  R1/(R1+R2) = V * 10/20 = 1/2 V

即: V =  2 Va0

因此调整一下换算语句就能得出实际电压:

float volt = v * (5.0 / 1024.0) * 2

但经过分压电路的测量会降低分辨率 (R1+R2)/ R1 倍(上述电路为 2 倍),如果分压式电阻 R1 = 10KR2 = 20K ,可以测量 0 ~ 15V ,但分辨率降低 3 倍。换句话说,分压测量越高的电压,分辨率就越底。

我们会用温度传感器实验,来介绍 ADC 的分辨率,同时会学到怎样利用 Arduino 内部参考电压提高测量精度。

LM35 是美国国家半导体(现被 TI 收购)推出的精密温度传感,其信号输出为模拟量:电压值与温度(摄氏)呈正比。不仅体积非常小(常见 TO-92 封装),而且不需额外的校正,就能获得较高的精度。

Arduino Mega 2560测量电压与ADC精度

其主要特性:

供电电压: 4~35V
工作范围:与芯片有关, LM35A-55~150°C 常见 LM35D0~100°C
测量范围:与封装和电路有关,常用 TO-922 ~150°C

测量精度:与芯片有关, LM35A 性能最优,这次实验用的 LM35D 最差,其典型值为 ±0.8°C ,最大值 ±2°C

电压与温度的关系: Vout = Temperature × 10mV/°C

想了解更多,可以参考官方 DataSheet 。接线方式如下:

Arduino Mega 2560测量电压与ADC精度

电压转换方式:

Arduino Mega 2560测量电压与ADC精度

Vin 为输入(被测量)电压; Vref 是参考电压,若不设置就是供电电压, Arduino Mega 25605Vresolution 是模拟端口的 ADC bitArduino Mega 2560 模拟端口为 10bitResult 为模拟端口的测量结果,数值为 0~1023 。程序如下:

/*
  作者:Ardui.Co
  效果:LM35 简单温度测量
  版本:1.0
  更新时间:2017年1月9日
*/
int LM35 = A0; //指定A0端口读取LM35
float Vin; //存储传感器电压
float temperature; //存储温度测量结果
 
void setup()
{
  Serial.begin(9600); //初始化串口连接
}
void loop()
{
  Vin = analogRead(LM35) * 5.0 / 1024; //计算出A0的电压,单位为V
  temperature = Vin * 1000.0 / 10.0; //将A0电压要转换成mV,根据LM35转换系数10mV/°C,除以10,得出温度
  Serial.print("Temperature: "); //在串口监视器输出结果
  Serial.print(temperature);
  Serial.println(" *C");
  delay(500); //延时0.5s
}

ADC测量精度问题:

对于 5V 参考电压来说,每级为 5V / 1024 = 4.88mV ,转化为温度,每级分辨率就是 0.488 °C 。如果环境温度为 TArduino Mega 2560 的测量结果是 0.488 Result ,但 Result0 ~ 1023 的正整数,误差 τ 就是

τ = T mod 0.488mod 为求余运算)

Arduino Mega 2560 内置了 1.1v 参考电压,使用这个参考电压,每级为 1.1V / 1024  = 1.07mV ,每级分辨率提高到 0.107°C

如果环境温度为 10°C ,取 5V 参考电压的分辨率为 0.24°C ,取 1.1V 参考电压则为 0.049°C ;如果环境温度为 25°C ,取 5V 参考电压的误差为 0.112°C ,取 1.1V 参考电压则为 0.069°C

接线不变,调整一下程序,引入 Arduino 的内部参考电压:

/*
  作者:Ardui.Co
  效果:LM35 使用1.1内部参考电压提高分辨率
  版本:1.0
  更新时间:2017年1月9日
*/
int LM35 = A0; //指定A0端口读取LM35
float Vin; //存储传感器电压
float temperature; //存储温度测量结果
 
void setup()
{
  analogReference(INTERNAL); //使用内部参考电压
  Serial.begin(9600); 
}
void loop()
{
  Vin = analogRead(LM35) * 1.1 / 1024; //计算出A0的电压,单位为V
  temperature = Vin * 1000.0 / 10.0; //将A0电压要转换成mV,根据LM35转换系数10mV/°C,除以10,得出温度
  Serial.print("Temperature: "); //在串口监视器输出结果
  Serial.print(temperature);
  Serial.println(" *C");
  delay(500);
}

参考电压稳定性:

由于参考电压跟 Vin 和温度成正比,实际中的电源电压往往十分不稳定,电池电压会随着电量变化(比如:单个锂离子放电电压约为 4.25V ~ 2.95V ),开关电源会有 50 ~ 200mV 纹波,常见的USB电源在不同负载上约有 ±4% 的变化。

但别以为用 Arduino Mega 2560 内部参考电压就万事大吉,其误差更高达 5% 。因此,使用内部基准源在提高分辨能力的同时,也引入了额外的测量误差,所以要用稳定性高的参考电压。

其实,也有一个折中的方案。 Arduino Mega 2560 内部提供了一块 LDO (低压差稳压 IC ),为 3.3V 端口供电。 LDO 一般为德州仪器的 LP2985-33DBVR ,其误差小于 1.5% ,用它来做外部参考电压,相对 5V 来说分辨率更高,相对 1.1V 内部参考电压来说,测量误差更小。

要使用外部参考电压,将 Aref 连接到 3.3V 端口:

Arduino Mega 2560测量电压与ADC精度

我们将 3.3V 的端口跟 Aref 链接,并在内部程序中声明:

/*
  作者:Ardui.Co
  效果:LM35 使用3.3外部参考电压提高分辨率
  版本:1.0
  更新时间:2017年1月10日
*/
int LM35 = A0; //指定A0端口读取LM35
float Vin; //存储传感器电压
float temperature; //存储温度测量结果
 
void setup()
{
  analogReference(EXTERNAL); //使用内部参考电压
  Serial.begin(9600); 
}
void loop()
{
  Vin = analogRead(LM35) * 3.3 / 1024; //计算出A0的电压,单位为V
  temperature = Vin * 1000.0 / 10.0; //将A0电压要转换成mV,根据LM35转换系数10mV/°C,除以10,得出温度
  Serial.print("Temperature: "); //在串口监视器输出结果
  Serial.print(temperature);
  Serial.println(" *C");
  delay(500);
}

我们还可以 Aref 连接到 Arduino 开发板之外的参考源上,以获取更精确的测量结果。

另外,要提高的分辨率,除了改变参考电压,也可以采用高位数的 ADC 芯片,不少精密 ADC 可达 16bit 以上分辨率。

参考链接


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java语言程序设计

Java语言程序设计

(美) Y. Daniel Liang / 李娜 / 机械工业出版社 / 2011-6 / 75.00元

本书是Java语言的经典教材,多年来畅销不衰。本书全面整合了Java 6的特性,采用“基础优先,问题驱动”的教学方式,循序渐进地介绍了程序设计基础、解决问题的方法、面向对象程序设计、图形用户界面设计、异常处理、I/O和递归等内容。此外,本书还全面且深入地覆盖了一些高级主题,包括算法和数据结构、多线程、网络、国际化、高级GUI等内容。 本书中文版由《Java语言程序设计:基础篇》和《Java语......一起来看看 《Java语言程序设计》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具