Arduino 简明教程

Arduino - Quick Guide

Arduino - Overview

Arduino 是一个基于易于使用的硬件和软件的原型平台(开源)。它包括一个电路板,可以进行编程(称为微控制器),以及一个用于编写和将计算机代码上传到物理板的现成软件,称为 Arduino IDE(集成开发环境)。

主要功能 −

  1. Arduino 电路板能够从不同的传感器读取模拟或数字输入信号,并将其转换为输出,例如启动电机、打开/关闭 LED,连接云以及许多其他动作。

  2. 您可以通过 Arduino IDE(称为上载软件)向电路板上的微控制器发送一组指令来控制电路板功能。

  3. 与大多数以前的可编程电路板不同,Arduino 无需额外的硬件(称为编程器)即可将新代码加载到电路板上。您可以简单地使用 USB 数据线。

  4. 此外,Arduino IDE 使用 C++ 的简化版本,让编程更容易学习。

  5. 最后,Arduino 提供了标准的外形尺寸,将微控制器的功能分成更易于获取的封装。

board

Board Types

根据所用的不同微控制器,有各种类型的 Arduino 电路板。然而,所有的 Arduino 电路板有一个共同点:可以通过 Arduino IDE 进行编程。

差异基于输入和输出的数量(您可以在一块电路板上使用的传感器、LED 和按钮的数量)、速度、工作电压、外形尺寸等。一些电路板被设计成嵌入式,没有编程接口(硬件),您需要单独购买。一些可以直接通过 3.7V 电池供电,其他则至少需要 5V。

以下是不同 Arduino 电路板的列表。

Arduino boards based on ATMEGA328 microcontroller

Board Name

Operating Volt

Clock Speed

Digital i/o

Analog Inputs

PWM

UART

Programming Interface

Arduino Uno R3

5V

16MHz

14

6

6

1

USB via ATMega16U2

Arduino Uno R3 SMD

5V

16MHz

14

6

6

1

USB via ATMega16U2

Red Board

5V

16MHz

14

6

6

1

USB via FTDI

Arduino Pro 3.3v/8 MHz

3.3V

8MHz

14

6

6

1

FTDI-Compatible Header

Arduino Pro 5V/16MHz

5V

16MHz

14

6

6

1

FTDI-Compatible Header

Arduino mini 05

5V

16MHz

14

8

6

1

FTDI-Compatible Header

Arduino Pro mini 3.3v/8mhz

3.3V

8MHz

14

8

6

1

FTDI-Compatible Header

Arduino Pro mini 5v/16mhz

5V

16MHz

14

8

6

1

FTDI-Compatible Header

Arduino Ethernet

5V

16MHz

14

6

6

1

FTDI-Compatible Header

Arduino Fio

3.3V

8MHz

14

8

6

1

FTDI-Compatible Header

LilyPad Arduino 328 主电路板

3.3V

8MHz

14

6

6

1

FTDI-Compatible Header

LilyPad Arduino simple board

3.3V

8MHz

9

4

5

0

FTDI-Compatible Header

Arduino boards based on ATMEGA32u4 microcontroller

Board Name

Operating Volt

Clock Speed

Digital i/o

Analog Inputs

PWM

UART

Programming Interface

Arduino Leonardo

5V

16MHz

20

12

7

1

Native USB

Pro micro 5V/16MHz

5V

16MHz

14

6

6

1

Native USB

Pro micro 3.3V/8MHz

5V

16MHz

14

6

6

1

Native USB

LilyPad Arduino USB

3.3V

8MHz

14

6

6

1

Native USB

Arduino boards based on ATMEGA2560 microcontroller

Board Name

Operating Volt

Clock Speed

Digital i/o

Analog Inputs

PWM

UART

Programming Interface

Arduino Mega 2560 R3

5V

16MHz

54

16

14

4

USB via ATMega16U2B

Mega Pro 3.3V

3.3V

8MHz

54

16

14

4

FTDI-Compatible Header

Mega Pro 5V

5V

16MHz

54

16

14

4

FTDI-Compatible Header

Mega Pro Mini 3.3V

3.3V

8MHz

54

16

14

4

FTDI-Compatible Header

Arduino boards based on AT91SAM3X8E microcontroller

Board Name

Operating Volt

Clock Speed

Digital i/o

Analog Inputs

PWM

UART

Programming Interface

Arduino Mega 2560 R3

3.3V

84MHz

54

12

12

4

USB native

Arduino - Board Description

在本章中,我们将了解 Arduino 板上的不同组件。我们研究 Arduino UNO 板,因为它在 Arduino 板系列中是最流行的板。此外,它是开始学习电子和编码的最佳选择。一些板看起来与下面给出的有些不同,但大多数 Arduino 都具有这些组件的大部分共同点。

board description

Power USB Arduino 板可以使用来自计算机的 USB 电缆供电。您需要做的就是将 USB 数据线连接到 USB 连接器(1)。

Power (Barrel Jack) Arduino 板可以通过将其连接到 Barrel Jack(2)从交流主电源直接供电。

Voltage Regulator 电压调节器的作用是控制给 Arduino 板的电压并稳定处理器和其他元件使用的直流电压。

Crystal Oscillator 晶体振荡器帮助 Arduino 处理时间问题。Arduino 如何计算时间?答案是,通过使用晶体振荡器。印刷在 Arduino 晶体顶部的数字是 16.000H9H。它告诉我们频率是 16,000,000 赫兹或 16 兆赫。

Arduino Reset 您可以重置 Arduino 板,即从头开始运行程序。有两种方式可以重置 UNO 板。首先,使用板上的复位按钮(17)。其次,您可以将外部复位按钮连接到标记为 RESET(5)的 Arduino 引脚。

Pins (3.3, 5, GND, Vin) 3.3V(6)− 提供 3.3 输出伏5V(7)− 提供 5 输出伏与 Arduino 板一起使用的大多数组件都适用于 3.3 伏和 5 伏。GND(8)(接地)− Arduino 上有几个 GND 引脚,任何一个引脚都可以用来接地电路。Vin(9)− 此引脚也可用于从外部电源(如交流主电源)为 Arduino 板供电。

Analog pins Arduino UNO 板有六个模拟输入引脚 A0 至 A5。这些引脚可以读取模拟传感器(如湿度传感器或温度传感器)发来的信号,然后将其转换为微处理器可以读取的数字值。

Main microcontroller 每个 Arduino 板都有自己的微控制器 (11)。你可以把它当作板上的“大脑”。Arduino 上的主要 IC(集成电路)从一块板到另一块板略有不同。这些微控制器通常来自 ATMEL 公司。在从 Arduino IDE 加载新程序之前,你必须知道板上有什么 IC。此信息显示在 IC 的顶部。有关 IC 构造和功能的更多详细信息,请参阅数据表。

ICSP pin 通常,ICSP (12) 是一个 AVR,一个带有 MOSI、MISO、SCK、复位、VCC 和 GND 的微型编程头。它通常被称为 SPI(串行外围接口),可被认为是输出的“扩展”。实际上,你将输出设备用作 SPI 总线的从设备。

Power LED indicator 将 Arduino 插入电源后,此 LED 应亮起,表明你的板已正确通电。如果此指示灯未亮起,则连接有问题。

TX and RX LEDs 在你的板上,你会发现两个标签:TX(发送)和 RX(接收)。它们出现在 Arduino UNO 板上的两个位置。首先,在数字引脚 0 和 1 上,表示负责串行通信的引脚。其次,TX 和 RX LED (13)。发送串行数据时,TX LED 以不同的速度闪烁。闪烁速度取决于板使用的波特率。接收过程中,RX 会闪烁。

Digital I/O Arduino UNO 板有 14 个数字 I/O 引脚 (15)(其中 6 个提供 PWM(脉冲宽度调制)输出)。可以配置这些引脚,使其作为输入数字引脚工作,以读取逻辑值(0 或 1),或作为数字输出引脚,以驱动不同的模块,如 LED、继电器等。标记为“~”的引脚可用于产生 PWM。

AREF AREF 表示模拟参考。有时,它用于设置外部参考电压(0 到 5 伏特之间)作为模拟输入引脚的上限。

Arduino - Installation

在了解了 Arduino UNO 电路的各个主要部分后,我们便可以学习如何设置 Arduino IDE。一旦学会,我们便可以将程序上传至 Arduino 电路板。

在本部分中,我们将分步学习如何将 Arduino IDE 设置到我们的计算机上,并使用 USB 电缆准备电路板接收程序。

Step 1 − 首先,你必须准备 Arduino 电路板(你可以选择你偏好的电路板)和一条 USB 电缆。如果你使用 Arduino UNO、Arduino Duemilanove、Nano、Arduino Mega 2560 或 Diecimila,则需要一条标准 USB 电缆(A 型插头至 B 型插头),即你用于连接 USB 打印机的电缆,如以下图片所示。

usb cable

如果你使用 Arduino Nano,则你需要一条 A 型至 Mini-B 型电缆,如以下图片所示。

mini cable

Step 2 − Download Arduino IDE Software.

你可以在 Arduino 官方网站上的 Download page 获得不同版本的 Arduino IDE。你必须选择适合你的操作系统(Windows、IOS 或 Linux)的软件。下载文件完成后,解压该文件。

opening arduino nightly windows

Step 3 − Power up your board.

Arduino Uno、Mega、Duemilanove 和 Arduino Nano 自动从计算机的 USB 连接或外部电源获取电能。如果你使用的是 Arduino Diecimila,则必须确保电路板配置为从 USB 连接获取电能。电源通过跳线(小块塑料,可装在 USB 和电源插孔之间的三个插针中的两个插针上)选择。请检查跳线是否位于最靠近 USB 端口的两个插针上。

使用 USB 电缆将 Arduino 电路板连接至你的计算机。绿色的电源 LED(标记为 PWR)应亮起。

Step 4 − Launch Arduino IDE.

下载 Arduino IDE 软件后,你需要解压文件夹。在文件夹中,你可以找到带有无穷大符号(application.exe)的应用程序图标。双击该图标启动 IDE。

launch arduino ide

@[s0]

软件启动后,你有两个选择 -

  1. Create a new project.

  2. 打开现有项目示例。

要创建新项目,请选择文件 → @[s1]。

edit file

要打开现有项目示例,请选择文件 → 示例 → 基础 → 闪烁。

open project

此处,我们仅选择一个名为 Blink 的示例。它会延迟一段时间打开和关闭 LED 灯。你可以从列表中选择任何其他示例。

@[s3]

为了避免在将程序上传到电路上时出现错误,你必须选择正确的 Arduino 电路板名称,该名称与连接到计算机的电 路板相匹配。

转到工具 → 电路板,并选择你的电 路板。

select board

此处,我们根据教程选择了 Arduino Uno 电路板,但你必须选择与你使用的电 路板相匹配的名称。

@[s4]

选择 Arduino 电路板的串口设备。转到 @[s5] 菜单。此设备可能是 COM3 或更高版本(COM1 和 COM2 通常保留给硬件串行端口)。要查找,你可 以断开 Arduino 电路板并重新打开菜单,消失的条目应属于 Arduino 电路板。重新连接电 路板并选择该串行端口。

serial port

@[s6]

在解释如何将程序上传到电 路板之前,我们必须说明 Arduino IDE 工具栏中出现的每个符号的功能。

upload program

@[s7] - 用于检查是否存在任何编译错误。

@[s8] - 用于将程序上传到 Arduino 电路板。

@[s9] - 用于创建新草稿的快捷方式。

@[s10] - 用于直接打开一个示例草稿。

E − 用于保存你的草图。

F − 串行监视器用于从电路板接收串行数据并向电路板发送串行数据。

现在,只须点击环境中的“上传”按钮。等待几秒钟,你将看到电路板上的 RX 和 TX LED 闪烁。如果上传成功,状态栏中将出现“上传完成”信息。

Note − 如果你有 Arduino Mini、NG 或其他电路板,在点击 Arduino 软件上的上传按钮前,你需要在电路板上按复位按钮。

Arduino - Program Structure

在本章中,我们将深入学习 Arduino 程序结构,并将学习在 Arduino 世界中使用更多新术语。Arduino 软件是开源的。Java 环境的源代码在 GPL 下发布,C/C++ 微控制器库在 LGPL 下发布。

Sketch − 第一个新术语是名为“ sketch ”的 Arduino 程序。

Structure

Arduino 程序可以分为三个主要部分: Structure, Values (变量和常量)以及 Functions 。在本教程中,我们将逐步了解 Arduino 软件程序以及如何在不出现任何语法或编译错误的情况下编写程序。

让我们从 Structure 开始。软件结构包含两个主要函数 ——

  1. Setup( ) function

  2. Loop( ) function

structure
Void setup ( ) {

}
  1. PURPOSE − 当草图开始时,将调用 setup() 函数。使用它来初始化变量、引脚模式、开始使用库等。在 Arduino 电路板每次上电或复位后,设置函数只会运行一次。

  2. INPUT − -

  3. OUTPUT − -

  4. RETURN − -

Void Loop ( ) {

}
  1. PURPOSE − 在创建初始化并设置初始值的 setup() 函数后, loop() 函数准确地执行其名称所暗示的内容,并连续循环,使您的程序能够更改和作出响应。使用它来主动控制 Arduino 电路板。

  2. INPUT − -

  3. OUTPUT − -

  4. RETURN − -

Arduino - Data Types

C 中的数据类型是指用于声明不同类型的变量或函数的广泛系统。一个变量的类型决定了它在存储中占据多少空间以及存储的位模式如何解释。

下表提供了您在 Arduino 编程中将使用所有数据类型。

void

Boolean

char

Unsigned char

byte

int

Unsigned int

word

long

Unsigned long

short

float

double

array

String-char array

String-object

void

void 关键字仅用于函数声明。它表明该函数预计不会向其调用的函数返回任何信息。

Example

Void Loop ( ) {
   // rest of the code
}

Boolean

布尔值包含两个值之一,真或假。每个布尔值变量占据一个字节的内存。

Example

boolean val = false ; // declaration of variable with type boolean and initialize it with false
boolean state = true ; // declaration of variable with type boolean and initialize it with true

Char

占用一个字节的内存来存储字符值的数据类型。字符字面值用单引号编写,如下所示:'A',对于多个字符,字符串使用双引号:“ABC”。

然而,字符存储为数字。您可以在 ASCII chart 中看到特定编码。这意味着可以对字符执行算术运算,其中使用字符的 ASCII 值。例如,'A' + 1 的值为 66,因为大写字母 A 的 ASCII 值为 65。

Example

Char chr_a = ‘a’ ;//declaration of variable with type char and initialize it with character a
Char chr_c = 97 ;//declaration of variable with type char and initialize it with character 97
ascii char table

unsigned char

Unsigned char 是一个无符号数据类型,占用一个字节的内存。无符号 char 数据类型对 0 到 255 之间的值进行编码。

Example

Unsigned Char chr_y = 121 ; // declaration of variable with type Unsigned char and initialize it with character y

byte

字节存储一个 8 位无符号数字,从 0 到 255。

Example

byte m = 25 ;//declaration of variable with type byte and initialize it with 25

int

整数是用于存储数字的主要数据类型。int 存储一个 16 位(2 字节)的值。这产生了 -32,768 到 32,767 的范围(最小值 -2^15,最大值 (2^15) - 1)。

int 的大小因板而异。例如,在 Arduino Due 上,一个 int 存储一个 32 位(4 字节)的值。这产生了-2,147,483,648 到 2,147,483,647 的范围(最小值为 -2^31,最大值为 (2^31) - 1)。

Example

int counter = 32 ;// declaration of variable with type int and initialize it with 32

Unsigned int

无符号 int(无符号整数)在存储 2 字节的值方式上与 int 相同。但它们不存储负数,只存储正值,产生了 0 到 65,535 (2^16) - 1)的有用范围。Due 存储一个 4 字节(32 位)的值,其范围是从 0 到 4,294,967,295 (2^32 - 1)。

Example

Unsigned int counter = 60 ; // declaration of variable with
   type unsigned int and initialize it with 60

Word

在 Uno 和其他基于 ATMEGA 的板上,一个字存储一个 16 位无符号数字。在 Due 和 Zero 中,它存储一个 32 位无符号数字。

Example

word w = 1000 ;//declaration of variable with type word and initialize it with 1000

Long

长变量是用于存储数字的扩展大小变量,存储 32 位(4 字节),范围从 -2,147,483,648 到 2,147,483,647。

Example

Long velocity = 102346 ;//declaration of variable with type Long and initialize it with 102346

unsigned long

无符号长变量是用于存储数字的扩展大小变量,存储 32 位(4 字节)。与标准长不同,无符号长不会存储负数,其范围为 0 到 4,294,967,295 (2^32 - 1)。

Example

Unsigned Long velocity = 101006 ;// declaration of variable with
   type Unsigned Long and initialize it with 101006

short

一个短的是一个 16 位的数据类型。在所有 Arduino(基于 ATMega 和 ARM)上,一个短的存储一个 16 位(2 字节)的值。这产生了 -32,768 到 32,767 的范围(最小值 -2^15,最大值 (2^15) - 1)。

Example

short val = 13 ;//declaration of variable with type short and initialize it with 13

float

浮点数数据类型是一个具有小数点的数字。浮点数通常用于近似模拟和连续值,因为它们比整数具有更高的分辨率。

浮点数可以大至 3.4028235E+38,小至 -3.4028235E+38。它们以 32 位(4 字节)信息进行存储。

Example

float num = 1.352;//declaration of variable with type float and initialize it with 1.352

double

在 Uno 和其他基于 ATMEGA 的电路板上,双精度浮点数字占用四个字节。也就是说,double 的实现方式同 float 完全相同,精度没有得到提升。而在 Arduino Due 上,double 具有 8 个字节(64 位)的精度。

Example

double num = 45.352 ;// declaration of variable with type double and initialize it with 45.352

Arduino - Variables & Constants

在我们开始解释变量类型之前,我们需要确保你充分理解的一个非常重要的主题被称为 variable scope

What is Variable Scope?

Arduino 使用的 C 编程语言中的变量有一个称为作用域的属性。作用域是程序的一个区域,可以在三个地方声明变量。它们是 −

  1. 在函数或块内,称为 local variables

  2. 在函数参数的定义中,称为 formal parameters

  3. 在所有函数外部,称为 global variables

Local Variables

在函数或块内声明的变量是局部变量。它们只能由该函数或代码块内的语句使用。对于自己的函数外部,局部变量是未知的。下面是使用局部变量的示例 −

Void setup () {

}

Void loop () {
   int x , y ;
   int z ; Local variable declaration
   x = 0;
   y = 0; actual initialization
   z = 10;
}

Global Variables

全局变量在所有函数外部定义,通常在程序的顶部。全局变量将在程序的整个生命周期内保持其值。

任何函数都可以访问全局变量。也就是说,全局变量在声明后可以在整个程序中使用。

以下示例使用全局和局部变量 −

Int T , S ;
float c = 0 ; Global variable declaration

Void setup () {

}

Void loop () {
   int x , y ;
   int z ; Local variable declaration
   x = 0;
   y = 0; actual initialization
   z = 10;
}

Arduino - Operators

运算符是一个符号,它告诉编译器执行特定的数学或逻辑函数。C 语言拥有丰富的内置运算符,并提供了以下类型的运算符 −

  1. Arithmetic Operators

  2. Comparison Operators

  3. Boolean Operators

  4. Bitwise Operators

  5. Compound Operators

Arithmetic Operators

假设变量 A 保存 10,变量 B 保存 20,则 −

Operator name

Operator simple

Description

Example

assignment operator

=

将等号右侧的值保存到等号左侧变量中。

A = B

addition

+

Adds two operands

A + B 会给出 30

subtraction

-

从第一个操作数中减去第二个操作数

A - B 会给出 -10

multiplication

*

Multiply both operands

A * B 会给出 200

division

/

Divide numerator by denominator

B / A 会给出 2

modulo

%

模运算符,整数除法后的余数

B % A 会给出 0

Comparison Operators

假设变量 A 保存 10,变量 B 保存 20,则 −

Operator name

Operator simple

Description

Example

equal to

==

检查两个操作数的值是否相等,如果相等,则条件变为真。

(A == B) 为假

not equal to

!=

检查两个操作数的值是否相等,如果不相等,则条件变为真。

(A != B) 为真

less than

<

检查左操作数的值是否小于右操作数的值,如果小于,则条件变为真。

(A < B) 为真

greater than

>

检查左操作数的值是否大于右操作数的值,如果大于,则条件变为真。

(A > B) 不为真

小于或等于

检查左操作数的值是否小于或等于右操作数的值,如果小于或等于,则条件变为真。

(A ⇐ B) 为真

大于或等于

>=

检查左操作数的值是否大于或等于右操作数的值,如果大于或等于,则条件变为真。

(A >= B) 不为真

Boolean Operators

假设变量 A 保存 10,变量 B 保存 20,则 −

