0% found this document useful (0 votes)
104 views48 pages

Hallberg Gary - The Arduino Leonardo (Arduino Short Reads. Book 8) - 2021

Uploaded by

Tihomir Mihaylov
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)
104 views48 pages

Hallberg Gary - The Arduino Leonardo (Arduino Short Reads. Book 8) - 2021

Uploaded by

Tihomir Mihaylov
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
You are on page 1/ 48

The Arduino Leonardo

Book 8 of the Arduino Short Reads Series

Gary Hallberg

North Border Tech Training


First Edition
Copyright © 2021 Gary Hallberg and North Border Tech Training
All reserved. This book or any portion thereof may not be reproduced or used in any manner whatsoever
without the express written permission of the publisher except for the use of brief quotations in a book
review.
First Published, 2021
Contents
About the Arduino Short Reads Series .................................................................................................. 4
Foreword .............................................................................................................................................. 5
Prerequisites for this Book .................................................................................................................... 6
Download the Code ............................................................................................................................... 7
Chapter 1: An Introduction to the Arduino Leonardo ........................................................................... 8
Parts needed for this Chapter ....................................................................................................... 8
The Arduino Leonardo ...................................................................................................................... 8
Experiment 1: Arduino Leonardo Basic I/O ..................................................................................... 11
The Arduino Micro .......................................................................................................................... 15
Summary ......................................................................................................................................... 16
Chapter 2: Keyboard Emulation using the Arduino Leonardo ............................................................ 17
Parts needed for this Chapter ..................................................................................................... 17
Experiment 2: Water Level Monitor ................................................................................................ 17
Experiment 3: Locking your Computer using Light Levels .............................................................. 22
Summary ......................................................................................................................................... 23
Chapter 3: Mouse Emulation using the Arduino Leonardo ................................................................. 24
Parts needed for this Chapter ..................................................................................................... 24
The 2 Axis Analog Joystick .............................................................................................................. 24
Experiment 4: Leonardo Mouse ...................................................................................................... 26
Summary ......................................................................................................................................... 31
Chapter 4: Game Controllers and Joysticks ........................................................................................ 32
Parts needed for this Chapter ..................................................................................................... 32
A Simple Joystick using Keyboard Emulation ................................................................................. 32
Experiment 5: A Simple Digital Joystick using Keyboard Emulation .............................................. 33
The Arduino Joystick Library by Matthew Heironimus ................................................................... 35
Installing the Joystick Library ......................................................................................................... 35
Experiment 6: Joystick Test ............................................................................................................ 39
Experiment 7: A Simple Game Pad .................................................................................................. 41
Summary ......................................................................................................................................... 45
Epilogue .............................................................................................................................................. 46
About the Author ................................................................................................................................ 47
About the Arduino Short Reads Series

The idea underpinning the Arduino short reads series is to provide a comprehensive, easy to follow
tutorial set and reference guide for anybody wanting to learn about Arduino and basic electronics.
Having a short reads series means that students and hobbyists can select key topics of interest in the
field with minimal outlay. The series aims to provide an easy introduction to all topics of interest and
expand on these topics to provide a broader and deeper understanding of that focus area. The books
are currently only available in Kindle format to provide a very inexpensive package backed up by video
content and interactive social media.
The series is aimed at youngsters and adults interested in getting into electronics and it takes a modern
approach, combining the use of the inexpensive software driven Arduino controller board, with a
multitude of sensors and discreet electronic components. The experiments in this series of books are
easy to follow, inexpensive to implement and compelling for all interested in STEM education. I hope
to inspire anybody looking for a future career in technology or to simply to have fun.
The first book of this series looks at the Arduino microcontroller and explains its operation and purpose.
Experiments look to show you how to set up the programming environment and drive LEDs as well as
read input from switches, thermistors and photocells. Book 1 will give you a solid foundation of how
some basic electronic components work and how to use them to make simple designs.
Other books in the Arduino Short Reads Series focus on the following subjects:

• Book 1 – First Steps with Arduino


• Book 2 – Working with Displays
• Book 3 – Controlling Motors
• Book 4 – Range Finding, Object Detection and Object Avoidance
• Book 5 – Building a Simple Rover
• Book 6 – Arduino Special Functions
• Book 7 – Wireless Communications with Arduino and the ESP32

If you find this series of books useful then please leave your review and rating on
Amazon.
Follow North Border Tech Training on Facebook and Twitter for the latest news and
insights as to how this series will develop.
Foreword

If you have followed the books in this series sequentially then you will find this book to be the final
installment. In fact, we have covered all the key areas in the Arduino ecosystem bar the special
capabilities that set the Arduino Leonardo apart from the other Arduino platforms such as the Uno. The
Arduino Leonardo supports all the capabilities of the Arduino Uno and is compatible with the many
shields that are available, but the Arduino Leonardo can emulate USB devices that would normally be
connected to any PC or laptop. It can be used emulate keyboard and mouse functionality and it is this
capability that will explore in this final installment.
Prerequisites for this Book

This book assumes you have read Book 1 of the series (‘First Steps with Arduino’) or you already have
some experience of the Arduino platform, how to set up the IDE and undertake some basic Arduino
programming tasks. Basic functions such as ‘digitalRead’ and ‘digitalWrite’ are not covered here
but are explained in Book 1.
Download the Code

