Can You Debug Code In The Arduino IDE? Here’s How To Do It!
Even though I’m no Arduino expert, I do have over 2 years of programming experience. It’s enough for me to program independently and debug my code when issues in my code arise.
Debugging is basically locating and resolving any software (or hardware) issues that arise, and when I was programming with JavaScript (JS), I would often troubleshoot my code in the console.
When I made my transition to the Arduino IDE (Integrated Development Environment), I didn’t know where and how I can debug my code. Now that I am more experienced, I can answer the question: “Can you debug code in the Arduino IDE?”
You can debug your code in the Arduino IDE by utilizing these 2 different methods: clicking the ‘Verify’ button on the top left-hand corner of the Arduino IDE or using the serial monitor on the top right-hand corner of the Arduino IDE.
The first method (verifying your code) is the easiest. From my personal experience, you should press the verify button after every 2 to 4 lines of code you write. That way, you can catch your mistakes early on, which makes them easier to fix. If you wait until the end, this method won’t be as efficient as the second one.
Consequently, I want to dedicate the rest of this article to the serial monitor method. I’ll talk about what it is and how you should be using it to debug your code.
However, before I go into detail on those two topics, I want to first discuss serial communication and baud rate. They are what allow the serial monitor to do what it does best.
What Is Serial Communication?
In essence, serial communication is a process of transmitting and receiving bits of information one at a time from one device to another.
Similar to how there are many different ways for us to communicate with each other (i.e. languages), serial communication has many different forms. However, we’ll only need to worry about one when talking about the serial monitor: serial communication via USB (universal serial bus).
You can communicate with different serial communication protocols like the Inter-Integrated Circuit (I2C), but the one we need to focus on is called USART or Universal Synchronous/Asynchronous Receiver/Transmitter.
Basics of USART
USART is a physical hardware that can either be used by itself as an integrated circuit or come built into a microcontroller. How it works is by changing parallel data on one device to serial transmission, and then reverting it to parallel data on another device.
This communication protocol is very simple and easy to use, and many microcontrollers come with the USART built-in. For example, the Arduino Uno R3 uses the ATmega328P chip, which is equipped with the USART.
The USART on the board utilizes the TX and RX pins to transmit and receive data (respectively). Typically, the TX pin of one device is connected to the RX pin of another device. We’re able to transmit data over the wire when you toggle the state of the TX pin between LOW (0) and HIGH (1).
The LOW state would be associated with the start bit (or when you’re sending a message) whereas the HIGH state would correlate to the stop bit (basically the end of a message). In between those two bits, you would also get a specified amount of bits (typically around 8) and the occasional parity bit.
Some of you may not understand some of the jargon I just used, so let’s break them down:
What is the START bit?
The start bit changes the TX pin’s state from HIGH to LOW when the user is prepared to transmit data, and it is one bit.
The RX pin will be on the lookout for the change, so when the pin notices it, it’ll be thinking “The TX pin is transmitting something to me right now!”
Similar to how you can only send one bit at a time, the RX pin can only receive one bit at a time, too. However, it only starts sampling after waiting for every one and a half cycles starting from the starting state change.
The 1 and 1/2 cycle was used instead of a whole number like 1 or 2 because the receiver wanted to start sampling at the middle of the signal to make sure it was reading the signal correctly.
What is a PARITY bit?
A parity bit is mainly used by the receiver to scrutinize the information that is being received and whether there are any errors in the data frame.
How it works is that before the sender and receiver start transmitting and receiving messages, they both agree on whether they’re using an even or odd parity. The definition of parity is whether a number is odd or even. For example, the parity of the number 67 is odd.
Now, the parity is calculated when you count both the number of bits that have a value of 1 in the data frame and the parity bit. If you (the sender) and your friend (the receiver) both agree on an odd parity, the parity calculation must turn out to be an odd number. If it results in an even number, then there is an error.
What is the STOP bit?
A stop bit is the exact opposite of a start bit: it sets the transmitting (TX) pin to HIGH to stop the exchange of bits once the final bit has been received.
The TX pin’s state will continue to remain as HIGH until the next round of messages needs to be sent. The whole process will restart once the start bit turns the TX pin’s state to LOW.
Fortunately, we get to use a USB cable to let our Arduino board communicate with the computer.
What Is Baud Rate? Why Is It So Important?
Basically, the baud rate is the number of times in which the signal changes per second.
For our purposes, we would set the serial monitor’s baud rate to 9600 bps (bits per second) using the function Serial.begin() in our code, like this:
Serial.begin(9600); // the baud rate is the value that goes inside this function
Serial.print("Hey there"); // this just prints the message in the Serial monitor
A baud rate of 9600 bps essentially means that the signal changes every 1/9600 seconds.
Now, you may be wondering: “Why is the Arduino baud rate 9600 bps?”
We’re establishing 9600 as the baud rate because it’s a convention for all Arduino users. This baud rate is sufficient for almost all the serial communication done.
Because it works so well, everyone just decided to go with it. Why would you want to change something that works?
However, there isn’t any particular reason why you can’t use a different baud rate. You don’t have to use 9600 as the baud rate: you can set the baud to a higher or lower value.
If you do decide to go higher than 9600 bps, you have to make sure you change the baud rate on the serial monitor to match it.
Why is this important?
If you transmit information at a faster speed than the speed you’re receiving it at (or vice versa), there would be chaos because you simply can’t get all the information.
Necessary Serial Communication Functions Overview
Before we work with the serial monitor, there are necessary functions you’ll need to use:
- Serial.begin()
- Serial.print()
- Serial.println()
These functions are all part of the Serial library. A library in the Arduino IDE is basically a collection of functions that serve a common purpose.
Serial.begin()
When you’re using the serial monitor, the first function you need to type out is Serial.begin(). This is basically setting the serial communication between your Arduino board and your computer.
For example, if you’re cooking food, you first have to set up everything you need to cook. You’ll need to buy and wash fruits and vegetables, defrost fish, or chop up your meat. In this analogy, the Serial.begin() function is the preparation required before the cooking.
Most of the time, when you use this function, you’ll be putting it in the setup() function because you only need to run it once.
The syntax for this function is:
Serial.begin(baud rate);
Typically, the baud rate used in this function is 9600 bps (bits per second):
Serial.begin(9600);
Serial.print()
This function can print out messages on the serial monitor. The syntax for it is this:
Serial.print(val);
Serial.print(val, format);
The second parameter is optional, and it applies to only numbers as the ‘val’ parameter. The format can be binary (base 2), decimal (base 10), etc.
Anyways, you can print out numbers, text, characters, variables, etc by passing them through as the first argument (val). However, if you’re printing text or characters, you’ll need to put them in strings, which are anything inside double quotation marks (“”).
Serial.println()
This function does the same thing as Serial.print(), but it prints each new message on a different line.
For example:
// if you use Serial.print("hi");, you'll see:
hihihihihihihihihi
// if you use Serial.println("hi");, you'll see:
hi
hi
hi
hi
hi
hi
hi
hi
hi
As you can see, this is more human-readable and less confusing. The syntax is almost identical to Serial.print():
Serial.println(val)
Serial.println(val, format)
How To Debug In The Arduino IDE
The best method for debugging code in your Arduino IDE is by using a serial monitor.
The first thing you’ll need to do to start debugging is establishing the serial communication. To do this, go to your void setup() function and add Serial.begin(9600):
void setup() {
// your other code in setup goes here
Serial.begin(9600);
}
After that, you’d go into your loop function and choose one of these two options:
- Use Serial.print() with a string that says random things as the first parameter, or
- Use Serial.print() with a variable as the first parameter
Most of the time, I’ve found that errors in code occur because your if statements and/or your loops (such as while or for loops) have mistakes in which the condition will never be true. Alternatively, your while or for loops never specified an exit condition, which means your sketch will only run the code inside the loop because it can’t break out of it.
To fix these issues, I personally start with option one. I put a Serial.print() function (with a string inside it) inside the if statement or loop and another one outside of it. That way, I can see whether my sketch is running the code inside the if statement or loop and whether it’s exiting it properly.
For example:
int evenNum = 7;
void setup() {
// your other code in setup goes here
Serial.begin(9600);
}
void loop() {
if (evenNum == 2) {
Serial.print("I am inside now");
}
Serial.print("Not inside if statement");
}
As you can see, the string “I am inside now” will never show up because evenNum is a 7, not 2. This proves the if statement’s condition to be false, which means the code inside it won’t run.
Normally, I would’ve found all my mistakes and stopped there, but if I’m manipulating a variable inside these statements or loops (or even outside of loops), I would put the variable name in the Serial.print() function.
That way, I’d know if the variable is acting the way I want it to act. For example, if my code is:
int evenNum = 7;
void setup() {
// your other code in setup goes here
Serial.begin(9600);
}
void loop() {
if (evenNum == 2) {
Serial.print("I am inside now");
evenNum ++;
}
Serial.print("Not inside if statement");
}
and the result I’m getting in my serial monitor is this:
Not inside if statement
Then, I know something doesn’t add up (this pun was intended). I’ll be wondering why the evenNum variable is not increasing and start resolving the issue.
As I’ve mentioned previously, I’m not highly recommending the verifying button method since it can’t catch all your mistakes. You can think of it as the spell check feature in Microsoft Word or Google Docs: it’s very easy to use and can find your mistakes, but it won’t catch them all. You’ll have to go back through and double-check everything yourself.
Summary – tl;dr (Too Long; Didn’t Read)
I understand that this article threw a lot of information at you, so here are the key take aways:
- Serial communication lets the Arduino board and your computer communicate with each other. This is very useful because it’s easier for you to debug your code.
- Baud rate is basically the speed at which individual bits of information is sent. We typically use 9600 in our Serial.begin() function because it’s convenient.
- You don’t have to use it. You can pick a smaller or larger number. Just make sure you make that change in the serial monitor.
- If you don’t, you will get weird results. That’s because you can receive all the information quickly enough if you’re sending it faster than you can receive.
- You don’t have to use it. You can pick a smaller or larger number. Just make sure you make that change in the serial monitor.
- To debug your code, you’ll need to:
- Type “Serial.begin(9600);” inside the void setup() function.
- Then, write a “Serial.print();” inside an if statement or loop and another one outside the loop/if statement. In the parentheses, you should either put a variable that’s changing so you can monitor what is happening to it or a string with random text (“like this”) to see if all your code is being run correctly.
If you want to do something more advanced, go check out my Arduino IDE alternatives guide as it will show you what other IDEs you can use. I be going over the pros and cons of these alternatives, so you’re not going to want to miss it!
Now that you have a good understanding of serial communication, you should be well on your way to debugging your code! Forget Captain Crunch, this is the only serial you need!