Operator name

Operator simple

Description

Example

and

&&

称为逻辑 AND 运算符。如果两个操作数都是非零,则条件变为真。

(A && B) 为真

or

称为逻辑 OR 运算符。如果两个操作数中的任何一个是非零,则条件变为真。

(A

B) is true

not

!

称为逻辑 NOT 运算符。用于反转操作数的逻辑状态。如果条件为 true,则逻辑 NOT 运算符会将其变为 false。

!(A && B) 为假

Bitwise Operators

假设变量 A 保存 60,变量 B 保存 13,则 −

Operator name

Operator simple

Description

Example

and

&

二进制与运算符将位复制到结果中(如果它存在于两个操作数中)。

(A 和 B) 结果是 12,即 0000 1100

or

如果二进制 OR 运算符在任一操作数中存在位,则复制该位

(A

B) 结果是 61,即 0011 1101

xor

^

二进制 XOR 运算符会在其中一个操作数中但不在两个操作数中都设置的情况下复制比特。

(A ^ B) 结果为 49,即 0011 0001

not

~

二进制逻辑补运算符是单操作数运算符,它会“翻转”比特。

(~A ) 将得到 -60,即 1100 0011

shift left

<<

二进制左移运算符。左操作数的值会向左移动由右操作数指定的比特数。

A << 2 的结果是 240,即 1111 0000

shift right

>>

Compound Operators

假设变量 A 保存 10,变量 B 保存 20,则 −

Operator name

Operator simple

Description

Example

increment

++

自增运算符,将整数加一

A++ will give 11

decrement

 — 

自减运算符,将整数减一

A-- will give 9

compound addition

+=

增加且赋值运算符。 它将右操作数添加到左操作数,并将其结果赋予左操作数

B = A 等同于 B = B A

compound subtraction

-=

减去且赋值运算符。 它从左操作数中减去右操作数,并将其结果赋予左操作数

B -= A 等同于 B = B - A

compound multiplication

*=

乘以且赋值运算符。 它将右操作数乘以左操作数,并将其结果赋予左操作数

B*= A 等同于 B = B* A

compound division

/=

除以且赋值运算符。 它用右操作数除以左操作数,并将其结果赋予左操作数

B /= A 等同于 B = B / A

compound modulo

%=

取余且赋值运算符。 它用两个操作数取模,并将其结果赋予左操作数

B %= A 等同于 B = B % A

compound bitwise or

=

按位或且赋值运算符

A

= 2 等同于 A = A

2

compound bitwise and

Arduino - Control Statements

决策制定结构要求程序员指定一个或多个条件,供程序进行评估或测试。它应与确定条件为真的情况下要执行的语句或语句一起制定,并且可以选择性地制定在确定条件为假情况下要执行的其他语句。

以下是大多数编程语言中常见的典型决策结构的一般形式 −

decision making

控制语句是源代码中的元素,用于控制程序执行的流程。它们是 −

S.NO.

Control Statement & Description

1

If statement 它采用括号中的表达式和语句或语句块。如果表达式为真,那么语句或语句块将被执行,否则这些语句将被跳过。

2

If …else statement if 语句后面可以跟一个可选的 else 语句,当表达式为假时执行该语句。

3

If…else if …else statement if 语句后面可以跟一个可选的 else if&#8230;&#8203;else 语句,这对于使用单一的 if… else if 语句测试各种条件非常有用。

4

switch case statement 与 if 语句类似, switch&#8230;&#8203;case 通过允许程序员指定应在各种条件下执行的不同代码来控制程序流程。

5

Conditional Operator ? : 条件运算符 ? : 是 C 中唯一的三个运算符。

Arduino - Loops

编程语言提供了各种控制结构,允许执行更复杂的路径。

循环语句允许我们多次执行一个语句或一组语句,以下是大多数编程语言中循环语句的一般形式 −

loop architecture

C 编程语言提供以下类型的循环来处理循环要求。

S.NO.

Loop & Description

1

while loop while 循环将连续无限循环,直到圆括号 () 内的表达式变为假。某种东西必须改变被测的变量,否则 while 循环将永远不会退出。

2

do…while loop do…while 循环类似于 while 循环。在 while 循环中,循环持续条件在执行循环体之前在循环开始时接受测试。

3

for loop 一个 for loop 执行语句一个预先确定的次数。 循环的控制表达式完全在 for 循环括号内进行初始化、测试和操纵。

4

Nested Loop C 语言允许你在一个循环内使用另一个循环。下面的示例说明了这个概念。

5

Infinite loop 它是没有终止条件的循环,因此循环变成无限循环。

Arduino - Functions

函数允许对代码段进行结构化,针对各个任务。创建函数的典型情况是,当程序中需要多次执行相同操作时。

将代码片段标准化成函数具有多个优势 −

  1. 函数帮助程序员保持井井有条。这常常有助于概念化程序。

  2. 函数将一个操作编码在一个地方,这样就只需要考虑和调试一次函数。

  3. 如果需要更改代码,还可以减少修改错误的机会。

  4. 函数可以多次复用部分代码,使整个草图更小、更紧凑。

  5. 通过模块化更容易在其他程序中复用代码,并且使用函数可以常常提高代码可读性。

Arduino 草图或程序中的两个必需函数是:setup() 和 loop()。其他函数必须在两个函数的括号之外创建。

定义函数最常见的语法是 −

function

Function Declaration

可以在任何其他函数外部声明函数,高于或低于循环函数。

我们可以通过两种不同的方式声明函数 −

第一种方法是在循环函数的上方写出名为 a function prototype 的函数部分,其包括 −

  1. Function return type

  2. Function name

  3. 函数参数类型,无需写出参数名称

函数原型后必须跟分号 ( ; )。

下面的示例演示如何使用第一种方法进行函数声明。

Example

int sum_func (int x, int y) // function declaration {
   int z = 0;
   z = x+y ;
   return z; // return the value
}

void setup () {
   Statements // group of statements
}

Void loop () {
   int result = 0 ;
   result = Sum_func (5,6) ; // function call
}

第二部分称为函数定义或声明,必须在循环函数的下方声明,其包括 −

  1. Function return type

  2. Function name

  3. 函数参数类型,这里必须添加参数名称

  4. 函数体(当函数被调用时执行的函数内的语句)

下面的示例演示如何使用第二种方法声明函数。

Example

int sum_func (int , int ) ; // function prototype

void setup () {
   Statements // group of statements
}

Void loop () {
   int result = 0 ;
   result = Sum_func (5,6) ; // function call
}

int sum_func (int x, int y) // function declaration {
   int z = 0;
   z = x+y ;
   return z; // return the value
}

第二种方法只是在循环函数的上方声明函数。

Arduino - Strings

字符串用于存储文本。它们可用于在 LCD 上或 Arduino IDE 串行监视器窗口中显示文本。字符串对于存储用户输入也很有用。例如,用户在连接到 Arduino 的键盘上键入的字符。

在 Arduino 编程中有两种类型的字符串 -

  1. 字符数组,这与 C 编程中使用的字符串相同。

  2. Arduino String,它允许我们在草图中使用字符串对象。

在本章中,我们将学习字符串、对象以及字符串在 Arduino 草图中的用法。在本节末尾,你将学习在草图中使用哪种类型的字符串。

String Character Arrays

我们将学习的第一种类型的字符串是一系列 char 类型的字符。在上一章中,我们学习了数组是什么;一系列连续的同类型变量,存储在内存中。字符串是 char 变量的数组。

字符串是一个特殊的数组,其在字符串末尾有一个额外的元素,该元素的值始终为 0(零)。这被称为“空终止字符串”。

String Character Array Example

此示例将展示如何制作字符串并将其打印到串行监视器窗口。

Example

void setup() {
   char my_str[6]; // an array big enough for a 5 character string
   Serial.begin(9600);
   my_str[0] = 'H'; // the string consists of 5 characters
   my_str[1] = 'e';
   my_str[2] = 'l';
   my_str[3] = 'l';
   my_str[4] = 'o';
   my_str[5] = 0; // 6th array element is a null terminator
   Serial.println(my_str);
}

void loop() {

}

以下示例显示了字符串的构成;一个字符数组,其中包含可打印字符,并且 0 为数组的最后一个元素,以表明这是字符串的结束位置。可以使用 Serial.println() 并传递字符串的名称将字符串打印到 Arduino IDE 串行监视器窗口。

可以使用以下更简洁的方式编写此示例 -

Example

void setup() {
   char my_str[] = "Hello";
   Serial.begin(9600);
   Serial.println(my_str);
}

void loop() {

}

在此草图中,编译器计算字符串数组的大小,并使用零自动空终止字符串。与上一草图完全相同的方式创建了一个由六个元素组成且包含五个字符后跟一个零的数组。

Manipulating String Arrays

我们可以在草图中更改字符串数组,如下面的草图所示。

Example

void setup() {
   char like[] = "I like coffee and cake"; // create a string
   Serial.begin(9600);
   // (1) print the string
   Serial.println(like);
   // (2) delete part of the string
   like[13] = 0;
   Serial.println(like);
   // (3) substitute a word into the string
   like[13] = ' '; // replace the null terminator with a space
   like[18] = 't'; // insert the new word
   like[19] = 'e';
   like[20] = 'a';
   like[21] = 0; // terminate the string
   Serial.println(like);
}

void loop() {

}

Result

I like coffee and cake
I like coffee
I like coffee and tea

草图按以下方式工作。

Creating and Printing the String

在上面给出的草图中,创建了一个新字符串,然后打印出来在串行监视器窗口中显示。

Shortening the String

字符串通过将字符串中的第 14 个字符替换为空终止零 (2) 来缩短。这是元素编号 13,从 0 开始计算字符串数组。

当打印字符串时,所有字符都会打印到新的空终止零。其他字符不会消失,它们仍存在于内存中,字符串数组的大小保持不变。唯一的区别是任何使用字符串的函数都只会看到字符串直到第一个空终止符。

Changing a Word in the String

最后,草图将单词“cake”替换为“tea”(3)。它必须首先用空格替换 like[13] 处的空终止符,以便将字符串还原为最初创建的格式。

新字符用单词“tea”覆盖单词“cake”的“cak”。这是通过覆盖单个字符来完成的。“cake”的’e’被替换为一个新的空终止符。结果是字符串实际上以两个空字符结尾,第一个空字符位于字符串末尾,另一个空字符替换了“cake”中的’e'。当打印新字符串时,这没有任何区别,因为打印字符串的函数在遇到第一个空终止符时会停止打印字符串字符。

Functions to Manipulate String Arrays

前一节草图通过访问字符串中的单个字符来以一种手动的方式操纵字符串。要使其更容易操纵字符串数组,你可以编写你自己的函数来操作它们,或使用来自 C 语言库的部分字符串函数。

下一节草图使用了部分 C 字符串函数。

Example

void setup() {
   char str[] = "This is my string"; // create a string
   char out_str[40]; // output from string functions placed here
   int num; // general purpose integer
   Serial.begin(9600);

   // (1) print the string
   Serial.println(str);

   // (2) get the length of the string (excludes null terminator)
   num = strlen(str);
   Serial.print("String length is: ");
   Serial.println(num);

   // (3) get the length of the array (includes null terminator)
   num = sizeof(str); // sizeof() is not a C string function
   Serial.print("Size of the array: ");
   Serial.println(num);

   // (4) copy a string
   strcpy(out_str, str);
   Serial.println(out_str);

   // (5) add a string to the end of a string (append)
   strcat(out_str, " sketch.");
   Serial.println(out_str);
   num = strlen(out_str);
   Serial.print("String length is: ");
   Serial.println(num);
   num = sizeof(out_str);
   Serial.print("Size of the array out_str[]: ");
   Serial.println(num);
}

void loop() {

}

Result

This is my string
String length is: 17
Size of the array: 18
This is my string
This is my string sketch.
String length is: 25
Size of the array out_str[]: 40

草图按以下方式工作。

Print the String

新创建的字符串被打印到 Serial Monitor 窗口,正如在之前的草图中所做的一样。

Get the Length of the String

strlen() 函数用于获取字符串的长度。字符串的长度仅限于可打印字符,且不包含空终止符。

该字符串包含 17 个字符,所以我们将在 Serial Monitor 窗口中看到打印的 17。

Get the Length of the Array

sizeof() 运算符用于获取包含字符串的数组的长度。该长度包含空终止符,所以该长度比字符串长度多 1。

sizeof() 看起来像一个函数,但实际上它是一个运算符。它不是 C 字符串库的一部分,但在草图中使用了它来展示数组的大小和字符串的大小(或字符串长度)之间的差异。

Copy a String

strcpy() 函数用于将 str[] 字符串复制到 out_num[] 数组中。strcpy() 函数将传递给它的第二个字符串复制到第一个字符串中。该 out_num[] 数组中现在存在着该字符串的副本,但只占用该数组的 18 个元素,所以该数组中仍有 22 个空 char 元素。这些空元素在内存中字符串之后被找到。

该字符串之所以被复制到该数组中,是因为我们想在该数组中拥有额外的空间用于草图的下一部分,即在字符串末尾添加一个字符串。

Append a String to a String (Concatenate)

该草图将一个字符串与另一个字符串相连接,这被称为连接。这是使用 strcat() 函数来完成的。strcat() 函数将传递给它的第二个字符串放置在传递给它的第一个字符串的末尾。

在连接后,将打印出该字符串的长度以展示新的字符串长度。然后打印出该数组的长度以展示我们在一个 40 个元素长的数组中有 25 个字符长的字符串。

记住,该 25 个字符长的字符串实际上占用了该数组的 26 个字符,因为空终止零。

Array Bounds

当使用字符串和数组时,在字符串或数组的范围内工作非常重要。在示例草图中,创建了一个 40 个字符长的数组,为了分配可以用以操纵字符串的内存。

如果该数组变得过小,而我们试图复制一个比该数组更大的字符串到该数组中,那么该字符串将被复制到该数组的末尾。该数组末尾之外的内存可能包含草图中用到的其他重要数据,而后者将被我们的字符串覆盖。如果该字符串末尾之外的内存被覆写,则可能导致草图崩溃或造成意外的行为。

Arduino - String Object

Arduino 编程中使用的第二种类型的字符串是字符串对象。

What is an Object?

对象是一种同时包含数据和函数的结构。可以创建字符串对象,就像创建变量并为其分配一个值或字符串一样。字符串对象包含函数(在面向对象编程 (OOP) 中称为“方法”),这些函数对字符串对象中包含的字符串数据进行操作。

以下草图和说明将明确说明什么是对象以及如何使用字符串对象。

Example

void setup() {
   String my_str = "This is my string.";
   Serial.begin(9600);

   // (1) print the string
   Serial.println(my_str);

   // (2) change the string to upper-case
   my_str.toUpperCase();
   Serial.println(my_str);

   // (3) overwrite the string
   my_str = "My new string.";
   Serial.println(my_str);

   // (4) replace a word in the string
   my_str.replace("string", "Arduino sketch");
   Serial.println(my_str);

   // (5) get the length of the string
   Serial.print("String length is: ");
   Serial.println(my_str.length());
}

void loop() {

}

Result

This is my string.
THIS IS MY STRING.
My new string.
My new Arduino sketch.
String length is: 22

在草图顶部创建字符串对象并为其分配值(或字符串)。

String my_str = "This is my string." ;

这会创建一个名为 my_str 的字符串对象,并为其赋予“This is my string.” 的值。

这可以与创建变量并为其分配值(例如整数)进行比较

int my_var = 102;

草图按以下方式工作。

Printing the String

字符串可以像字符数组字符串一样打印到串口监视器窗口。

Convert the String to Upper-case

创建的字符串对象 my_str 具有一些可以对其进行操作的函数或方法。通过使用对象名称后跟点运算符(.),然后使用要使用的函数的名称来调用这些方法。

my_str.toUpperCase();

toUpperCase() 函数对 my_str 对象中包含的字符串进行操作,该对象类型为 String,并将对象包含的字符串数据(或文本)转换为大写字符。可以在 Arduino String 参考中找到 String 类中包含的函数的列表。从技术上讲,String 被称为一个类,用于创建 String 对象。

Overwrite a String

赋值运算符用于为替换旧字符串的 my_str 对象分配新字符串。

my_str = "My new string." ;

赋值运算符不能用于字符数组字符串,但仅适用于 String 对象。

Replacing a Word in the String

replace() 函数用于将传递给它的第一个字符串替换为传递给它的第二个字符串。replace() 是内置于 String 类的另一个函数,因此可以在 String 对象 my_str 上使用它。

Getting the Length of the String

使用 length() 可以轻松获取字符串的长度。在示例草图中,length() 返回的结果直接传递给 Serial.println(),而不使用中间变量。

When to Use a String Object

字符串对象比字符串字符数组更容易使用。对象具有内置函数,可以对字符串执行许多操作。

使用字符串对象的主要缺点是它使用大量内存,并且可能会快速耗尽 Arduino 的 RAM 内存,这可能导致 Arduino 悬空、崩溃或行为异常。如果 Arduino 上的一个草图很小并限制对对象的使用的,那么应该没有问题。

字符数组字符串更难使用,您可能需要编写自己的函数来操作这些类型的字符串。优点是您可以控制所制作的字符串数组的大小,因此您可以将数组保持较小以节省内存。

使用字符串数组时,你需要注意不要超出数组范围的末尾。String 对象没有这个问题,它会处理字符串范围,只要有足够的内存供它操作即可。String 对象在内存不足时可能会尝试写入不存在的内存,但它永远不会覆盖它正在操作的字符串的末尾。

Where Strings are Used

在本章中,我们学习了字符串、它们在内存中的行为及其操作。

字符串的实际用法将在本课程的下一部分中介绍,届时我们将学习如何从串行监视器窗口获取用户输入并将输入保存到字符串中。

Arduino - Time

Arduino 提供四个不同的时间处理函数。它们是 −

S.No.

Function & Description

1

delay () function delay() 函数的工作方式非常简单。它接受单个整数(或数字)参数。此数字表示时间(以毫秒为单位)。

2

delayMicroseconds () function delayMicroseconds() 函数接受单个整数(或数字)参数。毫秒中有 1000 微秒,而秒中有 100 万微秒。

3

millis () function 此函数用于返回毫秒数,此时 Arduino 板开始运行当前程序。

4

micros () function micros() 函数返回从 Arduino 板开始运行当前程序以来的微秒数。此数字会溢出,即在大约 70 分钟后返回 0。

Arduino - Arrays

数组是同类型的连续内存位置组。要提及数组中的特定位置或元素,我们指定数组的名称和数组中特定元素的位置编号。

下面给出的插图显示了一个名为 C 的整数数组,其中包含 11 个元素。您可以通过给出数组名后跟方括号([])中的特定元素的位置编号来引用这些元素中的任何一个。位置编号更正式的名称是下标或索引(此编号指定了从数组开始的元素数量)。第一个元素的下标为 0(零),有时称为零元素。

因此,数组 C 的元素为 C[0](读作“C 零下标”)、C[1]、C[2],依此类推。数组 C 中最高的下标是 10,比数组中的元素数量(11)少 1。数组名遵循与其他变量名相同的约定。

elements of array

下标必须是一个整数或整数表达式(使用任何整数类型)。如果程序使用表达式作为下标,则程序会计算该表达式的值以确定下标。例如,如果我们假设变量 a 等于 5 且变量 b 等于 6,那么该语句会将 2 添加到数组元素 C[11] 中。

带下标的数组名是一个左值,它可以像非数组变量名一样用在赋值的左侧。

我们更详细地研究给定图片中的数组 C。整个数组的名称是 C。其 11 个元素被称为 C[0] 到 C[10]。C[0] 的值为 -45,C[1] 的值为 6,C[2] 的值为 0,C[7] 的值为 62,C[10] 的值为 78。

要打印数组 C 的前三个元素中包含的值的总和,我们会写:

Serial.print (C[ 0 ] + C[ 1 ] + C[ 2 ] );

要将 C[6] 的值除以 2 并将结果分配给变量 x,我们会写:

x = C[ 6 ] / 2;

Declaring Arrays

数组占用内存中的空间。要指定数组中元素的类型和数组所需元素的数量,请使用以下形式的声明:

type arrayName [ arraySize ] ;

编译器会保留适当数量的内存。(回想一下,保留内存的声明更确切地称为定义)。arraySize 必须大于零的整数常量。例如,要告诉编译器为整数数组 C 保留 11 个元素,请使用声明:

int C[ 12 ]; // C is an array of 12 integers

可以声明数组以包含任何非引用数据类型的值。例如,可以将字符串类型的数组用于存储字符串。

Examples Using Arrays

本部分提供了许多示例,用以演示如何声明、初始化和操作数组。

Example 1: Declaring an Array and using a Loop to Initialize the Array’s Elements

