Arduino serial communication

Communication type

Communication is a technology used to exchange data between different electronic devices, in fact, it is to realize the "communication dialogue" between different electronic devices.

image-20200925105403249

Arduino serial communication

Arduino adopts the USART communication mode, which can be implemented in two ways: hard serial port and soft serial port.

Usually, the serial ports 0 (RX) and 1 (TX) that come with Arduino UNO are called hardware serial ports, which can communicate with peripheral serial port devices. The serial port simulated by the SoftwareSerial class library is called a software simulated serial port (soft serial port for short). If you want to connect more serial devices, you can use the soft serial port.

hard serial port

The operation class of the hard serial port is HardwareSerial, which is defined in the HardwareSerial.h source file, and publicly declares the Serial object to the user. The user can directly call Serial in the Arduino program to realize serial communication.

Common functions are:

Serial.begin()

  • Description: Open the serial port, usually placed in the setup() function.
  • prototype:
    • Serial.begin(speed)
    • Serial.begin(speed, config)
  • parameter:
    • speed: baud rate, generally 9600, 115200, etc.
    • config: Set data bits, parity bits and stop bits. The default SERIAL_8N1 means 8 data bits, no parity bit, and 1 stop bit.
  • Return value: None.

Serial.end()

  • Description: Disable serial transmission. At this time, the serial ports Rx and Tx can be used as digital IO pins.
  • Prototype: Serial.end()
  • Parameters: None.
  • Return value: None.

Serial.print()

  • Description: The serial port outputs data and writes character data to the serial port.
  • prototype:
    • Serial.print(val)
    • Serial.print(val, format)
  • parameter:
    • val: The printed value, any data type.
    • config: output data format. BIN (binary), OCT (octal), DEC (decimal), HEX (hexadecimal). For floating point numbers, this parameter specifies the number of decimal places to use.
  • Example:
    • Serial.print(78, BIN) gets "1001110"
    • Serial.print(78, OCT) gets "116"
    • Serial.print(78, DEC) gets "78"
    • Serial.print(78, HEX) gets "4E"
    • Serial.print(1.23456, 0) gets "1"
    • Serial.print(1.23456, 2) gets "1.23"
    • Serial.print(1.23456, 4) gets "1.2346"
    • Serial.print('N') gets "N"
    • Serial.print(“Hello world.”) 得到 “Hello world.”
  • Return Value: Returns the number of bytes written.

Serial.println()

  • Description: The serial port outputs data and wraps the line.
  • prototype:
    • Serial.println(val)
    • Serial.println(val, format)
  • parameter:
    • val: The printed value, any data type.
    • config: output data format.
  • Return Value: Returns the number of bytes written.

Serial.available()

  • Description: Judge the status of the serial port buffer and return the number of bytes read from the serial port buffer.
  • 原型:Serial.available()
  • Parameters: None.
  • Return value: The number of bytes that can be read.

Serial.read()

  • Description: Read serial port data, one character at a time, and delete the read data after reading.
  • Prototype: Serial.read()
  • Parameters: None.
  • Return value: Returns the first readable byte in the serial port buffer, and returns -1 when there is no readable data, integer type.

Specific operation function reference

Experiment 1:

String str="";

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

void loop() {
  str = "";
  while (Serial.available() > 0)
  {
    str += char(Serial.read());   // read是剪切,而不是复制
    delay(10);  // 延时
  }
  if (str.length() > 0)
  {
    Serial.print(F("命令行发送内容:"));
    Serial.println(str);
  }
}

Experimental phenomena:

image-20200925183633274

Experiment 2:

image-20200924142248512
/**
 * 通过串口改变Arduino 9号针脚接的LED灯的亮度
 */

int i,j,val; //定义i、j、val三个整型变量
char A[10];  //定义一个无符号数组A

void setup(){
  Serial.begin(9600);
  pinMode(9,OUTPUT);
}

void loop(){
  delay(100);  // 等待100ms

  j = Serial.available();  // 读取串口寄存器中的信息的帧数

  if(j != 0){   // 如果串口寄存器中有数据,那么依次读取这些数据,并存放到数组A中
    for(i = 0; i < j; i++){
      A[i] = Serial.read(); 
    }

    val = strtol(A,NULL,10);  // 将A中的字符转换成十进制数
  }
  analogWrite(9,val); // 将转换好的val输出给三号端口,驱动LED灯的亮度
}

experiment analysis:

Before understanding Arduino serial communication, you need to know some prior knowledge.

The serial connection between the computer and Arduino is as follows:

image-20200925214505843

