0% found this document useful (0 votes)
2 views42 pages

Week 1 Introduction To Arduino

The document provides an introduction to the Arduino ecosystem and the TinyML Kit used in the COM683 Edge and Embedded Intelligence module. It covers the setup of Arduino hardware and software, including the installation of necessary libraries and the basic structure of Arduino programming. The document also details the components of the TinyML Kit and instructions for connecting and configuring them for practical applications.

Uploaded by

dunemax5
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views42 pages

Week 1 Introduction To Arduino

The document provides an introduction to the Arduino ecosystem and the TinyML Kit used in the COM683 Edge and Embedded Intelligence module. It covers the setup of Arduino hardware and software, including the installation of necessary libraries and the basic structure of Arduino programming. The document also details the components of the TinyML Kit and instructions for connecting and configuring them for practical applications.

Uploaded by

dunemax5
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

COM683 Edge and Embedded Intelligence [Link].

uk
button

Week 1 Practical
Introduction to Arduino

Edge and Embedded


Intelligence
COM683
Page 1 of 42
COM683 Edge and Embedded Intelligence

Introduction
In this lab, you will:
• Be introduced to the Arduino ecosystem.
• Familiarise yourself with the Arduino TinyML Kit that will be used throughout the module.
• Configure the Arduino hardware and software.
• Deploy a simple programme (Sketch) onto the Arduino.
• Test the various sensors contained on the TinyML kit.

National Student Survey


Please take 10 minutes to complete the National Student Survey.
[Link]

Page 2 of 42
COM683 Edge and Embedded Intelligence

1. Introduction to Arduino
What is Arduino?
Arduino is an open-source electronics platform based on easy-to-use hardware and software. Arduino
boards can read inputs - light on a sensor, a finger on a button, or a Twitter message - and turn it into
an output - activating a motor, turning on an LED, publishing something online. You can tell your board
what to do by sending a set of instructions to the microcontroller on the board. To do so you use
the Arduino programming language, and the Arduino Software (IDE), based on Processing.

One thing we’d like to acknowledge here is that Arduino’s mission of creating easy-to-use hardware and
software has the necessary trade-off of limiting the feature set of its development environment to the
essentials. Over the years Arduino has been the brain of thousands of projects, from everyday objects
to complex scientific instruments. A worldwide community of makers - students, hobbyists, artists,
programmers, and professionals - has gathered around this open-source platform, their contributions
have added up to an incredible amount of accessible knowledge that can be of great help to novices
and experts alike.
There are many Arduino boards available for purchase. The selection of which relies on the application.
In this module we will use the TinlyML Kit. But we will get to that later. First let’s introduce the Arduino
Integrated Development Environment (IDE) which is used to programme Arduino.

What is an Integrated Development Environment (IDE)?


As is true for all forms of programming, an integrated development environment, or IDE, is an
application with a feature set that facilitates software development generally or within a particular
niche. The Arduino Desktop IDE is highly specific in the sense that it is intended to facilitate
software development for a specific set of microcontroller boards, in C++.
Within the niche of IDEs for embedded software, there is a noticeable dichotomy between
light-weight applications, (like Arduino’s IDE) that minimize functionality and abstract away details
in the name of simplicity and full-featured IDEs (like Keil µVision and Visual Studio Code) that exist
to support industry professionals.
If you’re interested in finding a happy medium to use in future embedded projects, we have had
good experience using VS Code with the hardware specific extension PlatformIO, that together
enable nice-to-have features like line completion, reference tracking, etcetera, without all of the
complexity that more advanced IDEs introduce. Having said this, this particular combination of VS
Code + PlatformIO will not be officially supported within this module.
Download the OS specific Arduino IDE

What is the Arduino IDE?


As you might expect given the description above, the Arduino IDE is a light-weight development
environment with features that permit you to very quickly manipulate microcontroller development
boards. While there is a cloud-based offering (the Arduino Create Web Editor) as

Page 3 of 42
COM683 Edge and Embedded Intelligence

well as a so-called Arduino Pro IDE that is in development (specifically in the alpha stage at the
time of writing), we are going to use the standard Arduino Desktop IDE in this module.

A Quick Tour of the IDE

<-Menus and Toolbars

<-Coding Area

<- Console

IDE stands for Integrated Development Environment. The IDE is a text editor-like program that
allows you to write Arduino code. When you save a file in Arduino, the file is called a sketch – a
sketch is where you save the computer code you have written.
When you open the Arduino program, you are opening the IDE. Click on File and open a blank
sketch. When you first open the IDE, you will see a screen that looks something like the above
screenshot.
Up at the top of the IDE, you will find the menus and the toolbar, which we will explore as we work
through the rest of this document and when we run the tests later in this section.
Below that, you will find the file tabs. For now, there will only be one file open that is most likely
named sketch_<date>, however, later in the module when we work through more complicated
examples, you will see all of the various files that make up the project across the file tab area. In
“Arduino speak,” a sketch is a simple project/application.

Page 4 of 42
COM683 Edge and Embedded Intelligence

In the middle of the screen, you will see the large code area. Each sketch can consist of many files
and use many libraries, but at its core, each sketch is made of two main functions, “setup” and
“loop”, which you can see pre-populated in the code area. We’ll explore what those functions are
used for through the Blink example later in this practical. For now, let's continue orienting ourselves
with and setting up the IDE.
Finally, at the bottom of the screen, you’ll find the console. This is where you will see debug and
error messages that result from compiling your C++ sketch and uploading it to your Arduino.

Coding in the Arduino Environment