该程序声明了一个 10 个元素的整数数组 n 。第 a-b 行使用 For 语句将数组元素初始化为零。与其他自动变量一样,不会隐式将自动数组初始化为零。第一个输出语句(第 c 行)显示了 subsequent for 语句(第 d-e 行)中打印的列的列标题,这些语句以表格格式打印数组。

Example

int n[ 10 ] ; // n is an array of 10 integers

void setup () {

}

void loop () {
   for ( int i = 0; i < 10; ++i ) // initialize elements of array n to 0 {
      n[ i ] = 0; // set element at location i to 0
      Serial.print (i) ;
      Serial.print (‘\r’) ;
   }
   for ( int j = 0; j < 10; ++j ) // output each array element's value {
      Serial.print (n[j]) ;
      Serial.print (‘\r’) ;
   }
}

Result − 将产生以下结果:

Element
Value



0
1
2
3
4
5
6
7
8
9


0
0
0
0
0
0
0
0
0
0

Example 2: Initializing an Array in a Declaration with an Initializer List

数组的元素也可以在数组声明中初始化,方法是在数组名称后跟一个等号和一个用花括号分隔的逗号分隔的初始化程序列表。该程序使用初始化程序列表使用 10 个值初始化一个整数数组(第 a 行),并将数组以表格格式打印(第 b-c 行)。

Example

// n is an array of 10 integers
int n[ 10 ] = { 32, 27, 64, 18, 95, 14, 90, 70, 60, 37 } ;

void setup () {

}

void loop () {
   for ( int i = 0; i < 10; ++i ) {
      Serial.print (i) ;
      Serial.print (‘\r’) ;
   }
   for ( int j = 0; j < 10; ++j ) // output each array element's value {
      Serial.print (n[j]) ;
      Serial.print (‘\r’) ;
   }
}

Result − 将产生以下结果:

Element
Value



0
1
2
3
4
5
6
7
8
9


32
27
64
18
95
14
90
70
60
37

Example 3: Summing the Elements of an Array

数组的元素通常表示要用于计算的一系列值。例如,如果数组的元素表示考试成绩,教授可能希望计算数组元素的总和,并使用该总和计算考试的班级平均成绩。该程序对 10 个元素的整型数组 a 中包含的值求和。

Example

const int arraySize = 10; // constant variable indicating size of array
int a[ arraySize ] = { 87, 68, 94, 100, 83, 78, 85, 91, 76, 87 };
int total = 0;

void setup () {

}
void loop () {
   // sum contents of array a
   for ( int i = 0; i < arraySize; ++i )
      total += a[ i ];
   Serial.print (“Total of array elements : ”) ;
   Serial.print(total) ;
}

Result − 将产生以下结果:

Total of array elements: 849

对于 Arduino 来说,阵列很重要,应该受到更多关注。以下与阵列相关的重要的概念应该对 Arduino 很清楚−

S.NO.

Concept & Description

1

Passing Arrays to Functions 要将数组参数传递给函数,请指定数组的名称,不要使用任何括号。

2

Multi-Dimensional Arrays 具有两个维度(即下标)的数组通常表示由按行和列排列的信息组成的数据表。

Arduino - I/O Functions

Arduino 板上的引脚可以配置为输入或输出。我们将在这些模式中解释引脚的功能。重要的是要注意,大多数 Arduino 模拟引脚可以按照与数字引脚完全相同的方式配置和使用。

Pins Configured as INPUT

Arduino 引脚默认配置为输入,因此当你将它们用作输入时,不需要用 pinMode() 显式声明为输入。这样配置的引脚称为处于高阻抗状态。输入引脚对它们采样的电路的要求极低,相当于引脚前的 100 兆欧姆串联电阻。

这意味着从一个状态转换到另一个状态的输入引脚只需很小的电流。这使得引脚可用于诸如实现电容式触摸传感器或将 LED 作为光电二极管读取的任务。

配置为 pinMode(pin, INPUT) 的引脚与未连接任何东西或连接到未连接到其他电路的电线,报告在引脚状态中的看似随机更改,从环境中拾取电噪声或电容耦合附近引脚的状态。

Pull-up Resistors

如果不存在输入,上拉电阻通常可用于将输入引脚引导到已知状态。可以通过在输入端添加上拉电阻(至 +5V)或下拉电阻(电阻至地)来实现这一点。10K 电阻是上拉或下拉电阻的良好值。

Using Built-in Pull-up Resistor with Pins Configured as Input

Atmega 芯片内置有 20000 个上拉电阻,可以通过软件访问。通过将 pinMode() 设置为 INPUT_PULLUP 来访问这些内置的上拉电阻。这实际上是反转了 INPUT 模式的行为,其中 HIGH 表示传感器已关,而 LOW 表示传感器已开。此上拉电阻的值取决于使用的微控制器。在大多数基于 AVR 的板上,该值保证在 20kΩ 到 50kΩ 之间。在 Arduino Due 上,它介于 50kΩ 和 150kΩ 之间。对于确切值,请参考板上微控制器的规格书。

在将传感器连接到使用 INPUT_PULLUP 配置的引脚时,另一端应连接到地。如果是简单的开关,当开关打开时,它会导致引脚读取 HIGH,当开关按下时,它会读取 LOW。上拉电阻提供足够的电流来点亮连接到配置为输入的引脚的微弱 LED。如果项目中的 LED 似乎工作正常,但非常微弱,这很可能正在发生的事情。

控制引脚是 HIGH 还是 LOW 的相同寄存器(内部芯片存储器位置)控制上拉电阻。因此,当引脚处于 INPUT 模式时配置为打开上拉电阻的引脚,如果然后使用 pinMode() 将引脚切换到 OUTPUT 模式,则引脚将配置为 HIGH。这种方法也适用于其他方向,而留在 HIGH 状态的输出引脚在使用 pinMode() 切换到输入时将设置上拉电阻。

Example

pinMode(3,INPUT) ; // set pin to input without using built in pull up resistor
pinMode(5,INPUT_PULLUP) ; // set pin to input using built in pull up resistor

Pins Configured as OUTPUT

使用 pinMode() 配置为 OUTPUT 的引脚称为处于低阻抗状态。这意味着它们可以为其他电路提供大量的电流。Atmega 引脚可以为其他设备/电路提供高达 40 mA (毫安) 的电流(提供正电流)或吸收(提供负电流)。此电流足以点亮 LED(不要忘记串联电阻)或运行许多传感器,但不足以运行继电器、电磁铁或电机。

如果尝试从输出引脚运行高电流设备,可能会损坏引脚中的输出晶体管或损坏整个 Atmega 芯片。通常,这会导致微控制器中的“死”引脚,但剩余的芯片仍然可以正常工作。出于此原因,最好通过 470Ω 或 1k 电阻将 OUTPUT 引脚连接到其他设备,除非需要最大电流因特定应用而从引脚中提取。

pinMode() Function

pinMode() 函数用于将特定引脚配置为输入或输出。可以使用 INPUT_PULLUP 模式启用内部上拉电阻。此外,INPUT 模式显式禁用内部上拉电阻。

pinMode() Function Syntax

Void setup () {
   pinMode (pin , mode);
}
  1. pin − 你希望设置其模式的引脚的编号

  2. mode − INPUT、OUTPUT 或 INPUT_PULLUP。

Example

int button = 5 ; // button connected to pin 5
int LED = 6; // LED connected to pin 6

void setup () {
   pinMode(button , INPUT_PULLUP);
   // set the digital pin as input with pull-up resistor
   pinMode(button , OUTPUT); // set the digital pin as output
}

void setup () {
   If (digitalRead(button ) == LOW) // if button pressed {
      digitalWrite(LED,HIGH); // turn on led
      delay(500); // delay for 500 ms
      digitalWrite(LED,LOW); // turn off led
      delay(500); // delay for 500 ms
   }
}

digitalWrite() Function

digitalWrite() 函数用于将 HIGH 或 LOW 值写入数字引脚。如果引脚已使用 pinMode() 配置为 OUTPUT,则其电压将设置为相应的值:对于 HIGH,为 5V(对于 3.3V 板为 3.3V);对于 LOW,为 0V(地)。如果引脚配置为 INPUT,digitalWrite() 将启用(HIGH)或禁用(LOW)输入引脚上的内部上拉电阻。建议将 pinMode() 设置为 INPUT_PULLUP 来启用内部上拉电阻。

如果你没有将 pinMode() 设置为 OUTPUT 并将 LED 连接到引脚,则在调用 digitalWrite(HIGH) 时,LED 可能显得昏暗。如果不显式设置 pinMode(),digitalWrite() 将启用内部上拉电阻,该电阻充当大限流电阻。

digitalWrite() Function Syntax

Void loop() {
   digitalWrite (pin ,value);
}
  1. pin − 你希望设置其模式的引脚的编号

  2. value − HIGH 或 LOW。

Example

int LED = 6; // LED connected to pin 6

void setup () {
   pinMode(LED, OUTPUT); // set the digital pin as output
}

void setup () {
   digitalWrite(LED,HIGH); // turn on led
   delay(500); // delay for 500 ms
   digitalWrite(LED,LOW); // turn off led
   delay(500); // delay for 500 ms
}

analogRead( ) function

Arduino 能够检测到是否向其某个引脚施加电压,并通过 digitalRead() 函数报告。传感物体存在与模拟传感器(其值不断变化)之间有区别。为了读取这种类型的传感器,我们需要不同类型的引脚。

在 Arduino 电路板的右下部分,您将看到六个标记为“Analog In”的针脚。这些特殊针脚不仅可以判断电压是否施加给它们,还可以判断电压值。通过使用 analogRead() 函数,我们可以读取施加给某个针脚的电压。

此函数返回一个介于 0 和 1023 之间的数字,代表 0 到 5 伏之间的电压。例如,如果将 2.5 V 的电压施加到针脚 0,则 analogRead(0) 返回 512。

analogRead() function Syntax

analogRead(pin);
  1. pin – 要从中读取模拟输入针脚的数量(大多数电路板为 0 到 5,Mini 和 Nano 为 0 到 7,Mega 为 0 到 15)

Example

int analogPin = 3;//potentiometer wiper (middle terminal)
   // connected to analog pin 3
int val = 0; // variable to store the value read

void setup() {
   Serial.begin(9600); // setup serial
}

void loop() {
   val = analogRead(analogPin); // read the input pin
   Serial.println(val); // debug value
}

Arduino - Advanced I/O Function

在本教程中,我们将学习一些高级输入和输出函数。

analogReference() Function

配置用于模拟输入的参考电压(即用作输入范围顶部的值)。选项有 -

  1. DEFAULT – 默认模拟基准 5 伏(用于 5V Arduino 电路板)或 3.3 伏(用于 3.3V Arduino 电路板)

  2. INTERNAL – 内建参考,等于 ATmega168 或 ATmega328 上的 1.1 伏和 ATmega8 上的 2.56 伏(在 Arduino Mega 上不可用)

  3. INTERNAL1V1 – 内建 1.1V 参考(仅限 Arduino Mega)

  4. INTERNAL2V56 – 内建 2.56V 参考(仅限 Arduino Mega)

  5. EXTERNAL – 施加到 AREF 针脚的电压(仅为 0 到 5V)用作参考

analogReference() Function Syntax

analogReference (type);

type – 可以使用以下任何类型(DEFAULT、INTERNAL、INTERNAL1V1、INTERNAL2V56、EXTERNAL)

不要对 AREF 针脚上的外部参考电压使用低于 0V 或高于 5V 的电压。如果您在 AREF 针脚上使用外部参考,您必须在调用 analogRead() 函数之前将模拟参考设置为 EXTERNAL。否则,您将短路已激活的参考电压(内部产生)和 AREF 针脚,可能损坏您 Arduino 电路板上的微控制器。

microcontroller

或者,您可以通过 5K 电阻将外部参考电压连接到 AREF 针脚,这样就可以在外部参考电压和内部参考电压之间切换。

请注意,电阻器将改变用作参考的电压,因为 AREF 针脚上有一个 32K 电阻器。这两个电阻器充当分压器。例如,通过电阻器施加的 2.5V 将在 AREF 针脚产生 2.5 * 32 / (32 + 5) = ~2.2V。

Example

int analogPin = 3;// potentiometer wiper (middle terminal) connected to analog pin 3
int val = 0; // variable to store the read value

void setup() {
   Serial.begin(9600); // setup serial
   analogReference(EXTERNAL); // the voltage applied to the AREF pin (0 to 5V only)
      // is used as the reference.
}

void loop() {
   val = analogRead(analogPin); // read the input pin
   Serial.println(val); // debug value
}

Arduino - Character Functions

所有数据都以字符的形式输入计算机,其中包括字母、数字和各种特殊符号。在本节中,我们将讨论 C++ 检查和操作各个字符的能力。

字符处理库包括几个执行有用的字符数据测试和操作的函数。每个函数接收一个表示为 int 的字符,或将 EOF 作为参数。字符通常被作为整数进行操作。

请记住,EOF 通常具有值 –1,并且某些硬件体系结构不允许将负值存储在 char 变量中。因此,字符处理函数将字符作为整数来处理。

下表总结了字符处理库的函数。当使用字符处理库中的函数时,请包含 <cctype> 头。

S.No.

Prototype & Description

1

int isdigit( int c ) 如果 c 是一个数字,则返回 1,否则返回 0。

2

int isalpha( int c ) 如果 c 是一个字母,则返回 1,否则返回 0。

3

int isalnum( int c ) 如果 c 是一个数字或字母,则返回 1,否则返回 0。

4

int isxdigit( int c ) 如果 c 是一个十六进制数字字符,则返回 1,否则返回 0。(有关二进制数、八进制数、十进制数和十六进制数的详细解释,请参见附录 D,数字系统。)

5

int islower( int c ) 如果 c 是一个小写字母,则返回 1,否则返回 0。

6

int isupper( int c ) 如果 c 是一个大写字母,则返回 1;否则返回 0。

7

int isspace( int c ) 如果 c 是一个空白字符(换行 ('\n')、空格(' ')、换页 ('\f')、回车 ('\r')、水平制表符 ('\t') 或垂直制表符 ('\v'))则返回 1,否则返回 0。

8

int iscntrl( int c ) 如果 c 是一个控制字符,例如换行 ('\n')、换页 ('\f')、回车 ('\r')、水平制表符 ('\t')、垂直制表符 ('\v')、警告 ('\a') 或退格 ('\b'),则返回 1,否则返回 0。

9

int ispunct( int c ) 如果 c 是空格、数字或字母之外的打印字符,则返回 1,否则返回 0。

10

int isprint( int c ) 如果 c 是打印字符(包括空格 (' ')),则返回 1,否则返回 0。

11

int isgraph( int c ) 如果 c 是空格 (' ') 之外的打印字符,则返回 1,否则返回 0。

Examples

以下示例演示了函数 isdigit, isalpha, isalnumisxdigit 的用法。函数 isdigit 确定其参数是否是数字 (0-9)。函数 isalpha 确定其参数是否是仅大写字母 (A-Z) 或仅小写字母 (a-z)。函数 isalnum 确定其参数是否是仅大写字母、仅小写字母或数字。函数 isxdigit 确定其参数是否是十六进制数字 (A-F, a-f, 0-9)。

Example 1

