目录

Arduino - 快速指南

Arduino - Overview

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

主要特点是 -

  • Arduino板能够读取来自不同传感器的模拟或数字输入信号,并将其转换为输出,例如激活电机,打开/关闭LED,连接到云以及许多其他操作。

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

  • 与大多数以前的可编程电路板不同,Arduino不需要额外的硬件(称为编程器)来将新代码加载到电路板上。 您只需使用USB线即可。

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

  • 最后,Arduino提供了一个标准的外形,将微控制器的功能分解为更易于访问的包。

板

董事会类型

根据所使用的不同微控制器,可提供各种Arduino板。 但是,所有Arduino板都有一个共同点:它们是通过Arduino IDE编写的。

差异基于输入和输出的数量(可在单个板上使用的传感器,LED和按钮的数量),速度,工作电压,外形尺寸等。某些电路板设计为嵌入式且无编程接口(硬件),您需要单独购买。 有些可以直接从3.7V电池运行,有些则需要至少5V。

以下是可用的不同Arduino板的列表。

Arduino boards based on ATMEGA328 microcontroller

董事会名称 操作伏特 时钟速度 数字i/o 模拟输入 PWM UART 编程接口
Arduino Uno R3 5V16MHz14661USB via ATMega16U2
Arduino Uno R3 SMD 5V16MHz14661USB via ATMega16U2
Red Board5V16MHz14661USB via FTDI
Arduino Pro 3.3v/8 MHz 3.3V8MHz14661FTDI-Compatible Header
Arduino Pro 5V/16MHz 5V16MHz14661FTDI-Compatible Header
Arduino mini 05 5V16MHz14861FTDI-Compatible Header
Arduino Pro mini 3.3v/8mhz 3.3V8MHz14861FTDI-Compatible Header
Arduino Pro mini 5v/16mhz 5V16MHz14861FTDI-Compatible Header
Arduino以太网 5V16MHz14661FTDI-Compatible Header
Arduino Fio 3.3V8MHz14861FTDI-Compatible Header
LilyPad Arduino 328主板 3.3V8MHz14661FTDI-Compatible Header
LilyPad Arduino简单板 3.3V8MHz9450FTDI-Compatible Header

Arduino boards based on ATMEGA32u4 microcontroller

董事会名称 操作伏特 时钟速度 数字i/o 模拟输入 PWM UART 编程接口
Arduino Leonardo 5V16MHz201271Native USB
Pro micro 5V/16MHz 5V16MHz14661Native USB
专业微型3.3V/8MHz 5V16MHz14661Native USB
LilyPad Arduino USB 3.3V8MHz14661Native USB

Arduino boards based on ATMEGA2560 microcontroller

董事会名称 操作伏特 时钟速度 数字i/o 模拟输入 PWM UART 编程接口
Arduino Mega 2560 R3 5V16MHz5416144USB via ATMega16U2B
Mega Pro 3.3V 3.3V8MHz5416144FTDI-Compatible Header
Mega Pro 5V 5V16MHz5416144FTDI-Compatible Header
Mega Pro Mini 3.3V 3.3V8MHz5416144FTDI-Compatible Header

Arduino boards based on AT91SAM3X8E microcontroller

董事会名称 操作伏特 时钟速度 数字i/o 模拟输入 PWM UART 编程接口
Arduino Mega 2560 R3 3.3V84MHz5412124USB native

Arduino - Board Description

在本章中,我们将了解Arduino板上的不同组件。 我们将研究Arduino UNO板,因为它是Arduino板系列中最受欢迎的板。 此外,它是开始使用电子和编码的最佳主板。 有些电路板与下面给出的电路板略有不同,但大多数Arduinos都有大部分这些组件的共同点。

董事会描述
电源USB

Power USB

可以使用计算机上的USB电缆为Arduino板供电。 您只需将USB电缆连接到USB连接(1)即可。

桶杰克

Power (Barrel Jack)

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

电压调节器

Voltage Regulator

电压调节器的功能是控制给予Arduino板的电压并稳定处理器和其他元件使用的DC电压。

晶体振荡器

Crystal Oscillator

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

Arduino重置

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引脚

ICSP pin

大多数情况下,ICSP(12)是AVR,Arduino的微型编程头,包括MOSI,MISO,SCK,RESET,VCC和GND。 它通常被称为SPI(串行外设接口),可以将其视为输出的“扩展”。 实际上,您将输出设备从属于SPI总线的主设备。

电源LED指示灯

Power LED indicator

将Arduino插入电源时,此指示灯应亮起,表示电路板已正确通电。 如果此灯未亮起,则说明连接有问题。

TX和RX LED

TX and RX LEDs

在您的主板上,您将找到两个标签:TX(发送)和RX(接收)。 他们出现在Arduino UNO董事会的两个地方。 首先,在数字引脚0和1处,指示负责串行通信的引脚。 第二,TX和RX led(13)。 发送串行数据时,TX指示灯以不同的速度闪烁。 闪烁的速度取决于电路板使用的波特率。 RX在接收过程中闪烁。

数字I/O.

Digital I/O

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

AREF

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电缆(插头到B插头),您将连接到USB打印机,如下图所示。

USB电缆

如果您使用Arduino Nano,则需要使用A到Mini-B电缆,如下图所示。

迷你电缆

Step 2 − Download Arduino IDE Software.

您可以从Arduino官方网站的下载页面获得不同版本的Arduino IDE。 您必须选择与您的操作系统(Windows,IOS或Linux)兼容的软件。 文件下载完成后,解压缩文件。

每晚打开Arduino 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。

启动Arduino IDE

Step 5 − Open your first project.

软件启动后,您有两种选择 -

  • 创建一个新项目。
  • 打开现有项目示例。

要创建新项目,请选择“文件”→“ New

编辑文件

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

打开项目

在这里,我们只选择一个名为Blink的示例。 它会在一段时间内打开和关闭LED。 您可以从列表中选择任何其他示例。

Step 6 − Select your Arduino board.

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

转到工具→板,然后选择您的板。

选择Board

在这里,我们根据我们的教程选择了Arduino Uno板,但您必须选择与您正在使用的板匹配的名称。

Step 7 − Select your serial port.

选择Arduino板的串行设备。 转到Tools → Serial Port菜单。 这可能是COM3或更高版本(COM1和COM2通常保留用于硬件串行端口)。 要找到答案,你可以断开你的Arduino板并重新打开菜单,消失的条目应该是Arduino板。 重新连接电路板并选择该串行端口。

串行端口

Step 8 − Upload the program to your board.

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

上传程序

A - 用于检查是否存在编译错误。

B - 用于将程序上传到Arduino板。

C - 用于创建新草图的快捷方式。

D - 用于直接打开其中一个示例草图。

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开始。 软件结构包括两个主要功能 -

  • Setup()函数
  • Loop()函数
结构体
Void setup ( ) {
}
  • PURPOSE - 草图开始时调用setup()函数。 使用它来初始化变量,引脚模式,开始使用库等。设置功能仅在每次上电或复位Arduino板后运行一次。

  • INPUT - -

  • OUTPUT - -

  • RETURN - -

Void Loop ( ) {
}
  • PURPOSE - 在创建初始化和设置初始值的setup()函数之后, loop()函数正是其名称所暗示的,并且连续循环,允许程序进行更改和响应。 用它来主动控制Arduino板。

  • INPUT - -

  • OUTPUT - -

  • RETURN - -

Arduino - Data Types

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

下表提供了在Arduino编程期间将使用的所有数据类型。

voidBooleancharUnsigned charbyteintUnsigned intword
longUnsigned longshortfloatdoublearrayString-char arrayString-object

void

void关键字仅在函数声明中使用。 它表示该函数不会向调用它的函数返回任何信息。

例子 (Example)

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

Boolean

布尔值包含两个值之一,true或false。 每个布尔变量占用一个字节的内存。

例子 (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图表中看到特定的编码。 这意味着可以对字符进行算术运算,其中使用字符的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字符表

无符号的字符

Unsigned char是一种占用一个字节内存的无符号数据类型。 unsigned 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)。

每个板块的大小因板而异。 例如,在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

无符号整数

无符号整数(无符号整数)与存储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

无符号长

无符号长变量是数字存储的扩展大小变量,存储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

short是16位数据类型。 在所有Arduinos(基于ATMega和ARM)上,short存储一个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上,双精度具有8字节(64位)精度。

例子 (Example)

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

Arduino - Variables & Constants

在我们开始解释变量类型之前,我们需要确定一个非常重要的主题,您完全理解称为variable scope

什么是可变范围?

Arduino使用的C编程语言中的变量有一个名为scope的属性。 范围是程序的一个区域,有三个位置可以声明变量。 他们是 -

  • 在函数或块内部,称为local variables
  • 在函数参数的定义中,称为formal parameters
  • 在所有函数之外,称为global variables

局部变量