You can download the Arduino Code for the experiments in this book from GitHub using the link below.

https://github.com/ghallberg-nbtt/musical-happiness
I recommend that you do this as I have removed some of the comments from the code in the book
listings to aid readability in print form. I strongly recommend that you comment your code heavily to
facilitate understanding and to become familiar with best engineering practice.
Chapter 1: An Introduction to the Arduino
Leonardo

So, what makes the Arduino Leonardo special compared to the Arduino Uno and why does it merit
special attention? In previous books of this series, we have used the USB support for basic serial data
transport. However, the standard can accomplish so much more. The unlike the Arduino Uno, the
Arduino Leonardo has native USB support built into the MCU. The Arduino Uno has a secondary USB
chip external to the MCU. This means that Arduino Leonardo can emulate non serial USB devices such
as keyboards and computer mice. We will explore what this means in later chapters, but now we will
take a closer look at the Arduino Leonardo and compare it to the Arduino Uno.

Parts needed for this Chapter


• Arduino Leonardo or clone board
• Full or half size breadboard
• 1 x 220Ω resistors
• 1 x 10KΩ resistor
• 1 x clear LED
• 1 x cadmium sulfide photocell
• 1 x pushbutton switch
• Jumper wires

The Arduino Leonardo


Figure 1-1 shows the layout of the Arduino Leonardo.
Figure 1-1: The Arduino Leonardo
Image source: Arduiono.cc with annotations by the author
For comparison, Figure 1-2 shows the Arduino Uno
Figure 1-2: The Arduino Uno
Image source: Arduiono.cc with annotations by the author
You can see that the Arduino Leonardo is pin compatible with the Arduino Uno. This means it will
support the many shields available for the Uno platform. The voltage inputs and the logic levels are the
same. The Leonardo supports 5V logic. The main difference is the processor. The Leonardo supports
the Microchip ATmega32u4 compared to the Atmel ATmega328P of the Arduino Uno. You will also see
that the board has a much more compact micro-USB connector. What follows in Table 1-1 are the key
features of the Arduino Leonardo.
Microcontroller ATmega32u4
Operating Voltage 5V
Input Voltage (Recommended) 7-12V
Input Voltage (limits) 6-20V
Digital I/O Pins 20
PWM Channels 7
Analog Input Channels 12
DC Current per I/O Pin 40 mA
DC Current for 3.3V Pin 50 mA
Flash Memory 32 KB (ATmega32u4) of which 4 KB used by bootloader
SRAM 2.5 KB (ATmega32u4)
EEPROM 1 KB (ATmega32u4)
Clock Speed 16 MHz

Table 1-1: Key Features of the Arduino Leonardo

Experiment 1: Arduino Leonardo Basic I/O


In this simple experiment we look at using an analog input and Pulse Width Modulation output to
control the intensity of an LED. This experiment explores some of the similarities of the Arduino
Leonardo compared to the Arduino Uno. In fact, this is a near repeat of the ‘night light’ experiment
using the Arduino Uno in Book 1 of this series (‘First Steps with Arduino’), but here we will add an
on/off switch so that we can explore the ‘digitalRead’ function too. We will use a photocell as part
of a potential divider to provide the analog input. The circuit diagram for this is shown in Figure 1-3.

Figure 1-3: The Photocell and Potential Divider


We shall build a night light controlled by the ambient light level. This is an easy project to make. First,
we need to look closer at the light sensor and that is the photocell. Photocells are also called Light
Dependent Resistors (LDR) or photoresistors.
Photocells are passive components that decrease their resistance when exposed to light. They are found
in all sorts of devices such light meters, night lights and light triggered alarms. In the dark, the
resistance of a photocell could be in the Megaohm range and as low as a few hundred ohms in the light.
Photocells come in many forms and can be made of different materials. The most common and lowest
cost variants are made with Cadmium Sulfide. We will bias the photocell with a 10KΩ resistor to form
the potential divider.
First, build the breadboard layout as in Figure 1-4.

Figure 1-4: The Breadboard Layout for the Night Light


Image source: Created with Fritzing
For the first part of the experiment, we want to calibrate the night light. Load or type in the Sketch as
in Listing 1-1. What we want to do at this stage is measure the analog output values for both low and
high light extremes. Check the value in the serial monitor at a comfortable room light. We will want the
LED to be off at this light level. Next check the low light setting. You can simply place a cover over or
pinch the photocell to reduce the light hitting it. At this level we will want the LED to be fully on.
/*
Nightlight Calibration
Copyright 2021 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/musical-
happiness/blob/main/LICENSE
*/

// Define constant values


const int LIGHT=0; // Photocell on Analog Pin 0

// Define variables
int val = 0; // Holds the analog reading from photocell

void setup()
{
Serial.begin(9600);
}

void loop()
{
val = analogRead(LIGHT); // Read the light sensor
Serial.println(val);
delay (500);
}

Listing 1-1: The Sketch to Calibrate the Nightlight