void setup () {
   Serial.begin (9600);
   Serial.print ("According to isdigit:\r");
   Serial.print (isdigit( '8' ) ? "8 is a": "8 is not a");
   Serial.print (" digit\r" );
   Serial.print (isdigit( '8' ) ?"# is a": "# is not a") ;
   Serial.print (" digit\r");
   Serial.print ("\rAccording to isalpha:\r" );
   Serial.print (isalpha('A' ) ?"A is a": "A is not a");
   Serial.print (" letter\r");
   Serial.print (isalpha('A' ) ?"b is a": "b is not a");
   Serial.print (" letter\r");
   Serial.print (isalpha('A') ?"& is a": "& is not a");
   Serial.print (" letter\r");
   Serial.print (isalpha( 'A' ) ?"4 is a":"4 is not a");
   Serial.print (" letter\r");
   Serial.print ("\rAccording to isalnum:\r");
   Serial.print (isalnum( 'A' ) ?"A is a" : "A is not a" );

   Serial.print (" digit or a letter\r" );
   Serial.print (isalnum( '8' ) ?"8 is a" : "8 is not a" ) ;
   Serial.print (" digit or a letter\r");
   Serial.print (isalnum( '#' ) ?"# is a" : "# is not a" );
   Serial.print (" digit or a letter\r");
   Serial.print ("\rAccording to isxdigit:\r");
   Serial.print (isxdigit( 'F' ) ?"F is a" : "F is not a" );
   Serial.print (" hexadecimal digit\r" );
   Serial.print (isxdigit( 'J' ) ?"J is a" : "J is not a" ) ;
   Serial.print (" hexadecimal digit\r" );
   Serial.print (isxdigit( '7' ) ?"7 is a" : "7 is not a" ) ;

   Serial.print (" hexadecimal digit\r" );
   Serial.print (isxdigit( '$' ) ? "$ is a" : "$ is not a" );
   Serial.print (" hexadecimal digit\r" );
   Serial.print (isxdigit( 'f' ) ? “f is a" : "f is not a");

}

void loop () {

}

Result

According to isdigit:
8 is a digit
# is not a digit
According to isalpha:
A is a letter
b is a letter
& is not a letter
4 is not a letter
According to isalnum:
A is a digit or a letter

8 is a digit or a letter
# is not a digit or a letter
According to isxdigit:
F is a hexadecimal digit
J is not a hexadecimal digit
7 is a hexadecimal digit

$ is not a hexadecimal digit
f is a hexadecimal digit

我们对每个函数使用条件运算符 (?:) 来确定字符串 " 是一个 " 或字符串 " 不是一个 " 的内容是否应打印在每个所测试字符的输出中。例如,行 a 表明如果 '8' 是一个数字 - 即如果 isdigit 返回 true(非零)值 - 则打印字符串 "8 是一个 "。如果 '8' 不是一个数字(即如果 isdigit 返回 0),则打印字符串 " 8 不是一个 "。

Example 2

以下示例演示了函数 islowerisupper 的用法。函数 islower 确定其参数是否是仅小写字母 (a-z)。函数 isupper 确定其参数是否是仅大写字母 (A-Z)。

int thisChar = 0xA0;

void setup () {
   Serial.begin (9600);
   Serial.print ("According to islower:\r") ;
   Serial.print (islower( 'p' ) ? "p is a" : "p is not a" );
   Serial.print ( " lowercase letter\r" );
   Serial.print ( islower( 'P') ? "P is a" : "P is not a") ;
   Serial.print ("lowercase letter\r");
   Serial.print (islower( '5' ) ? "5 is a" : "5 is not a" );
   Serial.print ( " lowercase letter\r" );
   Serial.print ( islower( '!' )? "! is a" : "! is not a") ;
   Serial.print ("lowercase letter\r");

   Serial.print ("\rAccording to isupper:\r") ;
   Serial.print (isupper ( 'D' ) ? "D is a" : "D is not an" );
   Serial.print ( " uppercase letter\r" );
   Serial.print ( isupper ( 'd' )? "d is a" : "d is not an") ;
   Serial.print ( " uppercase letter\r" );
   Serial.print (isupper ( '8' ) ? "8 is a" : "8 is not an" );
   Serial.print ( " uppercase letter\r" );
   Serial.print ( islower( '$' )? "$ is a" : "$ is not an") ;
   Serial.print ("uppercase letter\r ");
}

void setup () {

}

Result

According to islower:
p is a lowercase letter
P is not a lowercase letter
5 is not a lowercase letter
! is not a lowercase letter

According to isupper:
D is an uppercase letter
d is not an uppercase letter
8 is not an uppercase letter
$ is not an uppercase letter

Example 3

以下示例演示了函数 isspace, iscntrl, ispunct, isprintisgraph 的用法。

  1. 函数 isspace 确定其参数是否是空白字符,例如空格 (' ')、换页 ('\f')、换行 ('\n')、回车 ('\r')、水平制表符 ('\t') 或垂直制表符 ('\v')。

  2. 函数 iscntrl 确定其参数是否是控制字符,例如水平制表符 ('\t')、垂直制表符 ('\v')、换页 ('\f')、警告 ('\a')、退格 ('\b')、回车 ('\r') 或换行 ('\n')。

  3. 函数 ispunct 确定其参数是否是空格、数字或字母之外的打印字符,例如 $, #, (, ), [, ], {, }, ;, : 或 %。

  4. 函数 isprint 确定其参数是否是可在屏幕上显示的字符(包括空格字符)。

  5. 函数 isgraph 对与 isprint 相同的字符进行测试,但不包括空格字符。

void setup () {
   Serial.begin (9600);
   Serial.print ( " According to isspace:\rNewline ") ;
   Serial.print (isspace( '\n' )? " is a" : " is not a" );
   Serial.print ( " whitespace character\rHorizontal tab") ;
   Serial.print (isspace( '\t' )? " is a" : " is not a" );
   Serial.print ( " whitespace character\n") ;
   Serial.print (isspace('%')? " % is a" : " % is not a" );

   Serial.print ( " \rAccording to iscntrl:\rNewline") ;
   Serial.print ( iscntrl( '\n' )?"is a" : " is not a" ) ;
   Serial.print (" control character\r");
   Serial.print (iscntrl( '$' ) ? " $ is a" : " $ is not a" );
   Serial.print (" control character\r");
   Serial.print ("\rAccording to ispunct:\r");
   Serial.print (ispunct(';' ) ?"; is a" : "; is not a" ) ;
   Serial.print (" punctuation character\r");
   Serial.print (ispunct('Y' ) ?"Y is a" : "Y is not a" ) ;
   Serial.print ("punctuation character\r");
   Serial.print (ispunct('#' ) ?"# is a" : "# is not a" ) ;
   Serial.print ("punctuation character\r");

   Serial.print ( "\r According to isprint:\r");
   Serial.print (isprint('$' ) ?"$ is a" : "$ is not a" );
   Serial.print (" printing character\rAlert ");
   Serial.print (isprint('\a' ) ?" is a" : " is not a" );
   Serial.print (" printing character\rSpace ");
   Serial.print (isprint(' ' ) ?" is a" : " is not a" );
   Serial.print (" printing character\r");

   Serial.print ("\r According to isgraph:\r");
   Serial.print (isgraph ('Q' ) ?"Q is a" : "Q is not a" );
   Serial.print ("printing character other than a space\rSpace ");
   Serial.print (isgraph (' ') ?" is a" : " is not a" );
   Serial.print ("printing character other than a space ");
}

void loop () {

}

Result

According to isspace:
Newline is a whitespace character
Horizontal tab is a whitespace character
% is not a whitespace character
According to iscntrl:
Newline is a control character
$ is not a control character
According to ispunct:
; is a punctuation character
Y is not a punctuation character
# is a punctuation character
According to isprint:
$ is a printing character
Alert is not a printing character
Space is a printing character
According to isgraph:
Q is a printing character other than a space
Space is not a printing character other than a space

Arduino - Math Library

Arduino Math 函数库(math.h)包含了许多用于操作浮点数的有用的数学函数。

Library Macros

以下是标头文件 math.h 中定义的宏 −

Library Functions

下面的函数在标头 math.h 中定义 −

Example

以下示例显示了如何使用最常用的 math.h 函数库函数 −

double double__x = 45.45 ;
double double__y = 30.20 ;

void setup() {
   Serial.begin(9600);
   Serial.print("cos num = ");
   Serial.println (cos (double__x) ); // returns cosine of x
   Serial.print("absolute value of num = ");
   Serial.println (fabs (double__x) ); // absolute value of a float
   Serial.print("floating point modulo = ");
   Serial.println (fmod (double__x, double__y)); // floating point modulo
   Serial.print("sine of num = ");
   Serial.println (sin (double__x) ) ;// returns sine of x
   Serial.print("square root of num : ");
   Serial.println ( sqrt (double__x) );// returns square root of x
   Serial.print("tangent of num : ");
   Serial.println ( tan (double__x) ); // returns tangent of x
   Serial.print("exponential value of num : ");
   Serial.println ( exp (double__x) ); // function returns the exponential value of x.
   Serial.print("cos num : ");

   Serial.println (atan (double__x) ); // arc tangent of x
   Serial.print("tangent of num : ");
   Serial.println (atan2 (double__y, double__x) );// arc tangent of y/x
   Serial.print("arc tangent of num : ");
   Serial.println (log (double__x) ) ; // natural logarithm of x
   Serial.print("cos num : ");
   Serial.println ( log10 (double__x)); // logarithm of x to base 10.
   Serial.print("logarithm of num to base 10 : ");
   Serial.println (pow (double__x, double__y) );// x to power of y
   Serial.print("power of num : ");
   Serial.println (square (double__x)); // square of x
}

void loop() {

}

Result

cos num = 0.10
absolute value of num = 45.45
floating point modulo =15.25
sine of num = 0.99
square root of num : 6.74
tangent of num : 9.67
exponential value of num : ovf
cos num : 1.55
tangent of num : 0.59
arc tangent of num : 3.82
cos num : 1.66
logarithm of num to base 10 : inf
power of num : 2065.70

Arduino - Trigonometric Functions

您需要实际使用三角函数,比如为移动物体或角速度计算距离。Arduino 提供了传统的三角函数(sin、cos、tan、asin、acos、atan),可以将其概括为编写这些函数的原型。Math.h 包含三角函数的原型。

Trigonometric Exact Syntax

double sin(double x); //returns sine of x radians
double cos(double y); //returns cosine of y radians
double tan(double x); //returns the tangent of x radians
double acos(double x); //returns A, the angle corresponding to cos (A) = x
double asin(double x); //returns A, the angle corresponding to sin (A) = x
double atan(double x); //returns A, the angle corresponding to tan (A) = x

Example

double sine = sin(2); // approximately 0.90929737091
double cosine = cos(2); // approximately -0.41614685058
double tangent = tan(2); // approximately -2.18503975868

Arduino - Due & Zero

Arduino Due 是一个基于 Atmel SAM3X8E ARM Cortex-M3 CPU 的微控制器电路板。它是第一个基于 32 位 ARM 核微控制器的 Arduino 电路板。

重要功能 −

  1. 它有 54 个数字输入/输出引脚(其中 12 个可用作 PWM 输出)

  2. 12 analog inputs

  3. 4 个 UART(硬件串行端口)

  4. 84 MHz 时钟,一个 USB OTG 可用连接

  5. 2 个 DAC(数字转模拟),2 个 TWI,一个电源插孔,一个 SPI 接头,一个 JTAG 接头

  6. 复位按钮和擦除按钮

arduino due

Characteristics of the Arduino Due Board

Operating volt

CPU speed

Analog in/out

Digital IO/ PWM

EEPROM [KB]

SRAM [KB]

Flash [KB]

USB

UART

3.3 Volt

84 Mhz

12/2

54/12

-

96

512

2 micro

4

Communication

  1. 4 Hardware UARTs

  2. 2 I2C

  3. 1 个 CAN 接口(汽车通信协议)

  4. 1 SPI

  5. 1 个接口 JTAG(10 针)

  6. 1 个 USB 主机(如同 Leonardo)

  7. 1 Programming Port

与大多数 Arduino 板不同,Arduino Due 板以 3.3V 运行。I/O 针脚可以承受的最大电压为 3.3V。对任何 I/O 针脚施加高于 3.3V 的电压都可能损坏电路板。

该板包含支持微控制器所需的一切。您只需将其连接到计算机上,使用微型 USB 电缆或交流转直流适配器或电池供电即可开始使用。Due 与所有以 3.3V 工作的 Arduino 扩展板兼容。

Arduino Zero

Zero 是 UNO 所建立的平台的简单而强大的 32 位扩展。该 Zero 电路板通过提供更高的性能来扩展该系列产品,为设备提供了各种项目机会,并且作为学习 32 位应用程序开发的优秀教育工具。

重要的功能有 −

  1. Zero 应用从智能物联网设备、可穿戴技术、高科技自动化到疯狂机器人,跨越很多领域。

  2. 该电板由 Atmel 的 SAMD21 MCU 供电,它具有 32 位 ARM Cortex® M0+ 内核。

  3. 其最重要的功能之一是 Atmel 的嵌入式调试器 (EDBG),它提供了完整调试界面,而无需额外的硬件,极大提升了软件调试的易用性。

  4. EDBG 还支持一个虚拟 COM 端口,该端口可用于设备和引导加载程序编程。

arduino zero

Characteristics of the Arduino Zero board

Operating volt

CPU speed

Analog in/out

Digital IO/ PWM

EEPROM [KB]

SRAM [KB]

Flash [KB]

USB

UART

3.3 Volt

48 Mhz

6/1

14/10

-

32

256

2 micro

2

与大多数 Arduino 和 Genuino 电路板不同,Zero 以 3.3V 运行。I/O 针脚可以承受的最大电压为 3.3V。对任何 I/O 针脚施加高于 3.3V 的电压都可能损坏电路板。

该板包含支持微控制器所需的一切。您只需将其连接到计算机上,使用微型 USB 电缆或交流转直流适配器或电池供电即可开始使用。Zero 与所有以 3.3V 工作的扩展板兼容。

Arduino - Pulse Width Modulation

脉冲宽度调制或 PWM 是一种常见的技术,用于改变脉冲串中脉冲的宽度。PWM 有许多应用,如控制伺服器和速度控制器,以及限制电机和 LED 的有效功率。

Basic Principle of PWM

脉冲宽度调制基本上是一个具有可变高低时间的方波。基本 PWM 信号如下图所示。

pwm

PWM 涉及到各种术语 −

  1. On-Time − 信号高电平持续时间。

  2. Off-Time − 信号低电平持续时间。

  3. Period − 表示为 PWM 信号的导通时间和关断时间的总和。

  4. Duty Cycle − 表示为 PWM 信号周期内信号保持导通时间的百分比。

Period

如下图所示,Ton 表示信号的导通时间,Toff 表示信号的关断时间。周期是导通时间和关断时间的总和,计算方法如下所示 −

Duty Cycle

占空比计算为周期中导通时间的比例。使用上述计算的周期,占空比的计算方法如下 −

analogWrite() Function

analogWrite() 函数向引脚写入模拟值(PWM 波形)。它可以用来点亮亮度可变的 LED 或驱动速度可变的电机。调用 analogWrite() 函数后,该引脚将生成指定占空比的稳定方波,持续到下一次调用 analogWrite() 或对同一引脚调用 digitalRead() 或 digitalWrite()。大多数引脚上的 PWM 信号频率约为 490 Hz。在 Uno 和类似的电路板上,引脚 5 和 6 的频率约为 980 Hz。Leonardo 上的引脚 3 和 11 也以 980 Hz 的频率运行。

在大多数 Arduino 电路板(带有 ATmega168 或 ATmega328 的电路板)上,此函数在引脚 3、5、6、9、10 和 11 上运行。在 Arduino Mega 上,它在引脚 2 - 13 和 44 - 46 上运行。具有 ATmega8 的较旧 Arduino 电路板仅支持引脚 9、10 和 11 上的 analogWrite()

uno pwm pins

Arduino Due 支持引脚 2 至 13 以及引脚 DAC0 和 DAC1 上的 analogWrite() 。与 PWM 引脚不同,DAC0 和 DAC1 是数模转换器,并作为真正的模拟输出。

在调用 analogWrite() 之前,无需调用 pinMode() 将引脚设置为输出。

analogWrite() Function Syntax

analogWrite ( pin , value ) ;

value —占空比:0(始终关闭)到 255(始终开启)之间的值。

Example

int ledPin = 9; // LED connected to digital pin 9
int analogPin = 3; // potentiometer connected to analog pin 3
int val = 0; // variable to store the read value

void setup() {
   pinMode(ledPin, OUTPUT); // sets the pin as output
}

void loop() {
   val = analogRead(analogPin); // read the input pin
   analogWrite(ledPin, (val / 4)); // analogRead values go from 0 to 1023,
      // analogWrite values from 0 to 255
}

Arduino - Random Numbers

要生成随机数,可以使用 Arduino 随机数函数。我们有两个函数:

  1. randomSeed(seed)

  2. random()

randomSeed (seed)

randomSeed(seed) 函数重置 Arduino 的伪随机数生成器。尽管 random() 返回的数字分布本质上是随机的,但该序列是可预测的。您应该将生成器重置为某个随机值。如果您有未连接的模拟引脚,它可能会从周围环境中拾取随机噪声。这些可能是无线电波、宇宙射线、来自手机、荧光灯等的电磁干扰。

Example

randomSeed(analogRead(5)); // randomize using noise from analog pin 5

random( )

random 函数生成伪随机数。以下是语法。

random( ) Statements Syntax

long random(max) // it generate random numbers from 0 to max
long random(min, max) // it generate random numbers from min to max

Example

long randNumber;

void setup() {
   Serial.begin(9600);
   // if analog input pin 0 is unconnected, random analog
   // noise will cause the call to randomSeed() to generate
   // different seed numbers each time the sketch runs.
   // randomSeed() will then shuffle the random function.
   randomSeed(analogRead(0));
}

void loop() {
   // print a random number from 0 to 299
   Serial.print("random1=");
   randNumber = random(300);
   Serial.println(randNumber); // print a random number from 0to 299
   Serial.print("random2=");
   randNumber = random(10, 20);// print a random number from 10 to 19
   Serial.println (randNumber);
   delay(50);
}

现在,让我们复习一些基本概念,例如位和字节。

Bits

位只是一个二进制数字。

  1. 二进制系统使用两个数字,0 和 1。

  2. 类似于该数字的位数不具有相同值的十进制数系统,位的“意义”取决于它在二进制数中的位置。例如,十进制数 666 中的数字相同,但具有不同的值。

bits

Bytes

字节是由八个位组成的。

  1. 如果一个位是一个数字,那么字节表示数字是合乎逻辑的。

  2. 所有数学运算都可以对其执行。

  3. 字节中的数字也没有相同的意义。

  4. 最左边的位具有称为最高有效位 (MSB) 的最大值。

  5. 最右边的位具有最小值,因此称为最低有效位 (LSB)。

  6. 由于一个字节的八个零和一可以以 256 种不同的方式组合,因此一个字节可以表示的最大十进制数为 255(一个组合表示为零)。

Arduino - Interrupts

中断停止 Arduino 的当前工作,以便完成一些其他工作。

假设你坐在家里与某人聊天。突然电话响了。您停止聊天,拿起电话与来电者交谈。结束电话交谈后,您回到电话响起之前与那个人聊天。

与之类似,你可以将主例程看作与人聊天,电话铃声会中断聊天。中断服务程序就是打电话的过程。当电话会话结束时,你再回到聊天的主例程中来。此示例准确地阐释了中断如何使处理器执行任务。

主程序正在运行并在电路中执行一些功能。但是,中断发生时,当另一个例程执行时,主程序会暂停。当这个例程结束后,处理器再次回到主例程中来。

interrupt

Important features

这里有一些关于中断的重要功能 −

  1. 中断可以来自各种来源。在本例中,我们使用的是一个硬件中断,该中断由一个数字管脚上的状态变化触发。

  2. 大多数 Arduino 设计有两个硬件中断(分别称为“interrupt0”和“interrupt1”),这两个中断硬连接到数字 I/O 管脚 2 和 3。

  3. Arduino Mega 有六个硬件中断,包括管脚 21、20、19 和 18 上的附加中断(“interrupt2”到“interrupt5”)。

  4. 你可以使用一个称为“中断服务程序”(通常称为 ISR)的特殊函数来定义一个例程。

  5. 你可以定义该例程并指定上升沿、下降沿或两者。在这些特定条件下,中断将被服务。

  6. 可以自动执行该函数,每次在输入管脚上发生事件时都会执行。

Types of Interrupts

有两种类型的中断 −

  1. Hardware Interrupts − 它们响应于外部事件,例如外部中断管脚变高或变低。

  2. Software Interrupts − 它们响应于软件中发送的指令。Arduino 语言支持的唯一类型的中断是 attachInterrupt() 函数。

Using Interrupts in Arduino

在 Arduino 程序中,中断非常有用,因为它有助于解决时序问题。中断的一个很好的应用是读取旋转编码器或观察用户输入。通常,ISR 应尽可能短且快。如果你的草图使用多个 ISR,一次只能运行一个 ISR。其他中断将在当前中断完成之后执行,其执行顺序取决于它们具有的优先级。

通常,全局变量用于在 ISR 和主程序之间传递数据。要确保在 ISR 和主程序之间共享的变量得到正确更新,将其声明为 volatile。

attachInterrupt Statement Syntax

attachInterrupt(digitalPinToInterrupt(pin),ISR,mode);//recommended for arduino board
attachInterrupt(pin, ISR, mode) ; //recommended Arduino Due, Zero only
//argument pin: the pin number
//argument ISR: the ISR to call when the interrupt occurs;
   //this function must take no parameters and return nothing.
   //This function is sometimes referred to as an interrupt service routine.
//argument mode: defines when the interrupt should be triggered.

预定义了下列三个常量作为有效值 −

  1. LOW 只要管脚变低就触发中断。

  2. CHANGE 只要管脚值改变就触发中断。

  3. FALLING 只要管脚从高变为低就触发中断。

Example

int pin = 2; //define interrupt pin to 2
volatile int state = LOW; // To make sure variables shared between an ISR
//the main program are updated correctly,declare them as volatile.

void setup() {
   pinMode(13, OUTPUT); //set pin 13 as output
   attachInterrupt(digitalPinToInterrupt(pin), blink, CHANGE);
   //interrupt at pin 2 blink ISR when pin to change the value
}
void loop() {
   digitalWrite(13, state); //pin 13 equal the state value
}

void blink() {
   //ISR function
   state = !state; //toggle the state when the interrupt occurs
}

Arduino - Communication

已经定义了数百种通信协议来实现此数据交换。每种协议都可以归类为两类之一:并行或串行。

Parallel Communication

Arduino 和外围设备之间通过输入/输出端口的并行连接是短距离(最长几米)的理想解决方案。然而,在其他情况下,当需要为更长距离的两个设备建立通信时,则无法使用并行连接。并行接口一次传输多位。它们通常需要数据总线——跨八根、十六根或更多根电线传输。数据以巨大的、汹涌的 1 和 0 波传输。

parallel communication

Advantages and Drawbacks of Parallel Communication

并行通信当然有其优势。它比串行更快、更直接,并且相对容易实现。但是,它需要许多输入/输出 (I/O) 端口和线路。如果您曾经不得不将项目从基本的 Arduino Uno 迁移到 Mega,那么您会知道微处理器上的 I/O 线路是多么宝贵和稀少。因此,我们更青睐串行通信,以牺牲潜在的速度来换取引脚空间。

Serial Communication Modules

如今,大多数 Arduino 板都内置了多个用于串行通信的不同系统作为标准设备。

使用以下因素决定使用哪种系统:

  1. 微控制器需要与多少设备交换数据?

  2. 数据交换需要多快?

  3. 这些设备之间的距离是多少?

  4. 是否需要同时发送和接收数据?

关于串行通信最重要的一件事就是 Protocol ,它应当严格遵守。这套规则必须应用才能让设备正确解释它们之间交换的数据。幸运的是,Arduino 会自动处理好这个过程,这样程序员/用户的工作就简化成简单的写入(发送数据)和读取(接收数据)。

Types of Serial Communications

串行通信还可以进一步分类:

  1. Synchronous − 同步设备使用同一时钟,它们的计时相互同步。

  2. Asynchronous − 异步设备有自己的时钟,并由前一状态的输出触发。

很容易发现某个设备是同步设备还是异步设备。如果所有连接的设备使用同一时钟,那么它们就是同步设备。如果没有时钟线,那么它们就是异步设备。

例如,UART(通用异步收发器)模块就是异步设备。

异步串行协议包含许多内置规则。这些规则不过是帮助确保数据传输稳健无误的机制。通过放弃外部时钟信号而获得的这些机制包括:

  1. Synchronization bits

  2. Data bits

  3. Parity bits

  4. Baud rate

Synchronization Bits

同步位是每次数据包传输时随数据一起传输的两个或三个特殊位。它们是起始位和停止位。顾名思义,这些位分别标记数据包的开始和结束。

起始位只有一个,但停止位的数量可以配置为一个或两个(尽管通常将其保留为一个)。

起始位始终由空闲数据线从 1 变为 0 表示,而停止位将通过将数据线保持在 1 上的状态转换回空闲状态。

synchronization bits

Data Bits

每个数据包中的数据量可以设置为从 5 到 9 位的任何大小。当然,标准数据大小是基本的 8 位字节,但其他大小也有其用途。如果只传输 7 位 ASCII 字符,7 位数据包的效率可能高于 8 位。

Parity Bits

用户可以选择是否需要奇偶校验位,如果需要,还可以选择奇偶校验为奇校验还是偶校验。如果数据位中 1 的数量为偶数,奇偶校验位为 0。奇校验正好相反。

Baud Rate

波特率一词用来表示每秒传输的位数 [bps]。注意,它是指位,不是字节。协议通常要求每个字节与几个控制位一起传输。这意味着串行数据流中的一个字节可能包含 11 位。例如,如果波特率为 300 bps,则每秒传输的最大字节数为 37,最少为 27。

Arduino UART

以下代码可以让 Arduino 在启动时发送“hello world”。

void setup() {
   Serial.begin(9600); //set up serial library baud rate to 9600
   Serial.println("hello world"); //print hello world
}

void loop() {

}

将 Arduino 草图上传到 Arduino 后,打开 Arduino IDE 右上角的串行监视器。

在串行监视器的顶部框中键入任意内容,然后按键盘上的发送或回车。这会向 Arduino 发送一系列字节。

以下代码会返回它收到的任何输入。

以下代码会让 Arduino 根据所提供的输入提供输出。

void setup() {
   Serial.begin(9600); //set up serial library baud rate to 9600
}

void loop() {
   if(Serial.available()) //if number of bytes (characters) available for reading from {
      serial port
      Serial.print("I received:"); //print I received
      Serial.write(Serial.read()); //send what you read
   }
}