在函数或块内声明的变量是局部变量。 它们只能由该函数或代码块中的语句使用。 不知道局部变量是否在其自身之外起作用。 以下是使用局部变量的示例 -

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

全局变量

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

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

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

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语言内置运算符丰富,并提供以下类型的运算符 -

  • 算术运算符
  • 比较运算符
  • 布尔运算符
  • 按位运算符
  • 复合算子

算术运算符 (Arithmetic Operators)

假设变量A保持10,变量B保持20然后 -

显示示例

运算符名称 运算符简单 描述
赋值运算符 = 将值存储在等号左侧的变量中等号的右侧。 A = B.
加法+ 添加两个操作数 A + B将给出30
减法- 从第一个减去第二个操作数 A - B将给-10
乘法* 将两个操作数相乘 A * B将给出200
division/Divide numerator by denominator B/A会给2
modulo% 模数运算符和整数除法后的余数 B%A将给出0

比较运算符 (Comparison Operators)

假设变量A保持10,变量B保持20然后 -

显示示例

运算符名称 运算符简单 描述
equal to== 检查两个操作数的值是否相等,如果是,则条件变为真。 (A == B)不是真的
not equal to != 检查两个操作数的值是否相等,如果值不相等则条件变为真。 (A!= B)是真的
less than< 检查左操作数的值是否小于右操作数的值,如果是,则条件变为真。 (A < B) 为真
greater than> 检查左操作数的值是否大于右操作数的值,如果是,则条件变为真。 (A> B)不是真的
小于或等于 <= 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件变为真。 (A <= B)是真的
大于或等于 >= 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件变为真。 (A> = B)不是真的

布尔运算符

假设变量A保持10,变量B保持20然后 -

显示示例

运算符名称 运算符简单 描述
and&& 称为逻辑AND运算符。 如果两个操作数都不为零,则条件变为真。 (A && B)是真的
or|| 称为逻辑OR运算符。 如果两个操作数中的任何一个非零,则条件变为真。 (A || B)是真的
not! 称为逻辑非运算符。 用于反转其操作数的逻辑状态。 如果条件为真,则Logical NOT运算符将为false。 !(A && B)是假的

按位运算符 (Bitwise Operators)

假设变量A保持60,变量B保持13然后 -

显示示例

运算符名称 运算符简单 描述
and& 如果二进制AND运算符存在于两个操作数中,则它会将结果复制到结果中。 (A&B)将给出12,即0000 1100
or| 二进制OR运算符如果存在于任一操作数中,则复制一位 (A | B)将给出61,即0011 1101
xor^ 二进制异或运算符如果在一个操作数中设置但不在两个操作数中设置,则复制该位。 (A ^ B)将给出49,即0011 0001
not~ 二元一元补语运算符是一元的,具有“翻转”位的效果。 (~A)将给出-60,即1100 0011
左移 << 二进制左移运算符。 左操作数值向左移动右操作数指定的位数。 A << 2将给出240,即1111 0000
右移 >> 二进制右移运算符。 左操作数值向右移动右操作数指定的位数。 A >> 2将给出15,即0000 1111

复合算子

假设变量A保持10,变量B保持20然后 -

显示示例

运算符名称 运算符简单 描述
increment++ 递增运算符,将整数值增加1 A ++将给出11
decrement-- 递减运算符,将整数值减一 A-- will give 9
compound addition+= 添加AND赋值运算符。 它将右操作数添加到左操作数并将结果分配给左操作数 B + = A等于B = B + A.
复合减法 -= 减去AND赋值运算符。 它从左操作数中减去右操作数,并将结果赋给左操作数 B - = A相当于B = B - A.
复合乘法 *= 乘以AND赋值运算符。 它将右操作数与左操作数相乘,并将结果赋给左操作数 B * = A等于B = B * A.
compound division /= 除法和赋值运算符。 它将左操作数与右操作数分开,并将结果赋给左操作数 B/= A相当于B = B/A.
复合模数 %= 模数和赋值运算符。 它使用两个操作数来获取模数,并将结果赋给左操作数 B%= A等于B = B%A
按位复合或 |= 按位包含OR和赋值运算符 A | = 2与A = A |相同 2
按位复合和 &= 按位AND赋值运算符 A&= 2与A = A和2相同

Arduino - Control Statements

决策结构要求程序员指定一个或多个要由程序评估或测试的条件。 如果条件被确定为真,则它应与要执行的一个或多个语句一起,并且如果确定条件为假,则应该可选地执行其他语句。

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

做决定

控制语句是源代码中控制程序执行流程的元素。 他们是 -

S.NO. 控制声明和描述
1

If statement

它在括号和语句或语句块中使用表达式。 如果表达式为true,则执行语句或语句块,否则将跳过这些语句。

2

If …else statement

if语句后面可以跟一个可选的else语句,该语句在表达式为false时执行。

3

If…else if …else statement

if语句之后可以跟一个可选的else if...else语句,这对于使用单个if ... else if语句测试各种条件非常有用。

4

switch case statement

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

5

条件运算符? :

条件运算符? :是C中唯一的三元运算符。

Arduino - Loops

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

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

循环架构

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

S.NO. 循环和描述
1

循环

while循环将连续循环,并且无限循环,直到括号内的表达式()变为false。 有些东西必须改变测试变量,否则while循环永远不会退出。

2

做... while循环

do…while循环类似于while循环。 在while循环中,循环继续条件在循环开始之前进行测试,然后执行循环体。

3

for循环

for loop执行语句预定次数。 循环的控制表达式在for循环括号内完全初始化,测试和操作。

4

嵌套循环

C语言允许您在另一个循环中使用一个循环。 以下示例说明了该概念。

5

无限循环

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

Arduino - 函数

函数允许在代码段中构造程序以执行单个任务。 创建函数的典型情况是需要在程序中多次执行相同的操作。

将代码片段标准化为函数有几个优点 -

  • 函数可以帮助程序员保持井井有条。 通常这有助于概念化程序。

  • 函数将一个动作编码在一个地方,这样只需要考虑和调试一次该函数。

  • 如果需要更改代码,这也减少了修改错误的机会。

  • 函数使整个草图更小,更紧凑,因为代码段可以重复使用多次。

  • 通过使代码模块化,可以更容易地在其他程序中重用代码,并且使用函数通常会使代码更具可读性。

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

定义函数的最常用语法是 -

功能

功能声明

函数在循环函数之上或之下的任何其他函数之外声明。

我们可以用两种不同的方式声明函数 -

第一种方法是将函数的一部分称为a function prototype ,在循环函数之上,其中包括 -

  • 函数返回类型
  • 功能名称
  • 函数参数类型,无需编写参数名称

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

以下示例显示了使用第一种方法演示函数声明。

例子 (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
}

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

  • 函数返回类型
  • 功能名称
  • 函数参数类型,这里必须添加参数名称
  • 函数体(调用函数时执行函数内的语句)

以下示例演示使用第二种方法声明函数。

