In this workshop you will learn:

This workshop is broken down into a few phases:

Download and install the Arduino IDE Click the JUST DOWNLOAD link to the left of the CONTRIBUTE & DOWNLOAD button. Once downloaded follow the instructions to install.

Create an account on GitHub if you don't already have one.

Get a git client. If you are comfortable using Git on the command line then go for it. As a reminder, Jon Reades did a great quick intro to Git and Github as part of Introduction to Programming.

If you prefer a GUI representation then download a git client to make your life easier. We use Tower which has a free version for students. We also hear good things about SourceTree and there are a few other open source GUI Clients here

First launch the Arduino IDE.

The screenshot below (from a Mac) shows an overview of the main elements of the Arduino 2.0 IDE you will work with today.

Arduino 2.0 IDE Screenshot

The screenshot below (from a Mac) shows an overview of the main elements of the Arduino 1.8 IDE. The notes in red highlight the main elements of the top navigation, the main body of the code and the message window at the bottom.

Arduino 1.8 IDE Screenshot

If you expand the File and Tools main menus. In the File menu Arduino ships with a bunch of useful examples to get you started and to help you explore. In the Tools menu there are a couple of menu items that you will need to get familiar with: the Board item shows you which kind of Arduino you are currently trying to program (in this case an Arduino Uno WiFi Rev2) and the Port item which shows you which USB port the device is connected to. In this case it is showing the port on a mac at /dev/cu.usbmodem14302 - if I was on a Windows machine it might say COM4.

Arduino Menus Screenshot

In the new IDE you can also the quick drop down to select your board.

Arduino Menus Screenshot

Further resources on the v2.0 IDE are available on the Arduino IDE 2 Tutorials page if you want to do a deeper dive into what is where.

In the next step we will upload are first Sketch and get the Arduino doing something for us.

To familiarise yourself with the Arduino platform load a basic blink sketch from the examples that are distributed with the Arduino IDE.

First off - plug in your Arduino to a USB port!
Arduino Board

Load the following sketch:
File -> Examples -> Basics -> Blink

Ensure board set to the Arduino you are using (e.g. Arduino Uno):
Tool -> Boards -> Arduino AVR boards -> Arduino Uno

Ensure the correct port for the Arduino Uno has been selected:
Tools -> Port:... as shown in the screenshot below for Windows:

and for Mac:

Note that the your board may connect on a different COM port to the one shown in the screenshot above (COM7) and will be called Arduino Uno (not Leonardo).

Now save and upload the sketch using the upload button (as shown below).

If you look at the Arduino board you should see the built in LED blinking every second.

Arduino Blinking

Next up we will run through the anatomy of a sketch (the setup and the loop) and then return to a bit of house keeping and work out where to store code on our own computers and in the cloud.

The light is flashing, but what was going on?

The beauty of microcontrollers are the simplicity of how programmes run. All Arduino sketches have two primary sections - void setup() which is executed once as the device is powered up, and void loop() which the continually runs until power is removed. Once the code within the latter function gets to the bottom it simply returns back to the start of the function and starts again - hence the name loop.

We look at each in turn:

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

In your blink sketch setup() calls just one function pinMode(). This function defines whether a pin you are connecting to is either an input or an output.

LED_BUILTIN is a variable within Arduino that defines which PIN the onboard LED is on. Traditionally this was on PIN 13 but some newer boards use PIN 6. To make it easier to manage this variable is defined by the board configuration so we don't have to think about it.

OUTPUT means that PIN is acting as an output ie current flows through it to drive an LED.

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(500);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(500);                       // wait for a second
}

In the loop() function we have 4 steps:

  1. the digitalWrite() function changes a digital pin with a value of HIGH or LOW. In this case we are setting the pin located at LED_BUILTIN (digital pin 13 on the Uno) to a value of HIGH. This sets the voltage level high and ‘turns on' the LED.
  2. the delay() function pauses the sketch for a defined number of milliseconds. In this case we are pausing for 500 milliseconds, or half a second.
  3. the value of LED_BUILTIN is now being set to LOW. This ‘turns off' the LED.
  4. finally we have another pause of half a second.