Connect a serial register to the USB interface of Arduino to temporarily store the information from the computer (the Arduino will then extract the data from the serial register according to the developer's program and save it to the Arduino memory), and communicate with the computer through the USB serial port. , the serial port register space allocated to Arduino UNO by default can store 63 frames of information. (A frame of information includes the frame header, data and frame end.) If the information is exceeded, the information behind will run on the previous information, resulting in information loss.

The read function reads the information in the serial port register. However, the main frequency of Arduino is 16M, that is, 1.6 million operations per second; and the speed of serial communication (that is, the baud rate mentioned above) is generally 115200, which is 115200 bits per second, which is about 14400. bytes. Therefore, the reading speed of Arduino is much faster than that of serial transmission, and a certain delay needs to be added before reading.

Now suppose we send three frames of data from the computer to Arduino, the contents of these three frames are 'a', 'b', 'c' respectively.

image-20200925214112037

First of all, during the period from step 1 to step 4 on the right side, the information enters the serial port register frame by frame. If we want to read all the information at one time, then during the period from step 1 to step 4 We cannot read the information, because the information has not been completely transmitted at this time, that is to say, all the information has not been entered into the register. If we start reading the information in the register at step 2 in Figure 6, then we will only get the information 'a'. For Arduino, a chip that performs 1.6 million operations per second, the transmission of serial information is very slow, so we must set a waiting time for Arduino at the beginning. This waiting time is generally set to 100ms, which is why The reason for adding the delay(100) command.

Then, when the waiting time is over, at this point we consider the information to have been fully transmitted. Of course, to be honest, this is all guesswork. We estimate that the information is transmitted in 100ms. Maybe the information is transmitted as early as 10ms. We can't feel it after waiting for dozens of milliseconds. Of course, if you feel sure, you can shorten the waiting time, for example, 50ms or even 20ms. You can try to use it. If there is no information loss, you can use more Short waiting time. After the information is completely transmitted, we start to read the information from the serial port register, that is, the process from step 5 to step 7. Note that the "big arrow" pointed to by the black line in Figure 6 is a pointer inside the Arduino. This pointer monitors the serial port register at all times. We can use the command Serial.available() to mobilize this pointer at any time to get the incoming information. Quantity, of course, as we said, we have to wait for all the information to be transmitted before starting to call. If we call Serial.available() in step 2, we can only detect one data. In step 4 in Figure 6, we can see that a total of three information are passed into the register, so the value obtained by calling Serial.available() at this time is 3, and then we assign this value to the variable j, so the variable j It represents the amount of information in the register.

Finally, this is the pointer. We can use the command Serial.read() to mobilize this pointer to grab the data. Note that Serial.read() can grab one frame of information at a time. After grabbing the information each time, in the register The space where this information was originally stored is empty, what I mean is: The Serial.read() command does not copy the information but cuts the information . Well, looking back, 3 pieces of information are grabbed 1 at a time, so in order to grab all the information in the register, we need to grab 3 times, so we use a for loop, the number of loops is set to j, so The information in all registers can be automatically captured. Each time we grab the data, we will store it in the array A, which is a character array we defined at the beginning of the program. There are two points to note about the A array: 1) It must be defined as a character array, because we have said that all the information input by the computer serial port is transmitted in the form of characters, even if it is an Arabic number, it is only a character, not a real Arabic number; 2) The space size of the A array should be sufficient when it is defined. If we plan to process 1 frame of data at a time, then the space of A should be given to 1 frame or more; if we plan to process 3 frames of data each time , then the space of A should be greater than or equal to 3 frames. Then we convert the "frame" into bytes to define the space of A.

soft serial port

The operation class of the soft serial port is SoftwareSerial, which is defined in the SoftwareSerial.h source file, but unlike the hard serial port, the soft serial port object is not declared in the source file in advance, and the soft serial port object needs to be created manually in the Arduino program.

Before using it, you need to declare that the SoftwareSerial.h header file is included.

Then call the constructor of the SoftwareSerial class, through which the soft serial port RX and TX pins can be specified.

SoftwareSerial mySerial= SoftwareSerial(rxPin, txPin)
SoftwareSerial mySerial(rxPin, txPin)
  • mySerial: user-defined software serial port object
  • rxPin: soft serial port receive pin
  • txPin: soft serial port send pin

The member functions defined in the SoftwareSerial class are similar to the hardware serial ports, available(), begin(), read(), write(), print(), println(), peek(), etc. are used in the same way.

Test code:

#include <SoftwareSerial.h> 

//定义管脚2/3分别为RX,TX.  
SoftwareSerial mySerial(2, 3); // RX, TX  
void setup()  
{  
  mySerial.begin(9600);  
}  
void loop()   
{  
   mySerial.println("Hello, world?");     //TX输出
   delay(1000);  
} 

Run the program, you will find that the serial monitor does not have any string output, why is this?

As mentioned in the hard serial port section, the computer communicates with the Arduino serial port through the hard serial port TX (1) and RX (0). When we use the soft serial port, the computer is still connected to these two pins. So even if the soft serial port TX (3) is outputting, it will not be read and displayed by the computer. So connect the hard serial port TX(1) and the soft serial port TX(3), so that the output of the soft serial port TX(3) will enter the hard serial port TX(1), and then send it to the computer.

image-20200925184211621

Experimental phenomena:

image-20200925183752914

refer to:

Arduino rookie popular version interpretation series (4) serial communication USART

Arduino rookie popular version interpretation series (7) summary of communication types

Guess you like

Origin blog.csdn.net/xiaoshihd/article/details/108805015