The coding language that Arduino uses is very much like C++ (“see plus plus”), which is a
common language in the world of computing. The code you learn to write for Arduino will be very
similar to the code you write in any other computer language – all the basic concepts remain the
same – it is just a matter of learning a new dialect should you pursue other programming
languages.
The code you write should be “human readable” and will be organized for a human to follow. In the
following assignments/applications you will be seeing a lot of code organized into different files.
This preserves readability and you can trace functions to their parent/header files(.hpp). The IDE
translates the code into machine-readable code to be executed by the Arduino. This process is
called compiling.
If you have errors in your computer code, the compiler will display an error message at the bottom
of the IDE and highlight the line of code that seems to be the issue.
Let’s look at some syntax. A semicolon needs to follow every statement written in the Arduino
programming language. For example,

int LEDpin = 9;
In the above statement, We declare an integer variable named ”LEDpin” (see what I did here,
human readable) and set it to tell the microcontroller that it is connected to pin 9 (could be a
digital or an analog pin).
Comments are what you use to annotate code. Good code should be commented on well.
//This is the pin on the Arduino that the LED is plugged into int
LEDpin = 9
Comments will be ignored by the compiler – so you can write whatever you like in them. We use
“//” for starting a one line comment and

/* The multi-line comment */

Page 5 of 42
COM683 Edge and Embedded Intelligence

Now, let’s talk about the two functions used in nearly EVERY Arduino program.

void setup ( )
The function, setup(), as the name implies, is used to set up the Arduino board. The Arduino
executes all the code that is contained between the curly braces of setup() only once. Typical
things that happen in setup() are setting the modes of pins, starting
void setup( )
{
//the code between the curly braces is only run once for setup()
}
You might be wondering what void means before the function setup(). Void means that the function
does not return information.
1. setup() only runs once.
2. setup() needs to be the first function in your Arduino sketch.
3. setup() must have opening and closing curly braces.

void loop( )
You have to love the Arduino developers because the function names are so telling. As the name
implies, all the code between the curly braces in loop() is repeated over and over again – in a loop.
The loop() function is where the body of your program will reside.
As with setup(), the function loop() does not return any values, therefore the word void precedes it.
void loop( )
{
//whatever code you put here is executed over and over
}

Page 6 of 42
COM683 Edge and Embedded Intelligence

2. The TinyML Kit


Introduction to the Tiny Machine Learning (TinyML) Kit
In the picture to the right, you can see
all of the components included in the
purpose-designed kit that are
developed with Arduino. Arduino’s
Tiny Machine Learning Shield, or
PCB cradle (in the middle), for the
Nano 33 BLE Sense AI-enabled
microcontroller board (on the left)
that serves to breakout the MCU’s IO
to connectors that permit easy,
reliable connections with the
camera module (on the right), as well
as other sensing modules via
connectors included pre-emptively
for expansion to new areas of application, calling upon the Grove system for nearly plug-and-play
compatibility with a range of transducers. Fortunately, while the shield can certainly make your life easier
and lends a hand in creating reliable connections with off-board sensors/actuators, we can readily
replace its function with other off-the-shelf components (e.g., a breadboard and some wires as listed
below).

The table below is a list of parts available to you:


Description Part Number
Nano 33 BLE Sense with headers ABX00035
USB microB cable, often to type A or C Varied

Breadboard Varied

Camera sensor with breakout PCB OV7675

Setting up the kit


The steps required to set up the hardware are below:

1. Slot the Nano 33 BLE Sense board into the Tiny Machine Learning Shield.

Page 7 of 42
COM683 Edge and Embedded Intelligence

You’ll want to target the pair of spatially separated 1x15 female headers. Carefully align the pins of the
microcontroller board with the headers below and then gently push down until the board is seated flush
against the top of each header. The downward facing pins should no longer be visible. As best you can,
avoid touching the components atop the board to prevent inadvertently damaging the surface mount
devices. Pay attention to the orientation of the board so that the indication of the USB port on the PCB
silkscreen matches the physical port on the board itself.

2. Slot the OV7675 camera module into the shield using the same technique.

You’ll want to target the 2x10 female header. Carefully align the pins of the camera module with the
headers and then gently push down until the board is seated flush against the top of each header. The
downward facing pins should no longer be visible. As best you can, avoid touching the camera module
atop the board to prevent inadvertent damage. Pay attention to the orientation of the camera module so
that the

Page 8 of 42
COM683 Edge and Embedded Intelligence

camera sensor is to the right of the header array (as shown), further from the microcontroller board than
the header array.

Finally, use the provided USB cable (type-A to microB) to connect the Nano 33 BLE Sense development
board to your machine. If your PC only features type-C USB ports, you will need to obtain an adaptor.

Note that if you are only calling upon hardware found on the Nano 33 BLE Sense development board
(say the MCU and IMU), you could forgo connecting it to the Tiny Machine Learning Shield. If you need
to remove either the Nano board or the camera module from the shield, grip each side of whichever
board and pull back with a gentle rocking motion (back and forth) to work the pins out from the headers
below.

Page 9 of 42
COM683 Edge and Embedded Intelligence

3. Software Assembly
Setting up the Software.
Now that we have successfully completed the hardware assembly. Let’s move on to the software. We
will be installing some important libraries which are essential for this module!

Installing the Board Files for the Nano 33 BLE Sense


One of the primary advantages that the Arduino ecosystem affords is the portability of code you write
for one or another board within their line-up or even in porting code to affiliate boards. This is made
possible by the support files organized in the Boards Manager, which coordinates a download and
installation of files that detail the Arduino functions (sometimes ‘core’) that are defined for that particular
board (which is how hardware differences between boards are abstracted) as well as compiler or linker
details specific to the given board.

To install the board files that you will need for your Arduino Nano 33 BLE Sense, please do the following:

Open the Boards Manager, which you can find via the Tools drop-down menu. Navigate, as follows:
Tools → Board → Boards Manager. Note that the Board may be set to “Arduino UNO” by default.