例子 (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编程中有两种类型的字符串 -

  • 字符数组,与C编程中使用的字符串相同。
  • Arduino String,它允许我们在草图中使用字符串对象。

在本章中,我们将学习字符串,对象以及Arduino草图中字符串的使用。 在本章结束时,您将了解在草图中使用哪种类型的字符串。

字符串字符数组

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

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

字符串字符数组示例

此示例将说明如何创建字符串并将其打印到串行监视器窗口。

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 Serial Monitor窗口并传递字符串的名称。

同样的例子可以用更方便的方式编写,如下所示 -

Example

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

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

操作字符串数组

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

例子 (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

草图以下列方式工作。

创建和打印字符串

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

缩短字符串

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

打印字符串时,所有字符都打印到新的null终止零。 其他角色不会消失; 它们仍然存在于内存中,字符串数组仍然是相同的大小。 唯一的区别是任何使用字符串的函数只能看到第一个空终止符的字符串。

更改字符串中的单词

最后,草图将“蛋糕”改为“茶”(3)。 它首先必须使用空格替换类似[13]的null终止符,以便将字符串恢复为最初创建的格式。

新角色用“茶”一词覆盖“蛋糕”一词的“cak”。 这是通过覆盖单个字符来完成的。 “cake”的“e”被替换为新的null终止字符。 结果是字符串实际上以两个空字符结束,原始字符串在字符串的末尾,而新的字符替换“cake”中的“e”。 打印新字符串时没有区别,因为打印字符串的函数在遇到第一个空终止符时会停止打印字符串字符。

操作字符串数组的函数

前面的草图通过访问字符串中的单个字符以手动方式操作字符串。 为了更容易操作字符串数组,您可以编写自己的函数来执行此操作,或者使用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

草图以下列方式工作。

打印字符串

新创建的字符串将打印到“串行监视器”窗口,如先前草图中所做。

获取字符串的长度

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

该字符串包含17个字符,因此我们在Serial Monitor窗口中看到17个字符。

获取数组的长度

运算符sizeof()用于获取包含字符串的数组的长度。 长度包括空终止符,因此长度比字符串的长度多一个。

sizeof()看起来像一个函数,但从技术上讲是一个操作符。 它不是C字符串库的一部分,但在草图中用于显示数组大小和字符串大小(或字符串长度)之间的差异。

复制字符串

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

字符串被复制到数组中,以便我们在数组中有一些额外的空间用于草图的下一部分,即在字符串的末尾添加一个字符串。

将字符串附加到字符串(连接)

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

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

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

数组边界

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

如果数组太小并且我们试图将比该数组大的字符串复制到该数组,则该字符串将被复制到数组的末尾。 超出数组末尾的内存可能包含草图中使用的其他重要数据,然后我们的字符串将覆盖这些数据。 如果超出字符串末尾的内存超出,则可能会使草图崩溃或导致意外行为。

Arduino - String Object

Arduino编程中使用的第二种字符串是String Object。

什么是对象?

对象是包含数据和函数的构造。 String对象可以像变量一样创建并分配值或字符串。 String对象包含函数(在面向对象编程(OOP)中称为“方法”),它们对String对象中包含的字符串数据进行操作。

下面的草图和说明将清楚说明对象是什么以及如何使用String对象。

例子 (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的String对象,并为其赋予值“This is my string。”。

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

int my_var = 102;

草图以下列方式工作。

打印字符串

该字符串可以像字符串数组一样打印到Serial Monitor窗口。

将字符串转换为大写字母

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

my_str.toUpperCase();

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

覆盖一个字符串

赋值运算符用于将新字符串分配给my_str对象,以替换旧字符串

my_str = "My new string." ;

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

替换字符串中的Word

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

获取字符串的长度

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

何时使用字符串对象

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

使用String对象的主要缺点是它使用大量内存并且可以快速耗尽Arduinos RAM内存,这可能导致Arduino挂起,崩溃或意外行为。 如果Arduino上的草图很小并且限制了对象的使用,那么应该没有问题。

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

您需要确保不使用字符串数组写入数组边界的末尾。 String对象没有这个问题,只要有足够的内存供它操作,它将为你处理字符串边界。 String对象可以尝试写入内存不足时不存在的内存,但永远不会写入它正在操作的字符串的末尾。

使用字符串的地方

在本章中,我们研究了字符串,它们在内存中的行为以及它们的操作。

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

Arduino - Time

Arduino提供四种不同的时间操作功能。 他们是 -

S.No. 功能说明
1

delay () function

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

2

delayMicroseconds () function

delayMicroseconds()函数接受单个整数(或数字)参数。 一毫秒内有一千微秒,一秒钟就有一百万微秒。

3

millis () function

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

4

micros () function

micros()函数返回从那时开始的微秒数,Arduino板开始运行当前程序。 这个数字溢出,即大约70分钟后回到零。

Arduino - Arrays

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

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

因此,数组C的元素是C [0](发音为“C sub zero”),C [1],C [2]等。 数组C中的最高下标是10,比数组(11)中的元素数少1。 数组名称遵循与其他变量名称相同的约定。

数组元素

下标必须是整数或整数表达式(使用任何整数类型)。 如果程序使用表达式作为下标,则程序将计算表达式以确定下标。 例如,如果我们假设变量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

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

示例使用数组

本节提供了许多演示如何声明,初始化和操作数组的示例。

示例1:声明一个数组并使用循环初始化数组的元素

该程序声明了一个10元素的整数数组n 。 a-b行使用For语句将数组元素初始化为零。 与其他自动变量一样,自动数组不会隐式初始化为零。 第一个输出语句(第c行)显示在后续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 - 它将产生以下结果 -

None
元件

0

1

2

3

4

5

6

7

8

9

0

0

0

0

0

0

0

0

0

0

示例2:使用初始化列表初始化声明中的数组

数组的元素也可以在数组声明中初始化,方法是在数组名称后面加上等号和大括号分隔的逗号分隔的初始化列表。 该程序使用初始化列表初始化具有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 - 它将产生以下结果 -

None
元件

0

1

2

3

4

5

6

7

8

9

32

27

64

18

95

14

90

70

60

37

示例3:对数组元素求和

通常,数组的元素表示要在计算中使用的一系列值。 例如,如果数组的元素代表考试成绩,教授可能希望总计数组的元素并使用该总和来计算考试的课程平均值。 程序对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. 概念与描述
1 将数组传递给函数

要将数组参数传递给函数,请指定不带任何括号的数组名称。

2 多维数组

具有两个维度(即,下标)的数组通常表示由以行和列排列的信息组成的值表。

Arduino - I/O 函数

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

引脚配置为INPUT

默认情况下,Arduino引脚被配置为输入,因此当您将它们用作输入时,不需要使用pinMode()显式声明它们作为输入。 以这种方式配置的引脚被称为处于高阻抗状态。 输入引脚对它们采样的电路提出极小的要求,相当于引脚前面100兆欧的串联电阻。

这意味着将输入引脚从一种状态切换到另一种状态所需的电流非常小。 这使得引脚可用于实现电容式触摸传感器或将LED读取为光电二极管等任务。

引脚配置为pinMode(引脚,INPUT),没有连接到它们,或连接到它们没有连接到其他电路的导线,报告看似引脚状态的随机变化,从环境中拾取电噪声,或电容耦合状态附近的一针。

Pull-up Resistors

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

使用带引脚的内置上拉电阻配置为输入

Atmega芯片内置了20,000个上拉电阻,可通过软件访问。 通过将pinMode()设置为INPUT_PULLUP来访问这些内置上拉电阻。 这有效地反转了INPUT模式的行为,其中HIGH表示传感器处于OFF状态,LOW表示传感器处于ON状态。 该上拉电阻的值取决于所使用的微控制器。 在大多数基于AVR的电路板上,该值保证在20kΩ和50kΩ之间。 在Arduino Due上,它介于50kΩ和150kΩ之间。 有关确切值,请参阅电路板上微控制器的数据表。

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

控制引脚是高电平还是低电平的相同寄存器(内部芯片存储器位置)控制上拉电阻。 因此,当引脚处于INPUT模式时,配置为使上拉电阻导通的引脚将使引脚配置为高电平,如果引脚随后通过pinMode()切换到OUTPUT模式。 这也适用于另一个方向,如果切换到带有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

引脚配置为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);
}
  • pin - 要设置其模式的引脚编号

  • 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,则其电压将设置为相应的值:5V(或3.3V板上3.3V)用于高电平,0V(接地)用于低电平。 如果引脚配置为INPUT,则digitalWrite()将使能(HIGH)或禁用(LOW)输入引脚上的内部上拉。 建议将pinMode()设置为INPUT_PULLUP以使能内部上拉电阻。

如果未将pinMode()设置为OUTPUT,并将LED连接到引脚,则在调用digitalWrite(HIGH)时,LED可能显得暗淡。 如果没有明确设置pinMode(),digitalWrite()将启用内部上拉电阻,该电阻就像一个大电流限制电阻。

digitalWrite() Function Syntax

Void loop() {
   digitalWrite (pin ,value);
}
  • pin - 要设置其模式的引脚编号

  • 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伏之间的电压。 例如,如果引脚号0上施加2.5 V电压,则analogRead(0)返回512。

analogRead() function Syntax

analogRead(pin);
  • 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

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

  • DEFAULT - 默认模拟参考电压为5伏(在5V Arduino电路板上)或3.3伏电压(在3.3V Arduino电路板上)

  • INTERNAL - 内置参考电压,ATmega168或ATmega328等于1.1伏,ATmega8等电压为2.56伏(Arduino Mega不提供)

  • INTERNAL1V1 - 内置1.1V基准电压源(仅限Arduino Mega)

  • INTERNAL2V56 - 内置2.56V基准电压源(仅限Arduino Mega)

  • EXTERNAL - 施加到AREF引脚的电压(仅0至5V)用作参考

analogReference() Function Syntax

analogReference (type);

type - 可以使用任何类型的跟随(DEFAULT,INTERNAL,INTERNAL1V1,INTERNAL2V56,EXTERNAL)

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

微控制器进行

或者,您可以通过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 - 字符函数

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

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

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

下表总结了字符处理库的功能。 使用字符处理库中的函数时,请包含《cctype》标头。

S.No. 原型和描述
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'),则返回1

(''),换页('\ f'),回车('\ r'),水平制表符('\ t')或垂直制表符('\ v') - 否则为0。

8

int iscntrl( int c )

如果c是控制字符,则返回1,例如换行符('\ n'),换页符('\ f'),回车符('\ r'),水平制表符('\ t'),垂直制表符('\v'),警告('\ a')或退格('\ b') - 否则为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确定其参数是大写字母(AZ)还是小写字母(a-z)。 函数isalnum确定其参数是大写,小写字母还是数字。 函数isxdigit确定其参数是否为十六进制数字(A-F,a-f,0-9)。

例子1 (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");
   <!--Serial.print (" hexadecimal digit\r" );-->
}
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”还是字符串“不是a”应该在输出中打印每个测试的字符。 例如,行a表示如果'8'是数字 - 即,如果isdigit返回真(非零)值 - 则打印字符串“8是a”。 如果'8'不是数字(即,如果isdigit返回0),则打印字符串“8不是a”。

例子2 (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

例子3 (Example 3)

以下示例演示了函数isspace, iscntrl, ispunct, isprintisgraph

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

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

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

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

  • 函数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宏 (Library Macros)

以下是头部math.h中定义的宏 -

Library 函数

标题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 - 三角函数 (Arduino - Trigonometric Functions)

您需要使用三角函数,就像计算移动物体的距离或角速度一样。 Arduino提供传统的三角函数(sin,cos,tan,asin,acos,atan),可以通过编写原型进行总结。 Math.h包含三角函数的原型。

三角精确语法

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板。

重要特征 -

  • 它有54个数字输入/输出引脚(其中12个可用作PWM输出)
  • 12个模拟输入
  • 4个UART(硬件串口)
  • 84 MHz时钟,USB OTG连接
  • 2个DAC(数字到模拟),2个TWI,一个电源插孔,一个SPI接头,一个JTAG接头
  • 重置按钮和删除按钮
Arduino到期

Arduino董事会的特征

工作电压 CPU速度 模拟输入/输出 数字IO/PWM EEPROM [KB] SRAM [KB] 闪光[KB] USB UART
3.3 Volt 84 Mhz 12/254/12-965122 micro4

沟通(Communication)

  • 4个硬件UART
  • 2 I2C
  • 1 CAN接口(汽车通信协议)
  • 1 SPI
  • 1接口JTAG(10针)
  • 1个USB主机(和Leonardo一样)
  • 1编程端口

与大多数Arduino板不同,Arduino Due板的电压为3.3V。 I/O引脚可承受的最大电压为3.3V。 向任何I/O引脚施加高于3.3V的电压可能会损坏电路板。

该板包含支持微控制器所需的一切。 您只需使用micro-USB线将其连接到计算机,或使用AC-DC适配器或电池为其启动即可。 Due与所有工作在3.3V的Arduino屏蔽兼容。

Arduino Zero

Zero是由UNO建立的简单而强大的32位平台扩展。 Zero board通过提供更高的性能,为设备提供各种项目机会来扩展系列,并且是学习32位应用程序开发的理想教育工具。

重要特征是 -

  • Zero应用程序涵盖从智能物联网设备,可穿戴技术,高科技自动化到疯狂机器人。

  • 该主板采用Atmel的SAMD21 MCU,采用32位ARMCortex®M0+内核。

  • 其最重要的功能之一是Atmel的嵌入式调试器(EDBG),它提供完整的调试接口,无需额外的硬件,大大提高了软件调试的易用性。

  • EDBG还支持可用于设备和引导加载程序编程的虚拟COM端口。

Arduino Zero

Arduino Zero板的特性

工作电压 CPU速度 模拟输入/输出 数字IO/PWM EEPROM [KB] SRAM [KB] 闪光[KB] USB UART
3.3 Volt 48 Mhz 6/114/10-322562 micro2

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

该板包含支持微控制器所需的一切。 您只需使用micro-USB线将其连接到计算机,或使用AC-DC适配器或电池为其启动即可。 Zero与所有工作在3.3V的屏蔽兼容。

Arduino - Pulse Width Modulation

脉冲宽度调制或PWM是用于改变脉冲序列中脉冲宽度的常用技术。 PWM具有许多应用,例如控制伺服和速度控制器,限制电机和LED的有效功率。

PWM的基本原理

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

PWM

有各种与PWM相关的术语 -

  • On-Time - 时间信号持续时间很长。

  • Off-Time - 时间信号持续时间很短。

  • Period - 表示为PWM信号的导通时间和关断时间之和。

  • Duty Cycle - 表示为PWM信号周期内保持的时间信号百分比。

Period

如图所示,T on表示导通时间,T off表示信号的关断时间。 期间是开启和关闭时间的总和,计算方法如下式所示 -

$$ T_ {total} = T_ {on} + T_ {off} $$

占空比

占空比计算为该时间段的接通时间。 使用上面计算的时间,工作周期计算如下 -

$$ D =\frac {T_ {on}} {T_ {on} + T_ {off}} =\frac {T_ {on}} {T_ {total}} $$

analogWrite() Function

analogWrite()函数将模拟值(PWM波)写入引脚。 它可用于点亮不同亮度的LED或以各种速度驱动电机。 在调用analogWrite()函数之后,该引脚将产生指定占空比的稳定方波,直到下一次调用analogWrite()或在同一引脚上调用digitalRead()或digitalWrite()。 大多数引脚上的PWM信号频率约为490 Hz。 在Uno和类似的板上,引脚5和6的频率约为980Hz。 莱昂纳多的第3和第11针也以980赫兹的速度运行。

在大多数Arduino板(带有ATmega168或ATmega328的板)上,此功能适用于引脚3,5,6,9,10和11.在Arduino Mega上,它适用于引脚2 - 13和44 - 46.较旧的Arduino具有ATmega8的电路板仅支持引脚9,10和11上的analogWrite()

UNO PWM引脚

Arduino Due支持引脚2至13上的analogWrite() ,以及引脚DAC0和DAC1。 与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随机数函数。 我们有两个功能 -

  • randomSeed(seed)
  • random()

randomSeed (seed)

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

例子 (Example)

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

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

一点只是一个二进制数字。

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

  • 类似于十进制数系统,其中数字的数字不具有相同的值,位的“重要性”取决于它在二进制数中的位置。 例如,十进制数666中的数字相同,但具有不同的值。

位

Bytes

一个字节由8位组成。

  • 如果位是数字,则字节表示数字是合乎逻辑的。

  • 可以对它们执行所有数学运算。

  • 字节中的数字也不具有相同的含义。

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

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

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

Arduino - Interrupts

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

假设你坐在家里和某人聊天。 电话突然响了起来。 你停止聊天,拿起电话与来电者通话。 当您完成电话交谈后,您会在电话响起之前重新与该人聊天。

同样,您可以将主要例程视为与某人聊天,电话铃声会导致您停止聊天。 中断服务程序是通过电话通话的过程。 电话会话结束后,您将回到主要的聊天程序。 此示例准确说明了中断如何导致处理器执行操作。

主程序正在运行并在电路中执行某些功能。 但是,当发生中断时,主程序停止,同时执行另一个例程。 当该例程完成时,处理器再次返回主程序。

打断

重要特征

以下是有关中断的一些重要功能 -

  • 中断可以来自各种来源。 在这种情况下,我们使用的硬件中断由其中一个数字引脚上的状态更改触发。

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

  • Arduino Mega有六个硬件中断,包括引脚21,20,19和18上的附加中断(“中断2”到“中断5”)。

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

  • 您可以定义例程并在上升沿,下降沿或两者中指定条件。 在这些特定条件下,中断将得到服务。

  • 每次在输入引脚上发生事件时,都可以自动执行该功能。

中断的类型

有两种类型的中断 -

  • Hardware Interrupts - 它们响应外部事件而发生,例如外部中断引脚变为高电平或低电平。

  • Software Interrupts - 它们响应软件发送的指令而发生。 “Arduino语言”支持的唯一中断类型是attachInterrupt()函数。

在Arduino中使用中断

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

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

attachInterrupt语句语法

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.

以下三个常量被预定义为有效值 -

  • LOW ,只要引脚为LOW就触发中断。

  • 当引脚改变值时, CHANGE触发中断。

  • 每当引脚从高电平变为低电平时下降。

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

已经定义了数百种通信协议来实现这种数据交换。 每个协议可以分为两类:并行或串行。

并行通信

通过输入/输出端口将Arduino与外设之间的并联连接是短距离达数米的理想解决方案。 但是,在其他情况下,当需要在两个设备之间建立更长距离的通信时,不可能使用并行连接。 并行接口同时传输多个位。 它们通常需要数据总线 - 通过八,十六或更多线路传输。 数据以1和0的巨大波浪传输。

并行通信

并行通信的优点和缺点

并行通信当然有其优点。 它比串行,简单,相对容易实现更快。 但是,它需要许多输入/输出(I/O)端口和线路。 如果您曾经不得不将项目从基本的Arduino Uno移动到Mega,您就会知道微处理器上的I/O线可能很少而且很少。 因此,我们更喜欢串行通信,牺牲引脚空间的潜在速度。

串行通信模块

今天,大多数Arduino板都是用几种不同的串行通信系统构建的标准设备。

使用以下哪些系统取决于以下因素 -

  • 微控制器有多少设备与之交换数据?
  • 数据交换的速度有多快?
  • 这些设备之间的距离是多少?
  • 是否有必要同时发送和接收数据?

有关串行通信的最重要的事情之一是Protocol ,应严格遵守。 它是一组规则,必须应用这些规则,以便设备可以正确地解释它们相互交换的数据。 幸运的是,Arduino会自动处理这个问题,因此程序员/用户的工作简化为简单的写入(要发送的数据)和读取(接收的数据)。

串行通信的类型

串行通信可进一步分类为 -

  • Synchronous - Synchronous设备使用相同的时钟,它们的时序彼此同步。

  • Asynchronous - Asynchronous设备有自己的时钟,由前一个状态的输出触发。

很容易找出设备是否同步。 如果为所有连接的设备提供相同的时钟,则它们是同步的。 如果没有时钟线,则它是异步的。

例如,UART(通用异步接收器发送器)模块是异步的。

异步串行协议有许多内置规则。 这些规则只不过是有助于确保稳健且无差错的数据传输的机制。 我们为避开外部时钟信号而采用的这些机制是 -

  • 同步位
  • 数据位
  • 奇偶校验位
  • 波特率

同步位

同步位是与每个数据包一起传送的两个或三个特殊位。 它们是起始位和停止位。 与它们的名称相反,这些位分别标记数​​据包的开头和结尾。

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

起始位始终由从1到0的空闲数据线指示,而停止位将通过将该行保持为1而转换回空闲状态。

同步位

数据位

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

平价位

用户可以选择是否应该存在奇偶校验位,如果是,则奇偶校验应该是奇数还是偶数。 如果数据位中的1的数量是偶数,则奇偶校验位为0。 奇怪的平价恰恰相反。

波特率

术语波特率用于表示每秒传输的位数[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的右上角。

在串行监视器的顶部框中键入任何内容,然后按键盘上的send或enter键。 这将向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 /秒(标准模式)或10 Kb /秒(慢波特率模式)。 最近出现了波特率为3.4 Mb/sec的系统。 通过I2C总线通信的设备之间的距离限制在几米。

I2C

板上I2C引脚

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

以下是不同Arduino板的引脚 -

  • Uno,Pro Mini A4(SDA),A5(SCL)
  • 到期20(SDA),21(SCL)
  • 莱昂纳多,云2(SDA),3(SCL)

Arduino I2C

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

  • 主发送器/从接收器
  • 主接收器/从发送器

主发送器/从接收器

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

主发射器

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

  • Wire.begin(address) - 在我们的例子中,地址是7位从地址,因为未指定主设备,它将作为主设备加入总线。

  • Wire.beginTransmission(address) - 使用给定地址开始传输到I2C从设备。

  • Wire.write(value) - 用于从主设备传输到从设备的队列字节(中间调用beginTransmission()和endTransmission())。

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

奴隶接收者

使用以下功能 -

  • Wire.begin(address) - 地址是7位从机地址。

  • Wire.onReceive(received data handler) - 从设备从主设备接收数据时要调用的函数。

  • 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被编程为请求,然后读取从唯一寻址的Slave 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); 
}

奴隶发射器

使用以下功能。

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通信系统。

板SPI引脚

SPI使用以下四条线 -

  • SCK - 这是由主机驱动的串行时钟。

  • MOSI - 这是主机驱动的主输出/从机输入。

  • MISO - 这是主机驱动的主输入/从机输出。

  • SS - 这是从选择线。

使用以下功能。 你必须包括SPI.h.

  • SPI.begin() - 通过将SCK,MOSI和SS设置为输出,将SCK和MOSI拉低,SS为高电平来初始化SPI总线。

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

  • Divider - 可以是(SPI_CLOCK_DIV2,SPI_CLOCK_DIV4,SPI_CLOCK_DIV8,SPI_CLOCK_DIV16,SPI_CLOCK_DIV32,SPI_CLOCK_DIV64,SPI_CLOCK_DIV128)。

  • SPI.transfer(val) - SPI传输基于同时发送和接收:接收的数据在receivedVal中返回。

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

我们在SPI中有四种操作模式如下 -

  • Mode 0 (the default) - 时钟通常为低电平(CPOL = 0),数据在从低电平到高电平(前沿)(CPHA = 0)的转换时采样。

  • Mode 1 - 时钟通常为低电平(CPOL = 0),数据在从高电平到低电平(后沿)(CPHA = 1)的转换中采样。

  • Mode 2 - 时钟通常为高电平(CPOL = 1),数据在从高电平到低电平(前沿)(CPHA = 0)的转换中进行采样。

  • Mode 3 - 时钟通常为高(CPOL = 1),数据在从低到高(后沿)(CPHA = 1)的转换中采样。

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

现在,我们将两个Arduino UNO板连接在一起; 一个作为主人,另一个作为奴隶。

  • (SS) : pin 10
  • (MOSI) : pin 11
  • (MISO) : pin 12
  • (SCK) : pin 13

地面很常见。 以下是两块板之间连接的图示 -

连接板

让我们看一下SPI作为Master和SPI作为Slave的例子。

SPI作为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作为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 × Breadboard
  • 1×Arduino Uno R3
  • 1×LED
  • 1×330Ω电阻器
  • 2 × Jumper

过程 (Procedure)

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

面包板

Note - 要找出LED的极性,请仔细查看。 两个腿中较短的一个朝向灯泡的平坦边缘指示负端子。

LED

像电阻器这样的元件需要将它们的端子弯成90°角,以便正确地安装面包板插座。 您也可以缩短端子。

电阻器

草图 (Sketch)

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

草图

Arduino代码 (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它是INPUT还是OUTPUT。 我们使用一个名为pinMode()的内置“函数”来执行此操作。

digitalWrite(2, HIGH) - 当您使用引脚作为OUTPUT时,您可以将其命令为HIGH(输出5 V)或LOW(输出0 V)。

结果 (Result)

您应该看到LED打开和关闭。 如果未看到所需的输出,请确保已正确组装电路,并验证并将代码上载到电路板。

Arduino - Fading LED

此示例演示了如何使用analogWrite()函数淡化LED。 AnalogWrite使用脉冲宽度调制(PWM),在打开和关闭之间以不同的比率非常快速地打开和关闭数字引脚,以产生衰落效果。

组件的要求 (Components Required)

您将需要以下组件 -

  • 1 × Breadboard
  • 1×Arduino Uno R3
  • 1×LED
  • 1×330Ω电阻器
  • 2 × Jumper

过程 (Procedure)

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

面包板上的组件

Note - 要找出LED的极性,请仔细查看。 两个腿中较短的一个朝向灯泡的平坦边缘指示负端子。

LED

像电阻器这样的元件需要将它们的端子弯成90°角,以便正确地安装面包板插座。 您也可以缩短端子。

电阻器

草图 (Sketch)

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

草图

Arduino代码 (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 × Breadboard
  • 1×Arduino Uno R3
  • 1×5K可变电阻(电位器)
  • 2 × Jumper

过程 (Procedure)

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

模拟面包板

电位器(Potentiometer)

电位计(或电位器)是一种简单的机电传感器。 它将来自输入运算符的旋转或线性运动转换为电阻变化。 这种变化是(或可以)用于控制从高保真音响系统的音量到巨大的集装箱船的方向。

我们所知道的锅最初被称为变阻器(一种可变线绕电阻器)。 各种可用的盆现在非常惊人,并且初学者(特别是)可能很难确定哪种类型适合于给定的任务。 一些不同的罐类型,可以全部用于相同的任务,使工作更难。

电位器

左侧的图像显示了锅的标准示意符号。 右边的图像是电位计。

草图 (Sketch)

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

草图

Arduino代码 (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更改为与电压对应的范围,引脚正在读取,您需要创建另一个变量,浮点数并进行一些计算。 要缩放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中的串行监视器。

串行监视器

结果 (Result)

您将看到稳定的数字流,范围从0.0到5.0。 当你转动电位器时,数值会改变,对应于引脚A0的电压。

Arduino - LED Bar Graph

此示例显示如何读取模拟引脚0处的模拟输入,将analogRead()中的值转换为电压,并将其打印到Arduino软件(IDE)的串行监视器。

组件的要求 (Components Required)

您将需要以下组件 -

  • 1 × Breadboard
  • 1×Arduino Uno R3
  • 1×5k欧姆可变电阻(电位器)
  • 2 × Jumper
  • 8×LED或您可以使用(LED条形图显示如下图所示)

过程 (Procedure)

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

酒吧面包板

连接到酒吧面包板

草图 (Sketch)

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

草图

10段LED条形图

LED条形图

这些10段条形图LED具有许多用途。 凭借紧凑的外形,简单的连接,它们易于原型或成品。 基本上,它们是10个单独的蓝色LED,每个LED都装在一起,每个LED都有一个独立的阳极和阴极连接。

它们还有黄色,红色和绿色可供选择。

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

Arduino代码 (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

草图的工作方式如下:首先,您阅读输入。 将输入值映射到输出范围,在本例中为10个LED。 然后设置for-loop以迭代输出。 如果系列中的输出数字低于映射的输入范围,则将其打开。 如果没有,请将其关闭。

结果 (Result)

当模拟读数值增加时,您会看到LED逐一亮起,当读数减小时,LED逐一关闭。

Arduino - Keyboard Logout

当ARDUINO UNO上的引脚2接地时,此示例使用键盘库将您从计算机上的用户会话中注销。 草图同时按两个或三个键的顺序模拟按键,并在短暂延迟后释放它们。

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

组件的要求 (Components Required)

您将需要以下组件 -

  • 1 × Breadboard
  • 1×Arduino Leonardo,Micro或Due board
  • 1×按钮
  • 1 × Jumper

过程 (Procedure)

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

键盘面包板

草图 (Sketch)

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

对于此示例,您需要使用Arduino IDE 1.6.7

草图

Note - 您必须在Arduino库文件中包含键盘库。 使用名称库(突出显示)将键盘库文件复制并粘贴到文件中,如以下屏幕截图所示。

Arduino库文件

Arduino代码 (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

在将程序上载到电路板之前,请确保将当前使用的正确OS分配给平台变量。

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

结果 (Result)

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

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

  • Windows ,CTRL-ALT-DEL后跟ALT-l

  • Ubuntu ,CTRL-ALT-DEL和ENTER

  • OSX ,CMD-SHIFT-q

Arduino - Keyboard Message

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

Warning - 使用Keyboard.print()命令时,Arduino将接管计算机的键盘。 为确保在使用此功能运行草图时不会失去对计算机的控制,请在调用Keyboard.print()之前设置可靠的控制系统。 该草图包括一个用于切换键盘的按钮,因此它仅在按下按钮后才会运行。

组件的要求 (Components Required)

您将需要以下组件 -

  • 1 × Breadboard
  • 1×Arduino Leonardo,Micro或Due board
  • 1×瞬时按钮
  • 1×10k欧姆电阻器

过程 (Procedure)

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

键盘消息面包板

草图 (Sketch)

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

草图

Arduino代码 (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将移动鼠标,将HIGH输入映射到适当方向的5的范围。

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

组件的要求 (Components Required)

您将需要以下组件 -

  • 1 × Breadboard
  • 1×Arduino Leonardo,Micro或Due board
  • 5×10k欧姆电阻器
  • 5×瞬时按钮

过程 (Procedure)

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

鼠标按钮面包板

草图 (Sketch)

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

对于此示例,您需要使用Arduino IDE 1.6.7

草图

Arduino代码 (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

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

Arduino - Keyboard Serial

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

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

组件的要求 (Components Required)

您将需要以下组件 -

  • 1×Arduino Leonardo,Micro或Due board

过程 (Procedure)

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

键盘串口面包板

草图 (Sketch)

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

草图

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

Arduino库文件

Arduino代码 (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板与不同的传感器连接。 我们将讨论以下传感器 -

  • 湿度传感器(DHT22)
  • 温度传感器(LM35)
  • 水质探测器传感器(简单水触发器)
  • PIR传感器
  • 超声波传感器
  • GPS

Humidity Sensor (DHT22)

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

在本例中,您将学习如何将此传感器与Arduino UNO配合使用。 室温和湿度将打印到串行监视器上。

DHT-22传感器

DHT-22传感器

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

技术细节

  • Power - 3-5V

  • Max Current - 2.5mA

  • Humidity - 0-100%,准确度2-5%

  • Temperature - 40至80°C,±0.5°C精度

组件的要求 (Components Required)

您将需要以下组件 -

  • 1 × Breadboard
  • 1×Arduino Uno R3
  • 1×DHT22
  • 1×10K欧姆电阻

过程 (Procedure)

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

湿度传感器电路连接

湿度传感器面包板

草图 (Sketch)

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

草图

Arduino代码 (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传感器有四个端子(V cc ,DATA,NC,GND),它们连接到电路板如下 -

  • 数据引脚为Arduino引脚号2
  • V cc引脚至5伏Arduino板
  • GND引脚连接到Arduino板的地
  • 我们需要在DATA和V cc引脚之间连接10k欧姆电阻(上拉电阻)

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

结果 (Result)

您将在串口监视器上看到温度和湿度显示,每2秒更新一次。

Arduino - Temperature Sensor

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

LM35器件优于以开尔文校准的线性温度传感器,因为用户无需从输出中减去大的恒定电压以获得方便的摄氏度。 LM35器件无需任何外部校准或微调即可在室温下提供±¼°C的典型精度,在-55°C至150°C的整个温度范围内提供±¾°C的典型精度。

LM35设备

技术规格

  • 直接在摄氏度(摄氏)校准
  • 线性+ 10-mV /°C比例因子
  • 0.5°C确保精度(25°C时)
  • 额定温度范围为-55°C至150°C
  • Suitable for remote applications

组件的要求 (Components Required)

您将需要以下组件 -

  • 1 × Breadboard
  • 1×Arduino Uno R3
  • 1×LM35传感器

过程 (Procedure)

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

温度传感器电路连接

草图 (Sketch)

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

草图

Arduino代码 (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传感器有三个端子--V s ,V out和GND。 我们将按如下方式连接传感器 -

  • 在Arduino板上将+ V s连接到+ 5v。
  • 将V 输出连接到Arduino板上的Analog0或A0。
  • 在Arduino上连接GND和GND。

模数转换器(ADC)根据公式ADC值=采样* 1024 /参考电压(+ 5v)将模拟值转换为数字近似值。 因此,使用+5伏参考,数字近似将等于输入电压* 205。

结果 (Result)

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

Arduino - Water Detector/Sensor

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

水检测器/传感器

将水传感器连接到Arduino是检测泄漏,溢出,洪水,雨水等的好方法。它可用于检测水的存在,水平,体积和/或缺水。 虽然这可以用来提醒你给植物浇水,但有一个更好的Grove传感器。 传感器有一系列暴露的痕迹,当检测到水时读数为低。

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

组件的要求 (Components Required)

您将需要以下组件 -

  • 1 × Breadboard
  • 1×Arduino Uno R3
  • 1×水传感器
  • 1×led
  • 1×330欧姆电阻器

过程 (Procedure)

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

水传感器电路连接

草图 (Sketch)

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

草图

Arduino代码 (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,V 输出 (+)和GND( - )。 按如下方式连接传感器 -

  • 在Arduino板上将+ V s连接到+ 5v。
  • 将S连接到Arduino板上的数字引脚8。
  • 在Arduino上连接GND和GND。
  • 将LED连接到Arduino板上的数字引脚9。

当传感器检测到水时,Arduino上的引脚8变为低电平,然后Arduino上的LED变为ON。

结果 (Result)

当传感器检测到水时,您将看到指示LED亮起。

Arduino - PIR Sensor

PIR传感器可让您感知运动。 它们用于检测人是否已移入或移出传感器的范围。 它们常见于家庭或企业使用的家用电器和小工具中。 它们通常被称为PIR,“被动红外”,“热电”或“IR运动”传感器。

以下是PIR传感器的优点 -

  • 体积小
  • Wide lens range
  • Easy to interface
  • Inexpensive
  • Low-power
  • 使用方便
  • Do not wear out
PIR传感器

PIR由热释电传感器制成,圆形金属罐中心有一个矩形晶体,可以检测红外辐射水平。 一切都发出低水平的辐射,更热的东西是,辐射越多。 运动检测器中的传感器分成两半。 这是为了检测运动(变化)而不是平均IR水平。 连接两半使它们相互抵消。 如果有一半看到的IR辐射比另一半更多或更少,则输出会高或低。

PIR

PIR具有可调节的设置,并在3针接地/输出/电源垫中安装了接头。

PIR可调节设置

对于许多需要检测人员何时离开或进入该区域的基本项目或产品,PIR传感器非常棒。 请注意,PIR不会告诉您周围的人数或他们与传感器的接近程度。 镜头通常固定在一定距离的一定扫描范围内,有时它们被房子里的宠物引起。

组件的要求 (Components Required)

您将需要以下组件 -

  • 1 × Breadboard
  • 1×Arduino Uno R3
  • 1×PIR传感器(MQ3)

过程 (Procedure)

按照电路图进行连接,如下图所示。

PIR传感器电路连接

草图 (Sketch)

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

草图

Arduino代码 (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传感器有三个端子--V cc ,OUT和GND。 按如下方式连接传感器 -

  • 在Arduino板上连接+ V cc至+ 5v。
  • 将OUT连接到Arduino板上的数字引脚2。
  • 在Arduino上连接GND和GND。

您可以通过位于传感器板底部的两个可变电阻来调整传感器灵敏度和延迟时间。

延迟时间调整

一旦传感器检测到任何动作,Arduino将通过串行端口发送消息,表示检测到动作。 PIR感应运动将延迟一定时间以检查是否存在新动作。 如果没有检测到动作,Arduino将发送一条新消息,说明动作已经结束。

结果 (Result)

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

Arduino - Ultrasonic Sensor

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

操作不受阳光或黑色材料的影响,虽然声学上很难检测到布料之类的柔软材料。 它配有超声波发射器和接收器模块。

超声波传感器

超声波传感器辐射

技术规格

  • 电源 - + 5V DC
  • 静态电流 - <2mA
  • 工作电流 - 15mA
  • 有效角度 - <15°
  • 测距距离 - 2厘米 - 400厘米/ 1英寸 - 13英尺
  • 分辨率 - 0.3厘米
  • 测量角度 - 30度

组件的要求 (Components Required)

您将需要以下组件 -

  • 1 × Breadboard
  • 1×Arduino Uno R3
  • 1×超声波传感器(HC-SR04)

过程 (Procedure)

按照电路图进行连接,如下图所示。

超声波电路连接

草图 (Sketch)

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

草图

Arduino代码 (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连接如下 -

  • 在Arduino板上将+ 5V引脚连接到+ 5v。
  • 将触发器连接到Arduino板上的数字引脚7。
  • 将Echo连接到Arduino板上的数字引脚6。
  • 在Arduino上连接GND和GND。

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

结果 (Result)

您将在Arduino串行监视器上看到传感器测量的距离,单位为英寸和厘米。

Arduino - Connecting Switch

按钮或开关连接电路中的两个开路端子。 当您按下连接到引脚8的按钮开关时,此示例将打开引脚2上的LED。

连接开关

Pull-down Resistor

下拉电阻用于电子逻辑电路,以确保如果外部器件断开或处于高阻态,Arduino的输入将达到预期的逻辑电平。 由于没有任何东西连接到输入引脚,因此并不意味着它是逻辑零。 下拉电阻连接在地和设备上的相应引脚之间。

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

下拉电阻必须具有比逻辑电路的阻抗更大的电阻,否则它可能将电压拉得太低并且引脚的输入电压将保持在恒定的逻辑低值,而不管开关位置如何。

下拉电阻

组件的要求 (Components Required)

您将需要以下组件 -

  • 1×Arduino UNO板
  • 1×330欧姆电阻器
  • 1×4.7K欧姆电阻(下拉)
  • 1×LED

过程 (Procedure)

按照电路图进行连接,如下图所示。

电路图的连接

草图 (Sketch)

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

草图

Arduino代码 (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

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

结果 (Result)

按下按钮时LED指示灯亮,释放按钮时指示灯熄灭。

Arduino - DC Motor

在本章中,我们将使用Arduino板(UNO)连接不同类型的电机,并向您展示如何连接电机并将其从电路板上驱动。

有三种不同类型的电机 -

  • 直流电机
  • 伺服电机
  • 步进电机

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

直流电机

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

我们将本章分为三部分 -

  • 只需让你的电机旋转
  • 控制电机速度
  • 控制直流电机的旋转方向

需要的组件

您将需要以下组件 -

  • 1x Arduino UNO董事会
  • 1x PN2222晶体管
  • 1x小型6V直流电机
  • 1x 1N4001二极管
  • 1x270Ω电阻

过程 Procedure

按照电路图进行连接,如下图所示。

直流电机连接

注意事项(Precautions)

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

  • 首先,确保晶体管以正确的方式连接。 如图所示,晶体管的扁平侧面应朝向Arduino板。

  • 其次,根据图像中所示的布置,二极管的条纹端应朝向+ 5V电源线。

Spin ControlArduino Code

int motorPin = 3;
void setup() {
}
void loop() {
   digitalWrite(motorPin, HIGH);
}

代码注意

晶体管就像一个开关,控制电机的电源。 Arduino引脚3用于打开和关闭晶体管,并在草图中命名为“motorPin”。

结果 (Result)

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

电机速度控制

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

电机速度控制

Arduino代码

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

代码注意

晶体管就像一个开关,控制电机的功率。 Arduino引脚3用于打开和关闭晶体管,并在草图中命名为“motorPin”。

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

命令窗口

在'loop'函数中,命令'Serial.parseInt'用于读取在串行监视器中作为文本输入的数字,并将其转换为'int'。 你可以在这里输入任何数字。 如果数字在0到255之间,则下一行中的“if”语句只使用此数字进行模拟写入。

结果 (Result)

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

旋转方向控制

为了控制直流电机的旋转方向,无需更换引线,您可以使用称为H-Bridge的电路。 H桥是可以在两个方向上驱动电动机的电子电路。 H桥用于许多不同的应用中。 最常见的应用之一是控制机器人中的电机。 它被称为H桥,因为它使用四个晶体管连接,使得原理图看起来像“H”。

我们将在这里使用L298 H桥IC。 L298可以控制直流电机和步进电机的速度和方向,可以同时控制两台电机。 每个电机的额定电流为2A。 但是,在这些电流下,您需要使用散热片。

旋转方向控制

需要的组件

您将需要以下组件 -

  • 1×L298桥接IC
  • 1×直流电机
  • 1×Arduino UNO
  • 1 × Breadboard
  • 10 × jumper wires

过程 Procedure

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

旋转方向控制连接

上图显示了如何连接L298 IC以控制两个电机。 每个电机有三个输入引脚,电机1的输入1(IN1),输入2(IN2)和启用1(EN1),电机2的输入4,输入4和启用2。

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

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

IN1 IN2 运动行为
BRAKE
1FORWARD
1BACKWARD
11BRAKE

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

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

连接步骤

  • 将5V和IC的地线分别连接到5V和Arduino的地。
  • 将电机连接到IC的引脚2和3。
  • 将IC的IN1连接到Arduino的引脚8。
  • 将IC的IN2连接到Arduino的引脚9。
  • 将IC的EN1连接到Arduino的引脚2。
  • 将SENS的IC引脚连接到地。
  • 使用Arduino USB线连接Arduino,并使用Arduino IDE软件将程序上传到Arduino。
  • 使用电源,电池或USB电缆为Arduino板供电。

Arduino代码

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

伺服电机是一种带有输出轴的小型设备。 通过向伺服机构发送编码信号,可以将该轴定位到特定的角度位置。 只要编码信号存在于输入线上,伺服就会保持轴的角位置。 如果编码信号改变,则轴的角位置改变。 在实践中,伺服系统用于无线电控制的飞机中以定位控制表面,如电梯和方向舵。 它们还用于无线电遥控车,Puppet,当然还有机器人。

伺服电机

伺服系统在机器人技术中非常有用。 电机体积小,内置控制电路,尺寸极其强大。 诸如Futaba S-148之类的标准伺服系统具有42盎司/英寸的扭矩,其尺寸很大。 它还消耗与机械负载成比例的功率。 因此,轻载伺服系统不会消耗太多能量。

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

伺服电机控制电路

伺服电机的工作

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

如果轴处于正确角度,则电机关闭。 如果电路发现角度不正确,它将转动电动机直到它达到所需的角度。 伺服的输出轴能够在大约180度的范围内行进。 通常,它在210度范围内,但是,它取决于制造商。 普通伺服用于控制0到180度的角运动。 由于主输出齿轮上的机械挡块,它在机械上不能再转动。

施加到电机的功率与其需要行进的距离成比例。 因此,如果轴需要转动很长的距离,电机将全速运转。 如果只需要少量转动,电机将以较慢的速度运转。 这称为proportional control

你如何沟通伺服转动的角度?

控制线用于传达角度。 该角度由施加到控制线的脉冲的持续时间确定。 这称为Pulse Coded Modulation 。 伺服器希望每20毫秒(0.02秒)看到一个脉冲。 脉冲长度将决定电机转动的距离。 例如,1.5毫秒的脉冲将使电机转到90度位置(通常称为中性位置)。 如果脉冲短于1.5毫秒,则电机将使轴更接近0度。 如果脉冲长于1.5毫秒,则轴转动接近180度。

角度转弯

组件的要求 (Components Required)

您将需要以下组件 -

  • 1×Arduino UNO板
  • 1×伺服电机
  • 1×ULN2003驱动IC
  • 1×10KΩ电阻器

过程 (Procedure)

按照电路图进行连接,如下图所示。

伺服电机连接

草图 (Sketch)

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

草图

Arduino代码 (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。

连接电位计

分压器/分压器是串联电路中的电阻器,其将输出电压缩放到所施加的输入电压的特定比率。 以下是电路图 -

连接电位器

$$V_{out} = (V_{in} \times R_{2})/ (R_{1} + R_{2})$$

V out是输出电位,取决于串联的输入电压(V in )和电阻(R 1和R 2 )。 这意味着流过R 1的电流也将流过R 2而不被分开。 在上面的等式中,随着R 2的值改变,V out相对于输入电压V in相应缩放。

通常,电位计是分压器,它可以根据可变电阻器的值来缩放电路的输出电压,可变电阻器的值使用旋钮进行缩放。 它有三个引脚:GND,信号和+ 5V,如下图所示 -

电位器描述

结果 (Result)

通过改变锅的NOP位置,伺服电机将改变其角度。

Arduino - Stepper Motor

步进电机或步进电机是无刷同步电机,它将整个旋转分成多个步骤。 与无刷直流电动机不同,无刷直流电动机在向其施加固定的直流电压时连续旋转,步进电动机以不连续的步进角度旋转。

因此,步进电机的每转步数为12,24,72,144,180和200,每步的步进角为30,15,5,2.5,2和1.8度。 可以在有或没有反馈的情况下控制步进电机。

想象一下RC飞机上的电机。 电机在一个方向或另一个方向上旋转得非常快。 您可以根据给予电机的功率来改变速度,但是您无法判断螺旋桨是否停在特定位置。

现在想象一下打印机。 打印机内部有许多活动部件,包括电机。 一个这样的马达充当纸张进给,旋转辊在纸张上印刷墨水时移动纸张。 该电机需要能够将纸张移动一段精确的距离,以便能够打印下一行文本或图像的下一行。

另一个电动机连接到螺纹杆上,前后移动打印头。 同样,该螺纹杆需要移动一个精确的数量,以便一个接一个地打印一个字母。 这是步进电机派上用场的地方。

步进电机

步进电机如何工作?

常规直流电机仅在方向上旋转,而步进电机可以以精确的增量旋转。

步进电机可以根据需要转动精确的度数(或步长)。 这使您可以完全控制电机,使您可以将其移动到一个确切的位置并保持该位置。 它通过在非常短的时间内为电动机内部的线圈供电来实现。 缺点是您必须始终为电机供电,以使其保持在您想要的位置。

你现在需要知道的是,为了移动步进电机,你要告诉它在一个方向或另一个方向上移动一定数量的步骤,并告诉它向这个方向迈进的速度。 步进电机有很多种。 此处描述的方法可用于推断如何使用本教程中未提及的其他电机和驱动程序。 但是,始终建议您查阅特定于您所拥有型号的电机和驱动器的数据表和指南。

内部步进电机

组件的要求 (Components Required)

您将需要以下组件 -

  • 1×Arduino UNO板
  • 1×小型双极步进电机如下图所示
  • 1×LM298驱动IC
LM298驱动IC

过程 (Procedure)

按照电路图进行连接,如下图所示。

步进电机连接

草图 (Sketch)

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

草图

Arduino代码 (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 Tone Library。 它只不过是一个Arduino库,它可以在任何Arduino引脚上产生指定频率(和50%占空比)的方波。 可以选择指定持续时间,否则wave将继续,直到调用stop()函数。 该引脚可以连接到压电蜂鸣器或扬声器以播放音调。

Warning - 请勿将引脚直接连接到任何音频输入。 电压远高于标准线路电压,可能会损坏声卡输入等。您可以使用分压器降低电压。

组件的要求 (Components Required)

您将需要以下组件 -

  • 1 × 8-ohm speaker
  • 1×1k电阻
  • 1×Arduino UNO板

过程 (Procedure)

按照电路图进行连接,如下图所示。

音色库连接

草图 (Sketch)

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

草图

要制作pitches.h文件,请单击串行监视器图标正下方的按钮,然后选择“新建选项卡”,或使用Ctrl + Shift + N.

新标签

然后粘贴以下代码 -

/*************************************************
* 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代码 (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 sharp,依此类推。 这张便条表最初是由Brett Hagman编写的,他的作品是tone()命令的基础。 每当你想制作音符时,你会发现它很有用。

结果 (Result)

您将听到保存在pitches.h中的音符。 文件。

Arduino - Wireless Communication

无线发射器和接收器模块的工作频率为315 Mhz。 它们可以轻松放入面包板中,并与微控制器配合使用,创建非常简单的无线数据链路。 使用一对发送器和接收器,模块只能单向通信数据​​,但是,您需要两对(不同频率)作为发送器/接收器对。

Note - 这些模块是不加选择的,并且会收到相当多的噪音。 发射器和接收器都以共同的频率工作,没有ID。

无线通信

接收器模块规格

  • 产品型号 - MX-05V
  • 工作电压 - DC5V
  • 静态电流 - 4mA
  • 接收频率 - 315Mhz
  • 接收器灵敏度 - -105DB
  • 尺寸 - 30 * 14 * 7mm

变送器模块规格

  • 产品型号 - MX-FS-03V
  • 发射距离 - 20-200米(不同电压,不同结果)
  • 工作电压 - 3.5-12V
  • 尺寸 - 19 * 19mm
  • 运行模式 - AM
  • 转移率 - 4KB/S.
  • 发射功率 - 10mW
  • 发射频率 - 315Mhz
  • 外置天线 - 25cm普通多芯或单芯线
  • 引脚输出从左→右 - (DATA; V CC ; GND)

组件的要求 (Components Required)

您将需要以下组件 -

  • 2×Arduino UNO板
  • 1×Rf链路发射机
  • 1×Rf链路接收器

过程 (Procedure)

按照电路图进行连接,如下图所示。

无线通信连接

草图 (Sketch)

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

草图

Note - 您必须在Arduino库文件中包含键盘库。 将VirtualWire.lib文件复制并粘贴到libraries文件夹中,如下面的屏幕截图所示。

Arduino库文件

Arduino发送器代码

//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接收器代码

//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”时,变为OFF。

Arduino - Network Communication

德州仪器(TI)的CC3000 WiFi模块是一款小型银色封装,最终为您的Arduino项目带来了易于使用,价格合理的WiFi功能。

它使用SPI进行通信(而不是UART!),因此您可以根据需要快速推送数据,也可以根据需要尽可能慢地推送数据。 它有一个带有IRQ引脚的适当中断系统,因此您可以进行异步连接。 它支持802.11b/g,开放/ WEP/WPA/WPA2安全性,TKIP和AES。 带有“BSD套接字”接口的内置TCP/IP堆栈支持客户端和服务器模式下的TCP和UDP。

网络通讯

组件的要求 (Components Required)

您将需要以下组件 -

  • 1×Arduino Uno
  • 1×Adafruit CC3000分线板
  • 1×5V继电器
  • 1 × Rectifier diode
  • 1×LED
  • 1×220欧姆电阻
  • 1×面包板和一些跳线

对于这个项目,您只需要通常的Arduino IDE,Adafruit的CC3000库和CC3000 MDNS库。 我们还将使用aREST库通过WiFi向中继发送命令。

过程 (Procedure)

按照电路图进行连接,如下图所示。

网络通信连接

该项目的硬件配置非常简单。

  • 将CC3000板的IRQ引脚连接到Arduino板的3号针脚。
  • VBAT到引脚5,CS到引脚10。
  • 将SPI引脚连接到Arduino板:MOSI,MISO和CLK分别连接到引脚11,12和13。
  • V in连接到Arduino 5V,GND连接到GND。

现在让我们连接继电器。

将继电器放在面包板上后,您可以开始识别继电器上的两个重要部件:用于控制继电器的线圈部件,以及用于连接LED的开关部件。

  • 首先,将Arduino板的引脚编号8连接到线圈的一个引脚。
  • 将另一个引脚连接到Arduino板的地。

您还必须将整流二极管(阳极连接到接地引脚)放在线圈的引脚上,以便在继电器切换时保护电路。

  • 将+ 5V的Arduino板连接到继电器开关的公共引脚。

  • 最后,将开关的另一个引脚(通常是继电器关闭时未连接的引脚)连接到与220欧姆电阻串联的LED,并将LED的另一端连接到Arduino的地板。

测试单个组件

您可以使用以下草图测试继电器 -

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将相应地打开和关闭。

添加WiFi连接

现在让我们使用CC3000 WiFi芯片无线控制继电器。 该项目的软件基于TCP协议。 但是,对于这个项目,Arduino板将运行一个小型Web服务器,因此我们可以“监听”来自计算机的命令。 我们将首先处理Arduino草图,然后我们将看到如何编写服务器端代码并​​创建一个漂亮的接口。

首先,Arduino草图。 这里的目标是连接到您的WiFi网络,创建Web服务器,检查是否有传入的TCP连接,然后相应地更改中继的状态。

守则的重要部分

#include <Adafruit_CC3000.h>
#include <SPI.h>
#include <CC3000_MDNS.h>
#include <Ethernet.h>
#include <aREST.h>

您需要在代码内部定义特定于您的配置的内容,即Wi-Fi名称和密码,以及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

您应该看到继电器自动打开。

构建中继接口

我们现在将编写项目的界面。 这里将有两个部分:一个包含接口的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文件即可。 您应该在浏览器中看到类似的内容 -

继电器控制

尝试单击Web界面上的按钮; 它应该几乎立即改变继电器的状态。

如果你设法让它工作,勇敢! 你刚刚建立了一个Wi-Fi控制的灯开关。 当然,你可以通过这个项目来控制光线。 只需确保您的继电器支持您想要控制的设备所需的电源,您就可以开始使用了。

↑回到顶部↑
WIKI教程 @2018