At the end of the loop() function the program returns back to the start of the loop() function and repeats. The structure of all sketches follow the same pattern.

The beauty of Arduino is there are loads of examples on the internet for you to experiment with. Most things you can imagine have probably already been implemented.

The Arduino IDE can be configured using the preferences section of the application. Equally if you have another code editor of choice they often have plugins to support Arduino sketch development. The Arduino page here has some guidance on tweaking your environment.

The last thing we encourage you to think about at this stage in setting up your Arduino coding environment is the location where you will store files. By default Arduino stores files in your /Documents folder on a Mac or /My Documents folder on Windows and then in a subfolder called /Arduino. It is worth thinking about how you will organise and back up all your code through the rest of the year.

In the next section we will focus on how to share code and collaborate with others.

You should now have an Arduino sketch saved somewhere locally on your computer. The next stage is to share it online so that others can comment or commit to your project. For example, in Connected Environments we share our code repositories on a CE GitHub.

As an example the repo below shows basic instructions and the code needed to build a RPi that can pull data from a Things Network MQTT feed and push it into a MySQL database on the RPi.

The Intro to GitHub page gives a great overview of the basic features, using the Hello World instructions set-up a code repository with a README file.

Create a repo similar to this:

Following the GitHub Hello World example create a test repository and edit the readme file to say something along the lines of "This is a test repository for a CE lab - I am editing the readme via the web interface."

[Cloning, Editing and Pushing]

You can work directly on the files in the browser (sometimes easier if you are doing something simple like editing the README file) but for work flow most people download a client such as Tower mentioned in the Prerequisites. In this next step we will clone a repository to our local code file store, edit our local copy of the readme file and then push that back to GitHub.

First browse to your repo on Github, click the clone or download button on and copy the link to the repository.

Then open up your client app on your local machine (screenshots below for Tower on a Mac):

At the very bottom left of the screen is a + button to add a new repository. We have one setup on Github so we need to select the clone repository option. On selecting this a dialogue will appear; copy in a link to you repo, add in your github credentials and select the location on your desktop where you want to store your files.

Once cloned if you open up your repository you should see a screen similar to below and if you browse to the folder location you specified to clone to, you should see a local copy of all the files.

Similar to the ‘Intro to GitHub' above you now have access to a number of pull and push features that we will explore over the next few weeks. Each client will have their own tutorials such as this tutorial on Tower.

As a first step you could try editing your README file and then pushing it to the Master on Github. Using your text editor of choice (vi, nano, textedit, sublime, vscode, atom, notepad++ etc.) open the README file on your local machine and edit it with something like "This is a test repository for a CE lab - which was edited originally via the web interface, and now I am editing the readme via my local copy." Save the file and then go back to your Git client.

Click on working copy and you should see the file you have just edited. In the screenshot below I have selected the file, added an update title and some description text. Click Commit when done.

This has saved the "Commit" to your local branch (probably called "main") of the repository but not to the remote version. To do this you need to Push your branch - select the main branch and the HEAD which represents your last changes and then click the Push button (highlighted in red on Tower for Mac below). A dialog will pop up asking if you want to Push the Head.

Now when you head back to GitHub on the web you should see your local copies have meen synchronised with those on the server.

You can either keep the test repository there for posterity or feel free to delete it - we will not be using it again in the course.

[Pin Layout, Shields, Plugging in LED + Blink code]

Now that the housekeeping is sorted we can return to making some lights flash. Make sure your Arduino code you have been working on is in the folder you set-up in the previous step (or if you want to start fresh open up the blink example File>Examples>01.Basics>Blink and save a copy of it in your folder).