In the Boards Manager dialog box, use the search bar at the top right to search for “mbed nano”
which should bring up a few results. We’re interested in the first result (as shown), named
“Arduino MBED OS Nano Boards,”. Make sure you select Version 2.3.1 or newer (tested up to
Version 3.0.1) and then click “Install.” As the install process

Page 10 of 42
COM683 Edge and Embedded Intelligence

progresses, you will see a blue completion bar work its way across the bottom of the Board
Manager window. Be patient, you may need to install USB drivers, which requires you to
approve an administrator privileges popup which can take a couple of minutes to appear.

After you have successfully installed the board, if you exit and re-open the Board Manager and
search again for “mbed nano” you will now see INSTALLED next to the library and the option
to “Remove” the library or install a different version.

Page 11 of 42
COM683 Edge and Embedded Intelligence

Installing the Libraries Needed for this Module


Another advantage of the Arduino ecosystem is the availability of a wide array of libraries for performing
various tasks, such as interfacing with a sensor module or manipulating data using common algorithms.
There are many libraries that can be accessed from within the Library Manager in the Arduino IDE as
described below. Check here for a complete list.

For this module, we are going to need four libraries. To install the libraries, please do the following and
make sure to install the version specified in the reading below or the tinyML applications will not work:

Open the Library Manager, which you can find via the Tools drop-down menu. Navigate, as follows: Tools
→ Manage Libraries.

Then, much like for the Boards Manager, in the Library Manager dialog box, use the search bar at the
top right to search for the following libraries, one at a time. Note that like with the Board manager, a blue
completion bar will appear across the bottom of the Library Manager window.

Page 12 of 42
COM683 Edge and Embedded Intelligence

The Tensorflow Lite Micro Library:


Search Term: Tensorflow
Library Name: Arduino_TensorFlowLite Version: 2.4.0-ALPHA

Google dropped the support for this library in their latest update. Don’t worry, you can still install it from
zip file. To do this:
• Go to the Blackboard Learn Area for this weeks practical.
• Download the Arduino_TensorFlowLite library.
• Unzip, copy and paste the library to the libraries folder of your arduino installation
(home/$USER/snap/arduino/current/libraries for linux users)
(~/Documents/Arduino/libraries for mac users (the Arduino folder is created in Documents
automatically during IDE install, if libraries folder does not yet exist, simply create and then
paste in the contents of the extracted "Arduino_TensorFlowLite" folder)).
• Restart the Arduino IDE and check that the library is installed by going to File/Examples/Custom
Libraries/.
• If the above steps do not work, then import the TensorFlowLite library by following the steps as
shown in the diagram below.

Page 13 of 42
COM683 Edge and Embedded Intelligence

The TinyML_COM683 Library for this Module!


You can download the library from Blackboard and follow the instructions to add it to your Arduino IDE.
There are 2 ways to do that:

1. Manually import the library


Once you get the library, just 3 steps are required before you can use it:
• Extract the archive.
• Place the library folder in Arduino/libraries/.
• Restart the Arduino IDE.

2. Import the library through the Arduino IDE

This will work only if you have created a .zip archive (not .rar or other extensions).

Simply open the Arduino IDE, click on “Sketch” > “Include Library” > “Add .ZIP Library…”, and browse
to find your .zip archive.

The Arduino IDE will extract the archive, place the library in the Arduino/libraries/folder, and update
itself so you don’t need to restart it.

Page 14 of 42
COM683 Edge and Embedded Intelligence

The library that supports the accelerometer, magnetometer, and


gyroscope on the Nano 33 BLE sense:
Search Term: LSM9DS1
Library Name: Arduino_LSM9DS1 Version: 1.1.0

Page 15 of 42
COM683 Edge and Embedded Intelligence

ArduinoBLE:
Search Term: ArduinoBLE Library Name: ArduinoBLE
Version: 1.2.1 or newer (tested up to 1.2.2)

Page 16 of 42
COM683 Edge and Embedded Intelligence

Setting your Preferences

You can adjust the preferences set for the Arduino Desktop IDE via the File drop-down menu, File →
Preferences or Arduino IDE → Settings.... There are a few preferences that we recommend enabling to
make the Arduino IDE a little easier to use, namely:

Show verbose output during: compilation and upload.


Enable code folding.
Display line numbers.

Note: If using version 2.X of the IDE, the preferences screen may look different. Code folding and line
numbering will not be an option but are included as default.

On final note, if you don’t like the default theme for the Arduino Desktop IDE, there is a nice tutorial for
a dark theme you can find here. Also, if you would like to learn more about the IDE, check out Arduino's
documentation.

And that’s it! Your Arduino IDE should be all configured for this module. Now that you have all of the
necessary board files and libraries installed, it’s time to explore the TinyML domain to the fullest.

Page 17 of 42
COM683 Edge and Embedded Intelligence

3. Deploying to the Arduino


The Arduino Blink Example
With the hardware and software all set up, we will now deploy the Arduino Blink example to make sure
everything is working properly and to give you your first experience deploying code to your Arduino!
Preparing for Deployment
Use a USB cable to connect the Arduino Nano 33 BLE Sense to your machine. You should see a green
LED power indicator come on when the board first receives power.

Open the [Link] sketch, which you can find via the File drop-down menu. Navigate, as follows: File
→ Examples → [Link] → Blink. You’ll notice that Arduino has provided a wealth of examples to
choose from should you like to explore the board more on your own outside of the course material. There
is great documentation about those examples on the Arduino website.

Use the Tools drop-down menu to select appropriate Port and Board. This is important as it is telling the
IDE which board files to use and on which serial connection it should send the code. In some cases, this
may happen automatically, but if not, you’ll want to select:

