第四阶段:Arduino 硬件平台 DIY 完全入门指南






4.98/5 (47投票s)
关于使用Arduino与传感器、执行器及其他硬件协同工作的一切
目录
1. 背景
2. 设置Arduino开发环境
3. Arduino电源管理
3.1 Arduino板供电
3.2 Arduino的输出功率
4. 指示灯与开关
4.1 LED
4.1.1 使用板载LED
4.1.2 连接和控制外部LED
4.2 蜂鸣器
4.3 开关
5. Arduino与显示屏
6. Arduino与传感器
6.1 传感器原理
6.2 A/D转换器
6.3 温度传感器
6.4 金属传感器
6.5 Arduino超声波传感器 7. PWM
7.1 PWM基础
7.2 Arduino的PWM支持
7.3 通过PWM控制LED亮度 8. 继电器应用
8.1 继电器基础
8.2 Arduino与继电器
8.2.1 通过晶体管控制继电器
8.2.2 通过光电耦合器控制继电器
9. 电机应用
9.1 通过晶体管控制直流电机
9.2 通过继电器控制电机
10. 红外传感器无线通信 11. 结论
1. 背景
Arduino是一个很棒的嵌入式平台,用于原型设计你的爱好项目。它非常容易学习,简单但高效且强大。Arduino板由Atmel微控制器系列供电。该板拥有许多对许多硬件应用至关重要的功能,包括数字引脚、驱动低功耗电机、PWM、通过串行通信连接其他设备的能力、板载A/D转换器,可以直接读取传感器值等等。尽管该平台声称仅用于原型设计,但我个人已将该板用于许多生产项目,并且在这些项目中效果也很好。在物联网时代,嵌入式系统的开发重点已完全转向为设备开发服务。然而,理解和学习这些设备的硬件能力、控制显示器、指示灯、蜂鸣器、执行器的方法、使用传感器也非常重要。它有助于构建此类设备的潜在能力框架,从而可以轻松地将这些板集成到物联网中。
尽管Arduino已经存在相当长一段时间并且经历了几次变化,但核心功能保持不变。有很多博客和文章解释了Arduino与不同硬件的工作原理,我没有找到一个网页条目能深入介绍该平台的整体硬件功能。因此,对于非嵌入式开发人员(非电子开发人员)来说,学习硬件部分是一个非常陡峭的学习曲线。在本教程中,我将尝试深入介绍Arduino的整体硬件功能,以及开发该平台实时项目所需的大多数常用硬件。本教程面向精通编程但正试图开始使用嵌入式平台(特别是Arduino)的开发人员。选择Arduino是显而易见的,因为它简单易学。对于大多数连接,我倾向于使用引脚连接器和面包板连接硬件,以便那些不熟悉焊接和PCB的人可以轻松跟随。
2. 设置Arduino开发环境
首先,请从Arduini官方软件下载站点下载最新的Arduino IDE。Windows用户将能够下载一个安装程序。安装程序包含IDE本身以及FTDI USB驱动程序。请优先安装USB驱动程序。这是必需的。没有USB驱动程序,您的IDE将无法与Arduino设备通信。
以下是我正在使用的设备的引脚描述。
图2.1:带引脚电平的Arduino Diecimilia/Duemilanova
安装软件后,将Arduino的USB电缆插入笔记本电脑。您将在任务栏看到通知“正在安装驱动程序”。驱动程序安装成功后,打开设备管理器(开始->右键单击计算机图标->属性->设备管理器)。
图2.2:插入Arduino后设备管理器
在“端口(COM和LPT)”部分,您会看到USB串行端口。对于Arduino Uno R3,您会在端口旁边看到Arduino Uno标记。当您拔出电缆时,将不再看到该端口。因此,这是您的Arduino设备所连接的端口。
如果您是第一次连接设备,您还会注意到数字引脚13旁边的LED正在闪烁。大多数Arduino板预装了一个闪烁程序,该程序会闪烁连接到引脚13的LED。
在开始编码之前,我们需要再进行几个步骤来设置IDE和开发板。
打开IDE。工具->开发板,选择您连接的开发板,如下图所示。
图2.3:Arduino开发板选择
选择开发板后,您需要设置正确的串行端口,就像您从图2.2中确定的那样。
图2.4:在IDE中选择USB串行端口
在开始编写开发板程序之前,我们将学习一些简单的Arduino C编程基础。
2.2 Arduino C程序基础
Arduino C程序的基本结构如下。Arduino C程序也称为草图。
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
setup()
函数在设备重置、重启或插入USB电缆时仅执行一次。loop()
函数会持续运行。主逻辑必须实现到loop函数中。
Arduino Duemilanova/Diecimilia/Uno R3(从现在开始简称为Arduino)板有14个数字I/O引脚。每个引脚都可以单独编程。引脚可以是OUTPUT模式或INPUT模式,需要在setup中使用以下命令指定:
pinMode(PIN_NO,OUTPUT)
或pinMode(PIN_NO,INPUT);
输入模式用于连接开关到引脚并希望引脚读取状态时。这些数字引脚处于输入模式时只能识别逻辑电平输入,如0和1。PIN_NO范围从0-13,取决于您正在编程的引脚。
在OUTPUT模式下,您可以在引脚上写入逻辑输出,或使用digitalWrite(PIN_NO,HIGH)/digitalWrite(PIN_NO,LOW)
和int n=digitalRead(PIN_NO)
分别读取引脚(1或0)的值。
数字端口中的一些引脚标记为PWM(例如图中的10和11)。它们可用于生成不同占空比的门控脉冲。使用analogWrite(PIN_NO,byteValue)
,PWm引脚可以编程生成特定占空比的完美方波门控脉冲,其中byteValue介于0到255之间,255表示最高或100%的占空比。PWM引脚可用于精确控制直流电机速度或通过MOSFET/IGBT等控制电灯的亮度。
Arduino在数字端口对面有6个模拟读取引脚(0到5)。这些是连接到10位ADC的输入引脚。传感器可以直接连接到这些引脚。Arduino可以读取引脚上的电压,使用int value=analogRead(ANALOG_PIN_NO)
。
该软件附带一个串行库,通过它可以与其他程序通过串行通信与Arduino进行通信。Arduino IDE还附带一个串行监视器,通过它可以测试串行通信。
要初始化串行通信,在setup函数中需要使用Serial.begin(BAUD_RATE)
初始化串行通信对象。波特率以96200的倍数变化。Serial.print("msg")
, Serial.println("msg")
, Serial.write(someVariable)
是常用的函数,通过这些函数,开发板可以在串行端口写入数据,任何能够通过串行端口与设备通信的外部程序都可以读取。
int v=Serial.read()
用于读取其他程序在串行端口写入的数据。
delay(delayInMilli);
用于使下一条指令以指定的毫秒为单位等待delayinMilli时间。
以上命令可以执行大多数基本的硬件输入和输出。
我请求您查阅我的Arduino入门教程,以获取有关Arduino C编程和串行通信基础的更多信息。
3. Arduino电源管理
3.1 Arduino板供电
嵌入式系统可能需要驱动各种负载,如电机、触发继电器、为传感器提供电源等。因此,了解设备消耗多少电量以及它能为其他外围硬件单元提供多少电量是嵌入式系统的一个非常重要的方面。在本节中,我们将学习Arduino的电源管理。
Arduino的工作电压是5V,与大多数嵌入式系统设备和板卡一样。它可以通过USB或外部电源供电。Arduino板载有稳压器,可以为板卡提供5V稳压电源。外部电源的电压通过它进行稳压。与任何稳压器一样,该单元需要较高的输入电压才能输出5V。因此,当Arduino通过外部电压源(如电池)供电时,它必须是9V电源。图3.1显示了给Arduino板供电的不同方式。
图3.1:Arduino供电的不同方式
您可以使用9V适配器直接将交流电转换为9V直流电,并通过其电源插孔输入Arduino。如果您希望设备完全由电池供电,您可以使用9V电池连接器并将其插入电源端口。Arduino还提供了两个标记为Vin和Gnd的引脚,它们紧邻模拟端口。您可以使用电池连接线通过这两个引脚将9V电池连接到Arduino。
然而,在USB插头附近有一个跳线,如果您使用USB为Arduino供电,则需要将其设置为USB;如果您使用外部电源,则需要将其设置为Vin。跳线如图3.2所示。
图:3.2 电源选择跳线设置
3.2 Arduino的输出功率
当您正面看Arduino板(如图3.1所示)时,可以看到一组引脚聚集在一起:RST, 3V, 5V, GND, GND, Vin。我将这些引脚组合称为电源端口。5V和3V引脚有时也称为VCC引脚,因为它们是其他设备的电源。例如,如果您想将传感器(例如LM 35)连接到Arduino,它需要5V才能工作。此电压由5V引脚提供。ZigBee等设备的工作电压为3V。这些设备可以通过3V VCC引脚供电。Vcc引脚的电流绘制能力为200mA。Arduino还拥有14个数字I/O引脚。当提供高逻辑电平时,这些引脚输出5V。但是,数字I/O引脚的电流绘制能力低至40mA。 由于电流绘制能力非常低,这些引脚无法驱动任何负载。即使是LED也难以用此电流驱动。因此,数字引脚只能通过像光电耦合器(MCT2E)或晶体管这样的开关电子设备来控制其他设备(数字设备切换稍后解释)。
重要的是要注意,数字引脚支持电压读取,就像控制设备一样。当一个数字开关连接到一个数字I/O引脚,并且引脚需要读取其逻辑电平时,该引脚被称为“汇”。应注意,通过所有I/O引脚汇集到设备的电流总和不得超过100mA。因此,始终建议使用限流电阻将开关输出连接到数字引脚。
可以提供给任何引脚的最大电流约为40mA。因此,如果您将5V-1A电源连接到任何模拟引脚,即使电压在范围内,过流也会损坏您的微控制器。因此,在使用Arduino时,必须充分注意了解设备的工作电压和电流规格,并在将任何引脚(模拟/数字)用作汇时,通过连接合适的限流电阻来限制输入电流。
从以上讨论中,我们得出以下要点:
1)Arduino 5V、3V Vcc引脚可直接用于驱动低电流负载(如LED、LCD、5V直流电机、传感器)。
2)Arduino数字引脚不足以驱动低电流负载。
3)Arduino数字引脚可用于为数字开关提供5V切换电压。Arduino可以使用光电耦合器或晶体管等设备切换高电流额定值的设备。
4)Arduino引脚作为汇的电流规格非常低。因此,不应将高电流源连接到任何配置为汇的引脚。将引脚作为汇时,请使用限流电阻。
有了这些知识,我们基本上可以继续进行Arduino开发了。
4. 指示灯与开关
在DIY项目中,您经常需要指示灯。例如,当您构建火警系统时,您的传感器可能会监测热量和光强度,当值超过阈值时,您希望它触发警报。
您可能还希望通过LED指示某个设备已激活。LED和蜂鸣器是几乎所有DIY项目中都包含的最常见的指示器。由于易于使用、成本效益高,硬件开发人员都喜欢这两种组件。
开关在触发设备外部事件方面起着重要作用。例如,您希望按下开关启动电机:让开发板读取事件并打开电机。您希望通过按下开关打开灯:使用简单的开关。
因此,指示灯和开关是任何硬件项目中最基本、最常见、最广泛使用的组件。它们便宜、高效且有效。因此,在本节中,我们将讨论如何在Arduino中使用LED和开关。
4.1 LED
4.1.1 使用板载LED
发光二极管(LED)是任何电子设备(从适配器到笔记本电脑)最常见的指示灯。它使用户能够直观地了解系统的某些部分是否正常运行。LED有不同的颜色和电流规格。LED的电流规格从30mA到几安培不等。由于LED消耗电流,因此它也被视为电流负载。LED的运行电压范围在1.2V到24V之间,具体取决于其规格。
Arduino板载有一个内置LED,可以通过数字引脚13进行控制。为了通过Arduino数字I/O引脚控制任何设备,我们必须将引脚配置为OUTPUT模式,并使用digitalWrite(13,HIGH)
将其设置为高电平。
您可以在Arduino示例中找到一个简单的闪烁代码:文件->示例->基础->闪烁。为了延续讨论,我在此处直接给出代码。
int led = 13;
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(led, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
这将使与引脚13关联的LED每秒钟轮流开启和关闭。LED的开启状态如图4.1所示。
图4.1:连接到引脚13的LED
4.1.2 连接和控制外部LED
板载LED很好,不需要电路连接。但是,如何连接外部LED并用数字引脚控制它呢?由于数字引脚可能不足以提供LED所需的电流,我们需要LED从可以提供足够电流的源汲取电流。因此,我们将LED的阳极(较长的引脚)连接到Arduino的5V Vcc。但如果我们将阴极(较短的引脚)直接连接到地,首先,我们无法控制LED,因为我们无法控制Vcc引脚。所以我们把LED的阴极连接到NPN晶体管的发射极(我使用了BC 548,您可以使用任何其他NPN型晶体管)。晶体管的集电极接地。虽然在4.2 a)中LED没有电阻,但我建议您在LED和BC548之间连接一个100欧姆的电阻。它限制了电流,并防止LED烧毁。
晶体管的基极通过偏置电阻R2(100/470欧姆)连接到Arduino的任意数字I/O引脚(例如引脚12)。当引脚为高电平时,晶体管获得基极电压,完成晶体管电路,LED通过晶体管接地。当引脚为低电平时,晶体管不获得正向偏置电压,因此关闭。因此,LED的接地引脚未连接到LED。所以它是关闭的。
您实际上可以取一个3引脚连接器,将晶体管放入其中,并连接其电线。您也可以根据需要,在面包板上进行连接!
您现在可以使用4.1的代码列表进行实验。只需将引脚13更改为引脚12。或者,您也可以将引脚12添加为数字输出引脚,并用板载LED控制外部LED。4.2 b)显示了LED发光。
C)晶体管BC 548/547引脚定义
图4.2:用Arduino连接外部LED
为了您的方便,我还放了一个独立的图像,精确地展示了这一点,在4.3中。
图4.3:近距离查看连接
4.2 蜂鸣器
与LED一样,蜂鸣器也是一种输出组件。有许多不同类型的蜂鸣器,其中压电蜂鸣器最常见。但与LED不同,蜂鸣器的电流需求非常低。它可以在低至10mA的电流下工作。因此,我们可以直接将蜂鸣器连接到数字引脚和Arduino的地。
您可以将蜂鸣器连接到引脚8(尽量避免使用标记为PWM的引脚),就完成了。使用4.1的代码列表,每隔一秒交替打开和关闭蜂鸣器。不要忘记将引脚号更改为您连接蜂鸣器的引脚。
蜂鸣器要么有两个电线,要么有两个引脚。如果蜂鸣器有两个引脚,较长的引脚是阳极,必须连接到数字引脚;较短的引脚是阴极,必须连接到地。
如果蜂鸣器有电线(如图4.4所示),则红色电线是正极,蓝色/黑色电线是地。图4.4显示了蜂鸣器与Arduino的连接。
图4.4:Arduino与蜂鸣器
4.3 开关
不用说,有各种各样的开关。我们将要实验的是按钮开关。按下按钮时它保持开启状态,松开按钮时变为关闭状态。您将通过单击按钮来打开LED。
按钮开关有四个引脚,提供两对开关触点。图4.5 b)显示了引脚的配对方式。因此,在用开关切换单个设备时(我们通常会这样做),选择A对B或C对D。注意A、C和B、D是可互换的。
开关与LED的电路图如图4.5 A)所示。LED通过Arduino的5V通过电阻提供正向电压。阴极连接到开关的一个触点,同一对的另一个触点连接到地。因此,当按下开关时,LED的电路完成,它会发光。当释放开关时,LED的电路断开,它会关闭。
我们不需要为这个实验编写任何代码。结果可以从图4.6中看到。
C)物理连接
4.5 开关与Arduino
4.6 开关实验结果
5. Arduino与显示屏
LCD是嵌入式系统中最常见的输出设备。从饮料自动售货机到手持式票据打印机再到酒店计费系统,您都会在许多嵌入式系统中看到显示屏。有许多常用的显示屏。最常见的显示屏是:LCD显示屏、图形显示屏、七段数码管显示屏等等。双行LCD显示屏是嵌入式系统中最常用的设备。这是因为嵌入式系统的功能通常受限。因此,2行显示屏足以显示大部分内容。
在这里,我将向您展示如何在Arduino中使用显示屏。LCD是16引脚设备,工作电压为5V。Arduino的5V Vcc足以驱动LCD。然而,LCD没有引脚头,这使得在没有焊接的情况下很难工作。
然而,我们有一个解决所有这类问题的方法。看图5.1 c)。这是一个标准的多引脚连接器。市面上有8个多引脚连接器,价格约为0.5-1美元。您可以购买两个8引脚连接器,将公头插到LCD上,然后将相应母座预焊的电线连接到Arduino引脚。
LCD需要两个VCC:一个是点亮正面字符,另一个是背光,这是可选的。图5.1 A)显示了连接表。LCD引脚11、12、13、14是数据引脚,应连接到Arduino的数字I/O。RW' 应接地以启用写入操作。Enable和RS是两个控制引脚。
因此,从Arduino,我们只需要控制6个引脚。VO控制亮度。您可能希望根据环境光线进行调整。因此,将其与一个10K的可变电阻(称为电位器)连接到地。电位器的第一和最后一个引脚分别连接到5V和地。中间的引脚连接到LCD的VO引脚。
(单击图像查看全尺寸图像)
C)多引脚连接器
图5.1:用Arduino连接LCD
连接完成后,我们可以借助Arduino的LiquidCrystal库在LCD上进行打印。
#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11,5,4,3,2); //create the lcd variable
void setup()
{
pinMode(13,OUTPUT);
digitalWrite(13,HIGH);
lcd.clear(); //clear the LCD during setup
lcd.begin(16,2); //define the columns (16) and rows (2)
}
void loop() {
lcd.print("Codeproject.com");
lcd.setCursor(0,1);
lcd.print("Rupam, Gulbarga"); //print...
delay(2000);
lcd.clear(); //clear LCD, since we are still on 2nd line...
lcd.home(); //set the cursor the top left
}
LiquidCrystal lcd(12,11,5,4,3,2);
在此处最重要。lcd
是LiquidCrystal
类的一个变量,使用(RS,ENABLE,D4,D3,D2,D1)
进行初始化。其中所有值都是相应的Arduino引脚编号,而不是LCD引脚编号。
lcd.begin(NO_OF_CHARACTERS,NO_OF_LINES)
初始化LCD,用于每行打印NO_OF_LINES
和NO_OF_CHARACTERS
。lcd.home()
将光标移到第一行的第一个字符。lcd.print()
可以从光标当前所在的位置开始打印字符。
lcd.clear()
清除LCD上的所有数据。lcd.setCursor(CHARACTER_NO,LINE_NUMBER)
将光标移动到特定行LINE_NUMBER
和该行的CHARECTER_NO
。
图5.2显示了上述列表的输出,以及5.2 A)中指定的电路图。您可以随意更改引脚。但不要忘记相应地更改LCD初始化。
图5.2:实际连接和输出
6. Arduino与传感器
6.1 传感器原理
传感器是将物理参数转换为电参数的小型电子设备。有各种传感器可用于测量环境参数,如湿度、温度、湿度、CO2等。图6.1显示了可能与Arduino一起使用的各种传感器。
传感器通常有工作电压和电流范围。大多数常用传感器的工作电压为5V,需要中等范围的电流。这意味着传感器可以直接从Arduino的5V Vcc引脚供电。
传感器产生与工作电压范围相符的电输出。Arduino可以通过其模拟引脚读取此电压,有6个模拟引脚聚集在一起,位于底部最右侧的端口。这些引脚的工作电压范围为5V,工作电流约为100mA。您必须知道的一个重要事情是,如果您没有将任何传感器连接到任何模拟引脚,那么这些引脚仍然不会像预期的那样读取零。这是因为它们会拾取环境电荷。因此,在开放状态下,读取引脚将返回随机的低电压。
6.2 A/D转换器
由于工作电压为5V,大多数传感器都使用5V。然而,由于电参数是模拟的(连续的)性质,传感器的输出也是如此。
但微控制器只能处理数字数据。因此,Arduino提供了一个10位的板载A/D(模数转换器)。A/D转换器通过采样和量化的逻辑工作。它以等于A/D位数位数的采样对信号进行采样。然后将输入信号量化到最近的采样值。
您可以阅读这个A/D转换器维基百科,以更好地理解该概念。
这意味着最大电压,即5V,可以表示为2^10,即1024。因此,如果比如analogRead(5)返回的值是x,那么实际电压=
传感器输出电压=x*5/1024
此外,传感器的输出电压将与物理参数的某个值相关联。例如,我们很快将看到的温度传感器LM35,在0-92°C的温度范围内输出电压为0-1.1V。因此,1.1/92(或约0.1V)代表1个单位的温度。这也被称为传感器精度。
由于传感器根据其监测的物理参数输出电压或电流,因此它们也称为源,而Arduino(或任何读取传感器数据的设备)称为汇。当许多传感器通过无线技术连接,并且许多汇被连接到一个共同的目标(例如测量一个区域的平均温度)时,它被称为无线传感器网络或WSN。
图6.1:各种传感器
6.3 温度传感器
我在我关于Arduino实时气象站的教程中已经提供了温度和光传感器(LDR)的详细信息。然而,我写这篇特别的文章是为了绝对的初学者。因此,这和下一小节将基于上述教程中提出的概念。连接不会有任何变化。然而,我们在代码上会有区别。在这篇教程中,我不会像之前的教程那样使用ArdOS。
我们将从配置硬件并进行测试开始。然后我们将集成到物联网中。
我们将从温度传感器LM 35开始。这可能是最便宜有效的传感器之一,可以开始您的Arduino DIY。它是一个三引脚传感器,工作电压范围为0-5V,用于测量0-92°C范围内的温度。
如果您是硬件初学者,并且刚刚开始学习硬件,那么在开始使用组件之前研究其数据手册总是个好主意。它为您提供了与这些设备打交道所需的电气和逻辑理解。
LM35有三个引脚,需要连接到Arduino的地、Vcc和模拟引脚。您可以直接从Arduino的5V引脚为其供电,并将输出引脚连接到任何模拟引脚。我将其连接到引脚5。请参阅图2.1了解电路。
图6.2:LM 35与Arduino的连接
您可能会想如何连接这三个引脚到Arduino。许多教程会建议您使用面包板。因此,您可以使用面包板或三引脚连接器。我更喜欢短三引脚连接器,如图2.2所示。这样,您将LM35的引脚插入连接器的三个插槽,并将电线插入相应的Arduino插槽。
图6.3:使用3引脚连接器连接LM 35
现在,在我们编写LM 35的代码之前,理解一些概念很重要。
LM35将温度转换为0-1V范围内的电压。这意味着当温度约为90°C时,LM35的输出电压约为1V。现在,Arduino如何读取这个温度?
正如您所注意到的,LM35的输出电压连接到Arduino的模拟引脚5,Arduino将读取模拟电压,该电压将通过内部10位ADC转换为数字值。10位ADC意味着Arduino在电压为5V时读取1024(2^10)。但由于LM35的输出永远不会超过1V,所以4V的精度(约10%)会丢失。这可以通过简单地将参考电压从5V更改为1.1V来解决。这可以通过以下简单代码实现。
analogReference(INTERNAL);
然而,如果您使用1.1V作为参考电压,则方程式将完全改变。如果您将1.1V除以1024,则模拟读数每增加一步,大约等于0.001074V = 1.0742 mV。如果10mV等于1摄氏度,则10 / 1.0742 = ~9.31。因此,模拟读数每变化9.31,温度就变化一度。
因此,
温度值=引脚5读取的值/9.31(使用1.1参考电压)。让我们编写一个简单的程序,每秒探测一次温度。
这是我们为此编写的代码
float tempC;
int reading;
int tempPin = 0;
void setup()
{
analogReference(INTERNAL);
Serial.begin(9600);
}
void loop()
{
reading = analogRead(tempPin);
tempC = reading / 9.31;
Serial.print("Temp= ");
Serial.print(tempC);
Serial.println(" 'C");
delay(1000);
}
下面是LM35操作的截图。当我在传感器附近放一根熏香棒时,您可以看到温度升高。
图6.4:LM 35串行输出
6.4 LDR传感器
LDR代表光敏电阻。当光线照射到LDR表面时,其电阻增加,导致其两端电压降低。当光线减弱时,电阻也减小,导致其两端输出电压升高。因此,如果我们把LDR作为分压电路中的一个电阻,那么分压器两端的电压会随着光强度的变化而变化。图2.4显示了LDR的Arduino连接以及分压电路的原理。
图6.5:LDR传感器电路图
由于R2=1K/4.7k恒定,当R1减小时(光强度低时),Vout会减小;当R1增大时(光强度高时),Vout会增大。
因此,Arduino中的逻辑应遵循模拟引脚值与光强度值成正比的原理。我们可以将光强度表示为最大强度的百分比,如下所示:
光强度百分比= (模拟值)*100/1024
让我们看一下草图,以百分比的形式检测光强度变化,使用LDR电路。
float light;
int reading;
int lightPin = 5;
void setup()
{
Serial.begin(9600);
}
void loop()
{
reading = analogRead(lightPin);
light = (float)reading*100/1024.0;
Serial.print("Light = ");
Serial.print(light);
Serial.println(" %");
Serial.println(reading);
delay(1000);
}
结果如图6.6所示。
图6.6:LDR传感器结果
6.4 金属传感器
金属传感器是感应传感器。这意味着当金属靠近它时,它会感应电流。在这里,我们将看到ID18-3008NA金属传感器的工b作原理,它也充当开关。因此,这些传感器也被称为接近开关。您只需花费约3.5美元就可以获得一个金属传感器。其中18代表最大工作电压,N代表NPN型。您也有PNP型开关。回顾第4.1.2节,我们已经看到了NPN开关的功能。图6.7 A和B显示了接近传感器。
图6.7:Arduino与金属接近传感器
金属接近传感器有三根彩色电线:蓝色应接地,棕色是+Vcc,应连接到Arduino +5V Vcc。当您将金属靠近传感器时,它会感应出更大的电流,从而导致更高的电压。因此,您可以在串行端口打印来自模拟引脚的电压,然后设置一个阈值来确定是否检测到金属。
这是我连接到模拟引脚3的金属传感器的简单代码列表。
float metal;
int reading;
int metalPin = 3;
void setup()
{
Serial.begin(9600);
}
void loop()
{
reading = analogRead(metalPin);
metal = (float)reading*100/1024.0;
Serial.print("Metal in Proximity = ");
Serial.print(metal);
Serial.println(" %");
if(reading>250)
Serial.println("Metal Detected");
delay(1000);
}
通常,铁/铜或具有良好磁性能的金属在靠近金属传感器时会感应出超过1V的电压。(您无需触摸表面。它可以在大约3厘米的距离开始检测。)
几个月前,我做了一个很酷的模型,叫做自动化采矿。您可以查看此视频以了解金属传感器的工作原理。
6.5 Arduino超声波传感器
超声波是测量物体/障碍物距离的技术。它包含一个发射器和一个接收器。发射器定期发射一个短超声波脉冲。如果前面有物体,脉冲会撞击物体并返回。接收器然后测量往返时间,并可以根据往返时间估算距离。
介绍超声波传感器原因是a)它是DIY机器人最常用的传感器之一,b)它基于测量脉冲往返时间而不是模拟引脚上的电压的原理。
此外,超声波通过脉冲工作。因此,检测脉冲需要PWM引脚。所以超声波传感器的输出连接到PWM引脚而不是模拟引脚。
图6.8给出了超声波传感器的电路图。您只需将超声波设备的Vcc和Gnd连接到Arduino的Vcc和Gnd即可。触发器连接到任何非PWM引脚,回声连接到任何PWM引脚。
图6.8:超声波传感器电路图
为了准确计算往返脉冲时间,我们需要一个名为NewPing的库。从Google Code下载NewPing。从Google Code下载NewPing。
通过Sketch->Import Library-> Add Library在您的Arduino IDE中添加该库。
#include <NewPing.h>
#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN 11 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200
// Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 200-300cm.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
void setup() {
pinMode(13,OUTPUT);
Serial.begin(19200); // Open serial monitor at 115200 baud to see ping results.
}
void loop() {
delay(50);
// Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
Serial.print("Ping: ");
unsigned int dist=uS / US_ROUNDTRIP_CM;
if(dist<5 && dist>0)
{
digitalWrite(13,HIGH);
}
else
{
digitalWrite(13,LOW);
}
Serial.print(dist);
// Convert ping time to distance and print result (0 = outside set distance range, no ping echo)
Serial.println("cm");
}
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
将使用Echo, Trigger
引脚和脉冲预计传播的最大距离初始化一个NewPing
对象。
sonar.Ping()
将生成一个脉冲,并在脉冲撞击物体并返回时测量时间。如果没有物体在前,脉冲永远不会返回,它返回0。
距离的计算方法是将时间除以脉冲传播1厘米距离的单位时间。我们使用串行命令打印距离,并在物体距离传感器约5厘米时点亮LED。
7. PWM
脉冲宽度调制(PWM)是速度和亮度控制设备最重要技术之一。每个电子和电气负载,如灯泡、LED、电机,都依赖于流过它们的电流。电流可以通过改变电压的幅度来控制。一种方法是使用可变电阻或电位器。但事实是,电位器不能由微控制器控制。因此,控制流过设备的电流非常困难。
电流可以通过另一种方式控制。而不是改变电压幅度,而是可以控制施加到负载的电压的时间量。PWM是通过控制电压施加到负载的时间周期(通常称为占空比)来控制负载电流的原理。
7.1 PWM基础
顾名思义,脉冲宽度调制就是改变脉冲的导通时间。考虑以下代码片段:
float freq=1000;//1kHz
double T;
int onDelayUs,offDelayUs;
float dutyCycle=10;// in percentage
void setup()
{
pinMode(13, OUTPUT);
T=1*1000000/freq;// T in microsecond
onDelayUs=T*dutyCycle/100; // on delay in microsecond
offDelayUs=T*(100-dutyCycle)/100;// Off delay in Microsecond
}
void loop()
{
digitalWrite(13, HIGH);
delayMicroseconds(onDelayUs); // Approximately 10% duty cycle @ 1KHz
digitalWrite(13, LOW);
delayMicroseconds(offDelayUs);
}
上述代码非常简单,它使引脚13的LED在每隔offDelayUs周期之后,保持onDelayUs的导通时间。所以基本上,您正在为引脚13产生一个具有特定占空比的脉冲。图7.2显示了各种占空比的波形。
现在,当您连接第4.1.2节的电路,并将晶体管基极通过电阻连接到引脚13时,晶体管仅在onDelayUs的时间内导通,负载电流开始增加,然后晶体管关闭,停止向负载施加电压,导致负载电流降低。但在负载电流变为0之前,晶体管再次导通,电流增加。因此,电流可以根据晶体管导通的时间长短来改变,这又取决于占空比。
然而,这种技术有一些缺点。首先是数字I/O引脚的切换时间非常慢,所以我们得不到精确的方波脉冲。其次,这类引脚会受到中断的影响。因此,为了使用上面的列表,还必须禁用Arduino的所有中断。这种方法还会因为上述故障而导致负载出现抖动。
为了克服使用数字I/O引脚产生PWM的问题,Arduino通过ATMEGX微控制器的内部定时器提供了出色的PWM支持。
7.2 Arduino的PWM支持
见图7.1 A)。数字I/O引脚中的许多Arduino引脚,如引脚11,可以提供PWM支持。通过使用analogWrite(pin, value);命令,可以从这些引脚中的任何一个产生特定占空比的PWM信号。
是的,您没有读错。我们使用analogWrite()来处理数字引脚以产生PWM信号,因为PWM是连续信号(通断结合)。
analogWrite()期望值字段在0-255之间。其中255代表100%占空比。所需的占空比值可以通过以下方式计算:
Analog_Write_Value=100.0*dutyCycle/256.0;
输出频率是16MHz系统时钟频率除以预分频器值(64)。
7.3 通过PWM控制LED亮度
图7.1 A、B分别显示了测试PWM LED亮度控制的电路图和实际连接。这里使用引脚11 PWM引脚产生PWM。
图7.1:通过PWM控制光照强度
图7.2:PWM波形
这是一个简单的列表,用于测试电路。
int ledPin = 11; // LED连接到数字引脚9
void setup() {
// nothing happens in setup
// No need to use pinMode(11,OUTPUT) as we will be using PWM
}
int fadeValue=255;
void loop() {
// fade in from Max to min in increments of 5 points:
analogWrite(ledPin, fadeValue);
fadeValue=fadeValue-5;
if(fadeValue<0)
fadeValue=255;
delay(500);
}
上面的列表在每500毫秒内不断地使LED从最亮到熄灭,然后重复操作。图7.3显示了上述列表和电路的输出。
图7.3:使用PWM改变LED亮度
8. 继电器应用
8.1 继电器基础
到目前为止,我们已经看到了如何控制数字设备(大部分工作在低电压/电流范围内)的亮度。如果我们想在高电流范围内工作怎么办?如果我们想让我们的Arduino控制电灯的开关怎么办?如果我们想让Arduino控制电机的极性呢?当然,在这种情况下,负载不能通过晶体管接地,因为晶体管的电流额定值低,并且无法反转电流方向。
最常见、最有效、最广泛使用的解决方案是继电器。这些是强大的组件。如果您想成为一名熟练的硬件程序员,您绝对必须掌握理解和使用继电器的艺术。
继电器是机电开关,可以通过电磁线圈的磁性吸引或排斥来选择连接器上的不同输入线。
我鼓励您阅读关于继电器的维基百科条目。
如您所见,有几种类型的继电器,主要分为SPST(单刀单掷)、SPDT(单刀双掷)、DPDT(双刀双掷)。“掷”指的是输入线,“刀”指的是输出。因此,SPDT继电器可以选择两个输入中的任何一个作为其输出。
图8.1 B显示了一个典型的SPDT继电器。它有5个引脚。顶部的中心引脚是触点引脚或输出。底部的两个引脚是继电器选择的输入线。当继电器关闭时,其中一个输入被连接,称为常闭(NC);当继电器激活时,选择另一个输入,称为常开(NO)。左上和右上引脚分别是+Vcc和Gnd引脚。+Vcc电压取决于继电器的额定工作电压。有不同规格的继电器:5V、6V、9V、12V、18V和24V继电器是常见的SPDT继电器类型。请注意,此电压是用于开启继电器的电压。常闭和常开的电压可以高几个数量级,甚至可以是交流电压。图8.1显示了一个典型的SPDT继电器、其引脚定义和内部原理图。
图8.1:继电器连接原理、原理图和引脚定义
8.2 Arduino与继电器
8.2.1 通过晶体管控制继电器
最低电压继电器,即5V继电器,需要大约200mA的电流才能在5V下工作。因此,我们很容易知道数字引脚不能直接驱动继电器。那么?嗯,我们需要将继电器本身视为一个负载。现在我们的问题解决了。我们可以将继电器的Vs连接到+Vcc,将Gnd连接到NPN晶体管(如BC548)的集电极。当我们通过一个数字引脚向晶体管提供基极电流时,晶体管通过其发射极完成继电器的接地电路,如图8.3所示。然而,晶体管通常会受到反向电流的影响。由于继电器的开关机制依赖于线圈中的磁性,当它驱动负载时,负载电流感应反电动势的可能性很高。因此,在与晶体管一起工作时,继电器上有一个反向并联的飞回二极管,其作用是为反向电动势接地。
晶体管驱动继电器电路的另一个缺点是,当您在PCB上工作时,如果晶体管因过流而损坏,则需要花费很多精力才能将其从PCB上更换为另一个晶体管。因此,我们使用了另一种机制。我们将继电器的Vs与Vcc耦合,使用一个称为光电耦合器的芯片。
8.2.2 通过光电耦合器控制继电器
最便宜、最容易获得的光电耦合器之一是MCT2E。芯片内部,光电耦合器在输入端有一个光发射器,可以在非常低的电流下工作,因此可以直接由Arduino数字引脚触发。在输出端,芯片有一个光电晶体管,一旦内部光二极管开始发光,它就会获得基极电流。该晶体管是NPN型。因此,一旦开启,它就可以产生施加到其集电极的相同电压,从引脚6到引脚4。由于输入端和输出端之间没有连接,因此该芯片不受任何反向电流的影响。这个概念也称为光隔离。MCT2E的数据手册称其光隔离能力约为1800V。
所以,光电耦合器的引脚1连接到Arduino的数字引脚,其引脚5连接到继电器的+Vcc(对于12V继电器,引脚5连接到12V电源;对于9V继电器,连接到9V)。引脚4是光电耦合器的输出引脚,连接到继电器的VS引脚。继电器、光电耦合器(引脚2)、电源(+Vcc)和Arduino的接地必须是共用的。在任何硬件项目中使用时,这一点非常非常重要。如果您忘记将所有这些设备的接地连接在一起,那么您的继电器将无法触发。
图8.2:带负载的继电器与Arduino连接
图8.3:用晶体管连接继电器
如果您不愿意使用独立的继电器设置,您也可以购买5V继电器扩展板,价格大约为3美元。但说实话,如果您自己组装继电器单元,成本大约为0.5美元!图8.4显示了一个典型的5V继电器扩展板。带有输入Vcc、Sig、Gnd的三个引脚连接器。这里的Sig是Vs。
输出端有三个带螺丝的母插槽。NO和NC是提供输入电压的引脚,Pole是输出。继电器还有一个内置LED,在继电器激活时会点亮。
由于继电器是5V的,我们需要将Vcc连接到Arduino Vcc,Gnd连接到Arduino Ground,Sig连接到任何数字I/O引脚。此时,我们想测试继电器的开关。所以不需要连接Pole、NO和NC。
图8.4:5V继电器扩展板
使用第4.1.1节的闪烁代码来测试继电器开关。您会听到一声清脆的“咔哒”声,LED会亮起然后熄灭,继电器也会每秒开关一次。当引脚13变为高电平时,继电器也打开。
图8.5:带有闪烁代码的继电器输出
9. 电机应用
9.1 通过晶体管控制直流电机
电机和执行器是构建机器人最重要的设备。直流电机是电机的重要类别。DIY项目中使用了各种类型的直流电机,例如无刷直流电机、齿轮电机等。这篇直流电机维基百科文章是一篇很棒的入门文章。
在本文中,我们关注的是控制直流电机。您可以购买一个6V/9V/12V电机。您也可以从旧CD/DVD驱动器中拆卸一个。电机也是负载,因此可以像继电器/LED一样进行切换。与继电器一样,电机容易产生反向电动势。因此,我们必须在电机两端连接一个飞回二极管,就像继电器一样。图8.1显示了一个典型电机开关的电路。Vcc取决于电机的额定电压。
如果您想控制电机的速度,可以将晶体管连接到PWM引脚,并使用PWM部分的列表来控制其速度。否则,如果目的只是将其打开和关闭,请将晶体管基极连接到引脚13等普通数字I/O引脚,并使用4.1.2的列表检查电机每秒的开关状态。
图9.1:使用晶体管通过Arduino控制直流电机
图9.2:通过PWM控制直流电机速度
9.2 通过继电器控制电机
请记住,继电器的切换时间比数字电路的切换时间慢很多倍。因此,继电器不能用于电机的速度控制。它们主要用于电机的开关。继电器的一个优点是,您可以为继电器的NC和NO提供+Vcc,-Vcc,其输出可以连接到另一个继电器的NO。现在,通过控制两个继电器,您可以使电机朝任一方向旋转。
用继电器连接电机很简单,不需要电机两端的二极管,因为继电器两端的飞回二极管会处理这个问题。
图9.3显示了5V继电器的电路图,实际连接如图9.4所示。我使用了9V电池作为Vcc。您也可以使用9V/12V适配器。
图9.3:使用继电器切换电机的电路图
图9.4:使用继电器切换电机的物理连接
您可以使用4.1.2节的闪烁列表来测试电路。
10. 红外传感器无线通信
Arduino是处理几乎所有您想用硬件做的事情的绝佳解决方案。无线通信也不例外。现在有适用于Arduino的蓝牙模块,工作得很好。您可以使用RF与Arduino通信。但最酷的支持之一是IR。
虽然IR(红外线)实际上是一个传感器,应该在传感器类别中介绍,但由于它广泛用于遥控设备,因此我将将其作为无线主题的一个独立主题来介绍。
IR接收器有不同的供应商,与其他传感器不同,它们没有标准的引脚定义。您可以花不到1美元订购一个IR传感器。但是,请确保您知道您订购的传感器的引脚定义。这一点非常重要,因为我亲眼见过各种类型的IR传感器及其引脚定义。
然而,大多数常见的IR传感器看起来都像图10.1,有Gnd、Vcc和O/P引脚。O/P必须连接到任何PWM引脚。IR的工作方式与超声波传感器类似。接收器可以检测调制在38KHz的IR脉冲。
您可以使用任何家用遥控器(电视/空调)来生成信号。
图10.1:Arduino与IR接收器
解码信号需要一个特殊的库。从GitHub下载IRemote库。从GitHub下载IRemote库。将库添加到您的Arduino IDE。该库带有一个很酷的IRcvDemo。将其另存为不同的名称,然后将草图上传到Arduino。我还在代码中添加了一些额外的调整。您可以通过代码来打开和关闭引脚13的LED。
#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
pinMode(13,OUTPUT);
digitalWrite(13,LOW);
irrecv.enableIRIn(); // Start the receiver
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
switch(results.value)
{
case 0x1111:
digitalWrite(13,HIGH);
Serial.println("LED ON");
break;
case 0x2222:
digitalWrite(13,LOW);
Serial.println("LED OFF");
break;
}
irrecv.resume(); // Receive the next value
}
}
这只有一个问题。每个遥控器/公司遵循不同的IR协议。换句话说,与按钮按下关联的十六进制值将不同。所以您可以做的是测试您的IR,读取任意两个按钮的代码,然后用该代码替换0x1111和0x2222。
串行监视器的转储如图10.2所示,实际结果如图10.3所示。
图10.2:使用IR接收器的串行监视器截图
图10.3: 通过IR接收器打开和关闭LED
观察遥控器上的标志和板载绿色LED!您可以看到,LED通过交替按下ON/OFF按钮来打开和关闭。
11. 结论
DIY/生产嵌入式项目中发挥重要作用的硬件组件和设备有很多。传感器和电机种类繁多,世界上没有一个教程能在单个教程中涵盖所有这些。然而,DIY爱好者必须知道一些基本的东西。一些基本的电压和电流知识,一些基本的传感器和执行器。一些显示的方法。我试图涵盖DIY项目所需的大部分重要、低成本硬件。我列出了独立的代码。本教程主要侧重于硬件部分。您还可以查看我的ArdOS教程,其中我提供了与Arduino配合使用ArdOS的详细描述。