In our initial sketch we flashed a builtin LED on pin 13. Next we will start using the Pins on the Arduino to prototype our own circuit. The Arduino has a number of exposed female pins that allow you to quickly and easily plug in wires to connect sensors or actuators. A key part of the process of prototyping with microcontrollers is getting familiar with the input and output pins on the board you are using. As an example the standard Arduino has both digital and analog pins as shown in the diagram below from the Introduction to the Arduino Board webpage.

The green pins are digital (can be set hi or low). The blue ones are analog (using a 10-bit analog to digital converter reading a voltage between 0V and either 3.3V or 5V - hence converting to 0 to 1023 or 2^10). The orange ones are power and ground.

You will notice the diagram shows the board having 5V and 9V. This is due to it being an image of an early board and highlights an important lesson:

For example, in setting up this tutorial an Arduino Uno Wifi Rev2 was used and the reference sheet found by googling arduino+pin+layout+uno+wifi+r2 and if you compare the two diagrams you will notice some differences.

Whilst the BUILTIN LED is great for debugging and checking the state of programmes, we want to flash a ‘real' LED.

The simplest way we can do this is to add an LED directly into the pins. The positive of the LED goes into PIN13 the negative needs to go to GND or ground which is conveniently located alongside.

Upload the blink sketch to the board and you should now see the LED flashing. LED not flashing? Two things you can check are at the bottom of the page.

In future workshops we will delve into LEDs in more detail and will caution about short circuits etc. But for now you have completed the Hello Word of physical computing!

_LED not flashing? This could either be because you have the long and short legs of the LED in the wrong pins, or you have defined your LED to be LED_BUILTIN rather than pin 13. Change all references to ‘LEDBUILTIN' below to ‘13'.

void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

Correct version when LED plugged into pin 13 and GND is:

void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(13, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

[Sensor, Breadboard, Ping code, Fritzing, Serial Monitor]

We previously saw that we could change the speed of flashing the light by changing the delay code in the Sketch.

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(500);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(500);                       // wait for a second
}

In this section we will introduce an sensor to programatically change the delay and therefore the rate at which the LED blinks. The sensor we will use is an ultrasonic rangefinder and can be seen as the ‘two eyed object' in the image below.

It works by sending a pulse to the sensor to initiate a reading, then listens for a pulse to return. The length of the returning pulse is proportional to the distance of the object from the sensor.

Whilst connecting directly into the pin sockets can be done, someone, somewhere, invented the really useful breadboard, which the ultrasonic rangefinder is plugged into in the image above. The breadboard essentially allows you to wire together circuits. To understand how they work it is worth seeing inside one:

As you plug in cables into the holes of the board you can make electrical connections - hence circuits.

The ultrasonic rangefinder we are using is the HC-SR04 - the web page and spec sheet highlight how the sensor works.

To get the HC-SR04 up and running we can use a variant on the PING example in File>Examples>06.Sensors>Ping. Can you spot why we cannot just use the code in the examples folder? (answer at bottom of page).

To update your blink sketch add the following code above the setup function:

#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.

// this constant won't change. It's the pin number of the sensor's output:
const int trigPin = 9;        //assign pin 9 to trigger
const int echoPin = 10;       //assign pin 10 to echo
const int LED = 13;           //keep the LED on pin 13
const boolean debug = false;  //variable to show hide debug info

// establish variables for duration of the ping, and the distance result in centimeters and one for LED blink rate:
long duration, cm;
int blinkrate = 0;

The code above defines the variables we will be using in the sketch. The comments describe what each variable is for. Add the following code into the setup function:

void setup() {
  // initialize serial communication:
  if(debug){
    Serial.begin(9600);
    Serial.println("Starting blinker");
  }
  pinMode(LED, OUTPUT);
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input     
}

In setup we are printing some information to the serial monitor if debug mode is true and defining the properties of the pins. Note that two pins are outputs (the LED and the trigger) and one is an input (the echopin which receives the response).