Listing source: The author
My measurements indicated a high value of 840 and a low value of 430. I also measured the resistance
of the photocell at that fell between 7.5KΩ for low light and 1.5KΩ for normal room light. If I wanted to
widen the range of analog values, then I could reduce the biasing resistor from 10KΩ to 4.7KΩ within
the potential divider, but I will stick with 10KΩ. I will set my actual values just inside the measured
limits. I.e., I will set the low level to 440 and the high level to 830.
We will move on to the full Sketch now, but we must consider the fact that the ADC returns a value
between 0 and 1023 and the PWM output can only support values between 0 and 255. Therefore, we
do not have a 1:1 mapping between the analog input and the PWM output. The Arduino programming
language does provide a convenient function to do this mapping. This is the ‘map’ function. In our
Sketch we will want to map the low light level to a PWM output of 255 and the high light level to a PWM
output of 0. The function will look like the one below:
val = map(val, 440, 830, 255, 0);

We can reuse the variable ‘val’. ‘val’ is the ADC value from the photocell. It will be proportionally
mapped to the new value between 0 and 255 and ‘val’ is overwritten with this new value for use as the
PWM output integer. There is one more point to consider. The map function does not constrain values
so if we recorded a value higher than 840, the map function will return a value below 0. This would
clearly cause and error in our code. Therefore, we must also use the ‘constrain’ function to constrain
the value of ‘val’ to between 0 and 255.
val = constrain (val, 0, 255);

These are two important functions in the Arduino programming language. Now try the full Sketch to
control the nightlight. This is shown in Listing 1-2. Review the code to make sure you understand it. We
are essentially looking for ‘HIGH’ to ‘LOW’ button transition to turn the light on or off and when on, the
photocell varies the light intensity. The switch needs to be debounced to negate the effect the
mechanical contact bounce.
/*
Nightlight
Copyright 2021 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/musical-
happiness/blob/main/LICENSE
*/

// Define constant values


const int LIGHT = 0; // Photocell on Analog Pin 0
const int LED = 3; // Set pin 3 as LED
const int ON_OFF_LED = 13; // Use internal LED as on off indicator
const int BUTTON = 2; // On off button
const int high_level = 830; // high light level
const int low_level = 440; // low light level

// Define variables
int val = 0; // Holds the analog reading from photocell
boolean previousButton = HIGH; // Var containing the previous button state
boolean currentButton = HIGH; // Var containing the current button state
boolean ledOn = false; // The present state of the LED (on or off)

void setup()
{
pinMode (ON_OFF_LED, OUTPUT); // on off LED
pinMode (BUTTON, INPUT_PULLUP); // Button input
}

void loop()
{
currentButton = digitalRead(BUTTON); // Read the switch state

if (previousButton != currentButton) // If switch pressed


{
delay(5); // Wait 5ms
currentButton = digitalRead(BUTTON); // Read switch again
}
if (previousButton == HIGH && currentButton == LOW) // btn press
{
ledOn = !ledOn; // Toggle the LED state on > off and off > on
}
previousButton = currentButton; // Reset button value
if (!ledOn) {
digitalWrite (LED, LOW); // turn off LED
digitalWrite (ON_OFF_LED, LOW); // turn off on/off indicator
} else {
digitalWrite (ON_OFF_LED, HIGH); // turn on on/off indicator
val = analogRead(LIGHT); // Read the light sensor
val = map (val, low_level, high_level, 255, 0); // ADC to PWM value
val = constrain (val, 0, 255); // Constrain the values
analogWrite (LED, val);
}
}

Listing 1-2: The Night Light Code


Listing source: The author
When I tested this code, I was able to interchange the Leonardo with the Uno and there was no need to
modify the Sketch.

The Arduino Micro


It is worth mentioning that there is another development board within the Arduino family that shares
the same ATmega32u4 processor. This is the Arduino Micro. It has an identical processor to the
Arduino Leonardo and hence identical functionality. The difference is the form factor. This board is 48
mm long by 18mm wide and has header pins that allow the board to be inserted into a breadboard.
An Arduino Micro is pictured in Figure 1-5.
Figure 1-5: The Arduino Micro
Image source: The Web (public domain)

Summary
In this chapter you were introduced to the Arduino Leonardo. You explored the pin assignments and
understood that it is compatible with the Arduino Uno from that perspective. You learnt that shields
produced for the Uno can be fitted to the Leonardo. You learnt that basic Sketch functions work in the
same way on both the Arduino Leonardo and the Arduino Uno.
Chapter 2: Keyboard Emulation using the
Arduino Leonardo

You can use the Leonardo’s unique capability to emulate USB connected peripherals to emulate a
keyboard and have it type data directly into a desktop program. We will explore this capability in this
chapter. There are 2 experiments. The first looks at sending keystrokes and key combinations to enter
data directly into a text file and then a spreadsheet program and the second looks at command functions
that we can use to control a computer running Microsoft Windows.

Parts needed for this Chapter


• Arduino Leonardo or clone board
• Full or half size breadboard
• 1 x pushbutton switch
• 1 x generic water level sensor
• 1 x 10KΩ resistor
• 1 x cadmium sulfide photocell
• Jumper wires including Dupont Jumpers

Experiment 2: Water Level Monitor


