资讯详情

Arduino Mega 2560测量电压与ADC精度

54707bc970eb239cf7702e9cab60b482.pngArduino Mega 2560能够读取0 ~ 5V将电压转换为10bit即0~1023级数字信号。怎么理解?

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

得到0~1023级测量结果后,简单转换程序中的电压(无复杂函数,仅乘除法)。接线图如下:

问题是,如何显示电压?这里使用最简单的IDE串口监视器,连接开发板,直接显示在电脑屏幕上,但我们必须先使用它Serial.begin()启动串口通信,然后通过Serial.print()在屏幕上打印电压:

/*

作者:Ardui.Co

效果:串口显示模拟端口的电压值

版本:1.0

更新时间:2017年1月8日

*/

void setup()

{

Serial.begin(9600); ///指定串口通信比率为9600

}

void loop()

{

int v = analogRead(A0); //从A模拟端口电压测量范围为0-5V,返回的值为0-1024

float volt = v * (5.0 / 1024.0); ///将返回值转换为电压

Serial.print(volt); //串口输出电压值

Serial.println(" V"); ///输出单位,换行

delay(1000); ///输出后等待1s,降低刷新速度

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/*

作者:Ardui.Co

效果:串口显示模拟端口的电压值

版本:1.0

更新时间:2017年1月8日

*/

voidsetup()

{

Serial.begin(9600)

}

voidloop()

{

intv=analogRead(A0);//从A0口读取电压,模拟端口电压测量范围为0-5V,返回的值为0-1024

floatvolt=v*(5.0/1024.0)

Serial.print(volt);//串口输出电压值

Serial.println(" V");///输出单位,换行

delay(1000)s,降低刷新速度

}

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

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

即:V = 2 Va0

因此,调整转换句可以获得实际电压:

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

1

floatvolt=v*(5.0/1024.0)*2

但测量分压电路会降低分辨率(R1 R2)/ R如果分压电阻1倍(上述电路为2倍)R1 = 10K,R2 = 20K,可以测量0 ~ 15V,但是分辨率降低了3倍。换句话说,电压测量越高,分辨率越低。

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

LM35是美国国家半导体(现在)TI信号输出为模拟量:电压值与温度(摄氏度)成正比。不仅体积很小(常见)TO-92包装),不需要额外的校正就能获得更高的精度。

其主要特点:

供电电压:4~35V

工作范围:与芯片有关,LM35A为-55~150°C 常见LM35D为0~100°C

测量范围:常用于包装和电路TO-92为2 ~150°C

测量精度:与芯片有关,LM35A性能最好,本实验使用LM35D典型值最差±0.8°C,最大值±2°C

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

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

电压转换方式:

Vin输入(测量)电压;Vref如果不设置为供电电压,则为参考电压,Arduino Mega 2560为5V;resolution模拟端口ADC bit,Arduino Mega 2560模拟端口为10bit,Result数值为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; //将A将0电压转换成mV,根据LM35转换系数10mV/°C,除以10,得到温度

Serial.print("Temperature: "); //在串口监视器输出结果

Serial.print(temperature);

Serial.println(" *C");

delay(500); //延时0.5s

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

/*

作者:Ardui.Co

效果:LM35 温度测量简单

版本:1.0

更新时间:2017年1月9日

*/

intLM35=A0;//指定A0端口读取LM35

floatVin;//存储传感器电压

floattemperature;///

voidsetup()

{

Serial.begin(9600)

}

voidloop()

{

Vin=analogRead(LM35)*5.0/1024;/计算A0电压,单位为V

temperature=Vin*1000.0/10.0;//将A将0电压转换成mV,根据LM35转换系数10mV/°C,除以10,得到温度

Serial.print("Temperature: ");////

Serial.print(temperature);

Serial.println(" *C");

delay(500).5s

}

ADC测量精度问题:p

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

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

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);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

/*

作者:Ardui.Co

效果:LM35 使用1.1内部参考电压提高分辨率

版本:1.0

更新时间:2017年1月9日

*/

intLM35=A0;//指定A0端口读取LM35

floatVin;//存储传感器电压

floattemperature;//存储温度测量结果

voidsetup()

{

analogReference(INTERNAL);//使用内部参考电压

Serial.begin(9600);

}

voidloop()

{

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端口:

我们将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);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

/*

作者:Ardui.Co

效果:LM35 使用3.3外部参考电压提高分辨率

版本:1.0

更新时间:2017年1月10日

*/

intLM35=A0;//指定A0端口读取LM35

floatVin;//存储传感器电压

floattemperature;//存储温度测量结果

voidsetup()

{

analogReference(EXTERNAL);//使用内部参考电压

Serial.begin(9600);

}

voidloop()

{

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以上分辨率。

参考链接

标签: va电压传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台