Select the Arduino Nano 33 BLE as the board by going to Tools → Board: <Current Board Name> →
Arduino Mbed OS Boards (nRF52840) → Arduino Nano 33 BLE. Note that on
Page 18 of 42
COM683 Edge and Embedded Intelligence

different operating systems, the exact name of the board may vary but/and, it should include the word
Nano at a minimum. If you do not see that as an option, then please go back to Setting up the Software
and make sure you have installed the necessary board files.

Then, select the USB Port associated with your board. This will appear differently on Windows, macOS,
Linux, but will likely indicate ‘Arduino Nano 33 BLE” in parenthesis. You can select this by going to Tools
→ Port: <Current Port (Board on Port)> → <TBD Based on OS> (Arduino Nano 33 BLE). Where <TBD
Based on OS> is most likely to come from the list below where <#> indicates some integer number.

Windows → COM<#>

macOS → /dev/[Link]<#>

Page 19 of 42
COM683 Edge and Embedded Intelligence

Linux → ttyUSB<#> or ttyACM<#>

Finally, use the checkmark button at the top left of the UI to verify that the code within the example
sketch is valid.

Verification will compile the code, so take note of the status and results indicated in the black console at
the bottom of the IDE. The level of detail presented here will depend on whether or not you have enabled
‘verbose output during compilation’ in Preferences. You should most likely at the end see a final output
indicating how much memory the sketch will take on the Arduino once it is uploaded. Something like:
“Sketch uses 86568 bytes (8%) of program storage space. Maximum is 983040 bytes. Global variables
use 44696 bytes (17%) of dynamic memory, leaving 217448 bytes for local variables. Maximum is
262144 bytes.” As you can see, this is a very simple example and does not take up much space. While,
as you’ll see in a moment, uploading your code will also verify your code automatically, it is often helpful
to verify your code first as you can iron out any compilation errors without having any hardware on hand.

Deploying (Uploading) the Sketch


Once we know that the code at hand is valid, we can ‘flash’ it to the MCU:

Use the rightward arrow next to the ‘compile’ checkmark to upload / flash the code.
Note that pragmatically, this step will re-compile the sketch before flashing the code, so that in the future
if you intend to sequentially compile and flash a program, you need to only press the ‘upload’ arrow.

As before, take note of the status and results indicated in the black console at the bottom of the IDE. The
level of detail presented here will depend on whether or not you have enabled ‘verbose output during
compilation’ in Preferences, accessible via the File drop-down menu in the IDE.

You’ll know the upload is complete when you see red text in the console at the bottom of the IDE that
shows 100% upload of the code and a statement that says something like “Done in
<#.#> seconds.” Again, if this is the first time you are uploading a sketch to an Arduino, the upload may
hang for a little while until you get another administrator approval popup and approve it. Don’t worry, this
is just a one time thing.

If you receive an error, you will see an orange error bar appear and a red error message in the console
(as shown below). Don’t worry -- there are many common reasons this may have

Page 20 of 42
COM683 Edge and Embedded Intelligence

occurred. To help you debug, please check out the FAQ appendix at the end of this document with
answers to the most common errors!

At this point, you’ll want to look at the board itself. The orange LED opposite the green LED power
indicator about the USB port should now be blinking!

Page 21 of 42
COM683 Edge and Embedded Intelligence

Understanding the Code in the Blink Example

Now that you have gotten the blink example deployed to your microcontroller, let's explore the code as
shown below.

You’ll notice that it consists of two functions: setup, and loop. As we mentioned before, this is the
standard setup for an Arduino sketch. This is because when the Arduino turns on it runs the setup()
function ONCE to initialize (aka setup) the sketch. Then it runs the loop() function infinitely many times
(aka it runs as an infinite loop) to execute the sketch. This works well for most tinyML applications as
they are designed to respond to continuous sensor input. You can imagine in the case of Keyword
spotting that we need to initialize the neural network and the microphone and then in a loop we want
to listen to audio and trigger (or not) depending upon the output of the neural network!

// the setup function runs once when you press reset or power the board

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

Page 22 of 42
COM683 Edge and Embedded Intelligence

digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW

delay(1000); // wait for a second

You’ll also notice that both functions have the void return type as they do not ever return anything
but instead have side effects.

For example, in the setup function the LED_BUILTIN (which is a shortcut name for the pin that
controls the voltage to the LED) is set to be an output for the duration of the loop. In general, you
will need to set all of the pins you use as either inputs or outputs during the setup function. If you
wired up the camera yourself, you have already explored a lot of the special names reserved for the
pins as shown on the pinout diagram.

In the loop function, you’ll notice that we are alternating between writing a HIGH (aka turning on the
LED) and writing a LOW (aka turning off the LED). The delay of 1000 milliseconds (1 second)
between each step is crucial as otherwise the light would turn on and off so fast that it would be
imperceptible. In fact, if you make the delay too short the light will simply seem to be dim. This is a
trick called Pulse Width Modulation that is actually used often in industry to e.g., control motors. If
you’d like, feel free to experiment with modifying these delays and redeploying the code to see its
effect!

Page 23 of 42
COM683 Edge and Embedded Intelligence

4. TensorFlow Light got Arduino


Testing the TFLM Installation
In this reading, we are going to walk through deploying the ‘Hello World’ example provided in the
TensorFlow Lite for Microcontrollers (TFLM) library. The Hello World application runs a neural
network model that can take a value, x, and predict its sine, y. Visually, the sine wave is a pleasant
curve that runs smoothly from –1 to 1 and back. This makes it perfect for controlling a visually
pleasing light show! We’ll be using the output of our model to power a smoother blink of your Arduino
LED.

