Arduino成长日记4 - 模拟IO操作

    xiaoxiao2022-07-02  188

    在Arduino控制器上,除了14个数字输入/输出引脚,还带有6个模拟引脚,即板上编号带“A”的引脚,模拟引脚可以做模拟量的读取及写入,例如读取引脚的电压输入,或是写入模拟量控制风扇的转速等。


    模拟信号

    在我们周围到处都能接触到模拟信号,如室温读取,电灯亮度调节。如图所示,模拟信号是随时间变化的连续的信号,在UNO板上,可以接收0 - 5V的模拟信号。 模拟引脚是带有ADC(模数转换器)功能的引脚,它将外部输入的模拟信号转换成芯片运算时能够识别的数字信号,从而实现读取模拟值的功能。Arduino模拟输入功能具有10位精度,即可以将 0 ~ 5V 的电压信号转换成 0 ~ 1023 的整数形式进行表示。

    数字信号与模拟信号的区别

    如上一篇所知道的数字信号知识,数字信号时一些离散的信号,通常以1或0表示,以Arduino 的IO口输出数字信号为例,要么是高电平输出,要么是低电平输出。 模拟信号则是一连串的连续信号,不能简单的用1或0来进行表示。以手机电池电量为例,肯定不能简单的用 “有电” 或是 “没电” 来告知我们当前的电量,而更多的是以电量的百分比来显示,这使我们可以更直观的知道什么时候没电了需要充电。 简单来说,数字信号只是控制风扇的开或关,而模拟信号则可以控制 0 ~ 5V 的整个区间来调节风扇的转速。当然,使用数字信号控制或者模拟信号控制都要根据引脚所支持的功能而定。


    模拟函数示例

    在Arduino 基础篇的时候讲过了模拟信号的相关函数,如下:

    analogWrite()

    描述:从一个针脚输出模拟值(脉冲宽度调制,Pluse Width Modulation,PWM),让LED以不同的亮度点亮或驱动电机以不同速度旋转。analogWrite()输出结束后,该针脚将产生一个稳定的特定占空比的PWM。PWM输出持续到下次调用analogWrite(),或在同一针脚调用digitalRead()或digitalWrite()。 PWM信号的频率大约是490Hz,大多数Arduino板(ATmega168或ATmega328)只有针脚3、5、6、9、10和11可以实现该功能。在Arduino Mega上,针脚2 ~ 13可以实现该功能。旧版本的Arduino板(ATmega8)只有9、10、11可以使用analogWrite()。在使用analogWrite()之前,不需要调用pinMode()来设置针脚为输出模式。

    语法:analogWrite(pin,value)。

    参数:pin,用于输入的针脚;value,占空比,取值范围为0(完全关闭)~ 255(完全打开)。

    analogWrite()案例

    比较常用的是呼吸灯或者控制蜂鸣器音量,下面分享一个简单的呼吸灯代码 ~

    //定义LED引脚,这里直接使用模拟引脚A0,也可以用数字引脚3、5、6、9、10、11 int ledPin = A0; void setup() { //初始化引脚为输出 pinMode(ledPin,OUTPUT); //熄灭LED analogWrite(ledPin,0); } void loop() { //使用for循环,渐渐点亮LED for(int i = 0; i <= 255; ++i) { //LED引脚写入PWM analogWrite(ledPin,i); //加延时,体现“呼吸灯”效果 delay(10); } //渐渐熄灭LED for(int i = 255; i >= 0; --i) { //LED引脚写入PWM analogWrite(ledPin,i); //加延时 delay(10); } }

    使用for循环,使引脚的模拟量(PWM)累加跟累减来点亮或熄灭LED,在for循环中加入延时,将整个点亮或熄灭的过程延长,可达到肉眼可见的呼吸灯效果。

    analogRead()

    描述:从指定的模拟引脚读取数值。Arduino板包含一个6通道(Mini和Nano有8通道,Mega有16通道)、10位模拟/数字转换器。这表示它将0 ~ 5V的输出电压映像到0 ~ 1023的整数值,即每个读数对应电压值5V/1024,每单位0.0049V(4.6mV)。输入范围和精度可以通过analogReferrnce函数改变,其大约现需要100μs(0.0001s)来读取模拟输入,所以最大的阅读速度是每秒1000次。

    语法:analogRead(pin)。

    参数:模拟引脚或带PWM功能的数字引脚。

    返回:从0 ~ 1023的整数值。

    analogRead()案例

    在这引用一个起床闹钟的例程,通过读取光敏电阻的模拟值来判断是否天亮,从而驱动蜂鸣器鸣叫 ~

    //定义模块引脚,光敏电阻A0,蜂鸣器D2 int LightSensor = A0; int buzzer = 2; void setup() { //初始化引脚模式 pinMode(LightSensor,INPUT); pinmode(buzzer,OUTPUT); } void loop() { //判断光敏电阻的返回数值 if(analogRead(LightSensor) < 400) { //蜂鸣器间接响起 digitalWrite(buzzer,HIGH); delay(300); digitalWrite(buzzer,LOW); delay(300) }else //光敏电阻返回数值不符合要求时,关闭蜂鸣器 digitalWrite(buzzer,LOW); }

    通过光敏电阻返回的数值来判断当前的光线情况,模拟信号所转换成整数形式的 0 ~ 1023,从中选取合适的对比数值作为 “闹钟” 开启的判断值。

    最新回复(0)