用Arduino做电压表其实是对模拟输入的最简单且最基本的应用,Arduino的模拟输入接口可以输入0~5v的电压,分辨率为1024级,比较精确,但是因为原理与真正的电压表有所不同,所以还是别用它完全替代电压表。
本文将教你如何用最简单的代码实现电压表的功能,并借助这个功能来体会Arduino的其它方面。
模拟信号
模拟信号是指信息参数在给定范围内表现为连续的信号。 或在一段连续的时间间隔内,其代表信息的特征量可以在任意瞬间呈现为任意数值的信号。模拟电压在一定范围内不断变化,电压(电位)值理论上可以无限精确(放在图上可以看到弧线更加顺滑),所以模拟信号的一大优点就是信息量大,比如我能用10101110101110来表示信息,但你却能用62124761831841来表示,那么同样的时间内,你(模拟信号)可传达的信息就多得多。但这造成了一个问题,分辨率越高的信号受干扰而导致信号形变的可能越大。——百度百科
电压可以以模拟信号的形式传递,Arduino当然可以做一个电压表了。
连接
Arduino UNO提供了A01~A05共6个模拟输入针脚,而Mega 2560则提供了16个(因为我写这篇文章前弄坏了我的UNO R3,所以本文的实例实际上都由Mega 2560来完成)。连接方式如图:
并联一个10K电阻是为了避免表笔在悬空状态下出现误读,减少干扰。
实物连接:
黑色线为黑表笔,红色线是红表笔。
程序
函数·读取模拟信号:analogRead(Pin)
Pin为一个能读取模拟信号的插脚。这个函数可以读取其中一个模拟信号针脚的值,读取限制为0~5v,对应电位值0~1023。所以需要对读取到的值换算成电压,即[latex]U=analogRead(Pin) \frac{5}{1023}[/latex]。可得这一部分的代码:
int sensorValue = analogRead(pin); //读取电位值 float voltage= sensorValue * (5.0 / 1023.0) //换算成电压
[infobox]事实上这样已经实现了核心的功能,但是我们需要得知Arduino测量出的电压,这项工作要由串口来完成。这是将电压数据通过串口发送出去的方法:
Serial.println(voltage, DEC);
[/infobox]
将以上的代码整理一下:
int pin = A0; void setup() { // put your setup code here, to run once: Serial.begin(9600); //设置串口波特率为9600 } void loop() { // put your main code here, to run repeatedly: int sensorValue = analogRead(pin); float voltage= sensorValue * (5.0 / 1023.0); Serial.println(voltage, DEC); delay(100); }
好,编译、上传!
查看数据
现在打开Arduino IDE的串口监视器,将左下角的波特率设置为9600,就可以看到Arduino发送过来的电压数据了:我们还没有连接任何电路,所以得到的值为0(如果不并联10K的电阻,会得到一串不断变动的数字,有一定规律,不知道为什么。)
测一下一节5号电池的电动势:
于是我们得到了相应的数据:
这样看有些费劲,这儿推荐一个叫SerialChart的工具,可以将这样的数据绘制成曲线图。打开SerialChart
顺便附上配置文件:
[_setup_] port=COM5 //根据你的实际串口号设置 baudrate=9600 width=1400 height=400 background_color = white grid_h_origin =100 grid_h_step = 10 grid_h_color = #EEE grid_h_origin_color = #CCC grid_v_origin = 100 grid_v_step = 10 grid_v_color = #EEE grid_v_origin_color=transparent [_default_] min=0 max=5 [Acc] color = green [Gryo] color = blue [angle] color = yellow [angle_dot] color = red
好了,你现在拥有一个量程5v,分度值为[latex]frac{5}{1023}[/latex]的电压表了!你还可以串联一个电阻来增大量程,不过精度也会下降。
comments powered by Disqus