While the result won’t differ greatly from what we’ve accomplished with the standard Arduino Blink
sketch we just deployed (in either case, an LED will be turning on and off), in this instance, we are
going to be deploying a model. Previously, we have learned about how neural networks can learn
to model patterns they see in training data to go on to make predictions. Here, the model we deploy
will map an input (x) to an output y = sin(x). While this is admittedly contrived, it will allow us to
quickly evaluate if the TFLM stack is functional on the hardware in front of us by using this output y
to control the intensity of light emitted by the on-board LED. As promised, below, you’ll find
instructions and screenshots and short videos walking you through the process!

Preparing for Deployment:


Use a USB cable to connect the Arduino Nano 33 BLE Sense to your machine.

Open the hello_world.ino sketch, which you can find via the File drop-down menu. Navigate, as
follows: File → Examples → Arduino_TensorFlowLite → hello_world.

Page 24 of 42
COM683 Edge and Embedded Intelligence

Just like with the Arduino Blink example (and as we will do for every deployment), use the Tools
drop-down menu to select appropriate Port and Board.

Select the Arduino Nano 33 BLE as the board by going to Tools → Board: <Current Board Name>
→ Arduino Mbed OS Boards (nRF52840) → Arduino Nano 33 BLE. Note that on different operating
systems the exact name of the board may vary but/and it should include the word Nano at a
minimum. If you do not see that as an option, then please go back to Setting up the Software and
make sure you have installed the necessary board files.

Page 25 of 42
COM683 Edge and Embedded Intelligence

Then select the USB Port associated with your board. This will appear differently on Windows,
macOS, Linux, but will likely indicate ‘Arduino Nano 33 BLE” in parenthesis. You can select this by
going to Tools → Port: <Current Port (Board on Port)> → <TBD Based on OS> (Arduino Nano 33
BLE). Where <TBD Based on OS> is most likely to come from the list below where <#> indicates
some integer number.

Windows → COM<#>

macOS → /dev/[Link]<#> Linux → ttyUSB<#> or ttyACM<#>

As always, it is best practice to then verify that the code is valid. Note that this may take a while the
first time you run this as all of TFLM is being compiled (it will compile much faster in the future). Also,
you may, or may not, see a series of compiling warnings (but not errors) as the code compiles, this
is entirely normal either way and is the result of TFLM being bleeding edge software.

Page 26 of 42
COM683 Edge and Embedded Intelligence

Deploying (Uploading) the Sketch


Once we know that the code at hand is valid, we can flash it to the MCU:

Use the rightward arrow next to the ‘compile’ checkmark to upload / flash the code.

You’ll know the upload is complete when you see red text in the console at the bottom of the IDE
that shows 100% upload of the code and a statement that says something like “Done in <#.#>
seconds.”

If you skipped the verification step, do note that this may take a while the first time you run this as
all of TFLM is being compiled (it will compile much faster in the future). Also, you may, or may not,
see a series of compiling warnings (but not errors) as the code compiles, this is entirely normal either
way and is the result of TFLM being bleeding edge software.

At this point, you’ll want to look at the board itself. The orange LED opposite the green LED power
indicator about the USB port should now be fading at the rate set by the sinusoidal model. Note that
the default rate is quite fast so it should almost appear to be blinking very quickly. However, if you
look closely you’ll notice that it is fading in and out vs. blinking.

Page 27 of 42
COM683 Edge and Embedded Intelligence

Congratulations! At this point, if all has gone well, you can be sure that your embedded
microcontroller is configured properly to run TensorFlow Micro.

Understanding the TFLM Hello World Example


The first thing you will notice when looking at this example is that there is a lot more code in this
TFLM version of blink! However, at a high level the code is structured the same. There is still a
setup() function that runs once to initialize things and a loop() function that runs continuously to blink
the LED.

As far as the high level differences go, in the main hello_world file, before either of those functions,
there are a set of #include lines and global variable definitions. The #include lines are used to (in
Python speak) import the various libraries we need for this example. In this case it is the TFLM library
and some other helper functions. The global variables are defined outside of the setup()and loop()
functions, so that there are references to variables that can be used in both the setup() function as
well as in every loop of the loop() function. For example, the global tensor_arena memory is used to
initialize and store our neural network once and then is used to execute the neural network every
loop iteration. This is much more efficient than re-initializing the neural network in each loop iteration.

One other high level difference is that you’ll notice that there are a series of tabs across the top of
the IDE window. These tabs each represent different files that make up this hello_world project.
Each holds some helper functions or definitions that our main hello_world file uses.

For example, the [Link] file contains a large array which contains the binary data for the neural
network model (in fact, it is simply the binary version of the TensorFlow Lite file) as well as an integer,
which tells TFLM how long that array is. We’ll explore how that binary file is generated later in the
course!

Page 28 of 42
COM683 Edge and Embedded Intelligence

Getting back to the main hello_world file, as mentioned above, the setup() function has a decent
amount of code in it, but at a high level, it does exactly what you would expect, it initializes our neural
network.

The loop() function also has a decent amount of code in it, but again at a high level, all it does is
keep track of a counter over time for the x-value and uses the neural network to compute the
approximate y-value of y = sin(x) and then set the brightness of the LED according to that
approximate y value.

Page 29 of 42
COM683 Edge and Embedded Intelligence

5. Testing the Sensors


With tests of the microprocessor itself and TFLM stack completed, we can turn our attention to
verifying that the sensors required for this course are functioning properly. To do so, we’ll be calling
on a predefined script that the course staff have put together. By the end of this reading, you will
have seen live data streams for the on-board microphone, the STMicroelectronics, MP34DT05, the
on-board internal measurement unit (IMU), the STMicroelectronics, LSM9DS1, as well as at least a
static image return from the off-board OV7675 camera module, the OmniVision OV7675. We will
also detail the optional extensions you’ll need to do to obtain a live video feed from the camera as
well.

The Serial Monitor & Plotter