请注意, Serial.printSerial.println 会发送回实际的 ASCII 码,而 Serial.write 会发送回实际的文本。有关更多信息,请参见 ASCII 码。

Arduino - Inter Integrated Circuit

集成电路间总线 (I2C) 是一种新一代微控制器和专用集成电路之间进行串行数据交换的系统。当它们之间的距离较短(接收器和发送器通常位于同一块印刷电路板上)时,它会被使用。连接通过两条导线建立。一条用于数据传输,另一条用于同步(时钟信号)。

如图所示,一台设备始终作为主设备。在通信开始之前,它会对一个从设备进行寻址。通过这种方式,一个微控制器可以与 112 个不同的设备通信。波特率通常为 100 Kb/s(标准模式)或 10 Kb/s(低波特率模式)。最近出现了波特率为 3.4 Mb/s 的系统。通过 I2C 总线通信的设备之间的距离限制为几米。

i2c

Board I2C Pins

I2C 总线由两个信号组成 - SCL 和 SDA。SCL 是时钟信号,SDA 是数据信号。当前总线主设备始终生成时钟信号。某些从设备有时可能强制将时钟降至低电平,以延迟主设备发送更多数据(或在主设备尝试将其时钟化之前需要更多时间准备数据)。这称为“时钟拉伸”。

以下是不同 Arduino 板的引脚−

  1. Uno、Pro Mini A4 (SDA)、A5 (SCL)

  2. Mega、Due 20 (SDA)、21 (SCL)

  3. Leonardo、Yun 2 (SDA)、3 (SCL)

Arduino I2C

我们有两种模式 - 主设备代码和从设备代码 - 使用 I2C 连接两个 Arduino 板。它们是−

  1. 主设备发送器/从设备接收器

  2. 主设备接收器/从设备发送器

Master Transmitter / Slave Receiver

现在让我们看看什么是主设备发送器和从设备接收器。

Master Transmitter

以下函数用于初始化 Wire 库,并将作为主设备或从设备加入 I2C 总线。此操作通常只调用一次。

  1. Wire.begin(address) − 在我们的例子中,地址是 7 位从机地址,因为没有指定主机,它会作为主机加入总线。

  2. Wire.beginTransmission(address) − 使用给定的地址开始向 I2C 从机设备传输。

  3. Wire.write(value) − 将字节排队从主机传输到从机设备(介于 beginTransmission() 和 endTransmission() 调用之间)。

  4. Wire.endTransmission() − 结束由 beginTransmission() 开始的对从机设备的传输,并传输由 wire.write() 排队的字节。

Example

#include <Wire.h> //include wire library

void setup() //this will run only once {
   Wire.begin(); // join i2c bus as master
}

short age = 0;

void loop() {
   Wire.beginTransmission(2);
   // transmit to device #2
   Wire.write("age is = ");
   Wire.write(age); // sends one byte
   Wire.endTransmission(); // stop transmitting
   delay(1000);
}

Slave Receiver

使用以下函数 −

  1. Wire.begin(address) − 地址是 7 位从机地址。

  2. Wire.onReceive(received data handler) − 从机设备从主机接收数据时调用的函数。

  3. Wire.available() − 返回可通过 Wire.read() 检索的字节数。应该在 Wire.onReceive() 处理程序中调用此函数。

Example

#include <Wire.h> //include wire library

void setup() {  //this will run only once
   Wire.begin(2); // join i2c bus with address #2
   Wire.onReceive(receiveEvent); // call receiveEvent when the master send any thing
   Serial.begin(9600); // start serial for output to print what we receive
}

void loop() {
   delay(250);
}

//-----this function will execute whenever data is received from master-----//

void receiveEvent(int howMany) {
   while (Wire.available()>1) // loop through all but the last {
      char c = Wire.read(); // receive byte as a character
      Serial.print(c); // print the character
   }
}

Master Receiver / Slave Transmitter

现在让我们了解一下什么主机接收器和从机发送器。

Master Receiver

主机被编程为请求,然后读取从唯一寻址的从机 Arduino 发送的数据字节。

使用以下函数 −

Wire.requestFrom(address,number of bytes) − 主机用来从从机设备请求字节。然后可以用 wire.available() 和 wire.read() 函数检索字节。

Example

#include <Wire.h> //include wire library void setup() {
   Wire.begin(); // join i2c bus (address optional for master)
   Serial.begin(9600); // start serial for output
}

void loop() {
   Wire.requestFrom(2, 1); // request 1 bytes from slave device #2
   while (Wire.available()) // slave may send less than requested {
      char c = Wire.read(); // receive a byte as character
      Serial.print(c); // print the character
   }
   delay(500);
}

Slave Transmitter

使用以下函数。

Wire.onRequest(handler) − 当主机从该从机设备请求数据时,会调用一个函数。

Example

#include <Wire.h>

void setup() {
   Wire.begin(2); // join i2c bus with address #2
   Wire.onRequest(requestEvent); // register event
}

Byte x = 0;

void loop() {
   delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()

void requestEvent() {
   Wire.write(x); // respond with message of 1 bytes as expected by master
   x++;
}

Arduino - Serial Peripheral Interface

串行外设接口 (SPI) 总线是一种串行通信系统,它使用多达四根导线,通常为三根。一根导线用于接收数据,一根用于发送数据,一根用于同步,一根用于选择要通信的设备。它是一种全双工连接,这意味着可以同时发送和接收数据。它的最大波特率高于 I2C 通信系统中的最大波特率。

Board SPI Pins

SPI 使用以下四根电线 −

  1. SCK − 这是由主器件驱动的串行时钟。

  2. MOSI − 这是由主器件驱动的发送数据输入/从输入。

  3. MISO − 这是由主器件驱动的输入数据输入/从器件输出。

  4. SS − 这是从器件选择导线。

用到的函数如下。需要包含 SPI.h。

  1. SPI.begin() − 为 SPI 总线设置 SCK、MOSI 和 SS 为输出,将 SCK 和 MOSI 置低,将 SS 置高,从而初始化 SPI 总线。

  2. SPI.setClockDivider(divider) − 设置相对于系统时钟的 SPI 时钟分频器。在基于 AVR 的板上,可用的分频器有 2、4、8、16、32、64 或 128。默认设置是 SPI_CLOCK_DIV4,它会将 SPI 时钟设置为系统时钟频率的四分之一(在 20 MHz 的板上为 5 MHz)。

  3. Divider − 它可能为 (SPI_CLOCK_DIV2、SPI_CLOCK_DIV4、SPI_CLOCK_DIV8、SPI_CLOCK_DIV16、SPI_CLOCK_DIV32、SPI_CLOCK_DIV64、SPI_CLOCK_DIV128)。

  4. SPI.transfer(val) − SPI 传输基于同时发送和接收:接收到的数据将返回到 receivedVal。

  5. SPI.beginTransaction(SPISettings(speedMaximum, dataOrder, dataMode)) - speedMaximum 是时钟、dataOrder(MSBFIRST 或 LSBFIRST)、dataMode(SPI_MODE0、SPI_MODE1、SPI_MODE2 或 SPI_MODE3)。

在 SPI 中,我们有四种操作模式,如下所示 −

  1. Mode 0 (the default) - 时钟通常为低 (CPOL = 0),数据在从低到高跃变 (前沿) (CPHA = 0) 时取样。

  2. Mode 1 - 时钟通常为低 (CPOL = 0),数据在从高到低跃变 (后沿) (CPHA = 1) 时取样。

  3. Mode 2 - 时钟通常为高 (CPOL = 1),数据在从高到低跃变 (前沿) (CPHA = 0) 时取样。

  4. Mode 3 - 时钟通常为高 (CPOL = 1),数据在从低到高跃变 (后沿) (CPHA = 1) 时取样。

  5. SPI.attachInterrupt(handler) - 从设备从主设备接收数据时调用的函数。

现在,我们将连接两个 Arduino UNO 板;一个作为主设备,另一个作为从设备。

  1. (SS) : pin 10

  2. (MOSI) : pin 11

  3. (MISO) : pin 12

  4. (SCK) : pin 13

接地是共用的。以下是两个板之间连接的示意图 −

connection of boards

让我们看看作为主设备的 SPI 和作为从设备的 SPI 的示例。

SPI as MASTER

Example

#include <SPI.h>

void setup (void) {
   Serial.begin(115200); //set baud rate to 115200 for usart
   digitalWrite(SS, HIGH); // disable Slave Select
   SPI.begin ();
   SPI.setClockDivider(SPI_CLOCK_DIV8);//divide the clock by 8
}

void loop (void) {
   char c;
   digitalWrite(SS, LOW); // enable Slave Select
   // send test string
   for (const char * p = "Hello, world!\r" ; c = *p; p++) {
      SPI.transfer (c);
      Serial.print(c);
   }
   digitalWrite(SS, HIGH); // disable Slave Select
   delay(2000);
}

SPI as SLAVE

Example

#include <SPI.h>
char buff [50];
volatile byte indx;
volatile boolean process;

void setup (void) {
   Serial.begin (115200);
   pinMode(MISO, OUTPUT); // have to send on master in so it set as output
   SPCR |= _BV(SPE); // turn on SPI in slave mode
   indx = 0; // buffer empty
   process = false;
   SPI.attachInterrupt(); // turn on interrupt
}
ISR (SPI_STC_vect) // SPI interrupt routine {
   byte c = SPDR; // read byte from SPI Data Register
   if (indx < sizeof buff) {
      buff [indx++] = c; // save data in the next index in the array buff
      if (c == '\r') //check for the end of the word
      process = true;
   }
}

void loop (void) {
   if (process) {
      process = false; //reset the process
      Serial.println (buff); //print the array on serial monitor
      indx= 0; //reset button to zero
   }
}

Arduino - Blinking LED

LED 是小巧、功能强大的灯,用于很多不同的应用。一开始,我们将操作使 LED 闪烁,这是微控制器的 Hello World。这就像开关一盏灯一样简单。建立此重要基线将为你打下坚实的基础,让我们朝更加复杂的实验进军。

Components Required

您将需要以下组件:

  1. 1 × Breadboard

  2. 1 × Arduino Uno R3

  3. 1 × LED

  4. 1 × 330Ω Resistor

  5. 2 × Jumper

Procedure

按照电路图并将组件连接到面包板上,如下图所示。

breadboard

Note − 要找出 LED 的极性,请仔细观察。灯泡扁平边缘朝向两条腿中较短的一条腿表示负极。

led

为了正确安装面包板插座,像电阻器这样的元件需要将其端子弯曲成 90° 角。您还可以剪短端子。

resistors

Sketch

在您的计算机上打开 Arduino IDE 软件。使用 Arduino 语言编写代码将控制您的电路。通过单击“新建”打开新草图文件。

sketch

Arduino Code

/*
   Blink
   Turns on an LED on for one second, then off for one second, repeatedly.
*/

// the setup function runs once when you press reset or power the board

void setup() {  // initialize digital pin 13 as an output.
   pinMode(2, OUTPUT);
}

// the loop function runs over and over again forever

void loop() {
   digitalWrite(2, HIGH); // turn the LED on (HIGH is the voltage level)
   delay(1000); // wait for a second
   digitalWrite(2, LOW); // turn the LED off by making the voltage LOW
   delay(1000); // wait for a second
}

Code to Note

pinMode(2, OUTPUT) − 在你使用 Arduino 的某一引脚之前,你需要告诉 Arduino Uno R3 它是一个输入还是输出。为此,我们要使用一个称为 pinMode() 的内置“函数”。

digitalWrite(2, HIGH) − 当你使用一个引脚作为输出时,你可以命令它为 HIGH(输出 5 伏特)或 LOW(输出 0 伏特)。

Result

你应该看到你的 LED 开启并关闭。如果没有看到所需的输出,请确保你正确地组装了电路,并验证并向你的电路板上传了代码。

Arduino - Fading LED

此示例演示了 analogWrite() 函数在关闭 LED 时如何使用淡出效果。AnalogWrite 使用脉宽调制 (PWM),快速地打开和关闭数字引脚,并使用开和关的不同比率来创建淡出效果。

Components Required

您将需要以下组件:

  1. 1 × Breadboard

  2. 1 × Arduino Uno R3

  3. 1 × LED

  4. 1 × 330Ω Resistor

  5. 2 × Jumper

Procedure

按照电路图并将组件连接到面包板上,如下图所示。

components on breadboard

Note − 要找出 LED 的极性,请仔细观察。灯泡扁平边缘朝向两条腿中较短的一条腿表示负极。

led

为了正确安装面包板插座,像电阻器这样的元件需要将其端子弯曲成 90° 角。您还可以剪短端子。

resistors

Sketch

在您的计算机上打开 Arduino IDE 软件。使用 Arduino 语言编写代码将控制您的电路。通过单击“新建”打开新草图文件。

sketch

Arduino Code

/*
   Fade
   This example shows how to fade an LED on pin 9 using the analogWrite() function.

   The analogWrite() function uses PWM, so if you want to change the pin you're using, be
   sure to use another PWM capable pin. On most Arduino, the PWM pins are identified with
   a "~" sign, like ~3, ~5, ~6, ~9, ~10 and ~11.
*/

int led = 9; // the PWM pin the LED is attached to
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
// the setup routine runs once when you press reset:

void setup() {
   // declare pin 9 to be an output:
   pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:

void loop() {
   // set the brightness of pin 9:
   analogWrite(led, brightness);
   // change the brightness for next time through the loop:
   brightness = brightness + fadeAmount;
   // reverse the direction of the fading at the ends of the fade:
   if (brightness == 0 || brightness == 255) {
      fadeAmount = -fadeAmount ;
   }
   // wait for 30 milliseconds to see the dimming effect
   delay(300);
}

Code to Note

将引脚 9 声明为 LED 引脚后,您的代码的 setup() 函数中无需执行任何操作。您将在代码的主循环中使用的 analogWrite() 函数需要两个参数:一个告诉函数要写入哪个引脚,另一个指示要写入的 PWM 值。

为了让 LED 淡入淡出,逐渐增加 PWM 值,从 0(完全关闭)到 255(完全开启),然后回到 0,以完成循环。在上面给出的草图中,使用名为亮度的变量设置 PWM 值。每次通过循环,它都会按变量的值 fadeAmount 增加。

如果亮度处于其值的任何极端(0 或 255),则 fadeAmount 会变为其负值。换句话说,如果 fadeAmount 为 5,则它将设置为 -5。如果为 -5,则将其设置为 5。下一次通过循环,此更改还会导致亮度改变方向。

analogWrite() 可以非常快地更改 PWM 值,因此草图末尾的延迟控制了淡出效果的速度。尝试更改延迟的值,看看它如何改变淡出效果。

Result

您应该看到 LED 亮度逐渐发生变化。

Arduino - Reading Analog Voltage

此示例将向你展示如何在模拟引脚 0 上读取模拟输入。输入从 analogRead() 转换为电压,并打印到 Arduino 软件 (IDE) 的串行监视器。

Components Required

您将需要以下组件:

  1. 1 × Breadboard

  2. 1 × Arduino Uno R3

  3. 1 × 5K 可变电阻器 (电位器)

  4. 2 × Jumper

Procedure

按照电路图并将组件连接到面包板上,如下图所示。

analog breadboard

Potentiometer

电位器(或电位计)是一种简单的机电传感器。它将输入操作者的旋转或线性运动转换为电阻变化。此变化(或可以)用于控制从立体声系统的音量到大型集装箱船的方向的任何事物。

我们所知的电位计最初被称为变阻器(基本上是一个可变绕线电阻器)。现有的各种电位计现在非常令人惊讶,对于初学者(特别是)来说,弄清楚哪种类型适合给定的任务可能非常困难。一些不同的电位计类型,所有这些类型都可以用于相同的任务,这使得这项工作更加困难。

potentiometer

左侧图片显示了电位计的标准原理图符号。右侧图片是电位器。

Sketch

在计算机上打开 Arduino IDE 软件。使用 Arduino 语言进行编码将控制您的电路。单击“新建”以新建一个草图文件。

sketch

Arduino Code

/*
   ReadAnalogVoltage
   Reads an analog input on pin 0, converts it to voltage,
   and prints the result to the serial monitor.
   Graphical representation is available using serial plotter (Tools > Serial Plotter menu)
   Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
*/

// the setup routine runs once when you press reset:

void setup() {
   // initialize serial communication at 9600 bits per second:
   Serial.begin(9600);
}

// the loop routine runs over and over again forever:

void loop() {
   // read the input on analog pin 0:
   int sensorValue = analogRead(A0);
   // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
   float voltage = sensorValue * (5.0 / 1023.0);
   // print out the value you read:
   Serial.println(voltage);
}

Code to Note

在下面给出的程序或草图中,在设置函数中你首先做的事情是开始串行通信,在你的主板和你的计算机之间,传输速率为 9600 位/秒,行如下所示 −

Serial.begin(9600);

在代码的主循环中,你需要建立一个变量来存储来自电位器的电阻值(介于 0 到 1023 之间,非常适合 int 数据类型)−

int sensorValue = analogRead(A0);

要将值从 0-1023 更改为与电压相对应的范围,引脚正在读取,你需要创建另一个变量,一个 float,并进行一些计算。要在 0.0 和 5.0 之间缩放数字,将 5.0 除以 1023.0,然后将其乘以 sensorValue −

float voltage= sensorValue * (5.0 / 1023.0);

最后,你需要将此信息打印到你的串行窗口。你可以在代码的最后一行使用 Serial.println() 命令执行此操作 −

Serial.println(voltage)

现在,通过单击顶部绿色栏右侧的图标或按 Ctrl+Shift+M,在 Arduino IDE 中打开串行监视器。

serial monitor

Result

你将看到一个稳定的数字流,范围从 0.0 到 5.0。当你转动电位器时,这些值将根据引脚 A0 上的电压而改变。

Arduino - LED Bar Graph

此示例向您展示如何读取模拟针脚 0 上的模拟输入,将 analogRead() 中的值转换成电压,并将其打印到 Arduino 软件 (IDE) 的串口监视器中。

Components Required

您将需要以下组件:

  1. 1 × Breadboard

  2. 1 × Arduino Uno R3

  3. 1 × 5k 欧姆可变电阻器(电位计)

  4. 2 × Jumper

  5. 8 × LED 或您可以使用(如以下图像中所示的 LED 条形图显示器)

Procedure

按照电路图并将组件连接到面包板上,如下图所示。

bar breadboard
connection to bar breadboard

Sketch

在计算机上打开 Arduino IDE 软件。使用 Arduino 语言进行编码将控制您的电路。单击“新建”以新建一个草图文件。

sketch

10 Segment LED Bar Graph

led bar graph

这些 10 段条形图 LED 有多种用途。它们占用空间小、连接简单,无论是用于原型设计还是成品都很容易使用。从本质上说,它们是 10 个单独的蓝色 LED 组合在一起,每个 LED 都具有一个单独的阳极和阴极连接。

它们还有黄色、红色和绿色。

Note − 这些条形图上的引脚分配可能与数据表上列出的不同。将设备旋转 180 度将更正更改,使引脚 11 成为第一引脚。

Arduino Code

/*
   LED bar graph
   Turns on a series of LEDs based on the value of an analog sensor.
   This is a simple way to make a bar graph display.
   Though this graph uses 8LEDs, you can use any number by
      changing the LED count and the pins in the array.
   This method can be used to control any series of digital
      outputs that depends on an analog input.
*/

// these constants won't change:
const int analogPin = A0; // the pin that the potentiometer is attached to
const int ledCount = 8; // the number of LEDs in the bar graph
int ledPins[] = {2, 3, 4, 5, 6, 7, 8, 9}; // an array of pin numbers to which LEDs are attached

void setup() {
   // loop over the pin array and set them all to output:
   for (int thisLed = 0; thisLed < ledCount; thisLed++) {
      pinMode(ledPins[thisLed], OUTPUT);
   }
}

void loop() {
   // read the potentiometer:
   int sensorReading = analogRead(analogPin);
   // map the result to a range from 0 to the number of LEDs:
   int ledLevel = map(sensorReading, 0, 1023, 0, ledCount);
   // loop over the LED array:
   for (int thisLed = 0; thisLed < ledCount; thisLed++) {
      // if the array element's index is less than ledLevel,
      // turn the pin for this element on:
      if (thisLed < ledLevel) {
         digitalWrite(ledPins[thisLed], HIGH);
      }else { // turn off all pins higher than the ledLevel:
         digitalWrite(ledPins[thisLed], LOW);
      }
   }
}

Code to Note

该草图的作用如下:首先,您读取输入。您将输入值映射到输出范围,在本例中为十个 LED。然后,您设置一个 for-loop 在输出上进行迭代。如果输出在序列中的数字低于映射的输入范围,则将其打开。否则,将其关闭。

Result

当模拟读数的值增加时,您将看到 LED 一个接一个地亮起,而在读数减小时,它们会一个个地熄灭。

Arduino - Keyboard Logout

此示例使用键盘库,当 ARDUINO UNO 上的引脚 2 拉至接地时,使你退出计算机上的用户会话。此草图模拟了同时按两个或三个键的顺序的按键,并且在短延迟后释放它们。

Warning − 当你使用 Keyboard.print() 命令时,Arduino 将接管你的计算机键盘。为确保在使用此函数运行草图时不会失去对计算机的控制,请在调用 Keyboard.print() 之前设置一个可靠的控制系统。此草图设计为仅在引脚拉至接地后发送键盘命令。

Components Required

您将需要以下组件:

  1. 1 × Breadboard

  2. 1 × Arduino Leonardo、Micro 或 Due 电路板

  3. 1 × pushbutton

  4. 1 × Jumper

Procedure

按照电路图,按照以下图片所示将组件连接到面包板上。

keyboard breadboard

Sketch

在计算机上打开 Arduino IDE 软件。使用 Arduino 语言进行编码将控制您的电路。单击“新建”以新建一个草图文件。

以下示例中,需要使用 Arduino IDE 1.6.7

sketch

Note − 必须在 Arduino 库文件中包含键盘库。将键盘库文件复制并粘贴到名为 libraries 的文件夹中(高亮),如下面的屏幕截图所示。

arduino library file

Arduino Code

/*
   Keyboard logout
   This sketch demonstrates the Keyboard library.
   When you connect pin 2 to ground, it performs a logout.
   It uses keyboard combinations to do this, as follows:
   On Windows, CTRL-ALT-DEL followed by ALT-l
   On Ubuntu, CTRL-ALT-DEL, and ENTER
   On OSX, CMD-SHIFT-q
   To wake: Spacebar.
   Circuit:
   * Arduino Leonardo or Micro
   * wire to connect D2 to ground.
*/

#define OSX 0
#define WINDOWS 1
#define UBUNTU 2

#include "Keyboard.h"

// change this to match your platform:
int platform = WINDOWS;

void setup() {
   // make pin 2 an input and turn on the
   // pullup resistor so it goes high unless
   // connected to ground:

   pinMode(2, INPUT_PULLUP);
   Keyboard.begin();
}

void loop() {
   while (digitalRead(2) == HIGH) {
      // do nothing until pin 2 goes low
      delay(500);
   }

   delay(1000);

   switch (platform) {
      case OSX:
      Keyboard.press(KEY_LEFT_GUI);

      // Shift-Q logs out:
      Keyboard.press(KEY_LEFT_SHIFT);
      Keyboard.press('Q');
      delay(100);

      // enter:
      Keyboard.write(KEY_RETURN);
      break;

      case WINDOWS:
      // CTRL-ALT-DEL:
      Keyboard.press(KEY_LEFT_CTRL);
      Keyboard.press(KEY_LEFT_ALT);
      Keyboard.press(KEY_DELETE);
      delay(100);
      Keyboard.releaseAll();

      //ALT-l:
      delay(2000);
      Keyboard.press(KEY_LEFT_ALT);
      Keyboard.press('l');
      Keyboard.releaseAll();
      break;

      case UBUNTU:
      // CTRL-ALT-DEL:
      Keyboard.press(KEY_LEFT_CTRL);
      Keyboard.press(KEY_LEFT_ALT);
      Keyboard.press(KEY_DELETE);

      delay(1000);
      Keyboard.releaseAll();

      // Enter to confirm logout:
      Keyboard.write(KEY_RETURN);
      break;
   }

   // do nothing:
   while (true);
}

Keyboard.releaseAll();

   // enter:
      Keyboard.write(KEY_RETURN);
      break;
      case WINDOWS:

   // CTRL-ALT-DEL:
      Keyboard.press(KEY_LEFT_CTRL);
      Keyboard.press(KEY_LEFT_ALT);
      Keyboard.press(KEY_DELETE);
      delay(100);
      Keyboard.releaseAll();

   //ALT-l:
      delay(2000);
      Keyboard.press(KEY_LEFT_ALT);
      Keyboard.press('l');
      Keyboard.releaseAll();
      break;

   case UBUNTU:
      // CTRL-ALT-DEL:
      Keyboard.press(KEY_LEFT_CTRL);
      Keyboard.press(KEY_LEFT_ALT);
      Keyboard.press(KEY_DELETE);
      delay(1000);
      Keyboard.releaseAll();

      // Enter to confirm logout:
      Keyboard.write(KEY_RETURN);
      break;
   }