Add the following code into an empty loop function (ie delete any existing code):

digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

The code segment above triggers the ultrasonic rangefinder. It works by setting the trigger pin to LOW, waiting a couple of microseconds, setting it high for 10 microseconds, and then setting it back to LOW.

Next add the code to read the echoPin. Here we set the variable duration to equal the result of the function called pulseIn - which is a standard Arduino function that measures how long it takes to receive a HIGH value on the echoPin. The second line uses the value of duration from the previous line to work out the distance in cm from the echo using a converter function we will define further down the page.

duration = pulseIn(echoPin, HIGH);
cm = microsecondsToCentimeters(duration);

The last section of the loop function essentially blinks the LED according to the distance of an object from the sensor. The if statements create action based on three conditional states: less than 30cm, less than 90cm or greater than 90cm. The map function converts a number from one range to another and is used here to define how quickly the light blinks based on the size of the cm value (this will be covered later, more info can be found here if you cannot wait). The shorter the distance, the quicker the blinkrate. The delay at the end is just to reduce the speed at which measurements are taken to make the interaction smoother.

if(cm < 100){

  if(cm < 30){
    blinkrate = map(cm, 1, 30, 10, 300);
  }
  else if(cm < 90){
    blinkrate = map(cm, 30, 90, 300, 1000);
  }
  else{
    blinkrate = 0;
  }

  if(debug){
    Serial.print(" cm: ");
    Serial.print(cm);
    Serial.print("   blinkrate: ");  
    Serial.println(blinkrate);
  }
  digitalWrite(LED, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(blinkrate);                       // wait for a second
  digitalWrite(LED, LOW);    // turn the LED off by making the voltage LOW
  delay(blinkrate);

}

delay(20);

The final code block needed is the helper function for converting the duration of echo to a cm measurement and is based on the speed of sound being 340 m/s or 29 microseconds per centimeter. So if a ping travels out and back, to find the distance of the object we take half of the distance travelled. Just add the code below under the loop function.

long microsecondsToCentimeters(long microseconds) {
  return microseconds / 29 / 2;
}

Once the code is all written the last task is to wire up the circuit. Connect up the parts as shown on the Fritzing circuit diagram below.

Compile the sketch and upload to your Arduino. In the screenshot below you can see that I changed the debug setting to true and then once compiled and uploaded I selected the Serial Monitor at the top right so that I could see the debug info being printed.

Output below from Serial Monitor shows distance in cm and the respective blinkrate.

The full code for the sketch is in the Blinking Monster repo in a folder called blinker.

Answer: the default Arduino example uses a different model of ultrasonic rangefinder which has 3 pins compared to the one we use which has four (5V, GND, data vs 5V, GND, Trig, Echo) - hence the wiring is a little different.

[saving locally, saving on GitHub]

Now is a good time to save all your work and upload it to GitHub.

To get up and running quickly we used all the default file locations for Arduino. As we are about to start a series of workshops to test out ideas it is useful to create a common location where you will store your sketches locally and on GitHub. To do this we need to:

This checks in your work locally and now you need to push it to the master branch. Select master branch as per screenshot below and then ‘push' your local copy (in Tower there is a push button which is circled in red below).

Well done! You have created an interactive system and shared your code on GitHub. In the final section we will point you towards some libraries you may want to explore to get started.

Computing is all about abstraction and decomposition, breaking tasks into small pieces to help make the overall picture easier to understand. Libraries are essentially programmes that other people have written so that you don't have to repeat what they have done, you can just start to work with their tools.

We will cover many Libraries as we go through the workshops but feel free to start exploring. If you browse to the Arduino Libraries reference you will see examples of where people have already written code so that you don't have to - for example, most sketches I wrote over the past year used the WiFi NINA library.

To install third party Libraries follow the guide on the Arduino reference page. We are particularly fond of the Adafruit NeoPixels Library