In this experiment, we will use a generic liquid level sensor of the type shown in Figure 2-1. Being a
generic sensor, it has no specific part number or manufacturer. These are low cost so ideal for
experimentation.
Figure 2-1: The Generic Liquid Level Monitor
Image source: The Web (public domain)
The unit is designed to detect water levels and a typical application is for use as a rainfall senor.
Essentially, the unit is made up of 10 bare copper conducting strips. 5 of the copper strips are powered
and the other 5 are sensor strips. The copper strips are not interconnected. However, when the sensor
unit is immersed in water it behaves like a variable resistor and electrical current can pass between the
strips. The resistance is controlled by the depth that the sensor is immersed into the water. The
resistance is inversely proportional to the height of the water. The higher the water level the lower the
resistance. The sensor produces an analog voltage according to the resistance. Therefore, the sensor has
3 pins: Supply, Ground and Signal. Do not immerse the sensor into water beyond the copper
strips.
First build the breadboard layout as in Figure 2-2.
Figure 2-2: The Breadboard Layout for the Water Level Monitor
Image source: Created with Fritzing
The button is used to start and stop the data collection. Next type in or load the Sketch as shown in
Listing 2-1.

#include <Keyboard.h>

const int BUTTON = 2; //Pushbutton


const int SENSOR = A0; //Water level sensor and keyboard emulation
const int ON_OFF_LED = 13; // Use internal LED as on off indicator

boolean previousButton = HIGH; // Contains the previous btn state


boolean currentButton = HIGH; // Contains the current btn state
boolean ledOn = false; //Sample collection on and off + LED
int sampleNumber; //A counter for the sample number

void setup() {
pinMode (BUTTON, INPUT_PULLUP);
Keyboard.begin(); //start keyboard emulation
}

void loop() {
currentButton = digitalRead(BUTTON); //Read the switch state

if (previousButton != currentButton) //If switch pressed


{
delay(5); // Wait 5ms
currentButton = digitalRead(BUTTON); //Read switch again
}

if (previousButton == HIGH && currentButton == LOW)


{
ledOn = !ledOn; //Toggle the LED state on > off and off > on
}

if (ledOn) {
//Collect samples
digitalWrite (ON_OFF_LED, HIGH); //Turn on LED
if (millis() % 2000 == 0) { //Collect every 2 seconds
int waterLevel = analogRead(SENSOR); //Read water level sensor
Keyboard.print (sampleNumber); //Print index
Keyboard.print (","); //Print a comma
Keyboard.println(waterLevel); //Print the water level and newline
sampleNumber++; //increment the sample number
}
}
else {
//Turn off sampling
digitalWrite (ON_OFF_LED, LOW); //Turn off
}
}

Listing 2-1: The Sketch for the Water Level Monitor


Listing source: The author
The first thing to note is that there is a library that facilitates keyboard emulation
#include <Keyboard.h>

As in previous experiments, we use a switch to turn the sampling on or off. It is important to use the
switch as the Arduino Leonardo will continue to transmit key presses that may affect the application
that has current focus on your desktop. If the sampling is on, we want to collect samples every 2 seconds.
You will notice we are not using the ‘delay’ function. The ‘delay’ function is blocking and so we would
not scan for the switch state continuously. This means we would most likely not detect a button press
to turn the sampling on or off. Instead, we can use the ‘millis’ function. This provides a count of
milliseconds since the program started. If the value of ‘millis’ mod 2000 is 0 then we know 2 seconds
has elapsed since the last sample was taken. We have a neat way of executing code periodically without
blocking the scanning of the switch.
if (millis() % 2000 == 0) {
//execute code every 2 seconds
}

Printing to the keyboard is straightforward using the ‘print’ function in the ‘Keyboard’ class.
int waterLevel = analogRead(SENSOR); //Read water level sensor
Keyboard.print (sampleNumber); //Print index
Keyboard.print (","); //Print a comma
Keyboard.println(waterLevel); //Print the water level and newline
sampleNumber++; //increment the sample number