// do nothing:
   while (true);
}

Code to Note

在将程序上传到电路板之前,确保为平台变量分配当前正在使用的正确操作系统。

在运行草图时,按下按钮会将引脚 2 连接到地,并且电路板会向连接 USB 的 PC 发送注销序列。

Result

将引脚 2 连接到地时,会执行注销操作。

它使用以下键盘组合注销 −

  1. Windows 上,CTRL-ALT-DEL,然后按 ALT-l

  2. Ubuntu 上,CTRL-ALT-DEL,然后按 ENTER

  3. On OSX, CMD-SHIFT-q

Arduino - Keyboard Message

在此示例中,当按下按钮时,一个文本字符串将作为键盘输入被发送到计算机。该字符串报告按钮被按下的次数。一旦对 Leonardo 进行了编程并将其连接好,打开您最喜欢的文本编辑器查看结果。

Warning − 在您使用 Keyboard.print() 命令时,Arduino 接管了您的电脑键盘。为了确保在使用此功能运行草图时不丢失对您电脑的控制,在调用 Keyboard.print() 之前设置一个可靠的控制系统。此草图包含一个按钮,用于切换键盘,因此只有在按下按钮后才运行此草图。

Components Required

您将需要以下组件:

  1. 1 × Breadboard

  2. 1 × Arduino Leonardo、Micro 或 Due 电路板

  3. 1 × momentary pushbutton

  4. 1 × 10k 欧姆电阻

Procedure

按照电路图并将组件连接到面包板上,如下图所示。

keyboard message breadboard

Sketch

在计算机上打开 Arduino IDE 软件。使用 Arduino 语言进行编码将控制您的电路。单击“新建”以新建一个草图文件。

sketch

Arduino Code

/*
   Keyboard Message test For the Arduino Leonardo and Micro,
      Sends a text string when a button is pressed.
   The circuit:
   * pushbutton attached from pin 4 to +5V
   * 10-kilohm resistor attached from pin 4 to ground
*/

#include "Keyboard.h"
const int buttonPin = 4; // input pin for pushbutton
int previousButtonState = HIGH; // for checking the state of a pushButton
int counter = 0; // button push counter

void setup() {
   pinMode(buttonPin, INPUT); // make the pushButton pin an input:
   Keyboard.begin(); // initialize control over the keyboard:
}

void loop() {
   int buttonState = digitalRead(buttonPin); // read the pushbutton:
   if ((buttonState != previousButtonState)&& (buttonState == HIGH)) // and it's currently pressed: {
      // increment the button counter
      counter++;
      // type out a message
      Keyboard.print("You pressed the button ");
      Keyboard.print(counter);
      Keyboard.println(" times.");
   }
   // save the current button state for comparison next time:
   previousButtonState = buttonState;
}

Code to Note

将按钮的一个端子连接到 Arduino 上的针脚 4。将另一个端子连接到 5V。通过将电阻连接成从针脚 4 到接地的下拉电阻,提供一个接地参考。

一旦对电路板进行编程,请拔下 USB 电缆,打开一个文本编辑器,并将文本光标放置在输入区域。通过 USB 再次将电路板连接到您的计算机,然后按下按钮在文档中写入。

Result

通过使用任何文本编辑器,它将显示通过 Arduino 发送的文本。

Arduino - Mouse Button Control

使用鼠标库,你可以用 Arduino Leonardo、Micro 或 Due 控制计算机屏幕上的光标。

此特定示例使用五个按钮来移动屏幕光标。四个按钮是方向性的(上、下、左、右),还有一个用于左键单击。从 Arduino 移动光标始终是相对的。每次读取输入时,光标的位置都相对于其当前位置更新。

只要按下方向按钮中的一个,Arduino 就会移动鼠标,将一个高输入映射到适当方向的 5 个范围。

第五个按钮用于控制鼠标的左键单击。释放按钮时,计算机将识别该事件。

Components Required

您将需要以下组件:

  1. 1 × Breadboard

  2. 1 × Arduino Leonardo、Micro 或 Due 电路板

  3. 5 × 10k 欧姆电阻

  4. 5 × momentary pushbuttons

Procedure

按照电路图,按照以下图片所示将组件连接到面包板上。

mouse button breadboard

Sketch

在计算机上打开 Arduino IDE 软件。使用 Arduino 语言进行编码将控制您的电路。单击“新建”以新建一个草图文件。

以下示例中,需要使用 Arduino IDE 1.6.7

sketch

Arduino Code

/*
   Button Mouse Control
   For Leonardo and Due boards only .Controls the mouse from
   five pushbuttons on an Arduino Leonardo, Micro or Due.
   Hardware:
   * 5 pushbuttons attached to D2, D3, D4, D5, D6
   The mouse movement is always relative. This sketch reads
   four pushbuttons, and uses them to set the movement of the mouse.
   WARNING: When you use the Mouse.move() command, the Arduino takes
   over your mouse! Make sure you have control before you use the mouse commands.
*/

#include "Mouse.h"
// set pin numbers for the five buttons:
const int upButton = 2;
const int downButton = 3;
const int leftButton = 4;
const int rightButton = 5;
const int mouseButton = 6;
int range = 5; // output range of X or Y movement; affects movement speed
int responseDelay = 10; // response delay of the mouse, in ms

void setup() {
   // initialize the buttons' inputs:
   pinMode(upButton, INPUT);
   pinMode(downButton, INPUT);
   pinMode(leftButton, INPUT);
   pinMode(rightButton, INPUT);
   pinMode(mouseButton, INPUT);
   // initialize mouse control:
   Mouse.begin();
}

void loop() {
   // read the buttons:
   int upState = digitalRead(upButton);
   int downState = digitalRead(downButton);
   int rightState = digitalRead(rightButton);
   int leftState = digitalRead(leftButton);
   int clickState = digitalRead(mouseButton);
   // calculate the movement distance based on the button states:
   int xDistance = (leftState - rightState) * range;
   int yDistance = (upState - downState) * range;
   // if X or Y is non-zero, move:
   if ((xDistance != 0) || (yDistance != 0)) {
      Mouse.move(xDistance, yDistance, 0);
   }

   // if the mouse button is pressed:
   if (clickState == HIGH) {
      // if the mouse is not pressed, press it:
      if (!Mouse.isPressed(MOUSE_LEFT)) {
         Mouse.press(MOUSE_LEFT);
      }
   } else {                           // else the mouse button is not pressed:
      // if the mouse is pressed, release it:
      if (Mouse.isPressed(MOUSE_LEFT)) {
         Mouse.release(MOUSE_LEFT);
      }
   }
   // a delay so the mouse does not move too fast:
   delay(responseDelay);
}

Code to Note

用微型 USB 线将电路板连接到计算机。这些按钮连接到引脚 2 至 6 的数字输入。请确保使用 10k 下拉电阻。

Arduino - Keyboard Serial

此示例侦听来自串行端口的字节。收到后,电路板会向计算机发送回一个击键。发送的击键比接收到的击键高一个,因此,如果您从串行监视器中发送一个“a”,您将从连接到计算机的电路板接收到一个“b”。“1”将返回“2”,依此类推。

Warning − 当您使用 Keyboard.print() 命令时,Leonardo、Micro 或 Due 电路板将接管您计算机的键盘。为了确保在使用此功能运行草图时不会失去对计算机的控制,在调用 Keyboard.print() 之前设置一个可靠的控制系统。此草图设计为只在电路板通过串行端口接收到一个字节后才发送键盘命令。

Components Required

您将需要以下组件:

  1. 1 × Arduino Leonardo、Micro 或 Due 电路板

Procedure

只需使用 USB 线将电路板连接到计算机即可。

keyboard serial breadboard

Sketch

在计算机上打开 Arduino IDE 软件。使用 Arduino 语言进行编码将控制您的电路。单击“新建”以新建一个草图文件。

sketch

Notes − 您必须在 Arduino 库文件中包含键盘库。将键盘库文件复制并粘贴到文件内,其中名为“libraries”的文件以黄色突出显示。

arduino library file

Arduino Code

/*
   Keyboard test
   For the Arduino Leonardo, Micro or Due Reads
      a byte from the serial port, sends a keystroke back.
   The sent keystroke is one higher than what's received, e.g. if you send a, you get b, send
      A you get B, and so forth.
   The circuit:
   * none
*/

#include "Keyboard.h"

void setup() {
   // open the serial port:
   Serial.begin(9600);
   // initialize control over the keyboard:
   Keyboard.begin();
}

void loop() {
   // check for incoming serial data:
   if (Serial.available() > 0) {
      // read incoming serial data:
      char inChar = Serial.read();
      // Type the next ASCII value from what you received:
      Keyboard.write(inChar + 1);
   }
}

Code to Note

编程后,打开串行监视器并发送一个字节。该电路板将用击键进行回复,该击键高一个数字。

Result

当您发送一个字节时,该电路板将用一个比 Arduino IDE 串行监视器高一个数字的击键进行回复。

Arduino - Humidity Sensor

在本节,我们将学习如何将 Arduino 电路板与不同的传感器连接。我们将讨论以下传感器 −

  1. Humidity sensor (DHT22)

  2. Temperature sensor (LM35)

  3. 水检测传感器(简单水触发器)

  4. PIR SENSOR

  5. ULTRASONIC SENSOR

  6. GPS

Humidity Sensor (DHT22)

DHT-22(也称为 AM2302)是一种数字输出、相对湿度和温度传感器。它使用电容式湿度传感器和热敏电阻来测量周围空气,并在数据引脚上发送数字信号。

在这个例子里,你将学习如何将该传感器与 Arduino UNO 一起使用。房间温度和湿度将打印到串行监视器中。

The DHT-22 Sensor

dht22 sensor

连接很简单。最左边的第一个引脚为 3-5V 电源,第二个引脚为数据输入引脚,最右边的引脚为地线。

Technical Details

  1. Power − 3-5V

  2. Max Current − 2.5mA

  3. Humidity − 0-100%,精度 2-5%

  4. Temperature − 40 至 80°C,精度 ±0.5°C

Components Required

您将需要以下组件:

  1. 1 × Breadboard

  2. 1 × Arduino Uno R3

  3. 1 × DHT22

  4. 1 × 10K 欧姆电阻

Procedure

按照电路图,按照以下图片所示将组件连接到面包板上。

humidity sensor circuit connection
humidity sensor breadboard

Sketch

在计算机上打开 Arduino IDE 软件。使用 Arduino 语言进行编码将控制您的电路。单击“新建”以新建一个草图文件。

sketch

Arduino Code

// Example testing sketch for various DHT humidity/temperature sensors

#include "DHT.h"
#define DHTPIN 2 // what digital pin we're connected to
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors. This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.
DHT dht(DHTPIN, DHTTYPE);

void setup() {
   Serial.begin(9600);
   Serial.println("DHTxx test!");
   dht.begin();
}

void loop() {
   delay(2000); // Wait a few seconds between measurements
   float h = dht.readHumidity();
   // Reading temperature or humidity takes about 250 milliseconds!
   float t = dht.readTemperature();
   // Read temperature as Celsius (the default)
   float f = dht.readTemperature(true);
   // Read temperature as Fahrenheit (isFahrenheit = true)
   // Check if any reads failed and exit early (to try again).
   if (isnan(h) || isnan(t) || isnan(f)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
   }

   // Compute heat index in Fahrenheit (the default)
   float hif = dht.computeHeatIndex(f, h);
   // Compute heat index in Celsius (isFahreheit = false)
   float hic = dht.computeHeatIndex(t, h, false);
   Serial.print ("Humidity: ");
   Serial.print (h);
   Serial.print (" %\t");
   Serial.print ("Temperature: ");
   Serial.print (t);
   Serial.print (" *C ");
   Serial.print (f);
   Serial.print (" *F\t");
   Serial.print ("Heat index: ");
   Serial.print (hic);
   Serial.print (" *C ");
   Serial.print (hif);
   Serial.println (" *F");
}

Code to Note

DHT22 传感器有四个端子(Vcc、DATA、NC、GND),其连接到电路板的方式如下 −

  1. DATA 引脚至 Arduino 引脚编号 2

  2. Vcc 引脚至 Arduino 电路板的 5 伏

  3. GND 引脚至 Arduino 电路板的地线

  4. 我们需要在 DATA 和 Vcc 引脚之间连接 10k 欧姆电阻(上拉电阻)

硬件连接完成后,你需要将 DHT22 库添加到你的 Arduino 库文件中,如前所述。

Result

你将看到串行端口监视器上显示的温度和湿度,它每 2 秒更新一次。

Arduino - Temperature Sensor

温度传感器 LM35 系列是精密集成电路温度器件,其输出电压与摄氏温度成线性比例。

LM35 器件比校准为开尔文的线性温度传感器有优势,因为用户不需要从输出中减去一个较大的恒定电压来获得便捷的摄氏度刻度。LM35 器件无需任何外部校准或调整,即可在室温下提供 ±¼°C 的典型精度,并在 −55°C 至 150°C 的全温度范围内提供 ±¾°C 的典型精度。

lm35 device

Technical Specifications

  1. 直接以摄氏度(摄氏度)为单位进行校准

  2. 线性 + 10-mV/°C 比例因子

  3. 0.5°C 确保精度(在 25°C)

  4. 额定值为 −55°C 至 150°C

  5. Suitable for remote applications

Components Required

您将需要以下组件:

  1. 1 × Breadboard

  2. 1 × Arduino Uno R3

  3. 1 × LM35 sensor

Procedure

按照电路图并将组件连接到面包板上,如下图所示。

temperature sensor circuit connection

Sketch

在计算机上打开 Arduino IDE 软件。使用 Arduino 语言进行编码将控制您的电路。单击“新建”以新建一个草图文件。

sketch

Arduino Code

float temp;
int tempPin = 0;

void setup() {
   Serial.begin(9600);
}

void loop() {
   temp = analogRead(tempPin);
   // read analog volt from sensor and save to variable temp
   temp = temp * 0.48828125;
   // convert the analog volt to its temperature equivalent
   Serial.print("TEMPERATURE = ");
   Serial.print(temp); // display temperature value
   Serial.print("*C");
   Serial.println();
   delay(1000); // update sensor reading each one second
}

Code to Note

LM35 传感器有三个端子 - Vs、Vout 和 GND。我们将按如下方式连接传感器 -

  1. 将 +Vs 连接到 Arduino 板上的 +5v。

  2. 将 Vout 连接到 Arduino 板上的 Analog0 或 A0。

  3. 将 GND 引脚连接到 Arduino 上的 GND。

模数转换器 (ADC) 将模拟值转换为基于公式 ADC 值 = 样本 * 1024 / 基准电压(+5v)的数字近似值。因此,有了 +5 伏特的基准电压,数字近似值将等于输入电压 * 205。

Result

您将在串行端口监视器上看到每秒更新一次的温度显示。

Arduino - Water Detector / Sensor

水传感器砖块专为检测水而设计,可广泛用于检测降雨、水位,甚至液体泄漏。

water detector sensor

将水传感器连接到 Arduino 是检测泄漏、溢出、洪水、降雨等的绝佳方式。它可用于检测水是否存在、水位、水量和/或不存在。虽然这可用于提醒你给植物浇水,但有更好的 Grove 传感器可用于此目的。该传感器有一系列暴露的走线,在检测到水时读数为低。

在本章中,我们将水传感器连接到 Arduino 上的数字引脚 8,并将使用非常方便的 LED 来帮助识别水传感器何时与水源接触。

Components Required

您将需要以下组件:

  1. 1 × Breadboard

  2. 1 × Arduino Uno R3

  3. 1 × Water Sensor

  4. 1 × led

  5. 1 × 330 欧姆电阻

Procedure

按照电路图并将组件连接到面包板上,如下图所示。

water sensor circuit connection

Sketch

在电脑上打开 Arduino IDE 软件。使用 Arduino 语言编写代码将控制你的电路。单击新建打开一个新草图文件。

sketch

Arduino Code

#define Grove_Water_Sensor 8 // Attach Water sensor to Arduino Digital Pin 8
#define LED 9 // Attach an LED to Digital Pin 9 (or use onboard LED)

void setup() {
   pinMode(Grove_Water_Sensor, INPUT); // The Water Sensor is an Input
   pinMode(LED, OUTPUT); // The LED is an Output
}

