Chapter 1: Hello World

There is an Arduino tradition that the first program written by a beginner should be one to blink the on-board LED. This reflects the assumption that you will be approaching the environment from an electronics viewpoint. The programming tradition is different. Programmers start with “Hello World”. That tradition goes back to a language called BCPL used by Brian Kernighan (or maybe Martin Richards) to write the first “Hello World” program probably in 1967. BCPL was commonly shortened to B so the programming language called C follows on.

The reason “Hello World” is an important start point when learning a new programming language or working with a new hardware platform is that it establishes a clear line of communication between running code and the programmer. There will always be a need to monitor events and program state during testing and throughout the development lifecycle. So, let’s keep with the programming tradition.

Plug your Arduino into your PC USB port. This will supply power to the Arduino and allow the Arduino IDE to upload and run new programs. For historical reasons the Arduino IDE refers to programs as “sketches”, here I will almost always use the term “program”.

Start the Arduino IDE and set the COM port for your device using the “Tools” menu if you have not already done so. By default, the IDE will display the last program you worked on when starting. If this is the first time you have run it then the IDE will create a default program format with just a couple of code statements. Selecting “New” from the “File” menu will also present you with a near empty program.

One of the challenges of introducing programming as a new skill set is that learning requires you to write some code before any explanations of syntax and meaning would make much sense. So, let’s just barge ahead and get something running before getting analytical. The empty program created by the IDE will contain two blocks of text and symbols. One starts “void setup()” and the other “void loop()”. These text blocks are known as functions and together they form the basic structure of any Arduino C program.

We are going to start by adding two lines of C code to the setup() function. Type the two lines from the boxed area just below into that function.

void setup() {
    // put your setup code here, to run once:
    Serial.begin(115200);
    Serial.println(" Hello World");
}

Letter case and punctuation are important so take a little care to type in the line as shown. Each program line (called a statement) is terminated by a semi-colon. The body of the function starts with a { curly brace and ends with a matching } closing curly brace. Code blocks of every sort in C start and end with {} brace pairs.

Your IDE window should now look like this.

Hello World IDE

Use the “Tools” menu option or the button with a magnifying glass icon to open the Serial Monitor. This is a new window that supports communication with your Arduino. Use the pull-down list at the bottom right of this window to select the 115200 baud rate.

Then click the upload button and you will be prompted to save your program with a meaningful name rather than the default. Choose any name you like although HelloWorld might be a good choice. Once saved the program will be compiled and uploaded to your Arduino – where it will run. You should see the output “Hello World” displayed in the Serial Monitor window. If the output is garbled or truncated then check the baud rate and then that the same rate is passed to the Serial.begin() method in the first line of code within the setup() function. The simplest way to re-run the program is to press the re-set button on the Arduino although you can also re-start it with another upload – which you will need to do if any code correction is required.

Now for a short review. An Arduino program has two required program elements called functions. The first is setup() where program initialisation takes place. The setup() code is only run once after the program is uploaded, or the re-set button is pressed on the Arduino or power is restored to a board after being powered down. The second program element or function is called loop() and this code executes continuously until the Arduino is powered down or another program is uploaded. In our first example program there are no program statements in the loop() function so the Arduino will just sit busily doing nothing after executing the code in setup().

The setup() program element already had one line in it and that line started with two backslash characters. This is a comment line and comment lines can be used to document your code. Well-chosen code comments can be particularly helpful when you return to some code and need to quickly understand what the code is trying to do. Comment lines are ignored by the Arduino even if they contain otherwise valid C code.

The first executable code line in our first setup() function was Serial.begin(115200);. Take a moment to highlight Serial.begin in that line and then right click the highlighted area. One of the proffered options is to “Find in reference”. Select that option and the relevant Arduino language reference page will be loaded into your default browser. The reference page will confirm that the Serial.begin is a program element called a function or method and that it sets the baud rate (bits per second) for serial communication. The documentation also mentions that additional parameters can be passed to that method that can set the number of data bits, the parity and the stop bits. If you are old enough to remember accessing the Internet using a dial up modem then this probably feels familiar if a little arcane but serial communications are still an important feature of microprocessor implementations. Arduino communication protocols are a feature of a later chapter.

You will have noticed that the various elements of the code have been colour coded which helps differentiate between individual components within a program line. These colours can be set to your personal preferences but for the moment the colours highlight program elements that are recognised as being of a particular type – plus they give some assurance that they have been typed into a program correctly. As an experiment try deleting the full stop (period) between “Serial” and “begin” and then replacing it. Watch how the IDE responds to the changes.

The second line of our program was Serial.println("Hello World");

