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 MKR 1010) 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 check everything works ok.

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!

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

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

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

and for Mac:

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 orange LED blinking every second.

Arduino Blinking

Next up we will run through a reminder of 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.

This is quite rare but some Arduino boards require a little fiddling with firmware before you can use them. The MKR1010 is one of those boards. The notes below run you through the process.

First, select the firmware updater in:

Firmware Updater Menu

Then select the board, hit check updates, select the latest firmare (in my case it was 1.5.0 in Oct 2024) and then hit install. This will overwrite the current sketch on the board. When you get the message Firmware Successfully Installed you can close the firmware updater pop-up window.

Your board is now running the latest firmware.

Re-install the blink sketch to make sure all is still ok.

A key attribute of this board is that it has Wifi! In this section we will get it connected to the internet. Open up a new blank Arduino sketch and we will step through adding the code needed. If the sketch has a template setup and loop function select all text and delete, we want to start with a blank file. We recommend you add in some comments as you go to remember what the code you are adding is doing.

To get started we will use a handy example in the WifiNINA library.

File > Examples > WifiNINA > SimpleWebServerWifi

Once you have your password you can enter in your connections into the arduino_secrets.h file. This is a handy way of being able to use .gitignore to NOT upload your plaintext password to GitHub (and therefore the internet). We do a whole lecture on IoT security towards the end of term 1!

For the ssid enter: CE-Hub-Student

#define SECRET_SSID "CE-Hub-Student"
#define SECRET_PASS "ENTER-THE-PASSWORD-HERE"

Save your file in your own CASA0014 folder - I saved mine as webled-mkr1010.ino - and then upload it to your board.

Once uploaded you should see a comment on the terminal saying it is trying to connect to Wifi - it might take a little while but you should then see further commands which tell which IP address the board has obtained. Go to that address and follow the links to control your board.

Getting the IP address

You are now controlling your Arduino over the internet!

The main .ino file is hopefully reasonably self explanatory - a quick over is broken down below:

Includes your password file so that you can hide your password.

#include "arduino_secrets.h" 
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)

We define a variable to hold the status of the webserver, initialise it and declare a webserver on port 80.

int status = WL_IDLE_STATUS;
WiFiServer server(80);

In the setup we define an LED pin we want to control (make sure to add an LED to pin 9 - long leg to pin 9 short leg to the GND pin).

We initialise the wifi, check to see if latest firmware is installed and try to connect to the network. We don't leave this loop until we are connected. Once we are we then print out some info on the connection. Most importantly we print out the IP address the device is given. The printWiFiStatus function is defined further down in the code.

void setup() {
  Serial.begin(9600);      // initialize serial communication
  pinMode(9, OUTPUT);      // set the LED pin mode

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);     // print the network name to the console;

    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);
    // wait 10 seconds for connection:
    delay(10000);
  }
  server.begin();    // start the web server on port 80
  printWifiStatus(); // you're connected now, so print out the status

}

In the main loop we are:

void loop() {
  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("Click <a href=\"/H\">here</a> turn the LED on pin 9 on<br>");
            client.print("Click <a href=\"/L\">here</a> turn the LED on pin 9 off<br>");

            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          }
          else {      // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        }
        else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /H")) {
          digitalWrite(9, HIGH);               // GET /H turns the LED on
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(9, LOW);                // GET /L turns the LED off
        }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

The function below is a nice way to abstract out the information we want to print that tells us about the connection. For example, once we know the IP address

void printWiFiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  // print where to go in a browser:
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
}



While you are waiting for everyone to complete this task why not try and add some more information or styling to your page. Have a go at editing these lines.

// the content of the HTTP response follows the header:
client.print("Click <a href=\"/H\">here</a> turn the LED on pin 9 on<br>");
client.print("Click <a href=\"/L\">here</a> turn the LED on pin 9 off<br>");

Hint: think of these lines as the window where you can add in any HTML instructions.

Or maybe you can use the built in RGB LED on the MKR1010.

RGB LED MKR1010 gif

Well done! You have created an interactive system using Arduino! In the final section we will discuss libraries.

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

The next 3 extra sections 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.

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 and 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).

The end! Welldone if you read to this stage of the workshop - you are obviously committed and that will be rewarded!