void loop() {
   /* The water sensor will switch LOW when water is detected.
   Get the Arduino to illuminate the LED and activate the buzzer
   when water is detected, and switch both off when no water is present */
   if( digitalRead(Grove_Water_Sensor) == LOW) {
      digitalWrite(LED,HIGH);
   }else {
      digitalWrite(LED,LOW);
   }
}

Code to Note

水传感器有三个端子 - S、Vout(+) 和 GND (-)。如下连接传感器 −

  1. 将 +Vs 连接到 Arduino 板上的 +5v。

  2. 将 S 引脚连接到 Arduino 电路板上的 8 号引脚。

  3. 将 GND 引脚连接到 Arduino 上的 GND。

  4. 将 LED 引脚连接到 Arduino 电路板上的 9 号引脚。

当传感器检测到水时,Arduino 上的 8 号引脚变为 LOW,然后 Arduino 上的 LED 被点亮。

Result

当传感器检测到水时,你会看到指示灯被点亮。

Arduino - PIR Sensor

PIR 传感器让您能够对运动进行感知。它们用于检测人是否在传感器的范围内进出。它们通常出现在家中或企业中使用的装置和小工具中。它们经常被称为 PIR、“被动红外”、“热释电”或“红外运动”传感器。

以下是 PIR 传感器的优势:

  1. Small in size

  2. Wide lens range

  3. Easy to interface

  4. Inexpensive

  5. Low-power

  6. Easy to use

  7. Do not wear out

pir sensor

PIR 由热释电传感器制成,传感器是一个圆形金属罐,中间有一个矩形晶体,可以检测红外辐射水平。任何东西都会发出低水平辐射,并且东西越热,发出的辐射就越多。运动探测器中的传感器被分成两半。这是检测运动(变化)而不是平均红外水平。这两个部分连接在一起,以便它们相互抵消。如果半部分比另一半看到更多或更少的红外辐射,则输出将高或低摆动。

pir

PIR 具有可调节设置,并且在 3 针接地/输出/电源焊盘中安装了一个接头。

pir adjustable settings

对于需要检测有人离开或进入指定区域的大多数基本项目或产品而言,PIR 传感器非常好。请注意,PIR 不会告诉您附近的人数或他们与传感器的距离。镜头通常固定在一定距离的某个扫掠范围,并且有时会被家中的宠物触发。

Components Required

您将需要以下组件:

  1. 1 × Breadboard

  2. 1 × Arduino Uno R3

  3. 1 × PIR 传感器 (MQ3)

Procedure

按照电路图进行操作,并按如下图像所示进行连接。

pir sensor circuit connection

Sketch

在计算机上打开 Arduino IDE 软件。使用 Arduino 语言进行编码将控制您的电路。单击“新建”以新建一个草图文件。

sketch

Arduino Code

#define pirPin 2
int calibrationTime = 30;
long unsigned int lowIn;
long unsigned int pause = 5000;
boolean lockLow = true;
boolean takeLowTime;
int PIRValue = 0;

void setup() {
   Serial.begin(9600);
   pinMode(pirPin, INPUT);
}

void loop() {
   PIRSensor();
}

void PIRSensor() {
   if(digitalRead(pirPin) == HIGH) {
      if(lockLow) {
         PIRValue = 1;
         lockLow = false;
         Serial.println("Motion detected.");
         delay(50);
      }
      takeLowTime = true;
   }
   if(digitalRead(pirPin) == LOW) {
      if(takeLowTime){
         lowIn = millis();takeLowTime = false;
      }
      if(!lockLow && millis() - lowIn > pause) {
         PIRValue = 0;
         lockLow = true;
         Serial.println("Motion ended.");
         delay(50);
      }
   }
}

Code to Note

PIR 传感器有三个端子 - Vcc、OUT 和 GND。按照如下方式连接传感器:

  1. 将 +Vcc 连接到 Arduino 板上的 +5v。

  2. 将 OUT 连接到 Arduino 板上的数字引脚 2。

  3. 将 GND 引脚连接到 Arduino 上的 GND。

通过传感器电路板底部的两个可变电阻可以调节传感器的灵敏度和延迟时间。

delay time adjust

传感器检测到任何动作后,Arduino 将通过串行端口发送一条消息来表明侦测到一个动作。PIR(红外热释电传感器)动作感知会延迟一段时间以检查是否有新的动作。如果没有检测到动作,Arduino 会发送一条新消息来说结束动作。

Result

如果检测到动作,您会在串行端口上看到一条消息,如果动作停止,您还会看到另一条消息。

Arduino - Ultrasonic Sensor

HC-SR04 超声波传感器使用声呐来确定物体的距离,就像蝙蝠一样。它可以从 2 厘米到 400 厘米或 1 英寸到 13 英尺的距离提供非接触式范围检测,具有高精度和稳定的读数,且易于使用。

虽然声音上柔软的材料(例如布料)可能难以检测,但日光或黑色材料不会影响操作。它配有超声波发射器和接收器模块。

ultrasonic sensor
ultrasonic sensor radiations

Technical Specifications

  1. 电源 − +5V 直流

  2. Quiescent Current − <2mA

  3. Working Current − 15mA

  4. Effectual Angle − <15°

  5. 测距 − 2 厘米到 400 厘米/1 英寸到 13 英尺

  6. Resolution − 0.3 cm

  7. 测量角度 − 30 度

Components Required

您将需要以下组件:

  1. 1 × Breadboard

  2. 1 × Arduino Uno R3

  3. 1 个超声波传感器(HC-SR04)

Procedure

按照电路图进行操作,并按照下面给出的图片所示进行连接。

ultrasonic circuit connection

Sketch

在计算机上打开 Arduino IDE 软件。使用 Arduino 语言进行编码将控制您的电路。单击“新建”以新建一个草图文件。

sketch

Arduino Code

const int pingPin = 7; // Trigger Pin of Ultrasonic Sensor
const int echoPin = 6; // Echo Pin of Ultrasonic Sensor

void setup() {
   Serial.begin(9600); // Starting Serial Terminal
}

void loop() {
   long duration, inches, cm;
   pinMode(pingPin, OUTPUT);
   digitalWrite(pingPin, LOW);
   delayMicroseconds(2);
   digitalWrite(pingPin, HIGH);
   delayMicroseconds(10);
   digitalWrite(pingPin, LOW);
   pinMode(echoPin, INPUT);
   duration = pulseIn(echoPin, HIGH);
   inches = microsecondsToInches(duration);
   cm = microsecondsToCentimeters(duration);
   Serial.print(inches);
   Serial.print("in, ");
   Serial.print(cm);
   Serial.print("cm");
   Serial.println();
   delay(100);
}

long microsecondsToInches(long microseconds) {
   return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds) {
   return microseconds / 29 / 2;
}

Code to Note

超声波传感器有四个端子(+5V、触发、回声和 GND),连接如下:

  1. 将 +5V 引脚连接到 Arduino 电路板上的 +5v。

  2. 将触发引脚连接到 Arduino 电路板上的 7 号引脚。

  3. 将回声引脚连接到 Arduino 电路板上的 6 号引脚。

  4. 将 GND 引脚连接到 Arduino 上的 GND。

在我们的程序中,我们通过串口以英寸和厘米显示了传感器测量的距离。

Result

您将看到传感器通过 Arduino 串口监视器测量的距离(以英寸和厘米为单位)。

Arduino - Connecting Switch

按钮或开关将电路中的两个开口端子连接起来。此示例在按连接到引脚8的按钮开关时打开引脚2上的LED。

connecting switch

Pull-down Resistor

下拉电阻用于电子逻辑电路中,以确保在外部设备断开连接或处于高阻抗时,输入到Arduino会稳定在预期的逻辑电平。因为没有任何东西连接到输入引脚,这并不意味着它是一个逻辑零。下拉电阻连接在接地和设备上相应的引脚之间。

数字电路中的下拉电阻示例如下图所示。按钮开关连接在电源电压和微控制器引脚之间。在这样的电路中,当开关闭合时,微控制器输入处于逻辑高值,但当开关打开时,下拉电阻将输入电压下拉至接地(逻辑零值),防止输入处于未定义状态。

下拉电阻的阻值必须大于逻辑电路的阻抗,否则它可能会将电压下拉得太低,并且无论开关位置如何,引脚上的输入电压仍将保持在恒定的逻辑低值。

pull down resistor

Components Required

您将需要以下组件:

  1. 1 × Arduino UNO 电路板

  2. 1 × 330 欧姆电阻

  3. 1个×4.7K欧姆电阻(下拉)

  4. 1 × LED

Procedure

按照电路图进行操作,并按照下面给出的图片所示进行连接。

connections of circuit diagram

Sketch

在电脑上打开 Arduino IDE 软件。使用 Arduino 语言编写代码将控制你的电路。单击新建打开一个新草图文件。

sketch

Arduino Code

// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 8; // the number of the pushbutton pin
const int ledPin = 2; // the number of the LED pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status

void setup() {
   // initialize the LED pin as an output:
   pinMode(ledPin, OUTPUT);
   // initialize the pushbutton pin as an input:
   pinMode(buttonPin, INPUT);
}

void loop() {
   // read the state of the pushbutton value:
   buttonState = digitalRead(buttonPin);
   // check if the pushbutton is pressed.
   // if it is, the buttonState is HIGH:
   if (buttonState == HIGH) {
      // turn LED on:
      digitalWrite(ledPin, HIGH);
   } else {
      // turn LED off:
      digitalWrite(ledPin, LOW);
   }
}

Code to Note

当开关打开时(未按下按钮),按钮的两个端子之间没有连接,所以引脚通过(下拉电阻)连接到地,我们读到一个LOW。当开关闭合时(按下按钮),它会在其两个端子之间建立连接,将引脚连接到5伏,这样我们就能读到一个HIGH。

Result

按下按钮时LED打开,松开时关闭。

Arduino - DC Motor

在本章中,我们将演示不同类型的电机与 Arduino 板 (UNO) 的接口,并向您展示如何连接电机并从您的板上进行驱动。

有三种不同类型的电机−

  1. DC motor

  2. Servo motor

  3. Stepper motor

直流电动机是最常见的电动机类型。直流电动机通常只有两个引线,一个正极和一个负极。如果您将这两根引线直接连接到电池上,则电机将旋转。如果您切换引线,电机将朝相反的方向旋转。

dc motor

Warning − 请勿直接从 Arduino 板引脚驱动电机。这可能会损坏电路板。使用驱动器电路或 IC。

我们将本章分为三个部分−

  1. 只需让电机旋转

  2. Control motor speed

  3. 控制直流电机的旋转方向

Components Required

您将需要以下组件:

  1. 1x Arduino UNO board

  2. 1x PN2222 Transistor

  3. 1x 小型 6V 直流电机

  4. 1x 1N4001 diode

  5. 1x 270 Ω Resistor

Procedure

按照电路图进行操作,并按照下面给出的图片所示进行连接。

dc motor connections

Precautions

在进行连接时采取以下预防措施。

  1. 首先,确保晶体管以正确的方式连接。如排列所示,晶体管的平面侧应面向 Arduino 板。

  2. 第二,根据图像中所示的排列方式,二极管的条纹端应朝向 +5V 电源线。

Spin ControlArduino Code

int motorPin = 3;

void setup() {

}

void loop() {
   digitalWrite(motorPin, HIGH);
}

Code to Note

晶体管起开关作用,控制流向电机的功率。3 号 Arduino 引脚用于打开和关闭晶体管,在素描中命名为“motorPin”。

Result

当 3 号 Arduino 引脚变高时,电机将高速旋转。

Motor Speed Control

以下是直流电机示意图,它连接到 Arduino 电路板。

motor speed control

Arduino Code

int motorPin = 9;

void setup() {
   pinMode(motorPin, OUTPUT);
   Serial.begin(9600);
   while (! Serial);
   Serial.println("Speed 0 to 255");
}

void loop() {
   if (Serial.available()) {
      int speed = Serial.parseInt();
      if (speed >= 0 && speed <= 255) {
         analogWrite(motorPin, speed);
      }
   }
}

Code to Note

晶体管起开关作用,控制流向电机的功率。3 号 Arduino 引脚用于打开和关闭晶体管,在素描中命名为“motorPin”。

当程序启动时,它会提示你给出控制电机速度的值。你需在串行监视器中输入 0 到 255 之间的值。

command window

在“循环”函数中,使用“Serial.parseInt”命令读取串行监视器中作为文本输入的数字,并将其转换为“int”。你可以在此处键入任意数字。如果数字在 0 到 255 之间,则下一行中的“if”语句仅使用此数字执行模拟写入。

Result

直流电机将根据通过串行端口接收的值(0 到 250)以不同的速度旋转。

Spin Direction Control

要控制直流电机旋转方向,无需交换引线,你可以使用名为 H-Bridge 的电路。H 桥是一个电子电路,可以驱动电机向两个方向转动。H 桥用于众多不同的应用。最常见的应用之一是控制机器中的电机。之所以称作 H 桥,是因为它使用的四个晶体管连接方式使示意图看起来像一个“H”。

我们将在此处使用 L298 H 桥 IC。L298 可以控制直流电机和步进电机的速度和方向,还可以同时控制两台电机。对每台电机,其额定电流为 2A。然而,在此电流下,你将需要使用散热器。

spin direction control

Components Required

您将需要以下组件:

  1. 1 × L298 桥接 IC

  2. 1 × DC motor

  3. 1 × Arduino UNO

  4. 1 × breadboard

  5. 10 × jumper wires

Procedure

以下是直流电机与 Arduino Uno 电路板接口的示意图。

spin direction control connections

上图展示了如何连接 L298 IC 以便控制两台电机。每台电机都有三个输入引脚,第 1 个输入引脚(IN1)、第 2 个输入引脚(IN2)和第 1 个使能引脚(EN1),用于电机 1;第 3 个输入引脚、第 4 个输入引脚和第 2 个使能引脚,用于电机 2。

由于我们在本示例中只控制一台电机,因此我们将 Arduino 连接到 L298 IC 的 IN1(引脚 5)、IN2(引脚 7)和 Enable1(引脚 6)。引脚 5 和 7 是数字引脚,即 ON 或 OFF 输入,而引脚 6 需要脉宽调制 (PWM) 信号才能控制电机速度。

下表显示了电机将根据 IN1 和 IN2 的数字值旋转的方向。

IN1

IN2

Motor Behavior

BRAKE

1

FORWARD

1

BACKWARD

1

1

BRAKE

IC L298 的 IN1 引脚连接到 Arduino 的引脚 8,而 IN2 连接到引脚 9。这两个 Arduino 数字引脚控制电机的方向。IC 的 EN A 引脚连接到 Arduino 的 PWM 引脚 2。这将控制电机的速度。

要设置 Arduino 引脚 8 和 9 的值,我们使用了 digitalWrite() 函数,而要设置引脚 2 的值,我们必须使用 analogWrite() 函数。

Connection Steps

  1. 将 IC 的 5V 和接地分别连接到 5V 和 Arduino 的接地。

  2. 将电机连接到 IC 的引脚 2 和 3。

  3. 将 IC 的 IN1 连接到 Arduino 的引脚 8。

  4. 将 IC 的 IN2 连接到 Arduino 的引脚 9。

  5. 将 IC 的 EN1 连接到 Arduino 的引脚 2。

  6. 将 IC 的 SENS A 引脚连接到接地。

  7. 使用 Arduino USB 线连接 Arduino,并使用 Arduino IDE 软件将程序上传到 Arduino。

  8. 使用电源、电池或 USB 线为 Arduino 电路板供电。

Arduino Code

const int pwm = 2 ; //initializing pin 2 as pwm
const int in_1 = 8 ;
const int in_2 = 9 ;
//For providing logic to L298 IC to choose the direction of the DC motor

void setup() {
   pinMode(pwm,OUTPUT) ; //we have to set PWM pin as output
   pinMode(in_1,OUTPUT) ; //Logic pins are also set as output
   pinMode(in_2,OUTPUT) ;
}

void loop() {
   //For Clock wise motion , in_1 = High , in_2 = Low
   digitalWrite(in_1,HIGH) ;
   digitalWrite(in_2,LOW) ;
   analogWrite(pwm,255) ;
   /* setting pwm of the motor to 255 we can change the speed of rotation
   by changing pwm input but we are only using arduino so we are using highest
   value to driver the motor */
   //Clockwise for 3 secs
   delay(3000) ;
   //For brake
   digitalWrite(in_1,HIGH) ;
   digitalWrite(in_2,HIGH) ;
   delay(1000) ;
   //For Anti Clock-wise motion - IN_1 = LOW , IN_2 = HIGH
   digitalWrite(in_1,LOW) ;
   digitalWrite(in_2,HIGH) ;
   delay(3000) ;
   //For brake
   digitalWrite(in_1,HIGH) ;
   digitalWrite(in_2,HIGH) ;
   delay(1000) ;
}

Result

电机将首先按顺时针 (CW) 方向运行 3 秒,然后按逆时针 (CCW) 方向运行 3 秒。

Arduino - Servo Motor

伺服电机是一种具有输出轴的小型设备。通过向伺服发送编码信号,可以将该轴定位到特定的角度位置。只要输入线路上存在编码信号,伺服就会保持轴的角度位置。如果编码信号发生变化,轴的角度位置就会发生变化。在实践中,伺服用于遥控飞机,以定位升降舵和方向舵等控制面。它们还用于遥控汽车、木偶,当然还有机器人。

servo motor

伺服在机器人技术中非常有用。这些电机小巧,具有内置控制电路,并且相对于其尺寸而言非常强大。标准伺服(如 Futaba S-148)具有 42 oz/inch 的转矩,对于其尺寸来说非常强劲。它还根据机械负载绘制功率。因此,负载较轻的伺服不会消耗太多能量。

伺服电机的内部结构如下图所示。可以看到控制电路、电机、一组齿轮和外壳。还可以看到连接到外部世界的三根电线。一根用于电源(+5 伏)、地线,并且白线是控制线。

servo motor control circuitry

Working of a Servo Motor

伺服电机具有一些控制电路和一个电位器(可变电阻器,又称电位器),连接到输出轴上。在上面的图片中,可以在电路板的右侧看到电位器。这个锅允许控制电路监控伺服电机的当前角度。

如果轴处于正确的角度,那么电机就会关闭。如果电路发现角度不正确,它会转动电机直到它达到所需的角度。伺服的输出轴能够移动大约 180 度。通常,它在 210 度范围内某处,但它会根据制造商而有所不同。通常的伺服用于控制 0 到 180 度的角运动。由于内置在主输出齿轮上的机械停止,它在机械上不能转得更远。

施加于电机的功率与它需要行进的距离成正比。因此,如果轴需要转动较大的距离,电机将以全速运转。如果它仅需转动较小的距离,电机将以较慢的速度运转。这被称为 proportional control

How Do You Communicate the Angle at Which the Servo Should Turn?

控制线用于传达角度。角度由施加于控制线的脉冲的持续时间决定。这被称为 Pulse Coded Modulation 。伺服器期望每隔20毫秒(0.02 秒)看到一个脉冲。脉冲的长度将决定电机转动多远。例如,1.5毫秒的脉冲将使电机转动到90度位置(通常称为中立位置)。如果脉冲短于1.5毫秒,则电机会将轴转动得更接近0度。如果脉冲长于1.5毫秒,则轴会转动得更接近180度。

angle turn

Components Required

您将需要以下组件:

  1. 1 × Arduino UNO 电路板

  2. 1 × Servo Motor

  3. 1个×ULN2003驱动IC

  4. 1个×10KΩ电阻器

Procedure

按照电路图进行操作,并按照下面给出的图片所示进行连接。

servo motor connections

Sketch

在电脑上打开 Arduino IDE 软件。使用 Arduino 语言编写代码将控制你的电路。单击新建打开一个新草图文件。

sketch

Arduino Code

/* Controlling a servo position using a potentiometer (variable resistor) */

#include <Servo.h>
   Servo myservo; // create servo object to control a servo
   int potpin = 0; // analog pin used to connect the potentiometer
   int val; // variable to read the value from the analog pin

