Serial Communication
This project will help you understand how to send data to and receive data from a microcontroller board connected to your computer over the most commonly used serial protocol. The Arduino and Thonny IDEs both have a function called Serial Monitor which is used to exchange data with the connected microcontroller board.
Learning Objectives
Components
| Component | Purpose |
|---|---|
| Arduino Nano | The microcontroller board. |
| USB Cable | To connect the board to the microcontroller. |
Circuit Diagram
There is no circuit diagram for this project, it only requires the board connected to the computer USB port using the appropriate cable.
Code
Compile and upload the code below. After the code has been uploaded, open the Serial Monitor in the IDE. You should see the messages printed by the board in the monitor. When prompted you can type any message in the input box of the serial monitor and it will be printed back from the development board.
You cannot open the Serial Monitor until the code has been uploaded. And then, quite often the code starts running before you open the Serial Monitor. If you miss any initial messages you expected from the board, you can restart the code by pressing the Reset button on the board.
/*
Project: Serial Communication
Function: Serial Communication
Circuit: Board only
Boards Supported: UNO R3/R4, Nano, ESP32
Description: This project shows you how to send data to and receive data from a board connected to your computer over the serial communication protocol.
Author: STEMVentor Educonsulting
This code is copyrighted. Please do not reuse or share for any purpose other than for learning with subscribed STEMVentor programs. This code is for educational purposes only and is not for production use.
*/
// LIBRARIES
// PIN DEFINTIONS
// CONSTANT DEFINITIONS
// GLOBAL VARIABLES
// To read by character define an array of characters with a pre-defined size in bytes.
// 1 byte = 1 character, including the newline or string terminator.
const byte num_chars = 32;
char received_chars[num_chars];
// To read a string.
String received_string;
// NOTE: Most boards have a serial input buffer size of 64 bytes. This is generally not a problem
// since the sketch almost always reads from the buffer faster than new data is pushed in.
// However, if the buffer is not cleared, new incoming data will overwrite the existing unread data.
boolean new_data = false;
// LOCAL FUNCTIONS
// Option 1: Read serial input by character and assemble into a string (array with line terminator).
void readSerialDataByChar() {
static byte index = 0;
char eol_char = '\n'; // Need to configure the serial monitor to send a Newline as the end character.
char in_char;
// This sends data to the serial monitor and is printed for the user to see.
// NOTE: In Serial.println enclosing a static string within F("") indicates that the
// string must be stored in Flash (ROM) memory instead of the RAM.
// This is useful if you would like to have extra RAM available for computations.
// Of course this takes up Flash memory which is also used to store your compiled code
// so it is a trade off depending on your sketch.
Serial.println(F("Enter characters (terminate with a newline char):"));
// Use the available() function to check if the serial buffer has data to read
// and also check if this is a new string of data and if so read each char until available or EOL.
while (Serial.available() > 0 && new_data == false) {
in_char = Serial.read();
if (in_char != eol_char) {
received_chars[index] = in_char;
index++;
if (index >= num_chars) {
index = num_chars - 1;
}
}
else {
received_chars[index] = '\0'; // terminate the string
index = 0;
new_data = true;
}
}
}
// Option2: Read an entire string.
// This is a blocking function and waits for data to be entered until timeout so not recommended.
void readSerialDataByString(){
Serial.println("Enter a data string:");
while (Serial.available() == 0) {} // Wait until data is available.
received_string = Serial.readString(); // Read until timeout
received_string.trim(); // Remove any '\r', '\n', or whitespace at the end of the string (optional).
}
// THE setup FUNCTION RUNS ONCE WHEN YOU PRESS RESET OR POWER THE BOARD.
void setup() {
Serial.begin(9600);
Serial.println("The board is ready!");
}
// THE loop FUNCTION RUNS OVER AND OVER AGAIN FOREVER UNTIL THE BOARD IS POWERED OFF.
// Run only one option at a time (comment out all code for the other option).
void loop() {
// Option 1: Read by character
// readSerialDataByChar();
// if (new_data == true) {
// Serial.print("Entered characters: ");
// Serial.println(received_chars);
// new_data = false;
// }
// Option 2: Read a string
readSerialDataByString();
Serial.print("Entered String: ");
Serial.println(received_string);
}