Arduino 串口发送与接收应用小实例

最近需要做一些通过串口发送指令的项目,自己简单总结了一下例子,方便以后查阅使用。

实验效果

实验1: 在串口监视器中输入的字符串,显示在串口监视器中。 例如输入 hello,lingshunlab! 按发送后,则会在串口监视器中显示

实验2: 改写实验1的代码,在串口监视器中输入自定义的字符后(例如 \'h\',\'b\',\'t\'),串口监视器则输出对应的的信息。

接线

本实验只需把Arduino Uno用数据线与电脑连接上,即可通信了。

程序提点

关于Arduino串口(Serial)的所有方法,请查阅:

https://www.arduino.cc/reference/en/language/functions/communication/serial/

这里介绍一下常用的:


Serial.begin()

说明

设置Arduino串口通讯时的数据传输速率(每秒传输字节数)。可使用以下速率:300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 115200。,你也可以根据你所使用的设备而设置其他传输速率。

语法

Serial.begin(speed) Serial.begin(speed, config)

顺便在这里备注一下,如果使用esp32还可以有以下语法:Serial.begin(speed, config, RDX, TDX)

参数

speed: 每秒传输字节数 – long(长整型数据) config: 设置数据位、奇偶校验和停止位。默认SERIAL_8N1表示8个数据位,无校验位,1个停止位。所有有效的设置列表:

  • SERIAL_5N1
  • SERIAL_6N1
  • SERIAL_7N1
  • SERIAL_8N1 默认
  • SERIAL_5N2
  • SERIAL_6N2
  • SERIAL_7N2
  • SERIAL_8N2
  • SERIAL_5E1 偶校验
  • SERIAL_6E1
  • SERIAL_7E1
  • SERIAL_8E1
  • SERIAL_5E2
  • SERIAL_6E2
  • SERIAL_7E2
  • SERIAL_8E2
  • SERIAL_5O1 奇校验
  • SERIAL_6O1
  • SERIAL_7O1
  • SERIAL_8O1
  • SERIAL_5O2
  • SERIAL_6O2
  • SERIAL_7O2
  • SERIAL_8O2

返回值

示例代码

void setup() {
    Serial.begin(9600); // 打开串口,并设置波特率为9600(单位:bps)
}

void loop() {}

Serial.available()

说明

available() 可用于检查设备串口缓冲区是否接收到数据。该函数将会返回等待读取的数据字节数。缓冲区默认大小为64个字节(bytes).

available()函数属于Stream类。该函数可被Stream类的子类所使用,如(Serial, WiFiClient, File 等)。

语法

Serial.available()

参数

返回值

等待读取的数据字节数。 返回值数据类型:int

示例代码

int incomingByte = 0; // 用于存储串口输入数据的大小

void setup() {
  Serial.begin(9600); // 打开串口,并设置波特率为9600(单位:bps)
}

void loop() {
  // 判断是否有收到数据
  if (Serial.available() > 0) { // 有,则运行一下代码
    // 逐个读取串口的数据
    incomingByte = Serial.read();

    // 在串口中显示输入的数据
    Serial.print("I received: ");
    Serial.println(incomingByte, DEC);  // 此处DEC为输出的数据格式是十进制
  }
}

Serial.read()

说明

读取串口数据,一次读一个字符,读完后删除已读数据。

语法

Serial.read()

参数

返回值

返回串口缓存中第一个可读字节,当没有可读数据时返回-1,整数类型。

程序代码

实验1代码:

// by lingshunlab.com

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

void loop() {
  // 判断串口是否有数据
  if(Serial.available()) {  // 有,则进行如下处理
    String inStr;  //声明一个String类型的变量,用于存放串口的数据

    // 当串口有数据则循环运行如下处理
    while(Serial.available()) { 
      inStr = inStr + (char)Serial.read(); // 把读取的串口数据,逐个组合到inStr变量里
    }
    // 可以在此对输入的数据进行处理...
    // ...
    Serial.println(inStr);  // 输出inStr,在串口中查看器中输输出输入的数据
  }

  delay(1000); // 延时一秒(1000毫秒)
}

实验2代码:

接下来,改动一下刚才的例子

// by lingshunlab.com

String Str; // 声明变量 Str ,用于存储串口输入的数据

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

// 获取串口数据函数
void GetSerialStuff(String& Str) {
  String tempStr = ""; // 声明变量 tempStr,用于临时存储串口输入的数据
  while(Serial.available()) { // 当串口有数据时,循环执行
    tempStr += (char)Serial.read();  // 把读取的串口数据,逐个组合到inStr变量里
  }
  Str = tempStr; // 把引用指针的变量赋值为 tempStr
}

void loop() {
  GetSerialStuff(Str);
  if(Str != "") {
    // 在串口中输出我们输入的数据,方便观察
    Serial.print("input: ");
    Serial.println(Str);

    switch ((byte)Str[0]) { // 把输入的字符转换成byte类型,进行对应指令的判断
      case 'h': // 串口输入 h 时,输出以下信息
        Serial.println("hello every body!");
        break;
      case 'b': // 串口输入 b 时,输出以下信息
        Serial.println("by Lingshunlab.com");
        break;
      case 't':  // 串口输入 t 时,输出以下信息
        Serial.println("Thanks for watch"); 
        break;
      default: // 没有对应的case时,则输出一下默认信息
        Serial.println("Please enter the correct command");
    }
  }

  delay(100); // 延时 100 毫秒
}

上传程序后,打开「串口监视器」,在输入框中输入特定字符按「发送」,即可看到相应的回应。