void setup() {
   myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop() {
   val = analogRead(potpin);
   // reads the value of the potentiometer (value between 0 and 1023)
   val = map(val, 0, 1023, 0, 180);
   // scale it to use it with the servo (value between 0 and 180)
   myservo.write(val); // sets the servo position according to the scaled value
   delay(15);
}

Code to Note

伺服电机具有三个端子 - 电源、接地和信号。电源线通常为红色,应连接到Arduino上的5V引脚。接地线通常为黑色或棕色,应连接到ULN2003 IC的一个端子(10 -16)。为保护您的Arduino板免受损坏,您将需要一些驱动器IC来完成此任务。在这里,我们使用了ULN2003 IC 来驱动伺服电机。信号线通常为黄色或橙色,应连接到Arduino引脚号9。

Connecting the Potentiometer

分压器/电位分压器是一种串联电路中的电阻器,它将输出电压调整为施加的输入电压的特定比率。以下是电路图 −

connecting potentiometer

V_{out} = (V_{in} \times R_{2})/ (R_{1} + R_{2})

Vout是输出电位,它取决于串联中的施加输入电压(Vin)和电阻器(R1和R2)。这意味着流过R1的电流也将流过R2而不被分流。在上面的等式中,随着R2值的改变,Vout会根据输入电压Vin相应地调整。

通常,电位器是一种电位分压器,它可以根据可变电阻的值来调整电路的输出电压,该值使用旋钮进行调整。它有三个引脚:GND、信号和+5V,如下所示 −

potentiometer with description

Result

通过改变电位器的NOP位置,伺服电机将改变其角度。

Arduino - Stepper Motor

步进电机是一种无刷同步电机,它将一个完全旋转划分为若干步。与直流无刷电机在施加固定直流电压后持续旋转不同,步进电机以离散的步进角度旋转。

因此,步进电机的每转步数为 12、24、72、144、180 和 200,从而导致每个步的步进角度为 30、15、5、2.5、2 和 1.8 度。可以控制带有或不带有反馈的步进电机。

想象一下遥控飞机上的一个电机。该电机在一个或另一个方向上非常快地旋转。你可以通过提供给电机的功率来改变速度,但你无法告诉螺旋桨在特定位置停止。

现在想象一下打印机。打印机内部有很多运动部件,包括电机。其中一个这样的电机充当送纸器,它旋转辊筒,在纸上打印墨水时移动纸张。该电机需要能够将纸张移动精确的距离,以便能够打印下一行文本或图像的下一行。

连接到螺纹杆的另一个电机来回移动打印头。同样,该螺纹杆需要移动一个精确的量,然后才能依次打印一个字母。这就是步进电机派上用场的地方。

stepper motor

How a Stepper Motor Works?

普通直流电机只能朝一个方向旋转,而步进电机可以以精确的增量旋转。

步进电机可以根据需要旋转精确的角度(或步数)。这使你可以完全控制电机,从而让你可以将它移动到精确的位置并保持该位置。它通过在非常短的时间内为电机内部的线圈供电来实现此目的。缺点是,你必须始终向电机供电,才能使其保持在你所需的位置。

现在,你所需要知道的是:要移动一个步进电机,就是要告诉它向一个方向或另一个方向移动一个确定的步数,并告诉它以什么速度沿该方向移动。步进电机有多种类型。这里描述的方法可用于推断出如何使用教程中未提到的其他电机和驱动器。但是,我们始终建议你查阅你所用的型号的电机和驱动器的说明书和指南。

inner stepper motor

Components Required

您将需要以下组件:

  1. 1 × Arduino UNO 电路板

  2. 1 × 小型双极步进电机,如下面给出的图片所示

  3. 1 × LM298 驱动 IC

lm298 driving ic

Procedure

按照电路图进行操作,并按照下面给出的图片所示进行连接。

stepper motor connections

Sketch

在计算机上打开 Arduino IDE 软件。使用 Arduino 语言进行编码将控制您的电路。单击“新建”以新建一个草图文件。

sketch

Arduino Code

/* Stepper Motor Control */

#include <Stepper.h>
const int stepsPerRevolution = 90;
// change this to fit the number of steps per revolution
// for your motor
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

void setup() {
   // set the speed at 60 rpm:
   myStepper.setSpeed(5);
   // initialize the serial port:
   Serial.begin(9600);
}

void loop() {
   // step one revolution in one direction:
   Serial.println("clockwise");
   myStepper.step(stepsPerRevolution);
   delay(500);
   // step one revolution in the other direction:
   Serial.println("counterclockwise");
   myStepper.step(-stepsPerRevolution);
   delay(500);
}

Code to Note

此程序驱动单极或双极步进电机。此电机连接到 Arduino 的数字引脚 8 - 11。

Result

电机将单向转动一圈,然后反向转动一圈。

Arduino - Tone Library

在本教程中,我们将使用 Arduino 音调库。它只不过是一个 Arduino 库,可在任何 Arduino 引脚上生成指定频率(和 50% 占空比)的方波。可以有选择地指定持续时间,否则该波会持续到调用 stop() 函数为止。可以将引脚连接到压电蜂鸣器或扬声器来播放音调。

Warning − 不要将引脚直接连接到任何音频输入。电压远高于标准线路电平电压,并且可能损坏声卡输入等。您可以使用分压器来降低电压。

Components Required

您将需要以下组件:

  1. 1 × 8-ohm speaker

  2. 1 × 1k resistor

  3. 1 × Arduino UNO 电路板

Procedure

按照电路图进行操作,并按照下面给出的图片所示进行连接。

tone library connections

Sketch

在计算机上打开 Arduino IDE 软件。使用 Arduino 语言进行编码将控制您的电路。单击“新建”以新建一个草图文件。

sketch

为制作 pitches.h 文件,请单击串口监视器图标正下方的按钮并选择“新建选项卡”,或使用 Ctrl+Shift+N。

new tab

然后粘贴以下代码:

/*************************************************
* Public Constants
*************************************************/

#define NOTE_B0 31
#define NOTE_C1 33
#define NOTE_CS1 35
#define NOTE_D1 37
#define NOTE_DS1 39
#define NOTE_E1 41
#define NOTE_F1 44
#define NOTE_FS1 46
#define NOTE_G1 49
#define NOTE_GS1 52
#define NOTE_A1 55
#define NOTE_AS1 58
#define NOTE_B1 62
#define NOTE_C2 65
#define NOTE_CS2 69
#define NOTE_D2 73
#define NOTE_DS2 78
#define NOTE_E2 82
#define NOTE_F2 87
#define NOTE_FS2 93
#define NOTE_G2 98
#define NOTE_GS2 104
#define NOTE_A2 110
#define NOTE_AS2 117
#define NOTE_B2 123
#define NOTE_C3 131
#define NOTE_CS3 139
#define NOTE_D3 147
#define NOTE_DS3 156
#define NOTE_E3 165
#define NOTE_F3 175
#define NOTE_FS3 185
#define NOTE_G3 196
#define NOTE_GS3 208
#define NOTE_A3 220
#define NOTE_AS3 233
#define NOTE_B3 247
#define NOTE_C4 262
#define NOTE_CS4 277
#define NOTE_D4 294
#define NOTE_DS4 311
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_FS4 370
#define NOTE_G4 392
#define NOTE_GS4 415
#define NOTE_A4 440
#define NOTE_AS4 466
#define NOTE_B4 494
#define NOTE_C5 523
#define NOTE_CS5 554
#define NOTE_D5 587
#define NOTE_DS5 622
#define NOTE_E5 659
#define NOTE_F5 698
#define NOTE_FS5 740
#define NOTE_G5 784
#define NOTE_GS5 831
#define NOTE_A5 880
#define NOTE_AS5 932
#define NOTE_B5 988
#define NOTE_C6 1047
#define NOTE_CS6 1109
#define NOTE_D6 1175
#define NOTE_DS6 1245
#define NOTE_E6 1319
#define NOTE_F6 1397
#define NOTE_FS6 1480
#define NOTE_G6 1568
#define NOTE_GS6 1661
#define NOTE_A6 1760
#define NOTE_AS6 1865
#define NOTE_B6 1976
#define NOTE_C7 2093
#define NOTE_CS7 2217
#define NOTE_D7 2349
#define NOTE_DS7 2489
#define NOTE_E7 2637
#define NOTE_F7 2794
#define NOTE_FS7 2960
#define NOTE_G7 3136
#define NOTE_GS7 3322
#define NOTE_A7 3520
#define NOTE_AS7 3729
#define NOTE_B7 3951
#define NOTE_C8 4186
#define NOTE_CS8 4435
#define NOTE_D8 4699
#define NOTE_DS8 4978

将上述代码另存为 pitches.h

Arduino Code

#include "pitches.h"
// notes in the melody:
int melody[] = {
NOTE_C4, NOTE_G3,NOTE_G3, NOTE_GS3, NOTE_G3,0, NOTE_B3, NOTE_C4};
// note durations: 4 = quarter note, 8 = eighth note, etc.:

int noteDurations[] = {
   4, 8, 8, 4,4,4,4,4
};

void setup() {
   // iterate over the notes of the melody:
   for (int thisNote = 0; thisNote < 8; thisNote++) {
      // to calculate the note duration, take one second
      // divided by the note type.
      //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
      int noteDuration = 1000/noteDurations[thisNote];
      tone(8, melody[thisNote],noteDuration);
      //pause for the note's duration plus 30 ms:
      delay(noteDuration +30);
   }
}

void loop() {
   // no need to repeat the melody.
}

Code to Note

此代码使用另一个文件 pitches.h。该文件包含典型音符的所有音高值。例如,NOTE_C4 是中音 C。NOTE_FS4 是 F 尖,依此类推。此音符表最初由 Brett Hagman 编写,tone() 命令基于他的工作。每当要生成音符时,您可能会用到它。

Result

您将听到保存在 pitches.h 中的音符文件。

Arduino - Wireless Communication

无线收发器模块在 315 Mhz 下工作。它们可以轻松地装入面包板,并且与微控制器配合良好,可以创建非常简单的无线数据链路。在一对收发器上,模块只工作于单向通信数据,但是,你需要两对(不同频率)作为收发器对。

Note - 这些模块是很随意的,并且会收到相当多的噪声。收发器都在常见频率下工作,并且没有 ID。

wireless communication

Receiver Module Specifications

  1. Product Model − MX-05V

  2. Operating voltage − DC5V

  3. Quiescent Current − 4mA

  4. Receiving frequency − 315Mhz

  5. Receiver sensitivity − -105DB

  6. 尺寸 - 30 * 14 * 7mm

Transmitter Module Specifications

  1. Product Model − MX-FS-03V

  2. 发射距离 - 20-200 米(不同电压,不同结果)

  3. Operating voltage − 3.5-12V

  4. 尺寸 - 19 * 19mm

  5. Operating mode − AM

  6. 传输速率 - 4KB/S

  7. Transmitting power − 10mW

  8. Transmitting frequency − 315Mhz

  9. 外部天线 - 25cm 普通多芯或单芯线路

  10. 从左→右的引脚排列 - (数据;VCC;GND)

Components Required

您将需要以下组件:

  1. 2 × Arduino UNO 板

  2. 1 × 射频链路发射器

  3. 1 × 射频链路接收器

Procedure

按照电路图进行操作,并按照下面给出的图片所示进行连接。

wireless communication connections

Sketch

在计算机上打开 Arduino IDE 软件。使用 Arduino 语言进行编码将控制您的电路。单击“新建”以新建一个草图文件。

sketch

Note - 你必须在你的 Arduino 库文件中包含键盘库。复制 VirtualWire.lib 文件,并像下面给出的屏幕截图中高亮显示的那样将其粘贴到库文件夹中。

arduino library file

Arduino Code for Transmitter

//simple Tx on pin D12
#include <VirtualWire.h>
char *controller;

void setup() {
   pinMode(13,OUTPUT);
   vw_set_ptt_inverted(true);
   vw_set_tx_pin(12);
   vw_setup(4000);// speed of data transfer Kbps
}

void loop() {
   controller="1" ;
   vw_send((uint8_t *)controller, strlen(controller));
   vw_wait_tx(); // Wait until the whole message is gone
   digitalWrite(13,1);
   delay(2000);
   controller="0" ;
   vw_send((uint8_t *)controller, strlen(controller));
   vw_wait_tx(); // Wait until the whole message is gone
   digitalWrite(13,0);
   delay(2000);
}

Code to Note

这是一个简单的代码。首先,它会发送字符'1',两秒后会发送字符'0',等等。

Arduino Code for Receiver

//simple Rx on pin D12
#include <VirtualWire.h>

void setup() {
   vw_set_ptt_inverted(true); // Required for DR3100
   vw_set_rx_pin(12);
   vw_setup(4000); // Bits per sec
   pinMode(5, OUTPUT);
   vw_rx_start(); // Start the receiver PLL running
}

void loop() {
   uint8_t buf[VW_MAX_MESSAGE_LEN];
   uint8_t buflen = VW_MAX_MESSAGE_LEN;
   if (vw_get_message(buf, &buflen)) // Non-blocking {
      if(buf[0]=='1') {
         digitalWrite(5,1);
      }
      if(buf[0]=='0') {
         digitalWrite(5,0);
      }
   }
}

Code to Note

当收到字符'1’时,连接到 Arduino 板上的引脚号 5 的 LED 会亮起,当收到字符'0’时,LED 会关闭。

Arduino - Network Communication

Texas Instruments 的 CC3000 WiFi 模块是一款小型银色封装,它最终为你的 Arduino 项目带来了易于使用、价格低廉的 WiFi 功能。

它使用 SPI 进行通信(而非 UART!),因此你可以按照你想要的速度将数据推送出去。它有一个带 IRQ 引脚的适当中断系统,因此你可以拥有异步连接。它支持 802.11b/g、开放的/WEP/WPA/WPA2 安全性、TKIP 和 AES。一个带有“BSD 套接字”界面的内置 TCP/IP 协议栈,在客户端和服务器模式下都支持 TCP 和 UDP。

network communication

Components Required

您将需要以下组件:

  1. 1 × Arduino Uno

  2. 1 × Adafruit CC3000 扩展板

  3. 1 × 5V relay

  4. 1 × Rectifier diode

  5. 1 × LED

  6. 1 × 220 欧姆电阻

  7. 1 × 面包板和一些跳线

对于此项目,你只需要普通的 Arduino IDE,Adafruit 的 CC3000 库,和 CC3000 MDNS 库。我们还将使用 aREST 库,以便通过 WiFi 向继电器发送命令。

Procedure

按照电路图进行操作,并按照下面给出的图片所示进行连接。

network communication connections

此项目的硬件配置非常简单。

  1. 将 CC3000 板的 IRQ 引脚连接到 Arduino 板的 3 号引脚。

  2. 将 VBAT 连接到 5 号引脚,将 CS 连接到 10 号引脚。

  3. 将 SPI 引脚连接到 Arduino 板:将 MOSI、MISO 和 CLK 分别连接到 11 号、12 号和 13 号引脚。

  4. Vin 连接到 Arduino 5V,GND 连接到 GND。

现在,让我们连接继电器。

将继电器放在面包板上之后,您就可以开始识别继电器上的两个重要部分:继电器控制线圈部分和 LED 连接开关部分。

  1. 首先,将 Arduino 板的 8 号引脚连接到一个线圈引脚。

  2. 将另一个引脚连接到 Arduino 板的接地。

您还必须将整流二极管(阳极连接到接地引脚)放在线圈引脚上,以便继电器切换时保护电路。

  1. 将 Arduino 板的 +5V 连接到继电器开关的公共引脚。

  2. 最后,将开关的另一引脚(通常是继电器断开时未连接的引脚)连接到与 220 欧姆电阻串联的 LED,并将 LED 的另一边连接到 Arduino 板的接地。

Testing Individual Components

您可以使用以下草图对继电器进行测试 −

const int relay_pin = 8; // Relay pin

void setup() {
   Serial.begin(9600);
   pinMode(relay_pin,OUTPUT);
}

void loop() {
   // Activate relay
   digitalWrite(relay_pin, HIGH);
   // Wait for 1 second
   delay(1000);
   // Deactivate relay
   digitalWrite(relay_pin, LOW);
   // Wait for 1 second
   delay(1000);
}

Code to Note

代码不言自明。您只需将其上传到电路板,继电器就会每秒切换一次状态,LED 会相应地开关。

Adding WiFi Connectivity

现在,让我们使用 CC3000 WiFi 芯片无线控制继电器。此项目的软件基于 TCP 协议。但是,对于此项目,Arduino 板将运行一个小 web 服务器,以便我们可以“侦听”来自计算机的命令。我们首先处理 Arduino 草图,然后我们了解如何编写服务器端代码并创建漂亮界面。

首先,Arduino 草图。这里的目标是连接到您的 WiFi 网络,创建一个 web 服务器,检查是否有传入的 TCP 连接,然后相应地更改继电器状态。

Important Parts of the Code

#include <Adafruit_CC3000.h>
#include <SPI.h>
#include <CC3000_MDNS.h>
#include <Ethernet.h>
#include <aREST.h>

您需要在代码中定义具体配置的内容,即 WiFi 名称和密码,以及 TCP 通信端口(我们在此处使用了 80)。

// WiFi network (change with your settings!)
   #define WLAN_SSID "yourNetwork" // cannot be longer than 32 characters!
   #define WLAN_PASS "yourPassword"
   #define WLAN_SECURITY WLAN_SEC_WPA2 // This can be WLAN_SEC_UNSEC, WLAN_SEC_WEP,
   // WLAN_SEC_WPA or WLAN_SEC_WPA2

// The port to listen for incoming TCP connections
   #define LISTEN_PORT 80

然后我们可以创建 CC3000 实例、服务器和 aREST 实例 −

// Server instance
   Adafruit_CC3000_Server restServer(LISTEN_PORT); // DNS responder instance
   MDNSResponder mdns; // Create aREST instance
   aREST rest = aREST();

现在,在草图的设置(setup())部分,我们可以将 CC3000 芯片连接到网络 −

cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);

计算机如何知道在哪里发送数据?一种方法是运行一次草图,然后获取 CC3000 板的 IP 地址,然后再次修改服务器代码。但是,我们可以做得更好,CC3000 MDNS 库就在此处发挥作用。我们将使用此库为我们的 CC3000 板分配一个固定名称,以便我们可以直接将此名称写入服务器代码中。

这是通过以下代码完成的 −

if (!mdns.begin("arduino", cc3000)) {
   while(1);
}

我们还需要侦听传入连接。

restServer.begin();

接下来,我们将编写草图的 loop() 函数,该函数将持续执行。我们首先必须更新 mDNS 服务器。

mdns.update();

运行在 Arduino 板上的服务器将等待传入连接并处理请求。

Adafruit_CC3000_ClientRef client = restServer.available();
rest.handle(client);

现在,通过 WiFi 测试项目非常容易。确保已用你自己的 WiFi 名称和密码更新了草图,并将草图上传到 Arduino 板。打开 Arduino IDE 串行监视器,并查看电路板的 IP 地址。

让我们假设它类似于 192.168.1.103。

然后,只需转到你最喜欢的网络浏览器并输入以下内容即可:

192.168.1.103/digital/8/1

您应该看到您的继电器自动打开。

Building the Relay Interface

现在,我们将对项目的界面进行编码。这里将有两个部分:包含界面的 HTML 文件和客户端 JavaScript 文件,用于处理界面上的点击。这里的界面基于 aREST.js 项目,该项目旨在从您的计算机轻松控制 WiFi 设备。

让我们首先看看名为 interface.html 的 HTML 文件。第一部分包括导入界面所需的所有库:

<head>
   <meta charset = utf-8 />
   <title> Relay Control </title>
   <link rel = "stylesheet" type = "text/css"
      href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
   <link rel="stylesheet" type = "text/css" href = "style.css">
   <script type = "text/javascript"
      src = "https://code.jquery.com/jquery-2.1.4.min.js"></script>
   <script type = "text/javascript"
      src = "https://cdn.rawgit.com/Foliotek/AjaxQ/master/ajaxq.js"></script>
   <script type = "text/javascript"
      src = "https://cdn.rawgit.com/marcoschwartz/aREST.js/master/aREST.js"></script>
   <script type = "text/javascript"
      src = "script.js"></script>
</head>

然后,我们在界面中定义两个按钮,一个用于打开继电器,另一个用于再次将其关闭。

<div class = 'container'>
   <h1>Relay Control</h1>
   <div class = 'row'>
      <div class = "col-md-1">Relay</div>
      <div class = "col-md-2">
         <button id = 'on' class = 'btn btn-block btn-success'>On</button>
      </div>
      <div class = "col-md-2">
         <button id = 'off' class = 'btn btn-block btn-danger'>On</button>
      </div>
   </div>
</div>

现在,我们还需要一个客户端 JavaScript 文件来处理按钮上的点击。我们还将创建一个设备,将其链接到 Arduino 设备的 mDNS 名称。如果您在 Arduino 代码中更改了该名称,则还需要在此处修改它。

// Create device
var device = new Device("arduino.local");
// Button

$('#on').click(function() {
   device.digitalWrite(8, 1);
});

$('#off').click(function() {
   device.digitalWrite(8, 0);
});

该项目的完整代码可以在 GitHub 存储库中找到。转到界面文件夹,然后只需用你最喜欢的浏览器打开 HTML 文件。您应该在浏览​​器中看到类似的内容:

relay control

尝试单击网络界面上的某个按钮;它应该几乎立即更改继电器状态。

如果你成功了,恭喜!您刚刚构建了一个 Wi-Fi 控制的电灯开关。当然,通过该项目,您可以控制的远不止灯。只需确保继电器支持要控制设备所需的功率即可。