Arduino - 通信

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

并行通信

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

并行通信

并行通信的优点和缺点

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

串行通信模块

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

使用哪种系统取决于以下因素 −

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

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

串行通信的类型

串行通信可以进一步分为 −

  • 同步 − 同步的设备使用相同的时钟,并且它们的时序彼此同步。

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

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

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

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

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

同步位

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

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

起始位始终由从 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); //将串行库波特率设置为 9600
    Serial.println("hello world"); //打印 hello world
}

void loop() {

}

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

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

以下代码将返回其作为输入接收的任何内容。

以下代码将使 Arduino 根据提供的输入提供输出。

void setup() {
   Serial.begin(9600); //设置串行库波特率为 9600
}

void loop() {
   if(Serial.available()) //如果有可供读取的字节数(字符)
   { 
      serial port
      Serial.print("I received:"); ///打印我收到了
      Serial.write(Serial.read()); //发送你读到的内容
   }
}

请注意,Serial.printSerial.println 将返回实际的 ASCII 代码,而 Serial.write 将返回实际的文本。有关更多信息,请参阅 ASCII 代码。