# Arduino Serial Monitor Tutorial: Basic Input Functions
## **Introduction**
The Arduino Serial Monitor is a powerful tool for communication between your Arduino board and your computer. While most tutorials focus on output (sending data from Arduino to computer), this tutorial focuses on **input functions** - receiving and processing data from the computer to control your Arduino projects.
## **What is Serial Communication?**
Serial communication is a method of sending data one bit at a time, sequentially, over a communication channel. In Arduino, this allows your board to communicate with your computer through the USB cable.
### **Key Concepts:**
- **Baud Rate**: Speed of communication (bits per second)
- **ASCII**: Text-based communication
- **Buffering**: Temporary storage of incoming data
- **Parsing**: Converting text data to usable values
## **Basic Serial Monitor Setup**
### **Required Components:**
- **Arduino Board** (any model)
- **USB Cable**
- **Arduino IDE**
### **Basic Setup Code:**
```cpp
void setup() {
Serial.begin(9600); // Initialize serial communication at 9600 baud
Serial.println("Serial Monitor Ready!");
}
void loop() {
// Your code here
}
```
## **Serial Input Functions**
### **1. Serial.available()**
Checks if data is available to read from the serial buffer.
```cpp
void loop() {
if (Serial.available() > 0) {
// Data is available to read
Serial.println("Data received!");
}
delay(100);
}
```
**Key Points:**
- Returns the number of bytes available to read
- Returns 0 if no data is available
- Always check before reading data
### **2. Serial.read()**
Reads one character from the serial buffer.
```cpp
void loop() {
if (Serial.available() > 0) {
char incomingChar = Serial.read();
Serial.print("Received: ");
Serial.println(incomingChar);
}
}
```
**Key Points:**
- Reads one byte at a time
- Returns -1 if no data is available
- Returns ASCII value of the character
- Removes the character from the buffer
### **3. Serial.readString()**
Reads characters from the serial buffer into a String.
```cpp
void loop() {
if (Serial.available() > 0) {
String incomingString = Serial.readString();
Serial.print("Received: ");
Serial.println(incomingString);
}
}
```
**Key Points:**
- Reads until timeout (default 1 second)
- Returns empty String if no data
- Includes newline characters
- Good for receiving complete messages
### **4. Serial.readStringUntil()**
Reads characters until a specific terminator character.
```cpp
void loop() {
if (Serial.available() > 0) {
String incomingString = Serial.readStringUntil('\n'); // Read until newline
Serial.print("Received: ");
Serial.println(incomingString);
}
}
```
**Key Points:**
- Stops reading at the terminator character
- Excludes the terminator from the result
- Common terminators: '\n' (newline), '\r' (carriage return)
- More precise than readString()
### **5. Serial.parseInt()**
Reads and parses the next valid integer from the serial buffer.
```cpp
void loop() {
if (Serial.available() > 0) {
int number = Serial.parseInt();
Serial.print("Received number: ");
Serial.println(number);
}
}
```
**Key Points:**
- Skips non-numeric characters
- Returns 0 if no valid number found
- Good for receiving numeric input
- Handles negative numbers
### **6. Serial.parseFloat()**
Reads and parses the next valid floating-point number.
```cpp
void loop() {
if (Serial.available() > 0) {
float number = Serial.parseFloat();
Serial.print("Received float: ");
Serial.println(number);
}
}
```
**Key Points:**
- Skips non-numeric characters
- Returns 0.0 if no valid number found
- Handles decimal points
- Good for precise measurements
## **Practical Examples**
### **Example 1: Simple Command Interface**
```cpp
void setup() {
Serial.begin(9600);
Serial.println("Command Interface Ready!");
Serial.println("Commands: on, off, status");
}
void loop() {
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n');
command.trim(); // Remove whitespace
if (command == "on") {
Serial.println("Turning ON");
// Add your ON code here
}
else if (command == "off") {
Serial.println("Turning OFF");
// Add your OFF code here
}
else if (command == "status") {
Serial.println("System is running");
}
else {
Serial.println("Unknown command: " + command);
}
}
}
```
### **Example 2: Numeric Input Control**
```cpp
int ledBrightness = 0;
void setup() {
Serial.begin(9600);
Serial.println("LED Brightness Controller");
Serial.println("Enter number 0-255:");
}
void loop() {
if (Serial.available() > 0) {
int value = Serial.parseInt();
if (value >= 0 && value <= 255) {
ledBrightness = value;
Serial.print("Brightness set to: ");
Serial.println(ledBrightness);
// analogWrite(ledPin, ledBrightness);
}
else {
Serial.println("Invalid value! Enter 0-255");
}
}
}
```
### **Example 3: Character-Based Control**
```cpp
void setup() {
Serial.begin(9600);
Serial.println("Character Control System");
Serial.println("w: up, s: down, a: left, d: right, x: stop");
}
void loop() {
if (Serial.available() > 0) {
char input = Serial.read();
switch (input) {
case 'w':
Serial.println("Moving UP");
break;
case 's':
Serial.println("Moving DOWN");
break;
case 'a':
Serial.println("Moving LEFT");
break;
case 'd':
Serial.println("Moving RIGHT");
break;
case 'x':
Serial.println("STOPPED");
break;
default:
Serial.println("Unknown command");
break;
}
}
}
```
### **Example 4: Multiple Value Input**
```cpp
void setup() {
Serial.begin(9600);
Serial.println("RGB LED Controller");
Serial.println("Format: R,G,B (e.g., 255,128,64)");
}
void loop() {
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
input.trim();
// Parse comma-separated values
int firstComma = input.indexOf(',');
int secondComma = input.indexOf(',', firstComma + 1);
if (firstComma != -1 && secondComma != -1) {
int red = input.substring(0, firstComma).toInt();
int green = input.substring(firstComma + 1, secondComma).toInt();
int blue = input.substring(secondComma + 1).toInt();
Serial.print("RGB: ");
Serial.print(red);
Serial.print(", ");
Serial.print(green);
Serial.print(", ");
Serial.println(blue);
// analogWrite(redPin, red);
// analogWrite(greenPin, green);
// analogWrite(bluePin, blue);
}
else {
Serial.println("Invalid format! Use: R,G,B");
}
}
}
```
## **Common Input Patterns**
### **1. Command-Response Pattern**
```cpp
void loop() {
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n');
command.trim();
// Process command
processCommand(command);
// Send response
Serial.println("Command processed: " + command);
}
}
```
### **2. Continuous Data Reading**
```cpp
void loop() {
while (Serial.available() > 0) {
char c = Serial.read();
// Process each character
processCharacter(c);
}
}
```
### **3. Buffered Input**
```cpp
String inputBuffer = "";
void loop() {
if (Serial.available() > 0) {
char c = Serial.read();
if (c == '\n') {
// Process complete line
processLine(inputBuffer);
inputBuffer = "";
}
else {
inputBuffer += c;
}
}
}
```
## **Input Validation and Error Handling**
### **Basic Validation**
```cpp
void loop() {
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
input.trim();
if (input.length() > 0) {
// Valid input received
processInput(input);
}
else {
Serial.println("Empty input received");
}
}
}
```
### **Range Validation**
```cpp
void loop() {
if (Serial.available() > 0) {
int value = Serial.parseInt();
if (value >= 0 && value <= 100) {
Serial.print("Valid value: ");
Serial.println(value);
}
else {
Serial.println("Value out of range (0-100)");
}
}
}
```
### **Type Validation**
```cpp
void loop() {
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
input.trim();
// Check if input is numeric
for (int i = 0; i < input.length(); i++) {
if (!isDigit(input.charAt(i))) {
Serial.println("Invalid input - numbers only");
return;
}
}
int value = input.toInt();
Serial.print("Valid number: ");
Serial.println(value);
}
}
```
## **Serial Monitor Settings**
### **Baud Rate**
- **9600**: Standard rate, good for most applications
- **115200**: Faster rate, good for high-speed data
- **Must match between Arduino and Serial Monitor**
### **Line Ending**
- **No line ending**: Raw data
- **Newline**: Adds '\n' character
- **Carriage return**: Adds '\r' character
- **Both NL & CR**: Adds '\r\n' characters
### **Autoscroll**
- **Enabled**: Automatically shows new data
- **Disabled**: Manual scrolling required
## **Troubleshooting Common Issues**
### **1. No Data Received**
```cpp
// Check if Serial Monitor is open
void setup() {
Serial.begin(9600);
Serial.println("System ready");
}
void loop() {
if (Serial.available() > 0) {
Serial.println("Data received!");
}
else {
Serial.println("Waiting for data...");
delay(1000);
}
}
```
### **2. Incomplete Data**
```cpp
// Use proper termination
void loop() {
if (Serial.available() > 0) {
String data = Serial.readStringUntil('\n');
if (data.length() > 0) {
Serial.print("Complete data: ");
Serial.println(data);
}
}
}
```
### **3. Buffer Overflow**
```cpp
// Clear buffer if needed
void loop() {
if (Serial.available() > 50) {
Serial.println("Buffer overflow - clearing");
while (Serial.available()) {
Serial.read();
}
}
}
```
## **Best Practices**
### **1. Always Check Available Data**
```cpp
if (Serial.available() > 0) {
// Process data
}
```
### **2. Use Appropriate Input Functions**
- **Single characters**: `Serial.read()`
- **Complete strings**: `Serial.readStringUntil('\n')`
- **Numbers**: `Serial.parseInt()` or `Serial.parseFloat()`
### **3. Validate Input**
```cpp
// Check range
if (value >= min && value <= max) {
// Valid input
}
// Check type
if (isDigit(input.charAt(0))) {
// Numeric input
}
```
### **4. Provide Clear Feedback**
```cpp
Serial.println("Enter a number (0-100):");
int value = Serial.parseInt();
Serial.print("You entered: ");
Serial.println(value);
```
### **5. Handle Errors Gracefully**
```cpp
if (Serial.available() > 0) {
int value = Serial.parseInt();
if (value == 0 && !Serial.available()) {
Serial.println("Invalid input - please enter a number");
}
else {
Serial.print("Valid input: ");
Serial.println(value);
}
}
```
## **Advanced Input Techniques**
### **1. Non-blocking Input**
```cpp
unsigned long lastInputTime = 0;
const unsigned long INPUT_TIMEOUT = 5000; // 5 seconds
void loop() {
if (Serial.available() > 0) {
lastInputTime = millis();
String input = Serial.readStringUntil('\n');
processInput(input);
}
// Check for timeout
if (millis() - lastInputTime > INPUT_TIMEOUT) {
Serial.println("Input timeout - please enter data");
lastInputTime = millis();
}
}
```
### **2. Input with Echo**
```cpp
void loop() {
if (Serial.available() > 0) {
char c = Serial.read();
Serial.print(c); // Echo the character
processCharacter(c);
}
}
```
### **3. Password Input**
```cpp
String password = "";
bool passwordMode = false;
void loop() {
if (Serial.available() > 0) {
char c = Serial.read();
if (passwordMode) {
if (c == '\n') {
Serial.println();
Serial.print("Password: ");
Serial.println(password);
password = "";
passwordMode = false;
}
else {
password += c;
Serial.print('*'); // Hide password
}
}
else {
if (c == 'p') {
passwordMode = true;
Serial.println("Enter password:");
}
}
}
}
```
## **Applications**
### **1. Remote Control Systems**
- Control LED brightness
- Adjust motor speed
- Change system parameters
### **2. Data Logging**
- Receive sensor data
- Configure logging parameters
- Control logging intervals
### **3. Interactive Projects**
- Menu-driven interfaces
- Game controls
- Educational demonstrations
### **4. Debugging and Testing**
- Send test commands
- Monitor system status
- Adjust parameters in real-time
## **Next Steps**
1. **Practice with different input types**
2. **Build interactive projects**
3. **Learn about advanced parsing**
4. **Explore wireless serial communication**
## **Resources**
- **Arduino Serial Reference**: Official documentation
- **ASCII Table**: Character encoding reference
- **String Functions**: Advanced string manipulation
- **Serial Communication**: In-depth theory and practice
TinkerBlock UNO R3 Starter Kit
Dive into the world of electronics, Arduino programming, and STEM projects with the Lonely Binary TinkerBlock Series Starter Kit.
- Choosing a selection results in a full page refresh.