The Serial Monitor & Plotter are two core tools that you can use to get information from your Arduino
when it is connected to your computer with a data USB cable. In fact, as you develop your own
Arduino applications, you’ll probably find yourself opening up the Serial Monitor and using the
[Link]() command in your Arudino sketches much like how you have used the print() function
in Python or printf() function in C++. Since the Arduino sketch runs in an infinite loop, you may find
that it may be easier to plot the graph of the data you are sending back from the Arduino instead of
continuously printing the raw values, and that is where the Serial Plotter will come in.

While the primary function of the Serial Monitor (and the Serial Plotter) is to view data incoming from
the MCU, the Serial Monitor also features a text entry field that we will use to issue pre-
determined commands conveyed in the console.

Below we have included a screenshot of the Serial Monitor elements to differentiate where we
expect to see incoming data and where we can enter commands to send to the microcontroller:

You can open up the Serial Monitor (and Serial Plotter) by navigating through the menu to Tools
→ Serial Monitor or Tools → Serial Plotter.

Page 30 of 42
COM683 Edge and Embedded Intelligence

Testing the Microphone


Use a USB cable to connect the Arduino Nano 33 BLE Sense to your machine. You should see the
green LED power indicator come on when the board first receives power.

Open the test_microphone.ino sketch, which you can find via the File drop-down menu. Navigate,
as follows: File → Examples → TinyML_COM683 → test_microphone.

As always, use the Tools drop-down menu to select appropriate Port and Board.

Select the Arduino Nano 33 BLE as the board by going to Tools → Board: <Current Board Name>
→ Arduino Mbed OS Boards (nRF52840) → Arduino Nano 33 BLE. Note that on different operating
systems, the exact name of the board may vary, but/and, it should include the word Nano at a
minimum. If you do not see that as an option, then please go back to Setting up the Software and
make sure you have installed the necessary board files.

Then, select the USB Port associated with your board. This will appear differently on Windows,
macOS, Linux, but will likely indicate ‘Arduino Nano 33 BLE” in parenthesis. You can select this by
going to Tools → Port: <Current Port (Board on Port)> → <TBD Based on OS> (Arduino Nano 33
BLE). Where <TBD Based on OS> is most likely to come from the list below where <#> indicates
some integer number.

Page 31 of 42
COM683 Edge and Embedded Intelligence

Windows → COM<#>

macOS → /dev/[Link]<#> Linux → ttyUSB<#> or ttyACM<#>


Use the rightward arrow next to the ‘compile’ checkmark to upload / flash the code.
You’ll know the upload is complete when you see red text in the console at the bottom of the IDE
that shows 100% upload of the code and a statement that says something like “Done in
<#.#> seconds.”

Open the Serial Monitor. You can accomplish this in three different ways as shown below. If the
Serial Monitor fails to open, check to make sure the appropriate Port is selected. Sometimes, the
port is reset during the upload process.

Use the menu to select: Tools → Serial Monitor.

Click on the magnifying glass at the top right of the Arduino Desktop IDE.

Use the keyboard shortcut: CTRL + SHIFT + M or CMD + SHIFT + M depending on your operating
system.

When the Monitor opens, you should see the following text appear:

Welcome to the microphone test for the built-in microphone on the Nano 33 BLE Sense.

Use the on-shield button or send the command 'click’ to start and stop an audio recording Open the
Serial Plotter to view the corresponding waveform.

Page 32 of 42
COM683 Edge and Embedded Intelligence

Press the on-shield button to start an audio recording. After you do, a stream of data should appear
in the Serial Monitor. Press the button again to stop the recording. If the numbers were changing,
then your microphone is most likely correctly recording audio! Congratulations! If you do not have
the shield, you can also control the starting and stopping of the waveform by sending the command
click through the serial monitor. In the drop-down menu that reads “No line ending” by default at the
bottom right of the Serial Monitor, you need to select “Both NL & CR”. This tells the Serial Monitor
to send both a NL = new line character as well as a CR = carriage return character every time you
send a message. This is important for our application as our Arduino sketch is looking for that to
differentiate between each input.

To help visualize this a little better, we are going to use the Serial Plotter. Note that you cannot have
both the Serial Monitor and Serial Plotter open at the same time as the Arduino can only
communicate over a single serial port. Importantly, this also means that you cannot upload new
code to the Arduino if either the Serial Monitor or Plotter is open! You can open the Serial Plotter in
two ways:

Use the menu to select: Tools → Serial Plotter.


Use the keyboard shortcut: CTRL + SHIFT + L or CMD + SHIFT + L depending on your operating
system.

Perform the same experiment, press the on-shield button (or send the serial command click) to start
an audio recording and again to stop it. You should see a waveform appear on the Serial Plotter.
This is simply a graphical representation of the numbers you saw earlier on the Serial Monitor. Note
that the vertical axis of the Serial Plotter scales dynamically, so that the magnitude

Page 33 of 42
COM683 Edge and Embedded Intelligence

of the data conveyed is not fixed with respect to the enclosing window, but rather scaled to occupy
most of the headroom.

Now, record some audio again. This time, try to whistle or hum a constant tone. If you can keep the
tone constant, you should see the waveform start to look like a sinusoid. An example that the course
staff made is below. Don’t worry if you can’t get this to work perfectly. You should in general find
that a constant tone has a more constant pattern. If you make different sounds and you find that the
waveform changes, you can be confident that your microphone is working.

Note: The Arduino IDE 2 may not allow you to copy and paste from the serial monitor. If this is the
case, you can use another method, such as using PuTTy.

Page 34 of 42
COM683 Edge and Embedded Intelligence

Testing the Inertial Measurement Unit


Now, let’s open the test_IMU.ino sketch, which you can find via the File drop-down menu. Navigate,
as follows: File → Examples → TinyML_COM683 → test_IMU.