An image of my setup is shown in Figure 2-3 and a video demonstration of the experiment can be found
here (https://youtu.be/EWbKgUtMq1M).

Figure 2-3: The Water Level Monitor


Image source: The author
Experiment 3: Locking your Computer using Light Levels
In the previous experiment you explored keystrokes to send text to a spreadsheet program. In this
experiment we will look at key presses. The difference is that some commands require that a key is
pressed in combination with another to execute the command. In Microsoft Windows, the command
‘Windows+L’ will lock your computer. In Linux this is ‘Control+alt+L’. We can reuse the LDR from
Experiment 1 to lock a computer when the room lights are turned off.
First, build the breadboard layout as in Figure 2-4. We recorded high and low light levels as part of the
calibration for experiment so we can reuse those values.

Figure 2-4: The Light Controlled Computer Lock


Image source: Created with Fritzing
Next type in or copy the Sketch as in Listing 2-2:
/*
Light Controlled Computer Lock
Copyright 2021 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/musical-
happiness/blob/main/LICENSE
*/

#include <Keyboard.h>
const int LDR = A0; //LDR input
const int THRESHOLD = 400; //Light threshold

void setup() {
Keyboard.begin();
}

void loop() {
int lightLevel = analogRead (LDR); //Read light level
if (lightLevel < 400) {
//lock computer
Keyboard.press (KEY_LEFT_GUI);
Keyboard.press ('l');
delay (100);
Keyboard.releaseAll();
}
}

Listing 2-2: The Sketch to Lock your Computer using Light Levels
Listing source: The author
You can see that the Sketch is simple. When the light reading is below the set threshold the key press is
initiated. The ‘press’ function of the ‘Keyboard’ object emulates a key that is pressed and held down.
The first keypress represents the ‘Windows’ key followed by the ‘l’. After a short delay, all key presses
are released and the computer locks.

Summary
In this chapter you learnt that is it easy to emulate a computer keyboard using the Arduino Leonardo.
You learnt that the library ‘Keyboard.h’ makes this task easy. You learnt about the generic water
sensor and used a Light Dependent Resistor.
Chapter 3: Mouse Emulation using the
Arduino Leonardo

It follows that if we can emulate a computer keyboard then we can emulate a computer mouse. Like the
keyboard emulation we can utilize a library (‘Mouse.h’) to make the job easy.

Parts needed for this Chapter


• Arduino Leonardo or clone board
• Full or half size breadboard
• 1 x 2 axis analog joystick
• 3 x pushbutton switches
• 3 x 10KΩ resistor
• Jumper wires including Dupont Jumpers

The 2 Axis Analog Joystick


To create our mouse, you will need a 2 axis analog joystick. These are generic parts and do not have
manufacturer part numbers. The Type I am using is pictured in Figure 3-1.
Figure 3-1: The 2-axis Analog Joystick
Image source: The Web (public domain)
Aside from supply and ground pins, the joystick has horizontal and vertical control pins, and a switch
can also be activated by pressing the joystick. The x and y axis are simply potentiometers. By connecting
these to analog input pins on the Arduino Leonardo, we can read the voltage levels on the pins and
translate these into mouse movements. My joystick offers a range of 0 to 1023 when connected to the
analog inputs. Be sure to check the range that your joystick offers as you may need to adjust the ‘map’
function in the Sketch.
Experiment 4: Leonardo Mouse
Now let us build our Leonardo Mouse. Build the breadboard layout as in Figure 3-2. The three push
buttons represent left, middle and right click. It not a very practical mouse as you may need 2 hands to
operate it, but nevertheless, it demonstrates the Leonardo’s capability.

Figure 3-2: The Breadboard Layout for the Mouse


Image source: Created with Fritzing
Now type in or copy the Sketch as in Listing 3-1:
/*
Leonardo Mouse
Copyright 2021 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/musical-
happiness/blob/main/LICENSE
*/

#include <Mouse.h>

const int LEFT_BUTTON = 4;


const int MIDDLE_BUTTON = 3;
const int RIGHT_BUTTON = 2;
const int HORIZONTAL = A0;
const int VERTICAL = A1;

void setup() {
Mouse.begin();
}

void loop() {
int x = joystick(HORIZONTAL); //get horizontal movement
int y = joystick(VERTICAL); //get vertical movement
Mouse.move(x, y, 0); //move the mouse
mouseButton (LEFT_BUTTON, MOUSE_LEFT); //Left button control
mouseButton (MIDDLE_BUTTON, MOUSE_MIDDLE); //middle button control
mouseButton (RIGHT_BUTTON, MOUSE_RIGHT); //middle button control
delay (5); //this delay controls responsiveness
}

//Reads joystick values


int joystick(int axis) {
int val = analogRead(axis); //read the value
val = map (val, 0, 1023, -10, 10); //map pot readings to mouse travel
if (val <= 2 && val >= -2) {
return 0; //dead zone to stop mouse jitter
} else {
return val;
}
}

//Read Button and issues mouse command


void mouseButton (int ioPin, char mouseCommand) {
//button pressed
if (digitalRead (ioPin) == LOW) {
if (!Mouse.isPressed(mouseCommand)) {
Mouse.press(mouseCommand);
}
} else {
//button released
if (Mouse.isPressed(mouseCommand))
{
Mouse.release (mouseCommand);
}
}
}

Listing 3-1: The Sketch for the Leonardo Mouse


Listing source: The author
This is one of the more complex Sketches, so let us break it down carefully. We need to first include the
‘Mouse.h’ library.
#include <Mouse.h>

Next the Leonardo mouse is initiated.


Mouse.begin();

The code in the main ‘loop’ function first scans for changes in the joystick horizontal and vertical
values.
int x = joystick(HORIZONTAL); //get horizontal movement
int y = joystick(VERTICAL); //get vertical movement

We created a function named ‘joystick’ that returns either a horizontal or vertical value. We will
review the code in this function later. The next task is to move the mouse by the specified values
returned by the ‘joystick’ function. The third argument represents a mouse ‘wheel’ value that we set
to 0 as we do not have a wheel.
Mouse.move(x, y, 0); //move the mouse

The code in the Sketch then looks for button presses and acts on these presses. Again, we have created
a function that we will review later.

mouseButton (LEFT_BUTTON, MOUSE_LEFT); //Left button control


mouseButton (MIDDLE_BUTTON, MOUSE_MIDDLE); //middle button control
mouseButton (RIGHT_BUTTON, MOUSE_RIGHT); //middle button control

The delay controls the speed or responsiveness of the mouse and you may have to tweak this value.

delay (5); //this delay controls responsiveness


Let us take a closer look at the ‘joystick’ function. We need to send an argument that represents
whether we want to read the horizontal (x axis) or vertical (y axis) values. The function will return an
integer value that represents the movement in that direction.
int joystick(int axis) {
//process movement
}

Within the function, we first read the analog input for the joystick control and map the value to a mouse
travel in pixels. An analog value of 0 will represent one extreme and this equates to down or left, so we
map a joystick value of 0 to -10 pixels of travel. Likewise, a joystick value of 1023 is the other extreme,
so we map that to a value of +10. The value we map the joystick reading can also be tuned to optimize
the mouse’s responsiveness.
int val = analogRead(axis); //read the value
val = map (val, 0, 1023, -10, 10); //map pot readings to mouse travel

We then place a ‘dead zone’ into the mouse travel to prevent it juddering if the joystick is not being
moved. Being an analog, device the joystick will be prone to registering slightly different readings on
each pass, so having this dead zone will eliminate any mouse jitter. If the mapped value is less than or
equal to 2, or greater than or equal to -2, we return a value of 0. Otherwise, we can return the mouse
movement to the main ‘loop’ function.
if (val <= 2 && val >= -2) {
return 0; //dead zone to stop mouse jitter
} else {
return val;
}

The ‘mouseButton’ does not return any value but acts on the button press. We must pass the I/O pin
number of the button that is pressed and a predefined ‘char’ that is defined in the ‘Mouse.h’ library.
The ‘char’ represents the left, center or right button.
void mouseButton (int ioPin, char mouseCommand) {
//process button
}

We then check to see if the button is depressed by reading the state and seeing if it is ‘LOW’. We are using
pull-up resistors so a depressed state will read ‘LOW’. We then check whether the button was pressed on
a previous scan and if not, we act on the button press as if the respective mouse button is clicked. The
‘press’ function does this. If the button state is ‘HIGH’, it indicates that the button is released.
‘Mouse.isPressed’ will still be ‘TRUE’ until we execute the ‘Mouse.release’ command. Remember
that ‘mouseCommand’ is the indicator for which button is pressed.
//button pressed
if (digitalRead (ioPin) == LOW) {
if (!Mouse.isPressed(mouseCommand)) {
Mouse.press(mouseCommand);
}
} else {
//button released
if (Mouse.isPressed(mouseCommand))
{
Mouse.release (mouseCommand);
}
}

This seems a little complicated and it does take some experience to follow. Give the experiment a go
and work through the code. I have a photograph of my setup in Figure 3-3 and there is a video
demonstration of the mouse here (https://youtu.be/e4VuRX1YgcA).

Figure 3-3: My Arduino Leonardo Mouse


Image source: The author
Important note: After you have finished with the mouse, load some default code onto the
Arduino Leonardo. If you do not do this the Leonardo will still act as mouse when next
powered and connected to a PC. You will get unpredictable results if you have removed
the buttons. Some default code is below:
void setup() {
// put your setup code here, to run once:

void loop() {
// put your main code here, to run repeatedly:

Summary
In this chapter you learnt how to turn an Arduino Leonardo into a computer mouse. You learnt that a
library exists called ‘Mouse.h’ that makes the programming of this task easy.
Chapter 4: Game Controllers and Joysticks

Having looked at keyboards and mice the next step is to look at using the Arduino Leonardo as a game
controller or joystick like those which are commercially available. In this chapter we will look at this
subject and create a simple joystick and game controller as well as giving you a pathway to making
much more sophisticated controllers.

Parts needed for this Chapter


• Arduino Leonardo or clone board
• Full or half size breadboard
• 1 x 2 axis analog joystick
• 5 x pushbutton switches
• Jumper wires including Dupont Jumpers

A Simple Joystick using Keyboard Emulation


There are many games that can be controlled using a keyboard. Therefore, we can create a simple
joystick that reuses the analog joystick from Experiment 4 and then program the Arduino Leonardo to
send keystrokes based on inputs from that device. We will send characters for the up, down, left and
right arrows and space bar for fire. We will use the inbuilt button for fire button.

We need to identify Keyboard modifiers for use with the Leonardo’s Keyboard emulation control. The
standard ASCII character set normally works with printable characters. A modifier is a key on the
keyboard that modifiers the normal action of the key. This way we can initiate special functions such as
the Windows lock function of Experiment 3. The arrow keys are not printable and so modifiers have
been defined such that we can send the arrow keys codes as keypresses. The Arduino Leonardo
modifiers for the arrow keys are listed in Table 4-1.

Key Hexadecimal value Decimal value


KEY_UP_ARROW 0xDA 218
KEY_DOWN_ARROW 0xD9 217
KEY_LEFT_ARROW 0xD8 216
KEY_RIGHT_ARROW 0xD7 215

Table 4-1: Modifier Codes for the Keyboard Arrow Keys


Let us now move on to build our simple joystick controller.
Experiment 5: A Simple Digital Joystick using Keyboard Emulation
This is a digital joystick as we will send up arrow when the joystick is pushed forward, down arrow when
pulled down, left arrow when pushed left and right arrow when pushed right. Although the joystick
inputs are connected to analog inputs, the control from the Arduino Leonardo will be digital.
First build the layout as in Figure 4-1. A breadboard is not needed if using Dupont jumpers.

Figure 4-1: The Layout for the Simple Joystick Controller


Image source: Created with Fritzing
Now type in or copy the Sketch as in Listing 4-1.
/*
Joystick using Keyboard Emulation
Copyright 2021 Gary Hallberg
Licensed under MIT https://github.com/ghallberg-nbtt/musical-
happiness/blob/main/LICENSE
*/

#include <Keyboard.h>

const int BUTTON = 2;


const int HORIZONTAL = A0;
const int VERTICAL = A1;

int x, y;
int sw;

void setup() {
pinMode(BUTTON, INPUT_PULLUP);
Serial.begin(9600);
Keyboard.begin();
}

void loop() {
int x = analogRead(HORIZONTAL); //get horizontal movement
if (x == 1023)// fully right
{
Serial.println("Right");
Keyboard.press(215); //right arrow
}
else
{
Keyboard.release(215); //release the key
}

x = analogRead(HORIZONTAL); //get horizontal movement


if (x == 0) // fully left
{
Serial.println("Left");
Keyboard.press(216); //left arrow
}
else
{
Keyboard.release(216); //release the key
}

y = analogRead(VERTICAL); //get vertical movement


if (y == 0) // fully up
{
Serial.println("Up");
Keyboard.press(218); //up arrow
}
else
{
Keyboard.release(218); //release the key
}

y = analogRead(VERTICAL);
if (y == 1023) //fully down
{
Serial.println("Down");
Keyboard.press(217); //down arrow
}
else
{
Keyboard.release(217); //release the key
}
sw = digitalRead (BUTTON); //see if switch pressed

if (sw == 0) //switch pressed


{
Serial.println("Space bar");
Keyboard.println(" "); //space bar
}

delay (200); //this delay controls responsiveness


}

Listing 4-1: The Sketch for the Simple Joystick


Listing source: The author
So, there is not much to review here. We covered keyboard emulation in Chapter 2 and the rest is
straightforward code. You will need to work out the limits of your joystick sensor and equate them to
the respective arrow key. When I pushed the joystick forward, it equated to an Analog to Digital value
of 0 and 1023 for down.
You can see a video demonstration of this experiment here (https://youtu.be/LlfZTWUoOKE).

The Arduino Joystick Library by Matthew Heironimus


There may well come a time when you want to build a much more sophisticated games controller and
we can do this with the Arduino Leonardo using some prebuilt libraries. One of the most popular sets
of libraries were written by Matthew Heironimus. I will be working with version 2 of the library set.
After you install the library there are example Sketches written and instructions as to how to build the
respective controllers. We will look at a test example and then build a game pad.

Installing the Joystick Library


First you need to navigate to the Github repository for the library. It can be found at this URL:
https://github.com/MHeironimus/ArduinoJoystickLibrary/tree/version-2.0
You then need to download the library as a ‘zip’ file as shown in Figure 4-2.
Figure 4-2: Downloading the Library as a Zip File
Image source: The author
Now copy the file into your Arduino Libraries folder. On a Windows machine the location is as shown
in Figure 4-3.

Figure 4-3: Copying the Library into the Arduino Libraries Folder
Image source: The author
Next you need to add the library to your Arduino IDE. Open your IDE and select Sketch > Include
Library > Add. .ZIP Library… as shown in Figure 4-4.
Figure 4-4: Adding the Library to the IDE
Image source: The author
Select the ZIP file you just copied into the Arduino Libraries folder and click ‘open’. That is all there is
to it. I tend the restart the IDE. You can check that the library is installed by seeing if the examples are
in place as in Figure 4-5.
Figure 4-5: Checking that the Library has installed
Image source: The author
Experiment 6: Joystick Test
You can see from Figure 4-5 that the library has several examples. In this experiment we will look at
the ‘JoystickTest’ example Sketch. We will only need an Arduino Lenardo and a jumper wire for this
experiment. I will not list the code here as it would be difficult to review. The Sketch relies heavily on
calls to the classes and functions in the library so will make little sense. It is a complex task to look deep
into the library to gain a better understanding of what lies under the hood and that task would be
beyond the scope of this book. It is sufficient to know that these sorts of libraries exist and that they can
be used to build sophisticated projects. It is testament to the skills and generosity that these creators
offer such resources to the community of users.
First load the ‘JoystickTest’ example and upload it to your Arduino Leonardo. Once the upload is
complete you can check to see if the device is registered under your PC. On a Windows PC, go to
Control Panel > Hardware and Sound > Devices and Printers. Figure 4-6 shows my screen
under Windows 11.

Figure 4-6: The Arduino Leonardo showing as a Game Controller


Image source: Microsoft Windows
Right click over the Arduino Leonardo icon and select ‘Game controller settings’ as in Figure 4-7.
Figure 4-7: Selecting Game Controller Settings
Image source: Microsoft Windows
You will see the Arduino Leonardo listed in the resultant dialog box as in Figure 4-8:

Figure 4-8: The Game Controller Settings Dialog Box


Image source: Microsoft Windows
Now select properties and the test screen should be displayed as in Figure 4-9.
Figure 4-9: The Controller Test Screen
Image source: Microsoft Windows
What you now need to do is ground the A0 pin of the Arduino to initiate the test. Make sure that the
test screen has focus by clicking your mouse over it and observe the results.

Experiment 7: A Simple Game Pad


Listing 4-2 shows the simple game pad example from the joystick examples. Load the
‘GamepadExample’ Sketch. The location is shown in Figure 4-5.
// Simple gamepad example that demonstrates how to read five Arduino
// digital pins and map them to the Arduino Joystick library.
//
// The digital pins 2 - 6 are grounded when they are pressed.
// Pin 2 = UP
// Pin 3 = RIGHT
// Pin 4 = DOWN
// Pin 5 = LEFT
// Pin 6 = FIRE
//
// NOTE: This sketch file is for use with Arduino Leonardo and
// Arduino Micro only.
//
// by Matthew Heironimus
// 2016-11-24
//--------------------------------------------------------------------

#include <Joystick.h>

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
1, 0, // Button Count, Hat Switch Count
true, true, false, // X and Y, but no Z Axis
false, false, false, // No Rx, Ry, or Rz
false, false, // No rudder or throttle
false, false, false); // No accelerator, brake, or steering

void setup() {
// Initialize Button Pins
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);

// Initialize Joystick Library


Joystick.begin();
Joystick.setXAxisRange(-1, 1);
Joystick.setYAxisRange(-1, 1);
}

// Last state of the buttons


int lastButtonState[5] = {0,0,0,0,0};

void loop() {

// Read pin values


for (int index = 0; index < 5; index++)
{
int currentButtonState = !digitalRead(index + 2);
if (currentButtonState != lastButtonState[index])
{
switch (index) {
case 0: // UP
if (currentButtonState == 1) {
Joystick.setYAxis(-1);
} else {
Joystick.setYAxis(0);
}
break;
case 1: // RIGHT
if (currentButtonState == 1) {
Joystick.setXAxis(1);
} else {
Joystick.setXAxis(0);
}
break;
case 2: // DOWN
if (currentButtonState == 1) {
Joystick.setYAxis(1);
} else {
Joystick.setYAxis(0);
}
break;
case 3: // LEFT
if (currentButtonState == 1) {
Joystick.setXAxis(-1);
} else {
Joystick.setXAxis(0);
}
break;
case 4: // FIRE
Joystick.setButton(0, currentButtonState);
break;
}
lastButtonState[index] = currentButtonState;
}
}

delay(10);
}

Listing 4-2: The Game Pad Example Sketch


Listing source: Courtesy of Matthew Heironimus
Although we will not review the Sketch, it does give us the instructions as to how to build our game pad.
We will need 5 pushbutton switches and we will use the internal pullup resistors.
// Pin 2 = UP
// Pin 3 = RIGHT
// Pin 4 = DOWN
// Pin 5 = LEFT
// Pin 6 = FIRE

Now build the breadboard layout as in Figure 4-10.


Figure 4-10: The Breadboard Layout for the Game Pad
Image source: Created with Fritzing
You can go to the game controller settings as shown in Figure 4-7. A window will pop up like the one in
Figure 4-11.
Figure 4-11: The Setting Screen for our Game Pad
Image source: Microsoft Windows
Press the buttons and you will see the responses on the screen.

Summary
In this chapter you learnt how to use the Arduino Leonardo to emulate games controllers such as game
pads and joysticks. You learnt that you could use keyboard emulation to do this or call on a library that
gives you the tools to make sophisticated controllers. You learnt how to test these controllers in a
Microsoft Windows environment.
Epilogue

We have come to the end of this part of the journey and in fact if you have followed these books
sequentially, then you are at the end of what I can offer on this subject. We have covered all key aspects
to the Arduino ecosystem and you will have the skills in place to create the most imaginative and
complex projects.
For me it has been the most rewarding adventure and I too have learnt along the way and made many
new friends who have communicated and interacted on social media. I wish you all best wishes and
good luck on whatever part of your journey you are on, and I hope to have had a positive impact on your
learning.
If you like this book and the series of books, please leave a review on the Amazon website. For the latest
news on other books in the series you can follow my Facebook page, Twitter or follow me as an author
on Amazon.
About the Author

Gary Hallberg has over 34 years of experience in the telecommunications and data communications
industries. He started his career working with circuit switched voice and data technologies in PDH and
SDH environments and then moved on to work with early packet switched networks using Frame Relay
and ATM. His career shifted focus to IP routing when the Internet started to grow, designing large scale
service provider networks using leading edge equipment from vendors such as Juniper and Cisco. Gary
attained Cisco Certified Professional status during this time. Presently, he is working for a global
equipment vendor with a focus on Ethernet networks and is at the forefront of network evolution,
providing infrastructures for SD-WAN, Network Functions Virtualization, SDN and 5G backhaul. Gary
has a Bachelor of Engineering degree in electronic engineering and a Master of Philosophy degree in
robotics and manufacturing.

You might also like