The Serial object has two similar methods (print() and println()) that send a representation of a given data item to the serial port as text characters. The choice of the verb print for the method names is embedded deep into computing history and predates what came to be called visual display units (VDUs). The key point is that this program line sends the text (enclosed within double quotation marks) Hello World to the serial port where it is displayed by the Serial Monitor. We will explore the two forms of Serial.print() further in the next program.

Just a quick aside here. I have used the term “function” for the setup() code and then “method” for .println() when the two look to be much the same sort of thing. Indeed, they are almost identical program elements but there is a convention that the functions provided by a class are called methods while the common or garden variety retain the “function” name. The program object with the name “Serial” is a C++ class and we will learn more about classes and C++ later in the book. For the moment just make a mental note that the words function and method apply to near identical program elements – chunks of code that get things done.

Now that we have established that an Arduino can communicate with the Serial Monitor (and by implication with other devices connected to a serial port) perhaps we should check that this can be a two-way conversation.

Interactive

Select the “New” option on the “File” menu or click the new Button on the Arduino IDE. This will open a new code window laid out just like the first. The content of the setup() function is going to be very similar to the first program and you might like to copy and paste that code before editing it to read as follows:

void setup() {
    // put your setup code here, to run once:
    Serial.begin(115200);
    Serial.println("Type me a number");
}

Then add the following lines to the loop() function so that it reads:

void loop() {
    // put your main code here, to run repeatedly:
    char nChar = 0;
    if (Serial.available() > 0) {
        nChar = Serial.read();
        if(isDigit(nChar)){
            Serial.print("Number received: ");
            Serial.println(nChar);
            Serial.print("In binary: ");
            Serial.println(nChar - 48, BIN);
            Serial.println("Send me another");
        } else {
            Serial.println("Did not look like a number");
        }
    }
}

Make sure the Serial Monitor is still visible and then upload this new program to your Arduino. Once the upload has completed the program will run and you should see the prompt “Type me a number” sent by your Arduino and displayed by the Serial Monitor. Now type a single digit (a number from 1 to 9) into the text box at the top of the Serial Monitor window and click the “Send” button on the Serial Monitor window. I sent the number 5 to mine and this was the result returned by the Arduino.

received: 5
In binary: 101
Send me another

Before we look at the program in detail, try at least two more experiments. Try sending a two digit number from the Serial monitor (say 23) and then next try one or more letters.

Now we have run some initial tests, let’s explore what is happening in the loop() function. Given that chapter 3 will soon begin a full exploration of the elements of C we can take the code at a fairly brisk pace and avoid getting bogged down in definitions too early.

The first line after the comment is

char nChar = 0;

This line creates and initialises a variable to store a single character.

The next line starts with the key word if followed by (Serial.available() > 0) which is a test to see if there is any incoming data from the Serial port and then a code block that starts and ends with {} curly braces. If there is a character waiting then the first line within the code block is executed to read a character into the nChar variable. Then, because we are cautious programmers, we have another if which starts another conditional code block. This is a section of code executed if the condition is met.

The statement if(isDigit(nChar)) uses an Arduino C function isDigit() to check that the nChar variable holds a numeric character between 0 and 9. If it does, then the program executes the code block within the next set of {} curly braces to send the expected output to the Serial Monitor. Immediately following that code block there is another keyword else which has its own code block. That code block contains a statement that is executed if the character entered is not a digit – as you will have seen when you used the Serial Monitor send button to send a letter rather than a number to your Arduino. The if(isDigit(nChar)){…} conditional block validated the program input coming from the serial connection to ensure it was of the expected type and also dealt with data of the wrong type.

When the data received by the program was considered valid then the program made use of the two Serial print methods to send the program output to the Serial Monitor. The Serial.print() method sends the value within the () brackets to the Serial Monitor and the Serial.println() method does the same thing but also appends a “newline” character to the end of the text representation of the value passed to the method. The newline character tells the Serial Monitor to start a new line for any following text with the cursor placed at the left-hand edge of the Serial Monitor window.

The line that reads Serial.println(nChar - 48, BIN); demonstrates that the .println() method can be passed two values (known as arguments or parameters) the second of which sets how the first value should be presented as text. In this instance, the output is in the form of a binary (base 2) number. The C programming language uses a system for encoding characters as numbers called ASCII and a table of ASCII codes can be found in Appendix 2.

I am sure that these first programming efforts have not put you off and that you will quickly become familiar with the words and structure of the language. There might be a few steep hills to climb in places but these basic elements will quickly become old friends as you learn more about C and programming in general.

Before we leave serial communications and mix in some electronics it is worth remembering what happened when we used the ‘Send’ button to pass multiple numeric characters to the Arduino. Each was treated individually as the Serial.read() method only read one character at a time (with the other waiting somewhere for its turn). This perhaps hints at how we might handle more complex serial input in the future.

Not a number?