As always, use the Tools drop-down menu to select appropriate Port and Board.

Then use the rightward arrow next to the ‘compile’ checkmark to upload / flash the code. If you get
the error “Arduino_LSM9DS1.h: No such file or directory,” then please go back to Setting up the
Software and make sure you install the accelerometer, magnetometry, and gyroscope library! To
help you debug, please check out our FAQ appendix with answers to the most common errors!

Open the Serial Monitor and you should see the following. As a reminder, you can open the serial
monitor in one of three ways as shown below. If the Serial Monitor fails to open, check to make sure
the appropriate Port is selected. Sometimes, the port is reset during the upload process.

Use the menu to select: Tools → Serial Monitor.

Click on the magnifying glass at the top right of the Arduino Desktop IDE.

Use the keyboard shortcut: CTRL + SHIFT + M or CMD + SHIFT + M depending on your operating
system.

Welcome to the IMU test for the built-in IMU on the Nano 33 BLE Sense.

Available commands:
a - display accelerometer readings in g's in x, y, and z directions g - display gyroscope readings in
deg / s in x, y, and z directions m - display magnetometer readings in uT in x, y, and z directions

Like with the microphone, in the drop-down menu that reads “No line ending” by default at the
bottom right of the Serial Monitor, you need to select “Both NL & CR”.

Now, you can enter one of the possible arguments (a, g, or m) into the text entry bar across the top
of the Serial Monitor and click “Send.” As mentioned in the Serial Monitor, this will start to print the
data coming from the accelerometer (computing acceleration in the x, y, or z direction), the
gyroscope (computing the angular velocity -- the change in the roll, pith, and yaw), or the
magnetometer (computing the magnetic forces present on the IMU). Depending on your selection,
you should now see a stream of corresponding data. However, like with the microphone, this data
is hard to interpret in raw form. So, instead, let us open the Serial Plotter.
Close the Serial Monitor and open the Serial Plotter. As a reminder, you can open the Serial Plotter
in two ways:
1. Use the menu to select: Tools → Serial Plotter.
2. Use the keyboard shortcut: CTRL + SHIFT + L or CMD + SHIFT + L depending on your
operating system.

Page 35 of 42
COM683 Edge and Embedded Intelligence

With the Plotter open, you should see the same stream of data presented graphically. The most
interesting one to plot is the gyroscope. Again, make sure you have selected “Both NL & CR'' and

type “g” into the text entry box (now at the bottom of the window) and click “Send.”

Move the board around and observe the response. Can you figure out which axis of rotation is the
x, the y, and the z (also known as roll, pitch, and yaw)? If by moving the board around in different
directions you get different responses from the various lines in the Serial Plotter, you can feel
confident that you have a working IMU.

Page 36 of 42
COM683 Edge and Embedded Intelligence

Testing the OV7675 Camera


Now, let’s open the test_camera.ino sketch, which you can find via the File drop-down menu.
Navigate, as follows: File → Examples → TinyML_COM683 → test_camera.

As always, use the Tools drop-down menu to select appropriate Port and Board.
Note: if you did not purchase the Tiny Machine Learning Kit and sourced an OV7670, as compared
to the OV7675 that comes with the kit, you will need to make one software change as detailed at the
end of this document.

Then, use the rightward arrow next to the ‘compile’ checkmark to upload / flash the code. If you get
the error “Arduino_OV767X.h: No such file or directory,” then please go back to Setting up the
Software and make sure you install the accelerometer, magnetometry, and gyroscope library! To
help you debug, please check out our FAQ appendix with answers to the most common errors!
Note: if you get an error message that contains something like 'OV7675' was not declared in this
scope this means you already had a conflicting copy of the Arduino_OV767X library
installed on your system. We have bundled a forked copy of it with our library so please
uninstall the conflicting version.

Open up the Serial Monitor and you should see:


Welcome to the OV7675 test Available commands:
single - take a single image and print out the hexadecimal for each pixel (default) live - the raw bytes
of images will be streamed live over the serial port
capture - when in single mode, initiates an image capture

Type “single” in the text entry field and press send or hit the enter / return key.

The camera is now primed to take a picture. Now, you can either text “capture” or press the on-
shield button to take a selfie (or photo). To get the photo oriented correctly, make sure the “OV7675”
text on the camera module (or the “Tiny Machine Learning Shield” on the shield) is oriented such
that it would be readable by the subject of the photo (e.g., you if you are taking a selfie). The camera
does not have a large field of view, so if you are taking a selfie, make sure to hold the camera far
away from your face.

To view your image, you will need to copy the sequence of hexadecimal digits that will print to the
Serial Monitor and paste them into this Google Colab that we created to display the image (link
included below as well). If using V2.X of the IDE you may need to use Putty as before with the audio
sample. Note: in some versions of the IDE the large number of digits printed will cause an error in
the Serial Monitor and the text will seem to disappear. Don't worry the text is still there (it's just white
on a white background). Just highlight the whole line below "Image data will be printed out in 3
seconds..." and copy and paste it into the Colab and the digits will appear!

Page 37 of 42
COM683 Edge and Embedded Intelligence

[Link]
u sp=sharing

(Optional) Real-Time Video with Processing


If you are interested in seeing a live stream capture from the OV7675, you can do that, but not
through the Arduino IDE. You’ll have to use an additional piece of software, Processing. You
can download the application for your OS, here (we’ve tested with version 3.5.4). We would
like to note that we have found this to be buggy on Windows, which is why we provide this as
an optional extension and not the default suggested process.

