Arduino 简明教程

Arduino - Communication

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

Parallel Communication

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

parallel communication

Advantages and Drawbacks of Parallel Communication

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

Serial Communication Modules

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

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

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

  2. 数据交换需要多快?

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

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

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

Types of Serial Communications

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

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

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

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

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

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

  1. Synchronization bits

  2. Data bits

  3. Parity bits

  4. Baud rate

Synchronization Bits

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

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

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

synchronization bits

Data Bits

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

Parity Bits

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

Baud Rate

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

Arduino UART

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

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

void loop() {

}

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

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

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

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

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

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

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