As an exercise, you might like to remove the character type validation from this program and see what happens if you send non-numeric characters via the serial port. One way would be to place two backslash characters at the start of the lines you want to remove from the program – programmers call this “commenting out”. The loop() function would now look like:

void loop() {
    // put your main code here, to run repeatedly:
    char nChar = 0;
    if (Serial.available() > 0) {
        nChar = Serial.read();
        //if(isDigit(nChar)){
            Serial.print("Number received: ");
            Serial.println(nChar);
            Serial.print("In binary: ");
            Serial.println(nChar - 48, BIN);
            Serial.println("Send me another");
       // } else {
       //     Serial.println("Did not look like a number");
        //}
    }
}

Upload the revised program to your Arduino and give it a run.

What happens when you enter (say) the letter m? How about a capital M? Does this make sense after referring to the ASCII value table in Appendix 2?

Blink

Now let’s revert to type and run the standard microprocessor test program commonly known as “blink”. You may already done this when you first got your Arduino and wanted to check it was working but bear with me as there are things to learn here. We don’t need to write this code from scratch as it is available within the IDE as an Example program. Use the File menu to navigate to the Examples submenu, then take the 01.Basics option and then Blink. This will display a new code window containing the pre-written code sample.

The first few lines in the new code window are a long comment marked by the start characters /* and ended by */. This is a multi-line comment block and you can use this technique to add comments to your program alongside the single line comments we have already met. You can document your programs with as many comments as you like as they have no impact upon the resulting program size or performance. The compiler ignores comments and they are there for your benefit and the benefit of others who might read your code. In the case of this program they introduce the use of a digital pin to output alternate HIGH and LOW voltages rather well. As you progress you are unlikely to need to comment what digitalWrite(LED_BUILTIN, LOW); does as the meaning will become clear to you but you might write a comment saying why this line is being executed in circumstances where that was not immediately obvious from the context. Comments should be tailored to an audience – and you get to decide who that audience is and what their needs are.

Why not upload the program and admire the LED blinking on and off. The lines I would like to focus on are the two that say delay(1000);

The delay() function puts your Arduino into a state of paralysis for the stated number of milliseconds (thousandths of a second). This is great for a simple demo or test program but has a bit of a flaw. The microprocessor is unable to do anything else while the delay() function is executed. No input can be read from the Serial port, no digital or analogue pins can be set or read and no other program statements executed. This might be important if your Arduino were to be controlling the movement of a machine component and needed to know when a particular state had been reached – or perhaps when a robot you have built is about to run into a wall. Both these states might trigger a signal to one of the Arduino pins with the intention of “raising the alarm” or even just to record progress towards an objective.

There are occasions where the delay() function is useful – but in normal circumstances should only be used with much shorter time intervals – perhaps a single millisecond. A millisecond might seem pretty short to you and me but an Arduino can get a lot done in that sort of time-span. Fortunately, there is another example program available in your Arduino IDE that takes a different approach.

Blink Two

You can open the second blink example program by again using the File menu, Examples submenu, 02.Digital and then selecting Blink without delay. Open the example code, download it to your Arduino and check that once the program is loaded and executing that the LED blinks just as before. This version of “blink” makes use of the millis() function to read a counter maintained by your Arduino of the number of milliseconds that have elapsed since the current program was started. The loop() function can check this counter every time the loop function has completed the enclosed statements and is ready to execute them again. If enough time has passed, the code that changes the voltage state on the pin associated with the inbuilt LED can then be executed.

There are however a couple of potential snags that need highlighting even with this code sample. They help understand why effective C programming is just as important to an Arduino project as getting the electronics right. First off, the millisecond counter built into the Arduino will start again at zero one millisecond after it reaches 4,294,967,295. A quick calculation shows that will happen in a little less than 50 days (every 49.71026961805556 days to be a bit more precise). Arduinos, like all microprocessors, are designed to run a single program for ever and a day (well until something fails). If the timing of an event were more crucial than the duration of a LED blink then you might need to take this into account.

The timing functionality relies upon the program code checking the total elapsed time in milliseconds on schedule to turn the LED on or off. OK, the timing of a flashing LED may not be crucial but other timed activities might be. It is therefore important that any other processes, maybe monitoring input from the Arduino pins, executes in a short enough period of time to allow control to return to the elapsed time check. You will read about techniques for programming time critical tasks on an Arduino when you need to ensure they have priority and there are always a range of options available to help ensure that processes are efficient and integrate well with one another.

If we also take note that Arduinos have limited memory space (for program code and particularly for data storage) then it is clear that program efficiency could be the key to avoiding unexpected behaviours and even the difference between completing a project or finding it impractical. Fortunately, C is a programming language designed to be fast and compact. We have the software tool we need to navigate and avoid such hazards.

The next step is to explore just what a programming language is and then we can follow that with a properly paced introduction to C itself.