Launch the test_camera example through the Arduino IDE, open the Serial Monitor, and then
type “live” in the text entry field and press send or hit the enter / return key. Your camera will
now be live streaming the image to the computer at 1 frame per second. Make sure to then
close the Serial Monitor to free up the serial port as we will be using it again later.
With Processing installed (which for some operating systems is as simple as unzipping the
pre-built application folder), open the Processing Application. You’ll find that the application
looks a lot like the Arduino Desktop IDE.
Then find your Arduino folder. On most operating systems it is located either in your home or
Documents directory.
In Processing, open the file Arduino → Libraries → TinyML_COM683 → extras →
CameraVisualizerRawBytes → [Link].
Go to lines 34-36 and update them to be the name of the serial port on which your Arduino is
currently connected.
Now, click the “run” play button at the top left of the UI. A pop-up should appear streaming the
camera image. Again, we have found this to be buggy on Windows, so don’t be surprised if
the image looks odd on Windows.

Page 38 of 42
COM683 Edge and Embedded Intelligence

6. FAQ
This section contains answers to Frequently Asked Question (FAQ) encountered when
setting up the TinyML hardware and deploying an Arduino Sketch for the first time.

I cannot upload code / device not found on listed ports


First ensure that the following are true:

a. The microcontroller is plugged into your machine

b. You are using the provided USB cable or a functional USB cable that isn’t intended
solely for power delivery (that is, capable of data exchange)

c. You haven’t introduced a defective USB hub or adaptor between the microcontroller
board and your machine.

d. You have selected the correct Board and Port.

e. The protective foam is removed from the board. It is a common mistake to think that
the protective foam that comes with the box is not conductive and therefore it can stay
attached to the pins as the board is functioning. The foam is slightly conductive and
can cause malfunctions and undesired behaviours (unwanted resets, interferences...)
when kept attached to the pins. The foam needs to be slightly conductive to protect
the board from ESD during shipping, but it needs to be removed before the board gets
powered on.

f. You have installed the correct version of the board files. Go back to the Setting up the
Software reading and make sure you installed the correct version from the board
manager. Remember, the reading will have the most up to date versions of everything
but we may not be able to update the videos overtime.

If all of the above are satisfied then you may need to manually put your board into Bootloader
mode in order to upload code. This happens from time to time and is nothing to worry about.
To activate Bootloader mode simply double tap the small white RESET button. The orange
built-in LED on the board will fade in and out. Do note that on some operating systems, the
board may increment to a different serial port.

Once the LED is fading on and off, try to upload the sketch again. Check if the sketch was
uploaded correctly and if the LED is blinking as expected. Note the difference between fading
(in bootloader mode listening for new code) and blinking (sketch successfully uploaded)

Page 39 of 42
COM683 Edge and Embedded Intelligence

Finally, once you successfully upload code, you may need to press the reset button one more
time to exit bootloader mode, if it doesn’t do that automatically, and you may need to reselect
the Port after you do that.

So in summary: double tap reset → upload → single tap reset and you should be ready to go!

Board at <serial port> not available, upload error


First ensure that the following are true:

a. The microcontroller is plugged into your machine

b. You are using the provided USB cable or a functional USB cable that isn’t intended
solely for power delivery (that is, capable of data exchange)

c. You haven’t introduced a defective USB hub or adaptor between the microcontroller
board and your machine.

d. You have selected the correct Board and Port.

If those are all satisfied then be sure that there aren’t other applications competing for access
to your MCU over the same serial port — namely, that the Serial Monitor and Serial Plotter
are closed for upload (We’ll explore both of those in more detail in the course).

How do I know what version of <Arduino Library> is installed?


Use the menu to navigate to: Tools → Manage Libraries. Then type the name of the library in
the top search bar and you will see the word INSTALLED in teal next to the version number
of the library installed. For example you might find the below:

A screenshot of the library manager showing version 2.4.0-ALPHA of the TensofrFlow Lite for
Microcontrollers Arduion library being installed.

How do I know what version of the <Arduino Board Files> are


installed?
Use the menu to navigate to: Tools → Board: → Boards Manager. Then type the name of the
board files in the top search bar and you will see the word INSTALLED in teal next to the
version number of the board files. (See the image of the Library Manager above for an
example).

Unable to open a sketch in the Arduino IDE


The Arduino IDE requires every sketch (.ino file) to be stored in a folder with the same name
as the file, e.g. “[Link]” needs to be stored in a folder called “blink”. When you try to open a

Page 40 of 42
COM683 Edge and Embedded Intelligence

sketch that is not already in a folder with the same name, the IDE will attempt to create the
appropriate folder and move the sketch before opening:

A popup stating: The file "[Link]" needs to be inside a sketch folder named "FAQ". Create
this folder, move the file, and continue?

If a folder with the name of your sketch already exists in the current directory, you will get the
error messages below (one after the other):

A popup stating: A folder named "FAQ" already exists. Can't open sketch.

A popup stating: Failed to open sketch "PATH_TO_SKETCH".

To fix this, simply move or delete the conflicting directory (in this case, a directory called
“FAQ”), then either try opening the sketch again, or manually create a folder with the sketch
name and move the sketch into that folder then open the sketch.

What Arduino software versions do I need to install?


We have tested the TinyML kit on the following:
• Arduino IDE version 1.8.13
• Arduino mbed-enabled board files version 1.3.1
• TensorFlow Lite for Microcontrollers Arudino library version 2.4.0-ALPHA
• Arduino_LSM9DS1 Arudino library version 1.1.0
• ArduinoBLE version Arduino library 1.1.3
• TinyML_COM6830 Arudino library version 0.1.0

I'm getting the error fatal error: XXXX.h: No such file or directory
This usually means that you do not have a needed library installed. Please go back to the
software setup (and/or look at the list one question above) and make sure you have installed
all of the libraries needed by the course!

Page 41 of 42
COM683 Edge and Embedded Intelligence

Page 42 of 42

You might also like