Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Arduinoio Ug

Download as pdf or txt
Download as pdf or txt
You are on page 1of 296

MATLAB® Support Package for Arduino®

Hardware
User’s Guide

R2023b
How to Contact MathWorks

Latest news: www.mathworks.com

Sales and services: www.mathworks.com/sales_and_services

User community: www.mathworks.com/matlabcentral

Technical support: www.mathworks.com/support/contact_us

Phone: 508-647-7000

The MathWorks, Inc.


1 Apple Hill Drive
Natick, MA 01760-2098
MATLAB® Support Package for Arduino® Hardware User’s Guide
© COPYRIGHT 2014–2023 by The MathWorks, Inc.
The software described in this document is furnished under a license agreement. The software may be used or copied
only under the terms of the license agreement. No part of this manual may be photocopied or reproduced in any form
without prior written consent from The MathWorks, Inc.
FEDERAL ACQUISITION: This provision applies to all acquisitions of the Program and Documentation by, for, or through
the federal government of the United States. By accepting delivery of the Program or Documentation, the government
hereby agrees that this software or documentation qualifies as commercial computer software or commercial computer
software documentation as such terms are used or defined in FAR 12.212, DFARS Part 227.72, and DFARS 252.227-7014.
Accordingly, the terms and conditions of this Agreement and only those rights specified in this Agreement, shall pertain
to and govern the use, modification, reproduction, release, performance, display, and disclosure of the Program and
Documentation by the federal government (or other entity acquiring for or through the federal government) and shall
supersede any conflicting contractual terms or conditions. If this License fails to meet the government's needs or is
inconsistent in any respect with federal procurement law, the government agrees to return the Program and
Documentation, unused, to The MathWorks, Inc.
Trademarks
MATLAB and Simulink are registered trademarks of The MathWorks, Inc. See
www.mathworks.com/trademarks for a list of additional trademarks. Other product or brand names may be
trademarks or registered trademarks of their respective holders.
Patents
MathWorks products are protected by one or more U.S. patents. Please see www.mathworks.com/patents for
more information.
Revision History
September 2014 Online only New for Version 14.1.0 (R2014a)
March 2015 Online only Revised for Version 15.1.0 (R2015a)
September 2015 Online only Revised for Version 15.2.0 (R2015b)
March 2016 Online only Revised for Version 16.1.0 (R2016a)
September 2016 Online only Revised for Version 16.2.0 (R2016b)
March 2017 Online only Revised for Version 17.1.0 (R2017a)
September 2017 Online only Revised for Version 17.2.0 (R2017b)
March 2018 Online only Revised for Version 18.1.0 (R2018a)
September 2018 Online only Revised for Version 18.2.0 (R2018b)
March 2019 Online only Revised for Version 19.1.0 (R2019a)
September 2019 Online only Revised for Version 19.2.0 (R2019b)
March 2020 Online only Revised for Version 20.1.0 (R2020a)
September 2020 Online only Revised for Version 20.2.0 (R2020b)
March 2021 Online only Revised for Version 21.1.0 (R2021a)
September 2021 Online only Revised for Version 21.2.0 (R2021b)
March 2022 Online only Revised for Version 22.1.0 (R2022a)
September 2022 Online only Revised for Version 22.2.0 (R2022b)
March 2023 Online only Revised for Version 23.1.0 (R2023a)
September 2023 Online only Revised for Version 23.2.0 (R2023b)
Contents

Setup and Configuration


1
Product Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-2

Install Support for Arduino Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-3


Install, Uninstall, and Update the Support Package . . . . . . . . . . . . . . . . . . 1-3

Set up and Configure Arduino Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-4


Connection over USB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-4
Connection over Bluetooth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-6
Connection over WiFi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-10

Set up and Configure ESP32 Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-14


Connection over USB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-14
Connection over WiFi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-17
Connection over Bluetooth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-20

Pair a Bluetooth Device and Retrieve the Bluetooth Device Address . . . 1-27
Retrieve Bluetooth Address for Windows . . . . . . . . . . . . . . . . . . . . . . . . 1-27
Retrieve Bluetooth Address for Mac . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-28

Supported Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-30

Connect to Arduino Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-31

Find Board Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-32

Measure Temperature and Control Peripherals Using the Arduino


Explorer App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-33

Control LEDs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-38

Getting Started with MATLAB Support Package for Arduino Hardware


......................................................... 1-39

I2C Sensors
2
Arduino I2C Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2

Communicate with an I2C EEPROM Device . . . . . . . . . . . . . . . . . . . . . . . . 2-3

iii
Measure Temperature from I2C Device on Arduino Hardware . . . . . . . . . 2-5

Measure LSM9DS1 Sensor Outputs Using Nano 33 BLE Sense . . . . . . . . 2-9

SPI Sensors
3
Arduino and SPI Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-2

Communicate with a SPI EEPROM Device . . . . . . . . . . . . . . . . . . . . . . . . . 3-4

Communicate with SPI Device on Arduino Hardware . . . . . . . . . . . . . . . . 3-6

Servo Motors
4
Servo Motors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-2

Rotate a Servo Motor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-3

Control Servo Motors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-4

Shift Registers, Quadrature Encoders, Adafruit Motor Shield


V2 and CAN
5
Push Button Control with 74HC165 Shift Register . . . . . . . . . . . . . . . . . . 5-2

Control LEDs with 74HC595 Shift Register . . . . . . . . . . . . . . . . . . . . . . . . 5-5

Classify and Count Fruits Using Arduino Nano 33 BLE Sense,


ThingSpeak, and Machine Learning . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-8

Identify Shapes Using Machine Learning on Arduino Nano 33 BLE Sense


Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-26

Control 7-Segment Display with 74HC595 Shift Register . . . . . . . . . . . . 5-34

Control Rotary Encoder Knob . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-38

Steer Two-Wheel Robot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-41

Control Motors Using Adafruit Motor Shield V2 . . . . . . . . . . . . . . . . . . . 5-45

Adapt Add-ons to New matlabshared.addon.LibraryBase Class . . . . . . . 5-49

iv Contents
Calibrate BNO055 Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-50
Calibrate Magnetometer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-50
Calibrate Accelerometer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-50
Calibrate Gyroscope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-51

Connect BNO055 Sensor to Arduino Hardware . . . . . . . . . . . . . . . . . . . . 5-52

Create Standalone Applications for Arduino Hardware . . . . . . . . . . . . . . 5-53


LCD Add-on . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-53
Generate Standalone Application by Using Application Compiler App . . . 5-53
Install and Run Standalone Application on Target Computer . . . . . . . . . . 5-54

Deploy Arduino Functions to Arduino Hardware Using MATLAB Function


Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-56
Supported Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-56
Required Products . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-57
Deploy MATLAB IO Functions on Arduino Hardware . . . . . . . . . . . . . . . . 5-57
Run the MATLAB Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-58
Adding Delays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-58
Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-58
Other Things to Try . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-59

Estimating Orientation Using Inertial Sensor Fusion and MPU-9250 . . 5-60

Wireless Data Streaming Using BNO055 and Bluetooth and Estimating


Orientation Using Sensor Fusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-71

Plot Position Using GPS Connected to Arduino Hardware . . . . . . . . . . . . 5-77

Gyroscope-Based Pedometer Using MATLAB Functions . . . . . . . . . . . . . 5-80

Read and Write CAN Messages with Arduino Hardware . . . . . . . . . . . . . 5-84

Advanced CAN Communication with Arduino Using Vehicle Network


Toolbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-87

Overcome Buffer Size Limitation of Arduino . . . . . . . . . . . . . . . . . . . . . . 5-90

Read and Plot Real-Time Data from BNO055 Sensor in NDOF Mode . . . 5-95
Required Products . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-95
Required Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-95
Hardware Connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-95
Create Connection to BNO055 Sensor in NDOF Mode . . . . . . . . . . . . . . 5-96
Calibrate BNO055 Sensor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-96
Read Sensor Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-96
Clean Up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-99

Custom Arduino Libraries


6
Create Custom Arduino Add-On Library . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-2

v
Custom Add-On Library Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-3
Command Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-3
Required Knowledge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-3

Create Add-On Package Folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-5

Create and Configure C++ Header File . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-6


Install Third-Party Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-6
LibraryBase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-6
Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-7
Command Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-8
Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-9
Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-9
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-9

Create and Configure MATLAB Add-On Class . . . . . . . . . . . . . . . . . . . . . . 6-11


Command Identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-12
Library Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-12
Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-13
Destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-14
Resource Ownership . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-15

Create HelloWorld Add-On . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-16


Create Folder Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-16
Create C++ Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-17
Create MATLAB Wrapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-18
Register Add-On . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-19
Run MATLAB Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-20

Create LCD Add-on . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-21


Connect Arduino to LCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-21
Connect Arduino to LCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-24
Create C++ Header and Include Third-Party Source Files . . . . . . . . . . . 6-25
Create MATLAB Add-On Wrapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-29
Register Custom Library and Run MATLAB Code . . . . . . . . . . . . . . . . . . 6-32

Add-On Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-34


Counted . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-34
Shared . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-34

Physical Terminals and Pin Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-35

Register Add-On Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-36

Troubleshooting in MATLAB Support Package for Arduino


Hardware
7
Find Arduino Port on Windows, Mac, and Linux . . . . . . . . . . . . . . . . . . . . . 7-2
Find Port Number on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-2
Find Port Number on Macintosh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-2
Find Port Number on Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-2

vi Contents
Find ESP32 Port on Windows, Mac, and Linux . . . . . . . . . . . . . . . . . . . . . . 7-4
Find Port Number on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-4
Find Port Number on Macintosh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-4
Find Port Number on Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-5

Arduino Bluetooth Setup Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-6


Failure to Program Arduino Board . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-6
Configure a 5 V HC-05 or HC-06 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-6
Find FTDI Serial Port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-6

Arduino USB, Bluetooth, and Wi-Fi Connection Failure . . . . . . . . . . . . . . 7-8


Arduino USB Connection Failure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-8
Arduino Bluetooth Connection Failure . . . . . . . . . . . . . . . . . . . . . . . . . . 7-10
Arduino Wi-Fi Connection Failure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-10

ESP32 Board Setup Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-12


ESP32 Hardware Detection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-12
ESP32 Hardware Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-12

Lost Connection and Data Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-13


Lost Connection with Arduino Hardware . . . . . . . . . . . . . . . . . . . . . . . . 7-13
Data Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-14

Board Specific Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-15


Arduino ATmega328p Boards Does Not Work on Mac 10.9 . . . . . . . . . . . 7-15
Arduino Due . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-15
Arduino Leonardo and Micro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-16
Arduino Nano 33 IoT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-16
Arduino Nano 33 BLE and Nano 33 BLE Sense . . . . . . . . . . . . . . . . . . . . 7-17
Arduino MKR CAN Shield . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-17
Arduino Uno and Mega . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-17
Arduino MKR1000 or MKR1010 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-17
Boards Not Listed in Interactive Hardware Setup . . . . . . . . . . . . . . . . . . 7-19
Arduino to FTDI Adaptor Connection . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-19

Serial Device Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-21


Data Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-21

Arduino Resource Conflicts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-22

Adafruit Motor Shields and Servo Issues . . . . . . . . . . . . . . . . . . . . . . . . . 7-23


Adafruit Motor Shields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-23
Servo Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-24

Custom Arduino Library Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-25


Custom Library Class Not Detected . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-25

Troubleshooting Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-26


Error: Unable to receive data from the target hardware . . . . . . . . . . . . . 7-26
Unexpected response from IMU sensor . . . . . . . . . . . . . . . . . . . . . . . . . . 7-26

Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-27

Connect Arduino to MATLAB over Bluetooth . . . . . . . . . . . . . . . . . . . . . . 7-28

vii
Connect Arduino to MATLAB over Wi-Fi . . . . . . . . . . . . . . . . . . . . . . . . . . 7-29

Connect Arduino to MATLAB over USB . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-30

AEK
8
Using Arduino Engineering Kit Rev 2 with Pre-Configured Projects in
Support Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-2
License and Installation Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-2
Pre-Configured Projects Available with the Support Package . . . . . . . . . . . 8-3
Required Products for the Pre-Configured Projects . . . . . . . . . . . . . . . . . . 8-3

Webcam Controlled Rover Using Arduino Engineering Kit Rev 2 . . . . . . . 8-5

Drawing Robot Using Arduino Engineering Kit Rev 2 . . . . . . . . . . . . . . . . 8-7

Self-Balancing Motor Cycle Using Arduino Engineering Kit Rev 2 . . . . . . 8-9

Arduino Explorer
9
Using Arduino Explorer App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-2
Set Up and Connect to Official Arduino Boards and Clone Boards . . . . . . . 9-2
Configure Read and Write for GPIO Pins . . . . . . . . . . . . . . . . . . . . . . . . . . 9-5
Connect to SPI Device . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-7
Connect to I2C Device . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-8
Connect to Serial Device . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-11
Decode Read Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-13
Visualize and Record Data from Arduino Pins . . . . . . . . . . . . . . . . . . . . . 9-14
Generate MATLAB Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-18
Customizable Views in the App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-18

IoT-Based Automatic Cooling Fan Control Using ThingSpeak and Arduino


Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-20

IoT-Based Temperature Monitoring Using ThingSpeak and Arduino


Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-32

viii Contents
1

Setup and Configuration

• “Product Description” on page 1-2


• “Install Support for Arduino Hardware” on page 1-3
• “Set up and Configure Arduino Hardware” on page 1-4
• “Set up and Configure ESP32 Hardware” on page 1-14
• “Pair a Bluetooth Device and Retrieve the Bluetooth Device Address” on page 1-27
• “Supported Hardware” on page 1-30
• “Connect to Arduino Hardware” on page 1-31
• “Find Board Name” on page 1-32
• “Measure Temperature and Control Peripherals Using the Arduino Explorer App” on page 1-33
• “Control LEDs” on page 1-38
• “Getting Started with MATLAB Support Package for Arduino Hardware” on page 1-39
1 Setup and Configuration

Product Description
MATLAB Support Package for Arduino Hardware enables you to use MATLAB® to communicate with
the Arduino® board over a USB cable. This package is based on a server program running on the
board, which listens to commands arriving via serial port, executes the commands, and, if needed,
returns a result. This approach helps you:

• Start programming right away without any additional toolboxes.


• Work in theMATLAB for interactive development and debugging.
• Interactively develop programs to acquire analog and digital data, and to control DC, servo, and
stepper motors.
• Access peripheral devices and sensors connected over I2C or SPI.
• Run control loops at up to 25 Hz (not real time).
• Introduce mechatronics, signal processing, and electronics concepts in classroom labs.

This support package supports Arduino Uno, Arduino Mega 2560 and Arduino Due hardware.

1-2
Install Support for Arduino Hardware

Install Support for Arduino Hardware

Install the MATLAB Support Package for Arduino Hardware to add support for Arduino devices.

The installation adds these items on your host computer:

• Third-party software
• MATLAB functions
• Examples

When you complete installation, you can use MATLAB commands to control and retrieve data from
Arduino hardware and its peripherals.

Install, Uninstall, and Update the Support Package


Install the Support Package

To install support package for Arduino hardware:

• On the MATLAB Home tab, in the Environment section, click Add-Ons > Get Hardware
Support Packages.
• In the Add-On Explorer search bar, search for MATLAB Support Package for Arduino Hardware,
and then click the MATLAB Support Package for Arduino Hardware add-on.

Uninstall the Support Package

To uninstall support package for Arduino hardware:

• On the MATLAB Home tab, in the Environment section, click Add-Ons > Manage Add-Ons.
• In the Add-On Manager window, find and click the support package, and then click Uninstall.

Update the Support Package

To update support package for Arduino hardware:

• On the MATLAB Home tab, in the Environment section, click Help > Check for Updates.

For more information about using Add-On Explorer, see “Get and Manage Add-Ons”.

See Also

Related Examples
• “Set up and Configure Arduino Hardware” on page 1-4

1-3
1 Setup and Configuration

Set up and Configure Arduino Hardware


Once you have installed the MATLAB Support Package for Arduino Hardware, as described in “Install
the Support Package” on page 1-3, you can configure communication between the host computer and
the Arduino board. Type arduinosetup in the MATLAB Command window and choose one of the
following connection types:

Connection over USB


The Arduino hardware communicates with the host computer via a USB cable as shown.

To configure your Arduino hardware to communicate via USB:

1 Connect the Arduino hardware via USB, by choosing the connection type USB.
2 Choose the board type and the port number from the Choose board and Choose port menus.
Then, select the libraries that you want to include in your Arduino server. Click Program to
begin uploading the server to your Arduino board.

1-4
Set up and Configure Arduino Hardware

3 After the upload is complete, click Test connection to test the connection between your host
computer and the Arduino board.

1-5
1 Setup and Configuration

4 Click Finish to complete the hardware setup. To connect to your Arduino board, see “Connect to
Arduino Hardware” on page 1-31.

Connection over Bluetooth


Arduino hardware communicates with the host computer via Bluetooth®, as shown.

1-6
Set up and Configure Arduino Hardware

To configure your Arduino hardware to communicate via Bluetooth:

1 Connect the Arduino hardware via USB, and choose the connection type Bluetooth.
2 Choose the board type and the port number from the Choose board and Choose port menus.

1-7
1 Setup and Configuration

3 Select the libraries that you want to include in your Arduino server. Click Program to begin
uploading the server to your Arduino board.

If you are using MKR1010, Nano 33 IoT, Nano 33 BLE, or the Nano 33 BLE Sense board, on
the Upload Arduino Server screen:

• Use the Enter the name of the device or select from a list of available device menu to
select an Arduino device.
• Use the Select libraries to be included in the server drop-down menu to upload libraries
to the hardware.
• Click Program to complete uploading libraries to the Arduino device and retrieve the
Bluetooth Device address from the Arduino board.

1-8
Set up and Configure Arduino Hardware

4 If you are using the Uno, Due, Mega2560, Leonardo, Micro, or the Nano3 board, select the
Bluetooth device that you want to use to communicate with the Arduino board. If you are using
the HC-05 or HC-06 boards and you have not configured the device using the arduinosetup
interface, click No to first configure your Bluetooth device.
5 If you are using the Uno, Due, Mega2560, Leonardo, Micro, or the Nano3 board, to configure
your Bluetooth device, follow the on-screen links in the arduinosetup interface to pair your
Bluetooth Classic device and to get your Bluetooth serial port or address.

Note If you are using a Windows® desktop computer, connect a Bluetooth dongle to your
computer. You should use a dongle supporting Bluetooth 4.0 or higher to connect to the
MKR1010, Nano33 IoT, Nano 33 BLE, or, Nano 33 BLE Sense boards over Bluetooth.
6 If you are using ESP32-DevKitV1 or ESP32-DevKitC boards, see Configure ESP32 Hardware
over Bluetooth on page 1-20.
7 Click Test connection to test the connection between your host computer and the Arduino
board and click Next.

1-9
1 Setup and Configuration

Note If you are using the MKR1010, Nano 33 IoT, Nano 33 BLE, or the Nano 33 BLE Sense
board, your computer running MATLAB can detect Bluetooth. This computer acts as a Bluetooth
central.
8 Click Finish to complete the hardware setup.

Connection over WiFi


Arduino hardware communicates with the host computer via WiFi, as shown.

1-10
Set up and Configure Arduino Hardware

To configure your Arduino hardware to communicate via WiFi:

1 Connect the Arduino hardware via USB by choosing the connection type WiFi. Choose the
encryption type of your WiFi network, and enter the necessary credentials.

• If you have previously configured your Arduino board using WiFi via the arduinosetup
interface, you can select the Retrieve last configuration from Arduino board
option, which retrieves the necessary credentials from your previous configuration.
• If you select the Use static IP address box, make sure that you use an available static IP
address and that your router allows the usage of static IP.

Note Ensure that the Subnet Mask is 255.255.255.0 and the Default Gateway is the IP
address of the network gateway.
2 Choose the board type as MKR1000, MKR1010, or Nano 33 IoT and its port number. Also, select
the libraries that you want to include in your Arduino board. Click Program to begin uploading
the server to your Arduino board.

Note If you are using ESP32-DevKitV1 or ESP32-DevKitC boards, see Configure ESP32
Hardware over WiFi on page 1-17.

1-11
1 Setup and Configuration

3 After the upload is complete, click Test connection to test the connection between the host
computer and the Arduino board.

1-12
Set up and Configure Arduino Hardware

4 Click Finish to complete the hardware setup.

See Also
arduinosetup

Related Examples
• “Pair a Bluetooth Device and Retrieve the Bluetooth Device Address” on page 1-27

1-13
1 Setup and Configuration

Set up and Configure ESP32 Hardware


Once you have installed the MATLAB Support Package for Arduino Hardware, as described in “Install
the Support Package” on page 1-3, you can configure communication between the host computer and
the ESP32 board. Type arduinosetup in the MATLAB Command window and choose one of the
following connection types.

Note For setting up ESP32 and associated libraries for the support package installed on Linux,
ensure that you have logged in as root user. Also, ensure that you launch MATLAB as root user.

Connection over USB


The ESP32 hardware communicates with the host computer via a USB cable as shown.

To configure your ESP32 hardware to communicate via USB:

1 Connect the ESP32 hardware via USB, by choosing the connection type USB. Click Next.

1-14
Set up and Configure ESP32 Hardware

2 In the Upload Arduino Server screen, choose the board type and the port number from the
Choose board and Choose port menus.

The supported ESP32 boards are ESP32-WROOM-DevKitC and ESP32-WROOM-DevKitV1.

Then, select the libraries that you want to include in your ESP32 server.

Note Selecting the Install ESP32 third-party library option is mandatory to work with ESP32
boards. This option appears in the screen only for the first time you select ESP32 board (the
subsequent launch of Hardware Setup screen checks for ESP32 library installation and displays
the option only if the library is not available).

Note The CAN library is not supported for ESP32 board.


3 Click Program to begin uploading the server to your ESP32 board.

1-15
1 Setup and Configuration

4 After the upload is successful, click Next to proceed.


5 Click Test connection to test the connection between your host computer and the ESP32 board.

6 Click Finish to complete the hardware setup. To connect to your ESP32 board, see “Connect to
Arduino Hardware” on page 1-31.

1-16
Set up and Configure ESP32 Hardware

Connection over WiFi


ESP32 hardware communicates with the host computer via WiFi, as shown.

To configure your ESP32 hardware to communicate via WiFi:

1 Connect the ESP32 hardware via USB by choosing the connection type WiFi. Choose the
encryption type of your WiFi network, and enter the necessary credentials.

Note WEP encryption type is not supported for ESP32 boards.

• If you have previously configured your Arduino board using WiFi via the arduinosetup
interface, you can select the Retrieve last configuration from Arduino board option,
which retrieves the necessary credentials from your previous configuration.
• If you select the Use static IP address box, make sure that you use an available static IP
address and that your router allows the usage of static IP.

Note Ensure that the Subnet Mask is 255.255.255.0 and the Default Gateway is the IP
address of the network gateway.

1-17
1 Setup and Configuration

Click Next.
2 In the Upload Arduino Server screen, choose the board type and the port number from the
Choose board and Choose port menus.

The supported ESP32 boards are ESP32-WROOM-DevKitC and ESP32-WROOM-DevKitV1.

Then, select the libraries that you want to include in your ESP32 server.

Note Selecting the Install ESP32 third-party library option is mandatory to work with ESP32
boards. This option appears in the screen only for the first time you select ESP32 board (the
subsequent launch of Hardware Setup screen checks for ESP32 library installation and displays
the option only if the library is not available).

Note The CAN library is not supported for ESP32 board.


3 Click Program to begin uploading the server to your ESP32 board.
4 After the upload is successful, click Next to proceed.

1-18
Set up and Configure ESP32 Hardware

5 Click Test connection to test the connection between your host computer and the ESP32 board.

1-19
1 Setup and Configuration

6 Click Finish to complete the hardware setup.

Connection over Bluetooth


The ESP32 hardware communicates with the host computer via Bluetooth, as shown.

1-20
Set up and Configure ESP32 Hardware

To configure your ESP32 hardware to communicate via Bluetooth:

1 Connect the ESP32 hardware via USB, and choose the connection type Bluetooth.
2 Choose the board type and the port number from the Choose board and Choose port menus.

1-21
1 Setup and Configuration

3 Use the Enter the name of the device or select from a list of available device menu to
select an Arduino device.

Select the libraries that you want to include in your ESP32 server. Click Program to begin
uploading the server to your ESP32 board.

1-22
Set up and Configure ESP32 Hardware

4 After the upload is successful, click Next to proceed.

1-23
1 Setup and Configuration

5 If you are using a Windows desktop computer, connect a Bluetooth dongle to your computer. You
should use a dongle supporting Bluetooth 4.0 or higher to connect to the ESP32-DevKitV1 or
ESP32-DevKitC boards over Bluetooth.
6 Click Test connection to test the connection between your host computer and the Arduino
board and click Next.

1-24
Set up and Configure ESP32 Hardware

Note If you are using the ESP32-DevKitV1 or ESP32-DevKitC board, your computer running
MATLAB can detect Bluetooth. This computer acts as a Bluetooth central.
7 Click Finish to complete the hardware setup.

1-25
1 Setup and Configuration

See Also
arduinosetup

1-26
Pair a Bluetooth Device and Retrieve the Bluetooth Device Address

Pair a Bluetooth Device and Retrieve the Bluetooth Device


Address
You can pair the Bluetooth device to your host computer and retrieve the Bluetooth device address or
serial port based on your operating system. Before you pair, make sure that the Bluetooth device is
connected to the Arduino board and is powered properly.

Retrieve Bluetooth Address for Windows

Find the Bluetooth Address for HC-05 and HC-06

1 Open the Device Manager on your Windows machine.


2 Right-click on the HC-05 or HC-06 Bluetooth device under Bluetooth and select Properties.

3 Click Details menu, and then select the Property as Bluetooth device address. The Value
is the Bluetooth address of the device.

1-27
1 Setup and Configuration

4 Enter the Bluetooth device address on the arduinosetup interface and click Next to configure
the device.

Retrieve Bluetooth Address for Mac

1-28
Pair a Bluetooth Device and Retrieve the Bluetooth Device Address

Find the Bluetooth Address for HC-05 and HC-06

1 Before your pair HC-05 and HC-06 Bluetooth devices to your Mac, right-click on Pair under
Open Bluetooth Preferences in the Bluetooth menu. You see the Bluetooth address of your
device.

2 Enter the Bluetooth device address without dashes as an hexadecimal string on the
arduinosetup interface, and click Next to configure the device.

See Also

Related Examples
• “Set up and Configure Arduino Hardware” on page 1-4

1-29
1 Setup and Configuration

Supported Hardware
For a list of currently supported Arduino hardware, see the Supported Hardware page.

1-30
Connect to Arduino Hardware

Connect to Arduino Hardware


This example shows how to connect to Arduino or ESP32 hardware in MATLAB.

Make sure the Arduino or ESP32 hardware is connected to the computer. If the device is unofficial,
note the port and the board name.

Connect to an official Arduino hardware.

a = arduino()

a =

arduino with properties:

Port: 'COM4'
Board: 'Uno'
AvailablePins: {'D2-D13', 'A0-A5'}
AvailableDigitalPins: {'D2-D13', 'A0-A5'}
AvailablePWMPins: {'D3','D5-D6', 'D9-D11'}
AvailableAnalogPins: {'A0-A5'}
AvailableI2CBusIDs: [0]
Libraries: {'I2C','RotaryEncoder','SPI','Servo','ShiftRegister','Ultrasonic'}
Show all properties

Connect by specifying the port and board name.

If you are using an unofficial (clone) Arduino hardware, specify port and board name to establish
connection.

a = arduino('COM4','Uno')

a =

arduino with properties:

Port: 'COM4'
Board: 'Uno'
AvailablePins: {'D2-D13', 'A0-A5'}
AvailableDigitalPins: {'D2-D13', 'A0-A5'}
AvailablePWMPins: {'D3','D5-D6', 'D9-D11'}
AvailableAnalogPins: {'A0-A5'}
AvailableI2CBusIDs: [0]
Libraries: {'I2C','RotaryEncoder','SPI','Servo','ShiftRegister','Ultrasonic'}
Show all properties

1-31
1 Setup and Configuration

Find Board Name


Currently the MATLAB Support Package for Arduino Hardware supports the hardware listed in the
table. Use arduino to establish a connection to your Arduino hardware.

Arduino Board String used to create the arduino object


Arduino Uno Uno
Arduino Due Due
Arduino Mega 2560 Mega2560
Arduino Leonardo Leonardo
Arduino Mega ADK MegaADK
Arduino Micro Micro
Arduino MKR1000 MKR1000
Arduino MKR WiFi 1010 MKR1010
Arduino MKR Zero MKRZero
Arduino Nano 3.1 Nano3
Arduino Nano 33 IoT Nano33IoT
Arduino Pro Mini (ATmega328) ProMini328_3V, ProMini328_5V
Arduino Nano 33 BLE Nano33BLE
Arduino Nano 33 BLE Sense Nano33BLE
a
Arduino-compatible Boards String used to create the arduino object
Sparkfun Digital Sandbox DigitalSandbox
SparkFun Redboard Uno
Sainsmart Uno Uno
Sainsmart Mega 2560 Mega2560
Seeeduino V4.2 Uno
Grove Beginner Kit for Arduino (powered by Uno
Seeeduino Lotus)
Arduino-compatible ESP32 Development String used to create the arduino object
Boards
ESP32-DevKitV1 ESP32-WROOM-DevKitV1
ESP32-DevKitC ESP32-WROOM-DevKitC
a The Arduino-compatible boards listed in the table have been tested. If you are using other Arduino-compatible boards,
refer to the product documentation of the board for the board name you can use.

1-32
Measure Temperature and Control Peripherals Using the Arduino Explorer App

Measure Temperature and Control Peripherals Using the


Arduino Explorer App

This example helps you to use the Arduino® Explorer app to connect to an Arduino board and control
attached peripherals depending on the temperature variations.

In this example the Arduino board is attached to three peripherals: a servo motor, an LED, and a
temperature sensor.

The app provides a unified interface to monitor inputs from the temperature sensor and to provide
outputs to the LED and servo motor peripherals.

To open the app, on the MATLAB® Toolstrip, on the Apps tab, in the Test and Measurement
section, click Arduino Explorer.

Requirements

To run this example, you must have the following hardware:

• Arduino® board
• Analog output temperature sensor
• Servo motor
• LED
• Resistor

1-33
1 Setup and Configuration

Measure Temperature and Control Peripherals Using the Arduino Explorer App

The Arduino board has already been configured and connected over the USB. If the board needs pre-
configuration see, “Set up and Configure Arduino Hardware” on page 1-4.

Use the Pinout panel to view the pinout diagram of the board. The pinout diagram helps you to
identify the Arduino Pins to connect the peripherals to the board.

Configure the Arduino Board


1 Set up an analog pin A0 of the Arduino to receive analog inputs from the temperature sensor. On
the Pin Configuration pane, choose the row A0. In the Configure pin panel set the Mode as
AnalogInput and the Custom Name as TempData.
2 The Arduino Explorer App automatically plots the input data in the timescope. You may turn off
plotting by deselecting the pin in the Plot Pins pane. Similarly, set the Mode of digital pins D2
and D3, as DigitalOutput and Servo. You may also provide custom names to these pins. Note:
Arduino Explorer App plots pins that are in Read or Input mode.
3 The Read Value pane displays the incoming values of the pins. Pin A0 displays the input voltage
from the temperature sensor. Pin D2 displays the current angle of the servo motor shaft
(normalized).
4 You can use the Write Value to write data to the Arduino pins. Writing 1 to the digital pin D2 will
make the LED glow. For D3, writing a value that is different from the read value, will rotate the
servo motor shaft.
5 You may also record the data of the pins by selecting the Record Pin option under Pin
Configuration, and by clicking Record in the toolstrip. This data is recorded in the workspace
variables for the specified duration.

1-34
Measure Temperature and Control Peripherals Using the Arduino Explorer App

6 If you have the Signal Processing Toolbox, the recorded data can also be visualized using the
Signal Analyzer app by clicking on the Signal Analyzer Toolstrip button.

In the Arduino Explorer app toolstrip, click Generate Script, to open the MATLAB live editor and
display the equivalent MATLAB code. The code contains commands to create an Arduino®
connection, configure Arduino pins and to read and write data.

1-35
1 Setup and Configuration

You may add your own logic to the code, control the setup.

Now the setup is ready to control the servo motor when the temperature voltage increases beyond
the thresholdVoltage.

1-36
Measure Temperature and Control Peripherals Using the Arduino Explorer App

See Also

• “Using Arduino Explorer App” on page 9-2

1-37
1 Setup and Configuration

Control LEDs

This example shows how to configure LEDs to turn on and off and to dim and brighten using
MATLAB® commands.

Connect an LED to pin 9 and GND on your Arduino® hardware.

Create an arduino object.

a = arduino;

Write data to the digital pin to turn the LED on and off repeatedly for 10 seconds.

for idx = 0:10


writeDigitalPin(a,'D9',1);
pause(0.5);
writeDigitalPin(a,'D9',0);
pause(0.5);
end

Change the brightness from maximum to minimum using the digital pin's PWM duty cycle.

for brightness = 1:-0.1:0


writePWMDutyCycle(a,'D9',brightness);
pause(0.5);
end

Once the connection is no longer needed, clear the arduino object.

clear a

1-38
Getting Started with MATLAB Support Package for Arduino Hardware

Getting Started with MATLAB Support Package for Arduino


Hardware

This example shows how to use MATLAB® Support Package for Arduino® Hardware to perform basic
operations on the hardware such as turning an LED on and off, blinking LEDs and playing sound on a
speaker.

Hardware setup

Connect an LED to digital pin 11 on the Arduino hardware through a 1kOhm resistor.

1-39
1 Setup and Configuration

Create an arduino object


a = arduino();

If you have more than one Arduino board connected, specify the port and board type.
clear a;
a = arduino('COM4', 'Uno');

Turn LED on and off

Write value 1 or true to digital pin 11 turns on the LED and write a value of 0 or false turns it off.
Execute the following command at the MATLAB prompt to turn the LED off and on.
writeDigitalPin(a, 'D11', 0);
pause(2);
writeDigitalPin(a, 'D11', 1);

Configure the LED to blink at a period of 0.5 second.


for i = 1:10
writeDigitalPin(a, 'D11', 0);
pause(0.5);
writeDigitalPin(a, 'D11', 1);
pause(0.5);
end

Brighten and dim LED

Send pulse signals of specified width to the PWM pins on the Arduino hardware. PWM signals can
light up LEDs connected to the pin. The duty cycle of the pulse controls the brightness of the LED.
Calculate the amount that the LED brightens and dims by dividing the max and min duty cycle for the
pin by the number of iterations.
brightness_step = (1-0)/20;
for i = 1:20
writePWMDutyCycle(a, 'D11', i*brightness_step);
pause(0.1);
end

for i = 1:20
writePWMDutyCycle(a, 'D11', 1-i*brightness_step);
pause(0.1);
end

You can also brighten and dim the lights by changing the voltage of the PWM signal. Calculate the
amount that the LED brightens and dims by dividing the max and min voltage for the pin by the
number of iterations.
brightness_step = (5-0)/20;
for i = 1:20
writePWMVoltage(a, 'D11', i*brightness_step);
pause(0.1);
end

for i = 1:20
writePWMVoltage(a, 'D11', 5-i*brightness_step);
pause(0.1);
end

1-40
Getting Started with MATLAB Support Package for Arduino Hardware

Control an LED using a potentiometer

The potentiometer changes the voltage value read from analog pin 0 which can be used to set the
voltage level on the PWM pin to control the brightness of the LED connected. Connect a
potentiometer to Arduino hardware with the middle leg connected to analog pin 0 and the other two
connected to 5V and GND.

time = 200;
while time > 0
voltage = readVoltage(a, 'A0');
writePWMVoltage(a, 'D11', voltage);

time = time - 1;
pause(0.1);
end

1-41
1 Setup and Configuration

While the code is running, you can rotate the knob on the potentiometer to see how it affects the
brightness of the LED.

Control a Piezo speaker using a push button

This part of the example shows how to play a tone controlled by a push button connected to a digital
pin on the Arduino hardware. You can also configure a digital pin to pullup mode and use the built-
in pullup resistor.

1) Connect a Piezo speaker to digital pin 11.

2) Connect a push button to digital pin 12.

To play a tone on the speaker, you can use playTone method to specify the frequency and duration of
the sound. Second, the status of a push button can be detected by reading the connected digital pin's

1-42
Getting Started with MATLAB Support Package for Arduino Hardware

value. In order for the push button to work, a pullup resistor needs to be connected to the
corresponding digital pin on Arduino board. You can use the built-in pullup resistor by configuring the
digital pin mode to pullup to enable it. If the button has been pushed, meaning the read back value
is 0, a beep sound is played on the speaker. Execute the following command at the MATLAB prompt
to play a sound on the speaker when push button is pressed down.

configurePin(a, 'D12', 'pullup');


time = 200;
while time > 0
speaker_status = readDigitalPin(a, 'D12');
if speaker_status == 0
playTone(a, 'D11', 1200, 1);
else
% Change duration to zero to mute the speaker
playTone(a, 'D11', 1200, 0);
end

time = time - 1;
pause(0.1);
end

Clean up

Once the connection is no longer needed, clear the arduino object.

clear a

1-43
2

I2C Sensors

• “Arduino I2C Interface” on page 2-2


• “Communicate with an I2C EEPROM Device” on page 2-3
• “Measure Temperature from I2C Device on Arduino Hardware” on page 2-5
• “Measure LSM9DS1 Sensor Outputs Using Nano 33 BLE Sense” on page 2-9
2 I2C Sensors

Arduino I2C Interface


I2C, or Inter-Integrated Circuit, is a chip-to-chip protocol for communicating with low-speed
peripherals. MATLAB Support Package for Arduino Hardware includes the I2C library, which creates
an interface to communicate with I2C devices. Each Arduino board has specific pins for the I2C
interface. Refer to your hardware specifications to locate the correct pins.

You can use I2C devices in many applications, including:

• Real-time clocks
• Digital potentiometers
• Temperature sensors
• Digital compasses
• Memory chips
• FM radio circuits
• Input/output expanders
• LCD controllers
• Amplifiers

Note To create a custom I2C code, see “Create Custom Arduino Add-On Library” on page 6-2

Arduino devices have one or two I2C buses. Each bus has an I2C Central connected to two
bidirectional lines, serial data line (SDA) and serial clock (SCL). These two lines are connected to a
pair of pins on the hardware. You can connect multiple I2C devices, such as ADCs, LCDs, and sensors,
to the I2C pins on the Arduino hardware. Each I2C device on an I2C bus must have a unique address.
Most devices have a default address assigned by the manufacturer. If the address is not unique, refer
to the device data sheet and reconfigure the address. Often, you can reconfigure the address using a
pair of jumpers on the device. MATLAB Support Package for Arduino Hardware supports only 7-bit
addressing.

For more information on Arduino I2C devices see https://arduino.cc/en/reference/wire

2-2
Communicate with an I2C EEPROM Device

Communicate with an I2C EEPROM Device


This example shows how to store and retrieve data from an EEPROM on an I2C device. Using
EEPROM you can read, erase, and rewrite individual bits of data from the sensor’s memory. Before
using this example, wire an EEPROM to the I2C pins on your Arduino hardware.

This example uses 24LC02B – I2C Bus Serial EEPROM .

Create an I2C connection on your Arduino hardware.

Create an Arduino object and include the I2C library.

a = arduino('COM22','Uno','Libraries','I2C');

Scan for I2C address on the Arduino hardware.

addrs = scanI2CBus(a)

addrs =
8×1 cell array
{'0x50'}
{'0x51'}
{'0x52'}
{'0x53'}
{'0x54'}
{'0x55'}
{'0x56'}
{'0x57'}

Create an I2C device object using the address and the arduino object.

eeprom = device(a,'I2CAddress','0x54');

The bus number defaults to 0. Refer to your device datasheet to get the correct address for your
device.

Write “Hello World!” to the EEPROM from chip AT24C02. This device has eight bytes per page. You
must specify the page address in front of each byte of data to be written.

Write the first byte of the string, “Hello Wo” to address 0.

write(eeprom,[0 'Hello Wo']);

Write the second byte of the string, “rld!” to address 8.

write(eeprom,[8 'rld!']);

Write 0 in order to read from the first byte of the first page.

write(eeprom,0);

Read data from the EEPROM.

char(read(eeprom,12))

ans =

Hello World!

2-3
2 I2C Sensors

Write 5 to the register with address 80 on the EEPROM chip.

writeRegister(eeprom,80,5);

Read data from the address 80 on the EEPROM chip.

readRegister(eeprom,80)

ans =

2-4
Measure Temperature from I2C Device on Arduino Hardware

Measure Temperature from I2C Device on Arduino Hardware

This example shows how to use the MATLAB® Support Package for Arduino® Hardware and the I2C
interface to communicate with I2C devices.

Overview of TMP102 Temperature Sensor

This example uses TMP102, a two-wire serial output digital sensor, which can read temperature up to
a resolution of 0.0625 degree in Celsius. You can also read data from the device in Extended mode
with higher measurement limit.

Hardware Setup

1) Connect the SDA, SCL, GND and VCC pins of the sensor to the corresponding pins on Arduino
hardware. This examples connects SDA and SCL pins to A4 and A5 on Arduino Uno board. If you are
using a different board, check the correct pins before connection.

2) Securely connect the power line of the I2C sensor.

2-5
2 I2C Sensors

Create an I2C Device Object

1) Create an arduino object and include the I2C library.

a = arduino('COM9', 'Uno', 'Libraries', 'I2C');

2) Scan for available I2C addresses.

addrs = scanI2CBus(a)

addrs = 1×1 cell array


{'0x48'}

Note the address of the temperature sensor. You will use it to create the I2C device object.

2-6
Measure Temperature from I2C Device on Arduino Hardware

3) Create the I2C device object


tmp102 = device(a,'I2CAddress',0x48)

The bus defaults to 0. If you are using the dedicated I2C interfaces(SDA1, SCL1) on Due board, for
example, make sure to set bus to 1.

Read Temperature Value

The sensor's temperature reading is digitized into 12 bits in Normal mode with 8 bits in MSB and 4
bits in LSB. Each LSB equals 0.0625 degrees in Celsius. Write the register address to read from first
and then read two bytes of data from it. Use uint8 data type.

Calculate the temperature in °C by using the tmp102Temperature helper function. You can find this
helper function at the end of this example and attached to this example as a supporting file.
write(tmp102, 0x0, 'uint8');
data = read(tmp102, 2, 'uint8');
temperature = tmp102Temperature(data,12)

temperature = 26.6250

Read Temperature with Higher Measurement Limit

With the TMP102 sensor's extended mode, you can measure temperature above 128 degrees by using
13 bits. To do so, you need to write value 'B060' in hex to configuration register at address 1.
writeRegister(tmp102, 1, 0xB060, 'uint16');

Read the temperature from the register to get a more precise result. The TMP102's conversion rate
defaults to 4Hz. Hence, pause MATLAB for about 0.25s before each reading. Convert the data to °C
by using the tmp102Temperature helper function.
write(tmp102, 0x0, 'uint8');
pause(0.25);
data = read(tmp102, 2, 'uint8');
temperature = tmp102Temperature(data,13)

temperature = 26.6250

To change back the default configuration, type


writeRegister(tmp102, 1, 0xA060, 'uint16');

Clean Up

Once the connection is no longer needed, clear the associated object.


clear tmp102 a

Helper Function
function T = tmp102Temperature(data,numBits)
% tmp102Temperature Convert TMP102 raw temperature register data to temperature in °C
%
% T = tmp102Temperature(data,numBits)
% data is 1x2 row vector of uint8 values in big-endian order
% numBits corresponds to the TMP102 temperature mode (12 bits for normal
% mode, or 13 bits for extended mode)

2-7
2 I2C Sensors

% TMP102 resolution (°C / count)


resolution = 0.0625;

% Digital temperature output (counts)


numShiftBits = 16-numBits;
digitalT = bitshift(typecast(uint8(fliplr(data)),'int16'),-numShiftBits);

% Temperature in °C
T = double(digitalT) * resolution;
end

2-8
Measure LSM9DS1 Sensor Outputs Using Nano 33 BLE Sense

Measure LSM9DS1 Sensor Outputs Using Nano 33 BLE Sense

This example shows how to use the MATLAB® Support Package for Arduino® Hardware to connect
an Arduino Nano 33 BLE Sense board over Bluetooth® with an LSM9DS1.

The sensor is connected to the Arduino board over an I2C interface.

You can read data from the sensor using a computer that supports Bluetooth 4.0 or higher.

Overview

The lsm9ds1 sensor is a nine degrees of freedom (DOF) inertial measurement unit (IMU) used to
read acceleration, angular velocity, and magnetic field in all three dimensions.

The sensor object represents a connection to the device on the Arduino hardware I2C bus. The
LSM9DS1 sensor is present on the Nano 33 BLE Sense board. You can read the data from your sensor
in MATLAB using the object functions.

You can also use other sensors like hts221, lps22hb, or apds9960 on the Arduino board to connect
to MATLAB over Bluetooth.

To connect the Arduino board to MATLAB over Bluetooth, type arduinosetup in the MATLAB
command line and set the connection type as Bluetooth. After you select the board and the port, in
the Upload Arduino Server window, select I2C. For the complete workflow, see “Connection over
Bluetooth” on page 1-6.

Connect to Sensor and Read Sensor Output

Create an Arduino object.


a = arduino

a =
arduino with properties:

Address: 'DEBD293F7CDC'
Name: 'LSMOverBLE'
Connected: 1
Board: 'Nano33BLE'
AvailablePins: {'D0-D13', 'A0-A7'}
AvailableDigitalPins: {'D0-D13', 'A0-A7'}
AvailablePWMPins: {'D0-D13'}
AvailableAnalogPins: {'A0-A3', 'A6-A7'}
AvailableI2CBusIDs: [0, 1]
AvailableSerialPortIDs: [1]
Libraries: {'I2C', 'SPI', 'Servo'}
Show all properties

Create the sensor object. The LSM9DS1 sensor is connected to the I2C bus 1 of the Nano 33 BLE
Sense board.
lsmObj = lsm9ds1(a,"Bus",1)

lsmObj =
lsm9ds1 with properties:

2-9
2 I2C Sensors

I2CAddress: 107 ("0x6B")


: 30 ("0x1E")
Bus: 1
SCLPin: "SCL1"
SDAPin: "SDA1"
Show all properties all functions

Read acceleration.

acceleration = readAcceleration(lsmObj)

acceleration = 1×3

2.6315 -7.8341 5.6433

This function returns one sample of acceleration data. For more information, see
readAcceleration.

Read angular velocity.

angularVelocity = readAngularVelocity(lsmObj)

angularVelocity = 1×3

0.0053 0.0057 0.0078

This function returns one sample of angular velocity data. For more information, see
readAngularVelocity.

Read magnetic field.

magneticField = readMagneticField(lsmObj)

magneticField = 1×3

26.1100 27.0620 14.0140

This function returns one sample of magnetic field data. For more information, see
readMagneticField.

Clean up

Once the sensor connection is no longer needed, clear the associated object.

clear lsmObj a

2-10
3

SPI Sensors

• “Arduino and SPI Interface” on page 3-2


• “Communicate with a SPI EEPROM Device” on page 3-4
• “Communicate with SPI Device on Arduino Hardware” on page 3-6
3 SPI Sensors

Arduino and SPI Interface


SPI, or Serial Peripheral Interface is a full-duplex serial protocol for communicating with high-speed
peripherals, such as microcontrollers. You can communicate with SPI devices and sensors via SPI
interface on Arduino boards using MATLAB Support Package for Arduino Hardware. You can also use
this interface to communicate between two microcontrollers. Typically, SPI devices has one controller
device that controls all peripheral devices. The SPI library has three common pins that are hardwired
and a dedicated pin for output.

• SDI, receives data from the SPI peripheral device


• SDO, which outputs data to the SPI peripheral device
• SCLK, which outputs a serial clock signal to synchronize communications
• CE, which enables and disables peripheral devices from the controller

Note To create a custom SPI code, see “Create Custom Arduino Add-On Library” on page 6-2

Every SPI device implements SPI standards differently. Refer to the device datasheet to understand
how your device will work. SPI Devices transmit data in four basic modes and control the clock phase
and the clock polarity. For more information refer to the SPI standards documentation.

3-2
Arduino and SPI Interface

For more information on Arduino SPI devices, see https://arduino.cc/en/Reference/SPI.

3-3
3 SPI Sensors

Communicate with a SPI EEPROM Device


This example shows how to store and retrieve data from an EEPROM on a SPI device. Using EEPROM
you can read, erase, and rewrite individual bits of data from the sensor’s memory. This example uses
SPI EEPROM 25AA080C device from Microchip Technology with the Arduino Mega 2560. Before
using this example, wire an EEPROM to the SPI pins on your Arduino as described:

SPI EEPROM Pins Arduino Pins


/CS Digital pin 10
SO ICSP-1 (SDI)
/WP 50k or 100k ohm resistor tied to Vcc
VSS Arduino Gnd
SI ICSP-4 (SDO)
SCK ICSP-3 (SCK)
/HOLD Vcc
Vcc 5v pin

It is also recommended that you place a 1uF decoupling capacitor between VCC and Gnd.

Create a SPI connection on your Arduino.

Create an Arduino object and include the SPI library.

a = arduino('COM10', 'Mega2560', 'Libraries', 'I2C, SPI, Servo');

Write to, and read back data from an EEPROM, which is a micro controller designed to interface
directly with the Serial Peripheral Interface (SPI). For more information about the read and write
sequence in an EEPROM, refer to the functional description in the EEPROM Data Sheet.

Create a chip select pin connection.

Cspin = 'D10';

Create a SPI device object.

eeprom = device(a, 'SPIChipSelectPin', Cspin', 'BitOrder', 'msbfirst', 'SPIMode', 0)

eeprom =

device with properties:

Interface: SPI
SPIChipSelectPin: D10
SCLPin: D21
SDIPin: D50
SDOPin: D51
Show all properties, functions

Specify the read, write and write enable commands referring to the EEPROM instruction set .

3-4
Communicate with a SPI EEPROM Device

Instruction Instruction Format Description


Name
read 0000 0011 Read data from memory array beginning at selected
address
write 0000 0010 Write data to memory array beginning at selected address
wrdi 0000 0100 Reset the write enable latch (disable write operations)
wren 0000 0110 Set the write enable latch (enable write operations)
rdsr 0000 0101 Read STATUS Register
wrsr 0000 0001 Write STATUS Register

readCmd = 0b00000011;
writeCmd = 0b00000010;
writeEnable = 0b00000110;

Write enable the device.

writeRead(eeprom, writeEnable);

Set the device address. The address is a 16–bit value, with 8 upper and 8 lower bits. The highest
value on the address can be 0x03FF.

address = [0 0];

Write 'Hello' at the 0th address of EEPROM.

dataToWrite = [writeCmd,address double('Hello')];


writeRead(eeprom, dataToWrite)

ans =

0 0 0 0 0 0 0 0

Read back the data from the EEPROM.

dataToWrite2 = [readCmd address zeros(1,5)];


returnedData = writeRead(eeprom, dataToWrite2)

returnedData =

0 0 0 72 101 108 108 111

Display the result.

disp(char(returnedData(4:end)));

Hello

3-5
3 SPI Sensors

Communicate with SPI Device on Arduino Hardware

This example shows how to use the MATLAB® Support Package for Arduino® Hardware to use SPI
interface to communicate with MCP42010 Digital Potentiometer.

Overview of MCP42010 Digital Potentiometer

The MCP42010 device is a 256-position 10KOhm potentiometer SPI device with two independent
channels.

It has channel 1 on pin 5(PB1), 6(PW1) and 7(PA1), and also channel 0 on pin 10(PB0), 9(PW0),
8(PA0). Pin 6 and pin 9 are wiper pins. This example uses CS, SCK, SI, SO, VDD, VSS, PB1, PW1 and
PA1.

Hardware setup

1) Connect the SI, SO, SCK, CS, VDD and VSS pins of a MCP42010 10KOhm digital potentiometer to
the Arduino hardware. This example uses an Arduino Uno board with the following connection.

• SI(SDO) - digital pin 11


• SO(SDI) - digital pin 12
• SCK - digital pin 13
• CS - digital pin 10
• VDD - 5V
• VSS - GND

If you are using a different board, make sure you connect to the correct pins.

2) Connect a multimeter to PA1 and PW1 to measure the resistance.

3-6
Communicate with SPI Device on Arduino Hardware

Control the digital potentiometer

Create an arduino object and include the SPI library.


a = arduino();

Or, you can explicitly specify it in the Libraries Name-Value pair at creation of arduino object.
clear a;
a = arduino('COM4', 'Uno', 'Libraries', 'SPI');

Updating server code on board Uno (COM4). This may take a few minutes.

Create an spidev object and specify the pin number for chip select.
d_pot = device(a, 'SPIChipSelectPin', 'D10');

3-7
3 SPI Sensors

Send two bytes of data to change the resistance. Since we are controlling channel 1, the first byte
should be 0b00010010 which is 12 in hex. The second byte is the new register data in the range of 0
and 255. The following commands change the resistance of the potentiometer gradually.

Rab = 10*1000;
Rw = 52; % actual wiper resistance
for regVal = 0:50:250
pot_resistance = Rab*regVal/256+Rw;
writeRead(d_pot, [hex2dec('12'), regVal], 'uint8');
fprintf('Current resistance is %d Ohm\n', pot_resistance);
pause(2);
end

Current resistance is 52 Ohm


Current resistance is 2.005125e+03 Ohm
Current resistance is 3.958250e+03 Ohm
Current resistance is 5.911375e+03 Ohm
Current resistance is 7.864500e+03 Ohm
Current resistance is 9.817625e+03 Ohm

The code runs and displays the readings of the potentiometer.

Clean up

Once the connection is no longer needed, clear the associate object.

clear d_pot a

3-8
4

Servo Motors

• “Servo Motors” on page 4-2


• “Rotate a Servo Motor” on page 4-3
• “Control Servo Motors” on page 4-4
4 Servo Motors

Servo Motors
Servo motors have integrated circuitry inside the motor unit. The shaft is typically fitted with a gear
and can be positioned as needed. You can use MATLAB Support Package for Arduino Hardware to
control movement of the shaft.

Servo motors can turn in either direction. You can control the angle at which the motor can turn
based on the maximum and minimum pulse-width duration.

Note To create a custom servo code, see “Create Custom Arduino Add-On Library” on page 6-2

See Also

External Websites
• https://arduinotogo.com/2017/03/10/appendix-a-reading-resistor-codes/

4-2
Rotate a Servo Motor

Rotate a Servo Motor


This example shows how to rotate a servo motor by its maximum angle.

Create an Arduino object and include the servo library.

a = arduino('COM22', 'Uno', 'Libraries', 'Servo');

Configure a servo object using the PWM pin 9 and set the minimum pulse duration to 1e-3 seconds
and the maximum pulse durations to 2e-3 seconds.

s = servo(a, 'D9', 'MinPulseDuration', 1e-3, 'MaxPulseDuration', 2e-3);

Write 1, to turn the motor by the maximum angle.

writePosition(s, 1);

The angle depends on device pulse duration. Refer to your device data sheet for valid pulse duration
values.

4-3
4 Servo Motors

Control Servo Motors

This example shows how to use the MATLAB® Support Package for Arduino® Hardware to control a
hobby servo motor.

Hardware setup

Connect an FS5106B servo motor to Arduino hardware,

1 Connect the power wire (usually red) to the 5V pin.


2 Connect the ground wire (usually black) to the ground pin.
3 Connect the signal wire (usually orange) to digital pin 4.

4-4
Control Servo Motors

Create servo object and calibrate the motor

Create an arduino object and include the Servo library.


a = arduino();

Or, you can explicitly specify it in the Libraries Name-Value pair at creation of arduino object.
clear a;
a = arduino('COM4', 'Uno', 'Libraries', 'Servo');

Create a Servo object.


s = servo(a, 'D4')

4-5
4 Servo Motors

s =
Servo with properties:

Pin: 'D4'
MinPulseDuration: 5.44e-04 (seconds)
MaxPulseDuration: 2.40e-03 (seconds)

Check your servo motor's data sheet pulse width range values to calibrate the motor to rotate in
expected range. This example uses 700e-6 and 2300e-6 for the motor to move from 0 to 180 degrees.

clear s;
s = servo(a, 'D4', 'MinPulseDuration', 700e-6, 'MaxPulseDuration', 2300e-6)

s =
Servo with properties:

Pin: 'D4'
MinPulseDuration: 7.00e-04 (seconds)
MaxPulseDuration: 2.30e-03 (seconds)

Write and read Servo position

Change the shaft position of the servo motor from 0(minimum) to 1(maximum) with 0.2, e.g 36
degrees, increment. Display the current position each time the position changes.

for angle = 0:0.2:1


writePosition(s, angle);
current_pos = readPosition(s);
current_pos = current_pos*180;
fprintf('Current motor position is %d degrees\n', current_pos);
pause(2);
end

Current motor position is 0 degrees


Current motor position is 36 degrees
Current motor position is 72 degrees
Current motor position is 108 degrees
Current motor position is 144 degrees
Current motor position is 180 degrees

Clean up

Once the connection is no longer needed, clear the associate object.

clear s a

4-6
5

Shift Registers, Quadrature Encoders,


Adafruit Motor Shield V2 and CAN

• “Push Button Control with 74HC165 Shift Register” on page 5-2


• “Control LEDs with 74HC595 Shift Register” on page 5-5
• “Classify and Count Fruits Using Arduino Nano 33 BLE Sense, ThingSpeak, and Machine
Learning” on page 5-8
• “Identify Shapes Using Machine Learning on Arduino Nano 33 BLE Sense Hardware”
on page 5-26
• “Control 7-Segment Display with 74HC595 Shift Register” on page 5-34
• “Control Rotary Encoder Knob” on page 5-38
• “Steer Two-Wheel Robot” on page 5-41
• “Control Motors Using Adafruit Motor Shield V2” on page 5-45
• “Adapt Add-ons to New matlabshared.addon.LibraryBase Class” on page 5-49
• “Calibrate BNO055 Sensors” on page 5-50
• “Connect BNO055 Sensor to Arduino Hardware” on page 5-52
• “Create Standalone Applications for Arduino Hardware” on page 5-53
• “Deploy Arduino Functions to Arduino Hardware Using MATLAB Function Block” on page 5-56
• “Estimating Orientation Using Inertial Sensor Fusion and MPU-9250” on page 5-60
• “Wireless Data Streaming Using BNO055 and Bluetooth and Estimating Orientation Using Sensor
Fusion ” on page 5-71
• “Plot Position Using GPS Connected to Arduino Hardware” on page 5-77
• “Gyroscope-Based Pedometer Using MATLAB Functions” on page 5-80
• “Read and Write CAN Messages with Arduino Hardware” on page 5-84
• “Advanced CAN Communication with Arduino Using Vehicle Network Toolbox” on page 5-87
• “Overcome Buffer Size Limitation of Arduino” on page 5-90
• “Read and Plot Real-Time Data from BNO055 Sensor in NDOF Mode” on page 5-95
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Push Button Control with 74HC165 Shift Register

This example shows how to use the MATLAB® Support Package for Arduino® Hardware to collect
large number of push button states with a 74HC165 8-bit parallel-in-serial-out shift register. This
example uses four push buttons.

Hardware Requirements

• Arduino board
• Four push buttons
• 74HC165 8-bit parallel-in-serial-out shift register
• Four 10K ohm resistors
• Breadboard and wires

Hardware Setup

Connect push buttons and 74HC165 shift registers to Arduino hardware:

• Connect Vcc pin on 74HC165 to 5V pin on Arduino hardware.


• Connect GND pin on 74HC165 to GND pin on Arduino hardware.
• Connect Q7 pin on 74HC165 to digital pin 11 on Arduino hardware.
• Connect CP pin on 74HC165 to digital pin 8 on Arduino hardware.
• Connect PL pin on 74HC165 to digital pin 9 on Arduino hardware.
• Connect CE pin on 74HC165 to digital pin 10 on Arduino hardware.
• Connect a push button to pin D0, D4, D5 and D7 on 74HC165 with a pull down resistor to GND as
shown below.
• Connect pin D1, D2, D3 and D6 on 74HC165 to GND pin on Arduino hardware.

5-2
Push Button Control with 74HC165 Shift Register

5-3
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Create Shift Register Object

Create an arduino object, and include the ShiftRegister library.

a = arduino('COM4','Uno','Libraries','ShiftRegister')

Updating server code on board Uno (COM4). This may take a few minutes.

a =
arduino with properties:

Port: 'COM4'
Board: 'Uno'
AvailablePins: {'D2-D13', 'A0-A5'}
AvailableDigitalPins: {'D2-D13', 'A0-A5'}
AvailablePWMPins: {'D3', 'D5-D6', 'D9-D11'}
AvailableAnalogPins: {'A0-A5'}
AvailableI2CBusIDs: [0]
Libraries: {'ShiftRegister'}

Create shift register object, specifying the connected data pin, clock pin, load pin, and clock enable
pin.

dataPin = 'D11';
clockPin = 'D8';
loadPin = 'D9';
clockEnablePin = 'D10';
register = shiftRegister(a,'74HC165',dataPin,clockPin,loadPin,clockEnablePin)

register =
ShiftRegister with properties:

Model: '74HC165'
DataPin: 'D11'
ClockPin: 'D8'
LoadPin: 'D9'
ClockEnablePin: 'D10'

Read Push Button States

Monitor the states of the four push buttons, and print out a message if at least one button is pressed,

states = read(register, 8);


pressedButtons = find(states == 1)-1;
if ~isempty(pressedButtons)
bitsStr = num2str(pressedButtons, '%d ');
disp(['Push button(s) connected to bit ', bitsStr, ' is pressed']);
end

Push button(s) connected to bit 0 4 5 7 is pressed

Clean Up

When the connection is no longer needed, clear the shift register and arduino object.

clear register a

5-4
Control LEDs with 74HC595 Shift Register

Control LEDs with 74HC595 Shift Register

This example shows how to use the MATLAB® Support Package for Arduino® Hardware to control
multiple LEDs with two 74HC595 8-bit serial-in-parallel-out shift registers.

Hardware Requirements

• Arduino board
• Sixteen LEDs
• Two 74HC595 8-bit serial-in-parallel-out shift registers
• Sixteen 300-1K ohm resistors
• Breadboard and wires

Hardware Setup

Connect LEDs and 74HC595 shift registers to Arduino hardware:

• Connect Vcc pin on 74HC595 to 5V pin on Arduino hardware.


• Connect GND and OE pins on 74HC595 to GND pin on Arduino hardware.
• Connect DS or SER pin on 74HC595 to digital pin 8 on Arduino hardware.
• Connect SHCP or SRCLK pin on 74HC595 to digital pin 9 on Arduino hardware.
• Connect STCP or RCLK pin on 74HC595 to digital pin 10 on Arduino hardware.
• Connect MR or SRCLR pin on 74HC595 to digital pin 11 on Arduino hardware.
• Connect an LED through a resistor to each output of Q0-Q7 or QA-QH pins on the two 74HC595
shift registers.

5-5
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Create Shift Register Object

Create an arduino object, and include the ShiftRegister library.

5-6
Control LEDs with 74HC595 Shift Register

a = arduino('COM4','Uno','Libraries','ShiftRegister')

a =
arduino with properties:

Port: 'COM4'
Board: 'Uno'
AvailablePins: {'D2-D13', 'A0-A5'}
AvailableDigitalPins: {'D2-D13', 'A0-A5'}
AvailablePWMPins: {'D3', 'D5-D6', 'D9-D11'}
AvailableAnalogPins: {'A0-A5'}
AvailableI2CBusIDs: [0]
Libraries: {'ShiftRegister'}

Create shift register object, specifying the connected data pin, clock pin, latch pin, and reset pin.

dataPin = 'D8';
clockPin = 'D9';
latchPin = 'D10';
resetPin = 'D11';
register = shiftRegister(a,'74HC595',dataPin,clockPin,latchPin,resetPin)

register =
ShiftRegister with properties:

Model: '74HC595'
DataPin: 'D8'
ClockPin: 'D9'
LatchPin: 'D10'
ResetPin: 'D11'

Light Up LEDs

To turn on the LEDs one after another, run the following command,

sequenceTable = tril(ones(16));
for count = 1:16
write(register,sequenceTable(count,:),'uint16');
pause(0.5);
end

To turn off all LEDs at once, call reset on the shift register object,

reset(register);

Clean Up

When the connection is no longer needed, clear the shift register and arduino object.

clear register a

5-7
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Classify and Count Fruits Using Arduino Nano 33 BLE Sense,


ThingSpeak, and Machine Learning

This example shows how to collect RGB values of three types of fruits using the APDS9960 sensor
embedded in an Arduino® Nano 33 BLE board and use the MATLAB® Classification Learner app to
train a machine learning model with the RGB values to classify the fruits. This example also shows
how to use the ThingSpeak™ platform for tracking the number of fruits in a box and setting up an
email alert if the number of any one of the three types of fruits drops to zero.

This example createsa classification and counting sytem for three types of fruits, namely apple,
guava, and banana.

To access all the files for this example, click the Open Live Script button and download the files.

Overview

This example uses an Arduino Nano BLE 33 Sense board that you can connect to your machine using
a micro USB cable. The algorithm in the example completes these steps.

1 Capture the RGB values using the Arduino Nano BLE 33 Sense board and create a data set.
2 Use the Classification Learner app to determine the classification model and export the trained
model.
3 Create a ThingsSpeak channel to track the number of fruits in a box.
4 Set up an email alert if the number of any one of the three types of fruits drops to zero.

You can use the trained model included with this example instead of training the model on your own.

If you are using the trained model, skip the Create Data Set from RGB Values of Fruits and Export
Classification Algorithm section.

Create Data Set from RGB Values of Fruits

Place the Arduino Nano 33 BLE Sense board near the fruit for which you want to capture the RBG
values. This image shows a person capturing the RBG data for an apple.

Download the captureRGB.m file by clicking the Open Live Script button. Execute the file and
complete the instructions that display in the Command Window. Once you complete executing the file,

5-8
Classify and Count Fruits Using Arduino Nano 33 BLE Sense, ThingSpeak, and Machine Learning

you can view the trainingData variable of size 2001X3 in the MATLAB workspace. Add a fourth
field, fruit, to the trainingData table. Change all the entries in the column under the new field to
Apple.

trainingData.fruit(:) = "Apple" ;

Create a training data variable for apples.

trainingDataApple = trainingData ;

The new trainingDataApple variable of size 2001x4 is now visible in the MATLAB workspace.

To capture the RGB values for bananas, execute the captureRBG.m file again. Create a new field
called Banana and a training data variable for bananas.

trainingData.fruit(:) = "Banana" ;
trainingDataBanana = trainingData ;

To capture the RGB values for guavas, execute the captureRBG.m file again. Create a new field
called Guava and a training data variable for guavas.

trainingData.fruit(:) = "Guava" ;
trainingDataGuava = trainingData ;

The new trainingDataBanana and trainingDataGuava variables of size 2001x4 are now visible
in the MATLAB workspace.

Store the training data for the three fruits in a single variable finalTrainingData. The
finalTrainingData variable must be of the size 6003x4.

finalTrainingData = [trainingDataApple; trainingDataBanana; trainingDataGuava];

Export Classification Algorithm

Use the Classification Learner app to select a classification model. In the Apps tab on the MATLAB
toolstrip, search for the Classification Learner app.

In the app, click the New Session button, and then click From Workspace.

5-9
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

In the Data set pane, select the training variable finalTrainingData and click Start Session.

On the app toolstrip, in the Models section, click All, and in the Train section, click Train All.

The app provides you with a list of classification models and their results. For this example, select the
model with highest accuracy.

5-10
Classify and Count Fruits Using Arduino Nano 33 BLE Sense, ThingSpeak, and Machine Learning

On the app toolstrip, click Export and then click Export Model.

5-11
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Select Include the training data in the exported model and export the model.

Create ThingSpeak Channel and Add Widgets to Count Fruits

If you are using the trained model included with this example, skip the Create Data Set from RGB
Values of Fruits and Export Classification Algorithm sections and start with this section.

To download the trained model included with this example, click the Open Live Script button. To
load the trained model, type this command at the MATLAB command line.

load trainedModel.mat

5-12
Classify and Count Fruits Using Arduino Nano 33 BLE Sense, ThingSpeak, and Machine Learning

ThingSpeak is an IoT analytics platform service that you can use to aggregate, visualize, and analyze
live data streams in the cloud. For more information, see Get Started with ThingSpeak.

To track the number of fruits in the box using ThingSpeak™, sign in using your MathWorks® Account
credentials, or create a new account. Create a new channel in ThingSpeak to collect and analyze the
fruit count data. To create a new channel in ThingSpeak, on the Channels tab, click My Channels.
In the My Channels window, click New Channel and enter these values to customize the channel.

1 Name: Fruit Count


2 Field 1: Apple Count
3 Field 2: Guava Count
4 Field 3: Banana Count
5 Field 4: isEmpty

ThingSpeak uses the Field 4 field to track if the number of any one of the three types of fruits drops
to zero.

Click Save Channel to save the channel settings. In the Channels window, click Add Widgets to add
three numeric display widgets to track the number of fruits.

5-13
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Identify API Keys in ThingSpeak

Before you write the MATLAB code to track the number of fruits, identify the API keys of the
ThingSpeak channel. These keys allow you to read data from and write data to your channel.

To identify the API keys, on the Channels tab, click API Keys.

5-14
Classify and Count Fruits Using Arduino Nano 33 BLE Sense, ThingSpeak, and Machine Learning

5-15
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Execute MATLAB Code to Classify and Count Fruits

To track the number of fruits in the box, whenever you take a fruit from the box, place the fruit near
the sensor. The sensor then classifies the fruit and updates the fruit count in the ThingSpeak channel.

You can execute the following MATLAB code to read RGB data from the sensor and use this data to
predict the type of fruit based on a pretrained model and publish the data to ThingSpeak using the
channel ID and the Write API key of the channel. Run these commands, one after another, in the
MATLAB Command Window. This example assumes that the box contains 50 guavas, 40 bananas. This
example also assumes that 30 apples and the Arduino board is connected to the COM14 port.

% Create the arduino object with required library


arduinoObj = arduino("COM14","Nano33BLE","Libraries","APDS9960");

% Create an APDS9960 object


apds9960Obj = apds9960(arduinoObj, "Bus", 1, "BitRate", 100000);

% Variable to track the number of apples, bananas, and guavas


guavaCount = 50;
bananaCount = 40;
appleCount = 30;

%the variable to track if the fruit count of one of the fruits drops to zero
isEmpty = 0;

%isEmpty variable changes to 1 if the fruit count of one of the fruits drops to zero
if(guavaCount == 0 || bananaCount == 0 || appleCount == 0)
isEmpty = 1;
end

% ThingSpeak configurations
channelID = xxxxxxx;
writeAPI = 'xxxxxxxxxxxxxxxx'; %Update this to the writeAPI key identified your Thingspeak Channe

% Write the value to ThingSpeak channel


thingSpeakWrite(channelID,[appleCount,guavaCount,bananaCount,isEmpty],'WriteKey',writeAPI,'Fields

while(1)
% Continuously read the proximity readings
proximReadings = readProximity(apds9960Obj);
flag = 0;
while(proximReadings>0.1)
if(flag == 0)
% Alert to bring the object near the sensor
disp("Bring object near sensor");
end
proximReadings = readProximity(apds9960Obj);
flag = 1;
end

% Turn on the built-in LED when the object is near


writeDigitalPin(arduinoObj, 'D13', 1);

% Read the RGB value from apds9960


colorData = readColor(apds9960Obj);

5-16
Classify and Count Fruits Using Arduino Nano 33 BLE Sense, ThingSpeak, and Machine Learning

% Convert colorData to table format


colorDataInTableFormat = array2table(colorData);

% Call predict function


[predictedFruit,scores] = trainedModel.predictFcn(colorDataInTableFormat);
message = ["The object detected is ",predictedFruit];
disp(message);

% Update the fruit count according to the prediction


if(predictedFruit=="Apple")
appleCount = appleCount-1;
elseif(predictedFruit=="Banana")
bananaCount = bananaCount-1;
elseif(predictedFruit=="Guava")
guavaCount = guavaCount-1;
end

while(proximReadings <0.1)
proximReadings = readProximity(apds9960Obj);
end

if(guavaCount == 0 || bananaCount == 0 || appleCount == 0)


isEmpty = 1;
end

% Turn off the LED


writeDigitalPin(arduinoObj, 'D13', 0);

% Write data to ThingSpeak channel


thingSpeakWrite(channelID,[appleCount,guavaCount,bananaCount,isEmpty],'WriteKey',writeAPI,'Fi

end

This GIF shows the channel dashboard when you remove one fruit from the box.

5-17
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Set Up Email Alert

Configure ThingSpeak to alert you via email if the number of any one of the three types of fruits
drops to zero. ThingSpeak sends the email to the email address associated with your ThingSpeak
account.

To set up the email alert, on the Apps tab on the ThingSpeak toolstrip, click MATLAB Analysis.

Click New to select a code template.

Select the Custom (no starter code) option and then click Create to create the template.

5-18
Classify and Count Fruits Using Arduino Nano 33 BLE Sense, ThingSpeak, and Machine Learning

5-19
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Set the Name to RefillAlert and enter the code in the MATLAB Code window or copy the sample
code from the RefillAlert.m file provided with this example. To access the RefillAlert.m file,
click the Open Live Script button and download the file.

5-20
Classify and Count Fruits Using Arduino Nano 33 BLE Sense, ThingSpeak, and Machine Learning

5-21
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Specify the channel ID, Read API key, and Alerts API key corresponding to your channel in code.
You can access the alerts key from your ThingSpeak profile page.

To set up an email alert for when the number of any one of the three types of fruits drops to zero, on
the Apps tab in ThingSpeak, click Actions, and then click React. In the React window, set these
parameters.

• React Name — Enter a unique name for your alert. For this example, set it to Fruit Empty
Trigger.

5-22
Classify and Count Fruits Using Arduino Nano 33 BLE Sense, ThingSpeak, and Machine Learning

• Condition Type — Select Numeric.


• Test Frequency — Select On Data Insertion.
• Condition — Select the name of your channel and the field and set the condition for your alert. In
this example, select field 4 (isEmpty) and set the condition to is equal to 1.
• Action — Select MATLAB Analysis. In the code to execute list, select the name of the MATLAB
file where you stored the analysis code. For this example, select RefillAlert.
• Options — Select Run action only the first time the condition is met.

Click Save React to save your alert.

5-23
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

5-24
Classify and Count Fruits Using Arduino Nano 33 BLE Sense, ThingSpeak, and Machine Learning

When the number of any one of the three types of fruits drops to zero, ThingSpeak sends an email to
the registered email address. This is an image of a sample email sent by ThingSpeak.

5-25
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Identify Shapes Using Machine Learning on Arduino Nano 33


BLE Sense Hardware

This example shows how to use MATLAB® Support Package for Arduino® Hardware to identify
shapes using a machine learning algorithm. This example uses the Arduino Nano 33 BLE Sense
hardware board with an onboard LSM9DS1 inertial measurement unit (IMU) sensor.

To draw the shapes, hold the Arduino board in your palm and move your hand in the air. The IMU
sensor captures the linear acceleration and angular rate data along the X-, Y-, and Z-axes. Send this
data to the machine learning algorithm which identifies the shape you have drawn and transmits the
output over Bluetooth® to the Arduino board. The shape identified by the machine learning algorithm
then displays in the MATLAB Command Window.

To access all the files for this example, click Open Live Script and download the attached files.

Prerequisites

• For more information on how to use Arduino hardware with MATLAB, see Get Started with
MATLAB Support Package for Arduino Hardware.
• For more information on machine learning, see Get Started with Statistics and Machine Learning
Toolbox.

Required Hardware

• Use an Arduino board with an onboard IMU sensor. This example uses the Arduino Nano 33 BLE
Sense board that has an onboard LSM9DS1 IMU sensor. This helps you to easily hold the
hardware in your hand while you move your hand to draw shapes in the air. Alternatively, you can
connect an IMU sensor to any Arduino board that has a sufficiently large memory. For more
information on how to connect an IMU sensor to your Arduino board, refer to the sensor
datasheet.
• Either connect a Bluetooth dongle to the computer or use the computer's Bluetooth.

Hardware Setup

Connect the Arduino Nano 33 BLE Sense board to the host computer over Bluetooth. For more
information, see Set up and Configure Arduino Hardware.

In the Choose Connection Type window under Hardware Setup, set the connection type to Bluetooth.

5-26
Identify Shapes Using Machine Learning on Arduino Nano 33 BLE Sense Hardware

In the Upload Arduino Server window, select the I2C libraries.

5-27
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Capture Data to Train Machine Learning Algorithm

You can either use the shapes_training_data.mat file that contains the data set for the circle and
triangle shapes or capture the data and create the data set manually.

Import Training Data

To use the training data file included with this example, click Open Live Script and download the
shapes_training_data.mat file. The shapes_training_data MAT file contains 119 data
samples from the accelerometer and gyroscope on the IMU sensor. The 119 samples are grouped into
100 frames, with each frame representing a hand gesture. Each frame has six values from the X-, Y-,
and Z-axes of the accelerometer and gyroscope, respectively. The data set contains a total of 11,900
observations for the circle and triangle shapes.

Load the shapes_training_data.mat file.

load shapes_training_data

5-28
Identify Shapes Using Machine Learning on Arduino Nano 33 BLE Sense Hardware

Capture Data Manually

If you are using the shapes_training_data.mat file, skip this section. However, if you want to
capture the training data for the machine learning algorithm manually, execute the
capture_training_data.m file.

In the capture_training_data.m file, you can set the acceleration threshold in the
accelerationThreshold parameter. For this example, set the threshold to 2.5. For more
information on how to adjust the acceleration threshold for an IMU sensor, refer to the sensor
datasheet.

%Acceleration threshold to detect motion


accelerationThreshold = 2.5;

To set up a connection with the Arduino board, create an arduino object and specify name of the
board.

%Create arduino object


a=arduino('usersArduino'); % Change this to your Bluetooth name or address

To read data from the LSM9DS1 IMU sensor, create an lsm9ds1 object and specify the number of
samples to read in a single execution of the read function. For this example, set the number of
samples to read to 119.

%Initialize imu sensor


imu=lsm9ds1(a,'SamplesPerRead',119,'Bus',1);

Specify the number of frames to be captured per gesture in the while loop. For this example, set that
value to 100.

while(gesture < 100)


%Read acceleration data
accel=imu.readAcceleration;
%Sum up absolute values of acceleration
aSum=sum(abs(accel))/9.8;
%Capture values if there is significant motion
if aSum>=accelerationThreshold
gesture=gesture+1;
%Read IMU sensor data
imudata=imu.read;
imudatatable=timetable2table(imudata);
%Save values in data variable
data{gesture}=[imudatatable.Acceleration/9.8 rad2deg(imudatatable.AngularVelocity)];
%Display the captured gesture number
disp(['Gesture no.' num2str(gesture)]);
end
end

Hold the Arduino hardware in the palm of your hand and draw a circle in the air. If you want to create
a data set of 100 frames for a circle, draw a circle 100 times in the air. Capture the data for the circle
shape.

circledata = capture_training_data;

5-29
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Repeat the procedure for the triangle shape. Capture the data for the triangle shape.
triangledata = capture_training_data;

Store the data in the shapes_training_data.mat file.


save('shapes_training_data',circledata,triangledata);

Extract Feature, Prepare, and Train Data

Extract

The gr_script_shapes.m file included with this example preprocesses the


shapes_training_data.mat data set file, trains the machine learning algorithm with the data set,
and evaluates whether the algorithm accurately predicts the circle and triangle shapes. The MATLAB
function in this file performs a five-fold cross validation for the ensemble classifier and computes the
validation accuracy of the algorithm. Execute the gr_script_shapes.m file.
run gr_script_shapes.m

5-30
Identify Shapes Using Machine Learning on Arduino Nano 33 BLE Sense Hardware

validationAccuracy = 0.9833

testAccuracy = 1

The code in the gr_script_shapes.m file extracts features by calculating the mean and the standard
deviation of each column in a frame. Considering the data from the X-, Y-, and Z-axes for the
accelerometer and and the gyroscope and 100 frames per gesture, results in a 100-by-12 matrix of
observations for each gesture.
Nframe = 100;
for ind = 1:Nframe
featureC1(ind,:) = mean(circledata{ind});
featureC2(ind,:) = std(circledata{ind});
featureT1(ind,:) = mean(triangledata{ind});
featureT2(ind,:) = std(triangledata{ind});
end
X = [featureC1,featureC2;
featureT1,featureT2;
zeros(size(featureT1)),zeros(size(featureT2))];
% labels - 1: circle, 2: triangle, 3: idle
Y = [ones(Nframe,1);2*ones(Nframe,1);3*ones(Nframe,1)];

Note: You can configure the number of frames to be captured per gesture in the while loop.

Prepare

This example uses 80% of the observations to train a model that classifies two types of shapes and
20% of the observations to validate the trained model. Use to partition 20% of the data for the test
data set.
rng('default') % For reproducibility
Partition = cvpartition(Y,'Holdout',0.20);
trainingInds = training(Partition); % Indices for the training set
XTrain = X(trainingInds,:);
YTrain = Y(trainingInds);
testInds = test(Partition); % Indices for the test set

The training variables are visible in the Workspace pane in MATLAB.

Train Classification Model

Train the classification model using the ensemble classifier.


template = templateTree(...
'MaxNumSplits', 399);

ensMdl = fitcensemble(...
XTrain, ...
YTrain, ...
'Method', 'Bag', ...
'NumLearningCycles', 20, ...
'Learners', template, ...
'ClassNames', [1; 2; 3]);

Validate Classifier

Perform five-fold cross validation for the ensemble classifier and compute the validation accuracy to
evaluate the performance of test data.

5-31
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

%% Prediction accuracy
% Perform five-fold cross-validation for classificationEnsemble and compute the validation accura
partitionedModel = crossval(ensMdl,'KFold',5);
validationAccuracy = 1-kfoldLoss(partitionedModel)
%% Test data accuracy
% Evaluate performance of test data
testAccuracy = 1-loss(ensMdl,XTest,YTest)

Predict Shape

Run this MATLAB code to predict the shape.

% Create an arduino object with Bluetooth connection


aObj = arduino("usersArduino"); % Change this to required Bluetooth name or address

% Create LSM9DS1 object


imuObj = lsm9ds1(aObj,"Bus",1,"SamplesPerRead",119,'Bus',1);
disp('Start capturing gesture data.');

Start capturing gesture data.

% Set the accelation threshold


accelerationThreshold = 2.5;

% Predict the shapes for 10 seconds


tic;
while (toc<10)
% Read the acceleration
accel = readAcceleration(imuObj);

%Sum up absolute values of acceleration


aSum = sum(abs(accel))/9.8;

%Capture values if there is significant motion


if aSum >= accelerationThreshold
%Read IMU sensor data
imudata = read(imuObj);
imudatatable = timetable2table(imudata);

%Save values in data variable


testGesture = [imudatatable.Acceleration/9.8 rad2deg(imudatatable.AngularVelocity)];

% Get the features of the captured gestture


feature1 = mean(testGesture);
feature2 = std(testGesture);
features = [feature1 feature2];

% Predict the gesture


y = predict(ensMdl,features);
if y == 1
disp('Circle');
elseif y == 2
disp('Triangle');
end
end
end

5-32
Identify Shapes Using Machine Learning on Arduino Nano 33 BLE Sense Hardware

release(imuObj);
clear imuObj aObj;

5-33
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Control 7-Segment Display with 74HC595 Shift Register

This example shows how to use the MATLAB® Support Package for Arduino® Hardware to control a
1-Digit 7-Segment display with a 74HC595 8-bit serial-in-parallel-out shift register.

Hardware Requirements

• Arduino board
• Common anode 7-segment display
• 74HC595 8-bit serial-in-parallel-out shift register
• Eight 330 ohm resistors
• Breadboard and wires

Hardware Setup

Connect the 7-Segment display and 74HC595 shift register to Arduino hardware:

• Connect Vcc pin on 74HC595 to 5V pin on Arduino hardware.


• Connect GND and OE pins on 74HC595 to GND pin on Arduino hardware.
• Connect DS or SER pin on 74HC595 to digital pin 8 on Arduino hardware.
• Connect SHCP or SRCLK pin on 74HC595 to digital pin 10 on Arduino hardware.
• Connect STCP or RCLK pin on 74HC595 to digital pin 9 on Arduino hardware.
• Connect Q0-Q6 or QA-QG pin on 74HC595 to pin A-G on 7-segment display.
• Connect Q7 or QH pin on 74HC595 to pin DP on 7-segment display.
• Connect common anode pins (pin 3 and 8 on the diagram) on 7-segment display to 5V pin on
Arduino hardware.

5-34
Control 7-Segment Display with 74HC595 Shift Register

Create Shift Register Object

Create an arduino object, and include the ShiftRegister library.


a = arduino('COM4','Uno','Libraries','ShiftRegister')

a =
arduino with properties:

Port: 'COM4'
Board: 'Uno'
AvailablePins: {'D2-D13', 'A0-A5'}
AvailableDigitalPins: {'D2-D13', 'A0-A5'}
AvailablePWMPins: {'D3', 'D5-D6', 'D9-D11'}
AvailableAnalogPins: {'A0-A5'}
AvailableI2CBusIDs: [0]
Libraries: {'ShiftRegister'}

5-35
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Create shift register object for the display module, specifying the connected data pin, clock pin, and
latch pin.

dataPin = 'D8';
clockPin = 'D10';
latchPin = 'D9';
register = shiftRegister(a,'74HC595',dataPin,clockPin,latchPin)

register =
ShiftRegister with properties:

Model: '74HC595'
DataPin: 'D8'
ClockPin: 'D10'
LatchPin: 'D9'
ResetPin: Not specified

Display Numbers

Each segment of the 7-segment display is controlled by a pin corresponding to the segment, including
pin A-G and pin DP. Common anode 7-segment display means the segment pin needs to be low to turn
it on. Here is the mapping between the segments and the pins, including shift register outputs.

Create a table of binary character vectors for all single digit numbers.

digitTable = {...
'11000000', ... % 0
'11001111', ... % 1
'10100100', ... % 2
'10110000', ... % 3
'10011001', ... % 4
'10010010', ... % 5
'10000010', ... % 6
'11111000', ... % 7
'10000000', ... % 8
'10010000' ... % 9
};

To display a number on the module, write the corresponding 8-bit character vector to the shift
register, which will get reflected on its outputs, therefore controlling the on and off of the segments.
Here is the code to loop through the ten digits on the display,

for iLoop = 1:10


digit = digitTable{iLoop};
write(register,digit);

5-36
Control 7-Segment Display with 74HC595 Shift Register

pause(0.5);
end

Clean Up

When the connection is no longer needed, clear the shift register and arduino object.

clear register a

5-37
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Control Rotary Encoder Knob

This example shows how to use the MATLAB® Support Package for Arduino® Hardware to control a
12-step rotary encoder with a built-in push button.

Hardware Requirements

• Arduino Uno board


• SparkFun® 12-step rotary encoder with built-in push button

Hardware Setup

Connect the rotary encoder to Arduino hardware:

• Connect the common pin C on encoder to GND pin on Arduino hardware.


• Connect the output A and B on encoder to digital pin 2 and 3 on Arduino hardware.
• Connect the ground pin on encoder to GND pin on Arduino hardware.
• Connect the push button pin on encoder to digital pin 4 on Arduino hardware.

Note: If you are using a different Arduino board than Uno, instead of using digital pin 2 and 3, use
any two of the interrupt pins on your board. See Arduino Interrupts for more information about the
available interrupt pins.

5-38
Control Rotary Encoder Knob

Create Rotary Encoder Object

Create an arduino object, and include the 'RotaryEncoder' library.


a = arduino('COM4','Uno','Libraries','RotaryEncoder')

Updating server code on board Uno (COM4). This may take a few minutes.

a =
arduino with properties:

Port: 'COM4'
Board: 'Uno'
AvailablePins: {'D2-D13', 'A0-A5'}
AvailableDigitalPins: {'D2-D13', 'A0-A5'}
AvailablePWMPins: {'D3', 'D5-D6', 'D9-D11'}
AvailableAnalogPins: {'A0-A5'}
AvailableI2CBusIDs: [0]
Libraries: {'RotaryEncoder'}

Create rotary encoder object for knob, specifying the connected output channel A and channel B.
channelA = 'D2';
channelB = 'D3';
encoder = rotaryEncoder(a,channelA,channelB)

encoder =
RotaryEncoder with properties:

ChannelA: 'D2'
ChannelB: 'D3'
PulsesPerRevolution: []

Read Knob Position

The rotary encoder has 12 click positions for each revolution. Each click increases or decreases the
count by 4, depending on the direction in which it is rotated. Therefore, the knob position can be
represented by integers between 0 and 44.

Turn knob to starting position, and reset the count to 0.


resetCount(encoder);

Add logic to display the encoder position when the pushbutton is pressed. If unpressed, the
pushbutton pin returns 1. Otherwise, it returns 0.
pushbutton = 'D4';
configurePin(a,pushbutton,'Pullup');
while(~readDigitalPin(a,pushbutton))
count = readCount(encoder);
pos = mod(count,48);
fprintf('Current knob position: %d\n',pos);
pause(1);
end

Current knob position: 0


Current knob position: 42

5-39
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Current knob position: 24


Current knob position: 22
Current knob position: 4

Clean Up

When the connection is no longer needed, clear the rotary encoder and arduino object.

clear encoder a

5-40
Steer Two-Wheel Robot

Steer Two-Wheel Robot

This example shows how to use the MATLAB® Support Package for Arduino® Hardware to steer a
two-wheel Arduino-based robot with closed-loop control.

Hardware Requirements

• Arduino Due board


• MinSegShield™ Kit M2V3.2
• 9V battery pack

Hardware Setup

Assemble the hardware:

• Attach the MinSegShield M2V3.2 to Arduino Due board.


• Connect the Vcc of the battery pack to VIN port on the 2-terminal block on the MinSegShield.
• Connect the Gnd of the battery pack to GND port on the 2-terminal block on the MinSegShield.

Create Rotary Encoder Objects

Create an arduino object, and include the 'RotaryEncoder' library.

a = arduino('COM5','Due','Libraries','RotaryEncoder')

5-41
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Updating server code on board Due (COM5). This may take a few minutes.

a =
arduino with properties:

Port: 'COM5'
Board: 'Due'
AvailablePins: {'D2-D53', 'A0-A11'}
AvailableDigitalPins: {'D2-D53', 'A0-A11'}
AvailablePWMPins: {'D2-D13'}
AvailableAnalogPins: {'A0-A11'}
AvailableI2CBusIDs: [0, 1]
AvailableSerialPortIDs: [1, 2, 3]
Libraries: {'RotaryEncoder'}
Show all properties

Create rotary encoder objects for two encoders, specifying the connected output channel A and
channel B pins. The quadrature encoder that comes with the kit has a resolution of 180 pulses per
revolution.
channelA1 = 'A8';
channelB1 = 'D15';
channelA2 = 'D18';
channelB2 = 'D19';
encoder1 = rotaryEncoder(a,channelA1,channelB1,180)

encoder1 =
RotaryEncoder with properties:

ChannelA: 'A8'
ChannelB: 'D15'
PulsesPerRevolution: 180

encoder2 = rotaryEncoder(a,channelA2,channelB2,180)

encoder2 =
RotaryEncoder with properties:

ChannelA: 'D18'
ChannelB: 'D19'
PulsesPerRevolution: 180

Turn On Motors

Each motor is controlled by a PWM pin for speed and a digital pin for direction. To turn on a motor,
set the PWM voltage to above 0 and set the digital pin output to either 0 or 1 for forward or backward
direction.
motor1SpeedPin = 'D2';
motor1DirectionPin = 'D5';
motor2SpeedPin = 'D6';
motor2DirectionPin = 'D8';

Start rotating both motors by applying the same PWM voltage and setting the same direction.
direction = 0;
initialPWMVoltage = 1.5;

5-42
Steer Two-Wheel Robot

writeDigitalPin(a,motor1DirectionPin,direction);
writeDigitalPin(a,motor2DirectionPin,direction);
writePWMVoltage(a,motor1SpeedPin,initialPWMVoltage);
writePWMVoltage(a,motor2SpeedPin,initialPWMVoltage);
% wait for the change to take effect on the hardware
pause(3);

Measure Motor Speeds

To measure one motor speed, pass in the corresponding encoder object.

rpm = readSpeed(encoder1);
fprintf('Current motor speed is: %.2f\n',rpm);

Current motor speed is: -29.17

To measure both motor speeds at the same time, pass in an array of the two encoder objects.

rpms = readSpeed([encoder1,encoder2]);
fprintf('Current motor speeds are: %.2f, %.2f\n',rpms(1),rpms(2));

Current motor speeds are: -25.00, -33.33

Steer Robot Straight

Generally, applying the same power to each wheel does not result in both motors rotating at the same
speed, hence the robot does not move straight. To make it go straight, a closed-loop control algorithm
is used to adjust the power applied to the two motors based on difference in their actual speeds. In
this example, the proportional controller is used to help adjust the speeds. The following diagram
explains the controller logic.

Define controller execution time, target speed, sampling period, and proportional gain parameter.

executionTime = 5;
targetSpeed = -50;
period = 0.1;
Kp = 0.002;

Implement the closed-loop control algorithm to read both motor speeds and adjust one motor speed
based on the difference. Make sure the shield is powered with 9V battery pack so that the motors
rotate properly.

5-43
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

tic;
while toc < executionTime
rpms = readSpeed([encoder1,encoder2]);
diff = rpms-targetSpeed;
newPWMVoltages = initialPWMVoltage - diff*Kp;
writePWMVoltage(a,motor1SpeedPin,newPWMVoltages(1));
writePWMVoltage(a,motor2SpeedPin,newPWMVoltages(2));
pause(period);
end

Stop the motors by not applying power through the PWM pins.

writePWMVoltage(a,motor1SpeedPin,0);
writePWMVoltage(a,motor2SpeedPin,0);

Note that the controller is running in soft real-time as it runs in MATLAB but not on the Arduino
hardware. Hence, the quality of the control is affected by any other task running on your computer at
the same time, such as anti-virus activities. To get hard real-time control, use the Simulink Arduino
Support Package.

Clean Up

When the connection is no longer needed, clear the rotary encoder objects and arduino object.

clear encoder1 encoder2 a

5-44
Control Motors Using Adafruit Motor Shield V2

Control Motors Using Adafruit Motor Shield V2

This example shows how to use the MATLAB® Support Package for Arduino® Hardware to control
servo motors, DC motors, and stepper motors using the Adafruit® Motor Shield V2.

Hardware setup

1. Attach Adafruit motor shield to your Arduino hardware.

2. Connect an FS5106B motor to servo motor port 1, labeled 'Servo 1' on the shield.

3. Connect a DC toy/hobby motor to motor port 1, labeled 'M2' on the shield.

4. Connect a six-wire Portescap stepper motor to motor port 2, labeled 'M3' and 'M4' on the shield.
Connect the two middle wires on the stepper motor to the center of the port to ground them together.
If you are using four-wire or five-wire stepper motor, check your hardware specs for appropriate
connections of each wire.

5. Connect a battery pack that has three AA batteries to the DC jack, labeled with Power and remove
the jumper on pins labeled Vin Jumper. This step is optional if your stepper motor does not require a
high power supply.

Create shield object

By default, the Adafruit\MotorShieldV2 library is not included in the server code on the board. Create
an arduino object and include the Adafruit\MotorShieldV2 library to the hardware.
a = arduino('COM4','Uno','Libraries','Adafruit\MotorShieldV2')

5-45
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Updating server code on board Uno (COM4). This may take a few minutes.

a =
arduino with properties:

Port: 'COM4'
Board: 'Uno'
AvailablePins: {'D2-D13', 'A0-A5'}
AvailableDigitalPins: {'D2-D13', 'A0-A5'}
AvailablePWMPins: {'D3', 'D5-D6', 'D9-D11'}
AvailableAnalogPins: {'A0-A5'}
AvailableI2CBusIDs: [0]
Libraries: {'Adafruit/MotorShieldV2', 'I2C', 'Servo'}

Create an add-on shield object by specifying the required library name parameter:

shield = addon(a,'Adafruit\MotorShieldV2')

shield =
motorshieldv2 with properties:

SCLPin: 'A5'
SDAPin: 'A4'
I2CAddress: 96 ('0x60')
PWMFrequency: 1600 (Hz)

The I2CAddress of a shield is set to 0x60 by default if not specified. Search for available I2C
addresses on bus 0 to specify a different address.

addrs = scanI2CBus(a,0)

addrs = 2×1 cell array


{'0x60'}
{'0x70'}

Control servo motor on the shield

There are two servo motor ports available on each shield. To create a servo motor object at port 1.

s = servo(shield,1)

s =
Servo with properties:

MotorNumber: 1
Pin: 'D10'
MinPulseDuration: 5.44e-04 (seconds)
MaxPulseDuration: 2.40e-03 (seconds)

Set the position of the servo motor's shaft to its maximum position.

writePosition(s,1);

See “Control Servo Motors” example to learn how to use a servo object.

5-46
Control Motors Using Adafruit Motor Shield V2

Control DC motor on the shield

There are four DC motor ports available on each shield. Create a DC motor object at port 2.

dcm = dcmotor(shield,2)

dcm =
dcmotorv2 with properties:

MotorNumber: 2 (M2)
Speed: 0.00
IsRunning: 0

First, change the motor speed to 0.2. The sign of the value indicates the direction of the motor
rotation that also depends on the wiring of the motor.

dcm.Speed = 0.2;

Start the motor and change the speed while it is running. Stop the motor when you are done.

start(dcm);
dcm.Speed = 0.3;
pause(2);
dcm.Speed = -0.2;
pause(2);
stop(dcm);

Control stepper motor on the shield

There are two stepper motor ports available on each shield. To create a stepper motor object at port 2
with 200 steps per revolution.

sm = stepper(shield,2,200)

sm =
stepper with properties:

MotorNumber: 2
StepsPerRevolution: 200
RPM: 0
StepType: Single ('Single', 'Double', 'Interleave', 'Microstep')

Set the motor's RPM, e.g revolutions per minute, to 10 and move or step the motor 200 steps in one
direction and then another 200 steps in the reverse direction.

sm.RPM = 10;
move(sm, 200);
pause(2);
move(sm, -200);
release(sm);

Clean up

Once the connection is no longer needed, clear the associated object.

5-47
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

clear s dcm sm shield a

5-48
Adapt Add-ons to New matlabshared.addon.LibraryBase Class

Adapt Add-ons to New matlabshared.addon.LibraryBase Class

If you have been using the arduinoio.LibraryBase class, follow these steps to adapt your add-ons
to the new matlabshared.addon.LibraryBase class:

1 Inherit your custom add-on class from matlabshared.addon.LibraryBase

classdef MyAddon < matlabshared.addon.LibraryBase


2 Add the property Pins to your custom add-on class to continue using it, as this is not included in
matlabshared.addon.LibraryBase.

properties(Access = protected)
Pins
end
3 Change ArduinoLibraryHeaderFiles property to LibraryHeaderFiles.

LibraryName = 'ExampleLCD/LCDAddon'
DependentLibraries = {}
LibraryHeaderFiles = 'LiquidCrystal/LiquidCrystal.h'
CppHeaderFile = fullfile(arduinoio.FilePath(mfilename('fullpath')),'src','LCD.h')
CppClassName = 'LCD'

This ensures that the add-on library is up to date and detected by listArduinoLibraries .

See Also
matlabshared.addon.LibraryBase

5-49
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Calibrate BNO055 Sensors

To ensure the data from the accelerometer, gyroscope, and magnetometer is accurate, follow these
steps to calibrate the sensors.

Calibrate Magnetometer
To fully calibrate the magnetometer of the BNO055 sensor:

1 Hold the sensor parallel to the ground and move it in a figure 8 pattern.

Note Ensure that the sensor is far away from any magnetic interference.

2 Use the readCalibrationStatus function to read the calibration status of the sensor.
3 Repeat this process until the calibration value of the magnetometer is full.

Calibrate Accelerometer
To fully calibrate the accelerometer of the BNO055 sensor:

1 Place the BNO055 sensor in these six stable positions for a few seconds each.

5-50
Calibrate BNO055 Sensors

2 Use the readCalibrationStatus function to read the calibration status of the sensor.
3 Repeat this process until the calibration value of the accelerometer is full.

Calibrate Gyroscope
To fully calibrate the gyroscope of the BNO055 sensor:

1 Place the sensor in any stable position for a few seconds.


2 Use the readCalibrationStatus function to read the calibration status of the sensor.
3 Repeat this process until the calibration value of the gyroscope is full.

5-51
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Connect BNO055 Sensor to Arduino Hardware


To work with Adafruit\BNO055 add-on, connect the BNO055 sensor to your Arduino Hardware as
shown in the image.

5-52
Create Standalone Applications for Arduino Hardware

Create Standalone Applications for Arduino Hardware


This example shows how to create a standalone application by using the LCD add-on library from the
MATLAB Support Package for Arduino Hardware. You can install and run the generated application
on target computers that do not have MATLAB installed.

In this example, you will:


1 Generate the standalone application with a pre-written function that displays “Hello World!” on
an LCD.
2 Run the application on the target computer that does not have MATLAB installed.

LCD Add-on
To create the LCD add-on, see “Create LCD Add-on” on page 6-21.

Generate Standalone Application by Using Application Compiler App


Package a pre-written function that displays “Hello World!” on an LCD.

Required Products

These products must be installed on your computer:

• MATLAB Support Package for Arduino Hardware


• MATLAB Compiler

This example uses a function called LCDAddOnExample_deploy.

To create the LCDAddOnExample_deploy standalone application:


1 Set up the hardware as described in “Connect Arduino to LCD” on page 6-21.
2 Add the ExampleLCD/LCDAddon Add-on Library to path.
3 Save the LCDAddOnExample_deploy function. The function displays 'Hello World!' on the LCD.
function LCDAddOnExample_deploy()
a = arduino('COM5','Uno','Libraries','ExampleLCD/LCDAddon','ForceBuildOn',true);
lcd = addon(a,'ExampleLCD/LCDAddon','RegisterSelectPin','D7','EnablePin','D6','DataPins',{
initializeLCD(lcd);
printLCD(lcd,'Hello World!');
clearLCD(lcd);
end
4 In the Application Compiler project window, in the Main File section on the toolstrip, add the
LCDAddOnExample_deploy function as the main file of the MATLAB application that you want
to deploy. The Suggested Support Packages section of the app displays MATLAB Support
Package for Arduino Hardware.
5 In the Files required for your application to run section of the app, add ExampleLCD/
LCDAddon, the folder in which the LCD add-on library is present.
6 To generate the packaged application, click Package.

If Create log file is enabled in the Additional runtime settings section of the app before
packaging, the log file records display outputs in the log file.

5-53
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

MATLAB Compiler produces an installer that installs the standalone application and all the required
dependencies on a target computer.

For more details on the application compiler app, see Create Standalone Application from MATLAB
and Manage Support Packages.

Install and Run Standalone Application on Target Computer


To run the generated LCDAddOnExample_deploy application on the target computer:

1 Download the Arduino 1.8.10 from here.


2 Extract the files to a location like 'C:\Arduino\arduino-1.8.10'.
3 Create a portable folder inside Arduino\arduino-1.8.10.
4 Start the Arduino IDE.
5 Go to Tools > Board > Boards Manager, and install these cores:

• SAM boards 1.6.12 and SAMD boards 1.8.4


• Arduino Mbed OS Boards 1.3.2
• ESP32 1.0.6 (only if you are using an ESP32 board)
6 Set up the hardware as described in “Connect Arduino to LCD” on page 6-21.
7 Execute the application.

8 In the Configure Arduino window, select the serial port to which the board is connected. On
your Windowssystem, to find the serial port, navigate to Start menu > Control Panel > Device
Manager > Ports (COM & LPT). To find the serial port on Linux® and Mac systems, see “Find
Arduino Port on Windows, Mac, and Linux” on page 7-2.
9 Select the name of the board.
10 Enter the Arduino IDE path and click Submit.

Supported Third-Party Libraries

The third-party library versions listed in the table are supported.

5-54
Create Standalone Applications for Arduino Hardware

Library Version
Adafruit_Motor_Shield_V2_Library 1.0.4
MKRMotorCarrier 1.0.1
ACAN2515 2.0.2

If you are using any third-party library with your add-on, install it in this path:

• Windows and Linux — Arduino IDE path/portable/sketchbook/libraries/


• Mac — ~/Documents/Arduino/libraries/

5-55
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Deploy Arduino Functions to Arduino Hardware Using MATLAB


Function Block

In this section...
“Supported Hardware” on page 5-56
“Required Products” on page 5-57
“Deploy MATLAB IO Functions on Arduino Hardware” on page 5-57
“Run the MATLAB Function” on page 5-58
“Adding Delays” on page 5-58
“Limitations” on page 5-58
“Other Things to Try” on page 5-59

This example shows how to program a MATLAB Function block in Simulink® Support Package for
Arduino Hardware to access multiple peripherals on the Arduino hardware.

The MATLAB Function block enables you to implement custom MATLAB functions in a Simulink
model. You can use the MATLAB Function block to generate readable, efficient, and compact C/C++
code that can be deployed to the Arduino hardware.

For a detailed overview of the MATLAB Function block, see Implementing MATLAB Functions Using
Blocks (Simulink).

Using the MATLAB Function block for code generation provides:

• Scheduling and Multitasking – You can set the sample rate of the MATLAB Function block. The
generated code runs on the hardware at the specified sample rate. With the multitasking mode
(Simulink) On, you can run different blocks at different rates on the hardware.
• Monitor and Tuning – You can monitor signals and tune parameters by using the Monitor & Tune
feature in the Simulink model and observe or log the output signal.

Supported Hardware
MATLAB Function blocks support code generation on these boards:

• Arduino Due
• Arduino Nano 3.0
• Arduino Uno
• Arduino Mega 2560
• Arduino Mega ADK
• Arduino Leonardo
• Arduino Micro
• Arduino MKR1000
• Arduino MKR1010
• Arduino MKR Zero

5-56
Deploy Arduino Functions to Arduino Hardware Using MATLAB Function Block

Required Products
Deploying functions on Arduino Hardware by using the MATLAB Function block requires these
support packages:

• Simulink Support Package for Arduino Hardware


• MATLAB Support Package for Arduino Hardware

Deploy MATLAB IO Functions on Arduino Hardware


Deploy a function that sets the state of an LED pin based on its input, generates PWM signals, and
reads the analog voltage by using the functions listed in “Read and Write Data”.

To configure the model on the Arduino board:

1 Open the Simulink model. At the MATLAB command prompt, enter:

>> arduino_matlab_codegen

2 On the Hardware tab, click Hardware Settings to open the Configuration Parameters dialog
box.
3 Select the Hardware Implementation pane and select your Arduino hardware from the
Hardware board parameter list. Do not change any other settings. Click OK.
4 To see the function written in the editor, double click the MATLAB Function block.

5-57
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Tip Before you deploy the function, you must validate the function. See “Run the MATLAB
Function” on page 5-58.
5 To build the model and run it on the hardware, click Build, Deploy & Start on the Hardware
tab.
6 To perform signal monitoring and parameter tuning, click Monitor & Tune on the Hardware
tab. For example, you can change the PWM duty cycle and observe the generated PWM signal or
you can connect the analog pins to VCC or GND and log the analog voltages in the scope.

Follow the preceding steps for the arduino_matlab_codegen_initblock model. In this model, all
pin configurations you must perform at the beginning of a program execution are in the init block.
Configuring the pins in the init block makes the function in the MATLAB function block modular.

Run the MATLAB Function


Before deploying the function, run the function in the MATLAB Command Window. You can then:

• Verify that the MATLAB function communicates with the hardware as expected.
• Detect run-time errors, such as peripheral conflicts, that are harder to diagnose during
deployment.

Adding Delays
To add a delay in your function inside the MATLAB Function block, use this snippet:

if
coder.target('rtw')
coder.ceval('delay', duration);
end

The duration holds the delay value in milliseconds. Ensure that the total execution time, including
the delay, of the MATLAB Function block on the hardware is less than the sample time to avoid
overrun condition.

Limitations
Invalid PWM Pins

These PWM pin numbers are not allowed inside a MATLAB Function block.

Board PWM Pins


Arduino Mega 2560, Mega ADK 9,10
Arduino Leonardo, Micro 5
Arduino Uno, Nano3.0 3,11
Arduino Due 11,12
Arduino MKR1000, MKR WiFi 1010, MKR Zero 4,5

If you use a PWM function from the MATLAB Support Package for Arduino Hardware in the MATLAB
function block, then do not use the pins listed in this table in the Arduino PWM blocks from the
Simulink Support Package for Arduino Hardware. Simulink requires a timer for scheduling on the

5-58
Deploy Arduino Functions to Arduino Hardware Using MATLAB Function Block

Arduino hardware. When a PWM function is used in the MATLAB Function Block to generate a PWM
signal, a timer is chosen for scheduling on the Arduino hardware. The PWM pins connected to that
timer therefore cannot be used.

Simulink IO

If you run Simulink IO on your model that has the MATLAB Function block with “Read and Write
Data” functions and other Simulink Arduino blocks, Simulink IO does not run on the MATLAB
Function block. For the other Simulink Arduino blocks, Simulink IO runs normally.

Resource Conflicts

To avoid resource conflicts:

• Before you access the Arduino peripherals, set the mode of the pins by using configurePin to
the mode that you plan to use.
• Using the same pin across different peripherals in a model may lead to undefined behaviour. For
example, if you are using readDigitalPin to read digital input from a pin in the MATLAB
Function block, the same pin is not allowed as an output pin in another block in your model.

Other Things to Try


You can use I2C and SPI functions inside the MATLAB Function block. See “Gyroscope-Based
Pedometer Using MATLAB Functions” on page 5-80 for more details.

5-59
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Estimating Orientation Using Inertial Sensor Fusion and


MPU-9250

This example shows how to get data from an InvenSense MPU-9250 IMU sensor, and to use the 6-axis
and 9-axis fusion algorithms in the sensor data to compute orientation of the device.

MPU-9250 is a 9-axis sensor with accelerometer, gyroscope, and magnetometer. The accelerometer
measures acceleration, the gyroscope measures angular velocity, and the magnetometer measures
magnetic field in x-, y- and z- axis. The axis of the sensor depends on the make of the sensor.

Required MathWorks® Products

• MATLAB®
• MATLAB Support Package for Arduino® Hardware
• Navigation Toolbox™ or Sensor Fusion and Tracking Toolbox™

Required Hardware

• Arduino Uno
• InvenSense MPU-9250

Hardware Connection

Connect the SDA, SCL, GND, and the VCC pins of the MPU-9250 sensor to the corresponding pins on
the Arduino® Hardware. This example uses the Arduino Uno board with the following connections:

• SDA - A4
• SCL - A5
• VCC - +3.3V
• GND - GND

5-60
Estimating Orientation Using Inertial Sensor Fusion and MPU-9250

Ensure that the connections to the sensors are intact. It is recommended to use a prototype shield
and solder the sensor to it to avoid loose connections while moving the sensor. Refer the
“Troubleshooting Sensors” on page 7-26 page for sensors to debug the sensor related issues.

Create Sensor Object

Create an arduino object and include the I2C library.

a = arduino('COM9', 'Uno', 'Libraries', 'I2C');

Updating server code on board Uno (COM9). This may take a few minutes.

Create the MPU-9250 sensor object.

fs = 100; % Sample Rate in Hz


imu = mpu9250(a,'SampleRate',fs,'OutputFormat','matrix');

5-61
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Compensating Magnetometer Distortions

Fusion algorithms use magnetometer readings which need to be compensated for magnetic
distortions. In general, two effects exist: Hard iron distortions and soft iron distortions. To learn more
about this distortion, refer to . These distortions can be corrected by using the correction values that
can be determined using these steps:

1 Rotate the sensor from 0 to 360 degree along each axis.


2 Use the function, as shown below, to obtain the correction coefficients.

ts = tic;
stopTimer = 50;
magReadings=[];
while(toc(ts) < stopTimer)
% Rotate the sensor along x axis from 0 to 360 degree.
% Take 2-3 rotations to improve accuracy.
% For other axes, rotate along that axes.
[accel,gyro,mag] = read(imu);
magReadings = [magReadings;mag];
end

[A, b] = magcal(magReadings); % A = 3x3 matrix for soft iron correction


% b = 3x1 vector for hard iron correction

Aligning the axis of MPU-9250 sensor with NED Coordinates

Sensor fusion algorithms used in this example use North-East-Down(NED) as a fixed, parent
coordinate system. In the NED reference frame, the X-axis points north, the Y-axis points east, and
the Z-axis points down. Depending on the algorithm, north may either be the magnetic north or true
north. The algorithms in this example use the magnetic north. The algorithms used here expects all
the sensors in the object to have their axis aligned and is in accordance with NED convention.

MPU-9250 has two devices, the magnetometer and the accelerometer-gyroscope, on the same board.
The axes of these devices are different from each other. The magnetometer axis is aligned with the
NED coordinates. The axis of the accelerometer-gyroscope is different from magnetometer in
MPU-9250. The accelerometer and the gyroscope axis need to be swapped and/or inverted to match
the magnetometer axis. For more information refer to the section “Orientation of Axes” section in
MPU-9250 datasheet.

5-62
Estimating Orientation Using Inertial Sensor Fusion and MPU-9250

To align MPU-9250 accelerometer-gyroscope axes to NED coordinates, do the following:

1. Define device axes: Define the imaginary axis as the device axis on the sensor in accordance to
NED coordinate system which may or may not be same as sensor axes. For MPU-9250, magnetometer
axis can be considered as device axis.

2. Swap the x and y values of accelerometer and gyroscope readings, so that the accelerometer and
gyroscope axis is aligned with magnetometer axis.

3. Determine polarity values for accelerometer, and gyroscope.

a. Accelerometer

• Place the sensor such that device X axis is pointing downwards, perpendicular to the surface at
which sensor is kept. Accelerometer readings should read approximately [9.8 0 0]. If not negate
the x-values of accelerometer.
• Place the sensor such that device Y axis is pointing downwards, perpendicular to the surface at
which sensor is kept. Accelerometer readings should read approximately [0 9.8 0]. If not negate
the y-values of accelerometer.
• Place the sensor such that device Z axis is pointing downwards, perpendicular to the surface at
which sensor is kept. Accelerometer readings should read approximately [0 0 9.8]. If not negate
the z-values of accelerometer.

b. Gyroscope

Rotate the sensor along each axis and capture the readings. Use the right hand screw rule to correct
the polarity of rotation.

The above method is used to set the axis of the sensor in this example.

Tuning Filter Parameters

The algorithms used in this example, when properly tuned, enable estimation of orientation and are
robust against environmental noise sources. You must consider the situations in which the sensors
are used and tune the filters accordingly. See “Custom Tuning of Fusion Filters” (Sensor Fusion and
Tracking Toolbox) for more details related to tuning filter parameters.

5-63
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

The example demonstrates three algorithms to determine orientation, namely ahrsfilter,


imufilter, and ecompass. Refer “Determine Orientation Using Inertial Sensors” (Sensor Fusion
and Tracking Toolbox) for more details related to inertial fusion algorithms.

Accelerometer-Gyroscope-Magnetometer Fusion

An attitude and heading reference system (AHRS) consist of a 9-axis system that uses an
accelerometer, gyroscope, and magnetometer to compute orientation of the device. The ahrsfilter
produces a smoothly changing estimate of orientation of the device, while correctly estimating the
north direction. The ahrsfilter has the ability to remove gyroscope bias and can also detect and
reject mild magnetic jamming.

The following code snippets use ahrsfilter system object to determine orientation of the sensor
and creates a figure which gets updated as you move the sensor. The sensor has to be stationary,
before the start of this example.

% GyroscopeNoise and AccelerometerNoise is determined from datasheet.


GyroscopeNoiseMPU9250 = 3.0462e-06; % GyroscopeNoise (variance value) in units of rad/s
AccelerometerNoiseMPU9250 = 0.0061; % AccelerometerNoise(variance value)in units of m/s^2
viewer = HelperOrientationViewer('Title',{'AHRS Filter'});
FUSE = ahrsfilter('SampleRate',imu.SampleRate, 'GyroscopeNoise',GyroscopeNoiseMPU9250,'Accelerome
stopTimer = 100;

While the below code is getting executed, slowly move the sensor and check if the motion in the
figure matches the motion of the sensor.

% The correction factors A and b are obtained using magcal function as explained in one of the
% previous sections, 'Compensating Magnetometer Distortions'.
magx_correction = b(1);
magy_correction = b(2);
magz_correction = b(3);
ts = tic;
while(toc(ts) < stopTimer)
[accel,gyro,mag] = read(imu);
% Align coordinates in accordance with NED convention
accel = [-accel(:,2), -accel(:,1), accel(:,3)];
gyro = [gyro(:,2), gyro(:,1), -gyro(:,3)];
mag = [mag(:,1)-magx_correction, mag(:, 2)- magy_correction, mag(:,3)-magz_correction] * A;
rotators = FUSE(accel,gyro,mag);
for j = numel(rotators)
viewer(rotators(j));
end
end

When the device X axis of sensor is pointing to north, the device Y-axis is pointing to east and device
Z-axis is pointing down.

5-64
Estimating Orientation Using Inertial Sensor Fusion and MPU-9250

When the device X axis of sensor is pointing to north, device Y-axis is pointing to west and device Z-
axis is pointing upwards.

5-65
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Accelerometer-Gyroscope Fusion

The imufilter system object fuses accelerometer and gyroscope data using an internal error-state
Kalman filter. The filter is capable of removing the gyroscope bias noise, which drifts over time. The
filter does not process magnetometer data, so it does not correctly estimate the direction of north.
The algorithm assumes the initial position of the sensor is in such a way that device X-axis of the
sensor is pointing towards magnetic north, the device Y-axis of the sensor is pointing to east and the
device Z-axis of the sensor is pointing downwards. The sensor must be stationary, before the start of
this example.

The following code snippets use imufilter object to determine orientation of the sensor and creates
a figure which gets updated as you move the sensor.

displayMessage(['This section uses IMU filter to determine orientation of the sensor by collecti
'system object. Move the sensor to visualize orientation of the sensor in the figure window.
'click OK'],...
'Estimate Orientation using IMU filter and MPU-9250.')
% GyroscopeNoise and AccelerometerNoise is determined from datasheet.
GyroscopeNoiseMPU9250 = 3.0462e-06; % GyroscopeNoise (variance) in units of rad/s
AccelerometerNoiseMPU9250 = 0.0061; % AccelerometerNoise (variance) in units of m/s^2
viewer = HelperOrientationViewer('Title',{'IMU Filter'});

5-66
Estimating Orientation Using Inertial Sensor Fusion and MPU-9250

FUSE = imufilter('SampleRate',imu.SampleRate, 'GyroscopeNoise',GyroscopeNoiseMPU9250,'Acceleromet


stopTimer=100;

While the below code is getting executed, slowly move the sensor and check if the motion in the
figure matches the motion of the sensor.

% Use imufilter to estimate orientation and update the viewer as the sensor moves for time specif
tic;
while(toc < stopTimer)
[accel,gyro] = read(imu);
accel = [-accel(:,2), -accel(:,1), accel(:,3)];
gyro = [gyro(:,2), gyro(:,1), -gyro(:,3)];
rotators = FUSE(accel,gyro);
for j = numel(rotators)
viewer(rotators(j));
end
end

The imufilter algorithm can also be used with MPU6050 as well, since it does not require
magnetometer values.

When the device X axis of sensor is pointing to north, device Z-axis is pointing downwards and device
Y-axis is pointing to east.

5-67
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

When the device X axis of sensor is pointing upwards, device Y-axis is points to west and device Z-axis
points to south.

5-68
Estimating Orientation Using Inertial Sensor Fusion and MPU-9250

Accelerometer-Magnetometer Fusion

The ecompass system object fuses the accelerometer and magnetometer data. The Ecompass
algorithm is a memoryless algorithm that requires no parameter tuning but is highly susceptible to
sensor noise. You could use spherical linear interpolation (SLERP) to lowpass filter a noisy trajectory.
Refer “Lowpass Filter Orientation Using Quaternion SLERP” (Sensor Fusion and Tracking Toolbox)
example for more details.
displayMessage(['This section uses \slecompass \rmfunction to determine orientation of the sensor
'\rmsystem object. Move the sensor to visualize orientation of the sensor in the figure windo
'Estimate Orientation using Ecompass algorithm.')
viewer = HelperOrientationViewer('Title',{'Ecompass Algorithm'});
% Use ecompass algorithm to estimate orientation and update the viewer as the sensor moves for ti
% The correction factors A and b are obtained using magcal function as explained in one of the
% previous sections, 'Compensating Magnetometer Distortions'.
magx_correction = b(1);
magy_correction = b(2);
magz_correction = b(3);
stopTimer = 100;
tic;
while(toc < stopTimer)
[accel,~,mag] = read(imu);

5-69
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

accel = [-accel(:,2), -accel(:,1), accel(:,3)];


mag = [mag(:,1)-magx_correction, mag(:, 2)- magy_correction, mag(:,3)-magz_correction] * A;
rotators = ecompass(accel,mag);
for j = numel(rotators)
viewer(rotators(j));
end
end

Clean Up

When the connection is no longer needed, release and clear the objects

release(imu);
clear;

Things to try

You can try this example with other sensors such as InvenSense MPU-6050 and STMicroelectronics
LSM9DS1. Note that the MPU-6050 sensor can be used only with the imufilter system object.

5-70
Wireless Data Streaming Using BNO055 and Bluetooth and Estimating Orientation Using Sensor Fusion

Wireless Data Streaming Using BNO055 and Bluetooth and


Estimating Orientation Using Sensor Fusion

This example shows how to get data from a Bosch BNO055 IMU sensor through HC-05 Bluetooth®
module and to use the 9-axis AHRS fusion algorithm on the sensor data to compute orientation of the
device. The example creates a figure which gets updated as you move the device.

BNO055 is a 9-axis sensor with accelerometer, gyroscope, and magnetometer. Accelerometer


measures acceleration, gyroscope measures angular velocity, and magnetometer measures magnetic
field in x-, y- and z- axes.

Required MathWorks® Products

• MATLAB®
• MATLAB Support Package for Arduino® Hardware
• Sensor Fusion and Tracking Toolbox™ or Navigation Toolbox™

Required Hardware

• Arduino Uno
• Bosch BNO055 Sensor
• HC-05 Bluetooth Module

5-71
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Hardware Connection

5-72
Wireless Data Streaming Using BNO055 and Bluetooth and Estimating Orientation Using Sensor Fusion

Connect the SDA, SCL, GND, and the VCC pins of the BNO055 sensor to the corresponding pins on
the Arduino® Uno board with the connections:

• SDA - A4
• SCL - A5
• VCC - +3.3V
• GND - GND

Connect the TX, RX, GND and VCC pins of the HC-05 module to the corresponding pins on the
Arduino® Uno board. This example uses the connections:

• TX – Digital Pin 0 (RX)


• RX – Digital Pin 1 (TX)
• VCC – 5V
• GND – GND

Ensure that the connections to the sensors and Bluetooth® module are intact. It is recommended to
use a BNO055 shield for Arduino Uno (Arduino 9 Axis Motion Shield). See “Troubleshooting Sensors”
on page 7-26 to debug the sensor related issues.

Setup and Configure Arduino for Bluetooth® Communication

Configure the Arduino Uno board to communicate through Bluetooth® using the arduinosetup
command from MATLAB command prompt. See Setup and Configure Arduino Hardware for steps on
how to configure the Arduino board for communication through Bluetooth®. Make sure to check the
box for I2C Libraries to be included during the Setup.

Create Sensor Object

Create an arduino object.


a = arduino('btspp://001908361009');

Create the bno055 sensor object in the OperatingMode 'amg'.


fs = 100; % Sample Rate in Hz
imu = bno055(a,'SampleRate',fs,'OutputFormat','matrix','OperatingMode','amg');

Compensating for Hard Iron and Soft Iron Distortions

Fusion algorithms use magnetometer readings which need to be compensated for magnetic
distortions such as hard iron distortion. Hard iron distortions are produced by materials which create
a magnetic field, resulting in shifting the origin on the response surface. These distortions can be
corrected by subtracting the correction values from the magnetometer readings for each axis. In
order to find the correction values,
1 Rotate the sensor from 0 to 360 degree along each axis.
2 Use the magcal function to obtain the correction coefficients.

These correction values change with the surroundings.

To obtain correction coefficients for both hard iron and soft iron distortions:
ts = tic;
stopTimer = 50;

5-73
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

magReadings=[];
while(toc(ts) < stopTimer)
% Rotate the sensor along x axis from 0 to 360 degree.
% Take 2-3 rotations to improve accuracy.
% For other axes, rotate along that axes.
[accel,gyro,mag] = read(imu);
magReadings = [magReadings;mag];
end

[A, b] = magcal(magReadings); % A = 3x3 matrix for soft iron correction


% b = 3x1 vector for hard iron correction

Aligning the Axis of BNO055 Sensor with NED Coordinates

Sensor Fusion algorithms used in this example use North-East-Down(NED) as a fixed, parent
coordinate system. In the NED reference frame, the x-axis points north, the y-axis points east, and the
z-axis points down. Depending on the algorithm, north may either be the magnetic north or true
north. The algorithms in this example use the magnetic north. The algorithms used here expect all
the sensors in the object to have their axes aligned with NED convention. The sensor values have to
be inverted so that they are in accordance with the NED coordinates.

Tuning Filter Parameters

The algorithms used in this example, when properly tuned, enable estimation of orientation and are
robust against environmental noise sources. You must consider the situations in which the sensors
are used and tune the filters accordingly. See Tuning Filter Parameters for more details related to
tuning filter parameters.

The example uses ahrsfilter to demonstrate orientation estimation. See, Determine Orientation Using
Inertial Sensors for more details related to inertial fusion algorithms.

Accelerometer-Gyroscope-Magnetometer Fusion

An attitude and heading reference system (AHRS) consists of a 9-axis system that uses an
accelerometer, gyroscope, and magnetometer to compute the orientation of the device. The
ahrsfilter produces a smoothly changing estimate of orientation of the device, while correctly
estimating the north direction. The ahrsfilter has the ability to remove gyroscope bias and can
also detect and reject mild magnetic jamming.

The following code snippets use ahrsfilter system object to determine the orientation of the
sensor and create a figure that gets updated as you move the sensor. The initial position of the sensor
should be such that the device x-axis is pointing towards magnetic north, the device y-axis is pointing
to east and the device z-axis is pointing downwards. You could use a cellphone or compass to
determine magnetic north.
% GyroscopeNoise, AccelerometerNoise and MagnetometerNoise are determined from the BNO055 datashe
% NoisePower = OutputNoisePowerDensityrms^2 * Bandwidth

GyroscopeNoiseBNO055 = 3.05e-06; % GyroscopeNoise (variance value) in units of (rad/s)^2


AccelerometerNoiseBNO055 = 67.53e-06; % AccelerometerNoise (variance value)in units of (m/s^2)^2
MagnetometerNoiseBNO055 = 1; %MagnetometerNoise (variance value) in units of uT^2

viewer = HelperOrientationViewer('Title',{'AHRS Filter'});

FUSE = ahrsfilter('SampleRate',imu.SampleRate,'GyroscopeNoise',GyroscopeNoiseBNO055,'Acceleromete

stopTimer=10;

5-74
Wireless Data Streaming Using BNO055 and Bluetooth and Estimating Orientation Using Sensor Fusion

After executing the below code snippet, slowly move the sensor and check if the motion in the figure
matches the motion of the sensor. Increase the stopTimer value, if you need to track the orientation
for longer time.

magx_correction = b(1);
magy_correction = b(2);
magz_correction = b(3);

ts = tic;
while(toc(ts) < stopTimer)
[accel,gyro,mag] = read(imu);
% Align coordinates in accordance with NED convention
accel = [-accel(:,1), accel(:,2), accel(:,3)];
gyro = [gyro(:,1), -gyro(:,2), -gyro(:,3)];
mag = [(mag(:,1)-magx_correction), -(mag(:,2)- magy_correction), -(mag(:,3)-magz_correction)]
rotators = FUSE(accel,gyro,mag);
for j = numel(rotators)
viewer(rotators(j));
end
end

If the sensor is stationary, at the initial position where the device x-axis points to the magnetic north,
the device y-axis points to the east and the device z-axis points downwards, the x-axis in the figure
will be parallel to and aligned with the positive x-axis, the y-axis in the figure will be parallel to and
aligned with the positive y-axis and the z-axis in the figure will be parallel to and aligned with the
positive z-axis.

5-75
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Clean Up

When the connection is no longer needed, release and clear the objects

release(imu);
delete(imu);
clear;

Things to Try

You can try this example with other sensors such as InvenSense MPU-6050, MPU-9250, and
STMicroelectronics LSM9DS1.

5-76
Plot Position Using GPS Connected to Arduino Hardware

Plot Position Using GPS Connected to Arduino Hardware

This example shows how to get the geographic location using the GPS module connected on Arduino
hardware and plot the location in a map.

Required Hardware

To run this example, you need:

• Arduino Mega2560
• UBlox Neo-6M GPS module
• GPS antenna
• USB cable
• Connecting wires

Hardware Connections

Connect the pins on the UBlox Neo-6M GPS module to the pins on your Arduino Mega 2560 board.
The connections are:

• +5V - 5V
• GND - GND
• RX - TX1(pin 18)
• TX - RX1(pin 19)

Connect the GPS antenna to the GPS module. GPS Fix can be easily acquired in locations that have a
clear view of the sky. Wait for the GPS module to acquire satelite signals(Fix).This can be verified by
checking the Fix LED of your GPS module

Create GPS Object

Create an arduino object and include the Serial library.

5-77
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

a = arduino('COM6','Mega2560','Libraries','Serial');

Create the GPS sensor object.

gps = gpsdev(a)

gps =
gpsdev with properties:

SerialPort: 1
BaudRate: 9600 (bits/s)

SamplesPerRead: 1
ReadMode: "latest"
SamplesRead: 0
SamplesAvailable: 0

Show all properties, functions

Read the GPS data

Read the GPS data and extract latitude, longitude, and time from it.

gpsData = gps.read;
latitude = gpsData.LLA(1);
longitude = gpsData.LLA(2);
gpsTime = gpsData.GPSReceiverTime;
% GPS returns UTC datetime. Convert it into system time zone.
gpsTime.TimeZone = 'local';

Plot the position in a map along with the timestamp

Plot the position in geographic axes with the data obtained from the GPS module. GPS should have fix
to get valid values for latitude, longitude and gpsTime.

If the GPS module does not have fix, the above commands give NaNs for latitude and longitude and
NaT for gpsTime. In this case, make sure the antenna is exposed to clear sky and wait for some time
and try the above steps again.

if(~isnan(latitude) && ~isnan(longitude))


% plot the position in geographic coordinates
fig = geoplot(latitude,longitude,'Marker',"o",'MarkerSize',6,'Color','red','MarkerFaceColor','re

% Sets the latitude and longitude limits of the base Map


geolimits([latitude-0.05,latitude+0.05],[longitude-0.05,longitude+0.05]) ;

% Selects the basemap


geobasemap streets;
timeString = strcat("Timestamp: ",string(gpsTime));

% Create annotation and display time received from GPS


annotation('textbox', [0.005, 0.98, 0.6, 0.01], 'FitBoxToText','on','string', timeString,'Color'
end

5-78
Plot Position Using GPS Connected to Arduino Hardware

Clean Up

When the connection is no longer needed, clear the associated object.

delete(gps);
clear gps;
clear a;

5-79
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Gyroscope-Based Pedometer Using MATLAB Functions

This example shows how MATLAB® Function blocks are used in Simulink® models to implement
algorithms using MATLAB functions. An Arduino® MKR1000 board is used to count the number of
steps a person takes while walking. The pedometer is attached to the thigh of the person in such a
way that the x-axis of the gyroscope is perpendicular to the direction of walking. The data from a
gyroscope sensor is sent to an Android device using the User Datagram Protocol (UDP).

Android devices provide wireless access and a user interface. The Arduino MKR1000 board senses
the data using MPU-9250 sensor connected to the board. After calculating the steps, the board sends
the data to the Android device connected to the Arduino board over WiFi.

Pedometer Algorithm

The pedometer algorithm is implemented inside the MATLAB function block in the Arduino model.
You can use the model with other sensors after modifying the data read and sensor specific
information. The data is read by the I2C device read functions inside the MATLAB function block.

While walking, one leg moves forward and the heel touches the ground. This is called an initial
contact. Then, the body is pushed forward. The same leg lifts from the ground and moves forward and
again the heel touches the ground, making the next initial contact. The duration between the first
initial contact and the next initial contact is called a stride cycle.

Just before the leg lifts from the ground, the angular velocity of the thigh (on which the gyroscope is
attached to) is zero. Then, the leg moves forward, and the angular velocity increases attaining
maxima when the thigh is perpendicular to the ground. Again, the angular velocity decreases and
reaches zero when the heel touches the ground, that is, when the leg makes the next initial contact.
When the leg moves forward, the angular velocity has a positive gradient. In the stride cycle, when
the leg moves backward pushing the body forward, the angular velocity has a negative gradient.
Therefore, one stride cycle can be measured as the time between one negative gradient zero crossing
point and the next.

After receiving an incoming frame, MATLAB identifies all local maxima, local minima, and zero
crossings and then traverses the frame starting from the first zero crossing. If it is a negative
gradient zero crossing, MATLAB expects a local minima next. After identifying the local minima, if
MATLAB gets another zero crossing with positive gradient, MATLAB reads that as a valid step. The
positive gradient zero crossing is the time when the other leg makes the first initial contact.

MATLAB counts all the valid zero crossings, which equals the number of steps. To validate a local
maxima or minima, MATLAB uses a threshold value. The threshold is provided as an input to the
MATLAB Function block. The threshold can be adjusted depending on the minimum walking speed of
an individual.

Reusing the Model for Other Sensors

The Butterworth low pass filter defined inside the MATLAB Function block is set to a cut-off
frequency of 5 Hz, which is sufficient for detecting the steps. Most gyroscopes allow you to configure
the bandwidth and the output data rate. These parameters must be set according to the required
bandwidth in the initialization block. Also, the sample rate of the MATLAB function block named Step
Calculator, which reads gyroscope data from sensor, must be the same as the sampling rate of the
Butterworth low pass filter. In this example, both are set to 20 Hz.

This example uses these Simulink® models:

5-80
Gyroscope-Based Pedometer Using MATLAB Functions

• Arduino model: An Arduino board reads data from the MPU-9250 sensor and processes it inside a
MATLAB Function block, and calculates the number of steps in real time.
• Android model: The UDP Receive block receives the data from the Arduino board over WiFi.

With these models, you will:

1 Set up a network connection between the Arduino board and the Android device.
2 Configure and run Simulink models for the Arduino board and the Android device to calculate the
number of steps taken.

Prerequisites

Before you start this example, install these MathWorks® products:

• DSP System Toolbox™ along with MATLAB® and Simulink®


• Simulink Support Package for Android™ Devices
• Simulink Support Package for Arduino® Hardware
• MATLAB Support Package for Arduino® Hardware

We recommend completing these examples:

• “Getting Started with Android Devices” (Simulink Support Package for Android Devices)
• “Getting Started with MATLAB Support Package for Arduino Hardware” on page 1-39
• “Get Started with Wi-Fi on Arduino Hardware” (Simulink Support Package for Arduino Hardware)

Required Hardware

• Arduino MKR1000/MKR WiFi 1010


• Android device
• MPU-9250 sensor

Set Up a Network Connection

Setup a network connection between the Arduino board and the Android device using UDP. The
Arduino MKR1000/MKR WiFi 1010 board has an on-board WiFi chip and can be used without any
additional WiFi hardware.

1 Open the arduino_android_pedometer_MATLAB_codegen Simulink model.

5-81
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

1 Browse to Configuration Parameters > Hardware Implementation > Target hardware


resources > WiFi properties.
2 Specify the SSID of your WiFi network in the Service set identifier (SSID) parameter.
3 Select the WiFi encryption parameter based on your WiFi network encryption settings. For
more details on configuring the network settings for the Arduino WiFi hardware, see “Configure
Network Settings for WiFi” (Simulink Support Package for Arduino Hardware).
4 Connect the Android device to the same WiFi network to which the Arduino board is connected.

Configure and Run Models on the Arduino Board and the Android Device

1 Open the androidArduinoPedometer Simulink model.

5-82
Gyroscope-Based Pedometer Using MATLAB Functions

1 Click the Deploy to Hardware button of the Android model to run the model on the Android
device.
2 After the launch is complete, the app opens on the Android device.
3 Find the IP address of the Android device from the INFO pane of the app.
4 In the Arduino model, double-click the WiFi UDP Send block and set the Remote IP Address to
the IP address of the Android device.
5 Click the Deploy to Hardware button to run this model on the Arduino board.
6 After the model is deployed on the Arduino board, you can see the step count values in the app.

More About

MATLAB Function block

References

Jayalath S, Abhayasinghe N, Murray I. A Gyroscope Based Accurate Pedometer Algorithm, October


2013.

5-83
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Read and Write CAN Messages with Arduino Hardware

This example shows you how to use the MATLAB® Support Package for Arduino® Hardware to read
and write data from the CAN network using the specified CAN device.

Required Hardware

To run this example, you must have the following hardware:

• Sparkfun CAN-Bus Shield


• Arduino Uno
• MKR CAN Shield
• Arduino MKR1000

Connect the CAN Shields to the Arduino boards. The two Arduino boards form a CAN network. In this
example, the Arduino Uno is used as a transmitter, and the Arduino MKR1000 is used as a receiver.
Connect the CANH and CANL pins in the two shields to complete the connection.

This figure shows an example of connection for CAN communication between MKR CAN Shield and
Sparkfun CAN-Bus Shield.

Create Connection to CAN Channel to Write CAN Messages

Create an arduino object with the Arduino Uno board and include the CAN library.
arduinoUnoObj = arduino('COM15','Uno','Libraries','CAN')

arduinoUnoObj =
arduino with properties:

5-84
Read and Write CAN Messages with Arduino Hardware

Port: 'COM15'
Board: 'Uno'
AvailablePins: {'D2-D13', 'A0-A5'}
AvailableDigitalPins: {'D2-D13', 'A0-A5'}
AvailablePWMPins: {'D3', 'D5-D6', 'D9-D11'}
AvailableAnalogPins: {'A0-A5'}
AvailableI2CBusIDs: [0]
Libraries: {'CAN', 'SPI'}
Show all properties

Create a CAN channel object connected to the Sparkfun CAN-Bus Shield to write messages.

txObj = canChannel(arduinoUnoObj,'MCP2515','D10','D2')

txObj =
Channel with properties:

Device: 'MCP2515'
ProtocolMode: 'CAN'
BusSpeed: 500000
Database: []

Show all properties

Create Channel to Read CAN Messages

Create a connection to the Arduino MKR1000 board with the CAN library.

arduinoMKRObj = arduino('COM5','MKR1000','Libraries','CAN')

arduinoMKRObj =
arduino with properties:

Port: 'COM5'
Board: 'MKR1000'
AvailablePins: {'D0-D14', 'A0-A6'}
AvailableDigitalPins: {'D0-D14', 'A0-A6'}
AvailablePWMPins: {'D0-D8', 'D10', 'A3-A4'}
AvailableAnalogPins: {'A0-A6'}
AvailableI2CBusIDs: [0]
AvailableSerialPortIDs: [1]
Libraries: {'CAN', 'SPI'}
Show all properties

Create a CAN channel object connected to the MKR CAN Shield to read messages.

rxObj = canChannel(arduinoMKRObj,'MKR CAN Shield')

rxObj =
Channel with properties:

Device: 'MKR CAN Shield'


ProtocolMode: 'CAN'
BusSpeed: 500000
Database: []

5-85
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Show all properties

Write Data from Transmitter CAN Channel Object

Write a CAN message into the channel.

write(txObj, 100, false, [1:8])

Read Data from Receiver CAN Channel Object

Read the CAN message from the channel.

readMsg = read(rxObj)

readMsg=1×8 timetable
Time ID Extended Name Data Length Signa
________________________ ___ ________ __________ ___________ ______ _______

06-Feb-2020 14:33:52.901 100 false {0×0 char} {1×8 uint8} 8 {0×0 st

readMsg.Data

ans = 1×1 cell array


{1×8 uint8}

readMsg.Data{:}

ans =

1 2 3 4 5 6 7 8

Clean Up

When finished, clear the connections to the hardware.

clear txObj;
clear arduinoUnoObj;
clear rxObj;
clear arduinoMKRObj;

5-86
Advanced CAN Communication with Arduino Using Vehicle Network Toolbox

Advanced CAN Communication with Arduino Using Vehicle


Network Toolbox

This example shows you how to use the MATLAB® Support Package for Arduino® Hardware along
with the Vehicle Network Toolbox™ to read and write CAN messages and signals using a CAN
database.

Required Hardware

To run this example, you will need the following hardware:

• VN1610 Vector CAN Interface device


• Arduino Mega2560 board
• Seeed Studio CAN-Bus Shield V2

Hardware Setup

Mount the Seeed Studio CAN-Bus Shield V2 on the Arduino Mega2560 board. Use a properly
terminated custom cable to link the CANH and CANL pins of the Vector device to the Arduino CAN
shield.

This example demonstrates the bi-directional communication between the Arduino Mega2560 board
and the Vector VN1610 device.

Create CAN Channels

Create a CAN channel connected to the VN1610 device using the canChannel function from the
Vehicle Network Toolbox.

ch1 = canChannel('Vector','VN1610 1',1);

Create a connection to the CAN channel linked to the Arduino Mega2560 board using canChannel
from the MATLAB Support Package for Arduino Hardware.

arduinoObj = arduino('COM4', 'Mega2560','Libraries','CAN','F','true');


ch2 = canChannel(arduinoObj,'MCP2515','D9','D3');

The CAN database file, demoVNT_CANdbFiles.dbc, will be used to define and decode messages
using the canDatabase function from the Vehicle Network Toolbox. Create handle to the CAN
database file and attach it to the CAN channels.

db = canDatabase('demoVNT_CANdbFiles.dbc');
ch1.Database = db;
ch2.Database = db;

Create CAN Messages

Create CAN messages, with the definition from the CAN database file, using the canMessage function
from the Vehicle Network Toolbox.

msg = canMessage(db,'EngineMsg');

5-87
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Transmit CAN Messages from Vector Device and Read from Arduino Hardware

Transmit CAN messages from the Vector VN1610 device using the transmit function from the Vehicle
Network Toolbox. You must start the channel using the start function from the Vehicle Network
Toolbox before you transmit the messages.

start(ch1);
msg.Signals.EngineRPM = 2000;
transmit(ch1, msg);

Read the timetable which contains all the CAN frames from the channel linked to the Arduino Mega
2560 board using the read function.

arduinoRx = read(ch2)

arduinoRx=1×8 timetable
Time ID Extended Name Data Length Si
________________________ ___ ________ _____________ ___________ ______ ____

14-Jul-2020 17:07:15.403 100 false {'EngineMsg'} {1×8 uint8} 8 {1×1

arduinoRx.Signals{1}.EngineRPM

ans = 2000

You have now established successful communication between the nodes.

Write CAN Messages from Arduino Hardware and Receive from Vector Device

Now write new values into the CAN Message object and transmit it through the Arduino Hardware.
Write the CAN message from the Arduino Mega 2560 board using the write function.

msg.Signals.EngineRPM = 500;
write(ch2, msg)

Receive the CAN frames from the VN1610 Vector hardware using the receive function from the
Vehicle Network Toolbox. You must specify the value of ‘OutputFormat’ to 'timetable' when
using the receive function for optimal performance and representation of CAN messages in MATLAB.

vectorRx = receive(ch1,2,'OutputFormat','timetable')

vectorRx=2×8 timetable
Time ID Extended Name Data Length Signals
____________ ___ ________ _____________ ___________ ______ ____________

0.073982 sec 100 false {'EngineMsg'} {1×8 uint8} 8 {1×1 struct}


0.29798 sec 100 false {'EngineMsg'} {1×8 uint8} 8 {1×1 struct}

vectorRx.Signals{1}.EngineRPM

ans = 2000

vectorRx.Signals{2}.EngineRPM

ans = 500

5-88
Advanced CAN Communication with Arduino Using Vehicle Network Toolbox

The message which is transmitted from the Vehicle Network Toolbox, is available in the receive buffer
until it is received. Hence you see the first transmitted value in Signals{1}. You have received the
CAN message transmitted by Arduino hardware in Signals{2}.

Using Vehicle Network Toolbox you can extract the signals from the received timetable.

canSignalTimetable(vectorRx)

ans=2×2 timetable
Time VehicleSpeed EngineRPM
____________ ____________ _________

0.073982 sec 0 2000


0.29798 sec 0 500

There is a difference in Time output in the timetables from Vehicle Network Toolbox and MATLAB
Support Package for Arduino Hardware. The Time output from the MATLAB Support Package for
Arduino Hardware is the absolute time in datetime whereas the Time output from the Vehicle
Network Toolbox is the relative time as most of the VNT hardware drivers are built around relative
times. To fetch the absolute time, use the InitialTimestamp property of ch1.

ch1.InitialTimestamp

ans = datetime
14-Jul-2020 17:07:15

To see the table with absolute time, add the InitialTimestamp to the Time column of the
vectorRx timetable.

vectorRx.Time = vectorRx.Time + ch1.InitialTimestamp

vectorRx=2×8 timetable
Time ID Extended Name Data Length Signal
____________________ ___ ________ _____________ ___________ ______ ________

14-Jul-2020 17:07:15 100 false {'EngineMsg'} {1×8 uint8} 8 {1×1 str


14-Jul-2020 17:07:15 100 false {'EngineMsg'} {1×8 uint8} 8 {1×1 str

Clean Up

When finished, clear the connections to the hardware.

clear db;
clear msg;
clear arduinoRx;
clear vectorRx;
clear ch1;
clear ch2;
clear arduinoObj;

5-89
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

Overcome Buffer Size Limitation of Arduino

This example shows you the limitation of Arduino based CAN Nodes by using the automatic periodic
transmit feature of Vehicle Network Toolbox™. It also shows you how to overcome the limitation by
using the timer feature which is available with MATLAB.

Required Hardware

To run this example, you will need the following hardware:

• Vector CAN Case XL


• Arduino Mega2560 board
• Seeed Studio CAN-Bus Shield V2

Hardware Setup

Seeed Studio CAN-Bus Shield V2 mounted on Arduino Mega2560 and the Vector CAN Case XL are
the CAN nodes. Use the Vector CANcable 1 and Vector CANcable A combination to connect the CANH
and CANL of Vector and Arduino nodes together.

The example uses Vector CAN Case XL as the transmitter and the Arduino Mega2560 with Seeed
Studio CAN-Bus Shield V2 as the receiver.

Create the CAN Channels

Create the transmit CAN channel object on which you can use the automatic message transmit
commands using the canChannel function from Vehicle Network Toolbox™.

txCh = canChannel('Vector', 'CANCaseXL 1',1);

Create the receive CAN channel object.

arduinoObj = arduino('COM11', 'Mega2560', 'Libraries', 'CAN');


rxCh = canChannel(arduinoObj, 'Seeed Studio CAN-Bus Shield V2');

In this example, you will use a CAN database file to define and decode messages. Open the database
and attach it to the CAN channels.

db = canDatabase('demoVNT_CANdb.dbc');
txCh.Database = db;
rxCh.Database = db;

Create the CAN Messages

Create CAN messages for periodic transmit using the database information.

msgFast = canMessage(db, 'EngineMsg');


msgSlow = canMessage(db, 'TransmissionMsg');

Configure Messages for Periodic Transmit

To configure a message for periodic transmit, use the transmitPeriodic command from Vehicle
Network Toolbox™ to specify the channel, the message to register on the channel,a mode value, and
the periodic rate.

5-90
Overcome Buffer Size Limitation of Arduino

transmitPeriodic(txCh, msgFast, 'On', 0.200);


transmitPeriodic(txCh, msgSlow, 'On', 0.500);

Start the Periodic Message Transmit

When you start a channel which has periodic messages registered, transmit begins immediately.
Allow the channels to run for a short time.

start(txCh);
pause(2);

Modify Transmitted Data

Update the live message or signal data sent onto the CAN bus.

msgFast.Signals.VehicleSpeed = 60;
pause(1);
msgFast.Signals.VehicleSpeed = 65;
pause(1);
msgFast.Signals.VehicleSpeed = 70;
pause(1);

Read the Messages

Read all periodically transmitted messages.

read(rxCh, 100)

Analyze the Received Messages and take action

Having allowed the periodic messages to run for more than 5 seconds, at least 30 messages would
have been transmitted. The MATLAB Support Package for Arduino Hardware provides only 10 buffers
for CAN Frames. Since the messages have been received repeatedly, we see that more than 10
messages have been received. Also, only the oldest messages would be retained due to which Arduino
does not receive an update to Vehicle Speed. To use Arduino as an effective receiver, in a CAN
Network, we must do trial and error experiments to set it up according to the application.

To effectively receive all the messages that have been transmitted, the reading and data collection
must happen in parallel to the vehicle speed update exercise. We use a timer to set up reception in
Arduino.

msgRx = [];
stopArduinoReceptionTimer = false;
t = timer;
t.Name = 'ArduinoTimer';
t.ExecutionMode = 'fixedRate';
t.Period = 0.1;
t.TimerFcn = @collectData;
start(t);
pause(2);

Modify Transmitted Data Again

Update the live message or signal data sent onto the CAN bus.

msgFast.Signals.VehicleSpeed = 60;
pause(1);
msgFast.Signals.VehicleSpeed = 45;

5-91
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

pause(1);
msgFast.Signals.VehicleSpeed = 10;
pause(1);

Analyze the Periodic Transmit Behavior

Stop the transmission channel and the timer we created for Arduino to receive messages. You can
analyze the distribution of messages by plotting the identifiers of each message against their
timestamps. Notice the difference between how often the two messages appear according to their
periodic rates.

stop(txCh);
stopArduinoReceptionTimer = true;
pause(1);
plot(msgRx.Time, msgRx.ID, 'x')
ylim([0 400])
title('Message Distribution', 'FontWeight', 'bold')
xlabel('Timestamp')
ylabel('CAN Identifier')

For further analysis, separate the two messages into individual timetables.

msgRxFast = msgRx(strcmpi('EngineMsg', msgRx.Name), :);


msgRxFast(1:10, :)
msgRxSlow = msgRx(strcmpi('TransmissionMsg', msgRx.Name), :);
msgRxSlow(1:10, :)

5-92
Overcome Buffer Size Limitation of Arduino

Analyze the timestamps of each set of messages to see how closely the average of the differences
corresponds to the configured periodic rates.
avgPeriodFast = mean(milliseconds(diff(msgRxFast.Time)))
avgPeriodSlow = mean(milliseconds(diff(msgRxSlow.Time)))

A plot of the received signal data reflects the updates in the message data sent on the CAN bus.
signalTimetable = canSignalTimetable(msgRx, 'EngineMsg');
signalTimetable(10:25, :)
plot(signalTimetable.Time, signalTimetable.VehicleSpeed)
title('Vehicle Speed from EngineMsg', 'FontWeight', 'bold')
xlabel('Timestamp')
ylabel('Vehicle Speed')
ylim([-5 75])

View Messages Configured for Periodic Transmit

To see messages configured on a channel for periodic transmit, use the transmitConfiguration
command.
transmitConfiguration(txCh)

Clean Up

When finished, clear the connections to the hardware and the created messages.
clear txCh
clear arduinoObj

5-93
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

clear rxCh
clear msgFast
clear msgSlow
clear msgRx
clear msgRxFast
clear msgRxSlow
clear signalTimetable

Routine to collect data using Arduino

The collectData function is used to read CAN Messages in parallel to data update. For more
information on the collectData function, execute the following command in the MATLAB command
line:

open('collectData.m')

5-94
Read and Plot Real-Time Data from BNO055 Sensor in NDOF Mode

Read and Plot Real-Time Data from BNO055 Sensor in NDOF


Mode
This example shows you how to read and plot calibrated data from a Bosch Sensortec BNO055 a 9-
axis absolute orientation sensor in real time. To read the orientation values directly from the BNO055
sensor, configure the sensor in the NDOF operating mode.

BNO055 is a 9-axis sensor with an integrated accelerometer, gyroscope, and magnetometer. The
accelerometer measures acceleration, the gyroscope measures angular velocity, and the
magnetometer measures the magnetic field along x-, y-, and z-axis. The axis of the sensor depends on
the make of the sensor.

Required Products
• MATLAB
• MATLAB Support Package for Arduino Hardware

Required Hardware
• Arduino Uno
• Bosch BNO055 Sensor

Hardware Connection

Connect the SDA, SCL, GND, and the VCC pins of the BNO055 sensor to the corresponding pins on
the Arduino hardware. This example uses an Arduino Uno board with the following connections:

5-95
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

• SDA — A4
• SCL — A5
• VCC — +5V
• GND — GND

Ensure that the connections to the sensor is intact. We recommended that you use a prototype shield
and solder the sensor to it to avoid loose connections when moving the sensor. For information on
debugging sensor related issues, see “Troubleshooting Sensors” on page 7-26.

Create Connection to BNO055 Sensor in NDOF Mode


Create a connection to the BNO055 sensor in the NDOF mode. Ensure that you create the arduino
object with the library set to 'I2C'.
arduinoObj = arduino('COM7', 'Uno', 'Libraries', 'I2C');
bno = bno055(arduinoObj, 'OperatingMode', 'ndof');

Calibrate BNO055 Sensor


Calibrate the sensor using the steps described in “Calibrate BNO055 Sensors” on page 5-50.
% Accelerometer calibration flag
accCalib = 0;
% Gyroscope calibration flag
gyrCalib = 0;
% Magnetometer calibration flag
magCalib = 0;
fprintf('Calibrating the BNO055 sensor . . . \n');
while(prod([accCalib, gyrCalib, magCalib]) ~= 1)
if strcmpi(bno.readCalibrationStatus.Accelerometer, "full") && isequal(accCalib, 0)
accCalib = 1;
fprintf('Accelerometer is calibrated! . . .\n');
end
if strcmpi(bno.readCalibrationStatus.Gyroscope, "full") && isequal(gyrCalib, 0)
gyrCalib = 1;
fprintf('Gyroscope is calibrated! . . .\n');
end
if(strcmpi(bno.readCalibrationStatus.Magnetometer, "full"))&& isequal(magCalib, 0)
magCalib = 1;
fprintf('Magnetometer is calibrated! . . .\n');
end
end
fprintf('BNO055 sensor is fully calibrated!\n');

Read Sensor Data


Read the orientation, acceleration, angular velocity, and magnetic field strength from the BNO055
sensor.

Estimate the time between consecutive read cycles.


% Provide time frame in seconds
senseFrame = 60;
% Measure approximate execution time of a single read cycle

5-96
Read and Plot Real-Time Data from BNO055 Sensor in NDOF Mode

tic;
readOrientation(bno);
readAcceleration(bno);
readAngularVelocity(bno);
readMagneticField(bno);
tDelta = toc;
% Number of samples to be collected in the senseFrame time frame
numSamples = floor(senseFrame/tDelta);
% Time vector
tVector = linspace(0, senseFrame, numSamples);
tCorrection = 0;
recordedData = zeros(numSamples, 3, 4);

Set up the figure handles to plot the change in orientation, acceleration, and magnetic field strength
as the device moves.

subplot(4, 1, 1)
hold on
% Create handle to Azimuth animatedline object
hAzimuth = animatedline('color', 'r', 'linewidth', 1.25);
% Create handle to Pitch animatedline object
hPitch = animatedline('color', 'k', 'linewidth', 1.25);
% Create handle to Roll animatedline object
hRoll = animatedline('color', 'b', 'linewidth', 1.25);
legend('Azimuth (rad)','Pitch (rad)','Roll (rad)');
ylabel('Euler Angles (rad)');xlabel('Time (s)');
title('Reading Orientation of the BNO055 sensor', 'fontsize', 12);
axis([0 senseFrame -6.5 6.5])
grid minor
hold off

subplot(4, 1, 2)
hold on
% Create handle to X-axis acceleration animatedline object
hAx = animatedline('color', 'r', 'linewidth', 1.25);
% Create handle to Y-axis acceleration animatedline object
hAy = animatedline('color', 'k', 'linewidth', 1.25);
% Create handle to Z-axis acceleration animatedline object
hAz = animatedline('color', 'b', 'linewidth', 1.25);
legend('A_x (m/s^2)','A_y (m/s^2)','A_z (m/s^2)');
ylabel('Acceleration (m/s^2)');xlabel('Time (s)');
title('Reading Accelerometer values from BNO055 sensor', 'fontsize', 12);
axis([0 senseFrame -30 30]);
hold off
grid minor

subplot(4, 1, 3)
% Create handle to X-axis angular velocity animatedline object
hVx = animatedline('color', 'r', 'linewidth', 1.25);
% Create handle to Y-axis angular velocity animatedline object
hVy = animatedline('color', 'k', 'linewidth', 1.25);
% Create handle to Z-axis angular velocity animatedline object
hVz = animatedline('color', 'b', 'linewidth', 1.25);
legend('\omega_x (rad/s)','\omega_y (rad/s)','\omega_z (rad/s)');
ylabel('Angular Velocity (rad/s)');xlabel('Time (s)');
title('Reading Angular velocity values from BNO055 sensor', 'fontsize', 12);
axis([0 senseFrame -10 10]);
hold off

5-97
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN

grid minor

subplot(4, 1, 4)
% Create handle to X-axis magnetic field animatedline object
hMagx = animatedline('color', 'r', 'linewidth', 1.25);
% Create handle to Y-axis magnetic field animatedline object
hMagy = animatedline('color', 'k', 'linewidth', 1.25);
% Create handle to Z-axis magnetic field animatedline object
hMagz = animatedline('color', 'b', 'linewidth', 1.5);
legend('\mu_x (\muT)','\mu_y (\muT)','\mu_z (\muT)');
ylabel('Magnetic Field (\muT)');xlabel('Time (s)');
title('Reading Magnetometer values from BNO055 sensor', 'fontsize', 12);
axis([0 senseFrame -50 50]);
hold off
grid minor

Read and plot the calibrated data from the sensor.

for i = 1:numSamples
% Read Orientation values (Euler angles) from the sensor
[sensorVal, ~] = readOrientation(bno);
% Read Acceleration values from the sensor
[AccelVal, ~] = readAcceleration(bno);
% Read Angular velocity values from the sensor
[AngVelVal, ~] = readAngularVelocity(bno);
% Read Magnetic field strength values from the sensor
[MagVal, ~] = readMagneticField(bno);

tic;
addpoints(hAzimuth, tVector(i) + tCorrection,sensorVal(1));
addpoints(hPitch, tVector(i) + tCorrection,sensorVal(2));
addpoints(hRoll, tVector(i) + tCorrection,sensorVal(3));

addpoints(hAx, tVector(i) + tCorrection, AccelVal(1));


addpoints(hAy, tVector(i) + tCorrection, AccelVal(2));
addpoints(hAz, tVector(i) + tCorrection, AccelVal(3));

addpoints(hVx, tVector(i) + tCorrection, AngVelVal(1));


addpoints(hVy, tVector(i) + tCorrection, AngVelVal(2));
addpoints(hVz, tVector(i) + tCorrection, AngVelVal(3));

addpoints(hMagx, tVector(i) + tCorrection, MagVal(1));


addpoints(hMagy, tVector(i) + tCorrection, MagVal(2));
addpoints(hMagz, tVector(i) + tCorrection, MagVal(3));

recordedData(i, :, 1) = sensorVal;
recordedData(i, :, 2) = AccelVal;
recordedData(i, :, 3) = AngVelVal;
recordedData(i, :, 4) = MagVal;

tCorrection = toc;

drawnow;
end

5-98
Read and Plot Real-Time Data from BNO055 Sensor in NDOF Mode

Clean Up
When the connection is no longer needed, release and clear the objects.

release(bno);
clear arduinoObj;
clear bno;

5-99
6

Custom Arduino Libraries


6 Custom Arduino Libraries

Create Custom Arduino Add-On Library


The add-on SDK provides a framework to create a custom MATLAB Arduino add-on library. This
framework enables development of add-on libraries that can execute code on the Arduino hardware
in MATLAB.

The framework takes care of the communication and interaction between MATLAB and an Arduino
device, enabling you to focus on developing a particular feature. A MATLAB Arduino add-on library
has three components:

• “Create Add-On Package Folder” on page 6-5


• “Create and Configure MATLAB Add-On Class” on page 6-11
• “Create and Configure C++ Header File” on page 6-6

This table shows the steps required to create a custom Arduino add-on library.

Step Action More Information


s
1 Create add-on folder package and add subfolders to “Create Add-On Package Folder”
contain C++ header file and MATLAB add-on class on page 6-5
2 Create and configure C++ header file and add third part “Create and Configure C++
resources (if required) for custom library Header File” on page 6-6
3 Create and configure MATLAB add on class that inherits “Create and Configure MATLAB
from matlabshared.addon.LibraryBase. Add-On Class” on page 6-11
“Adapt Add-ons to New
matlabshared.addon.LibraryBase
Class” on page 5-49
4 Register add-on library and run MATLAB code “Register Add-On Library” on
page 6-36

See Also
“Custom Add-On Library Concepts” on page 6-3 | “Physical Terminals and Pin Numbers” on page 6-
35

Related Examples
• “Create HelloWorld Add-On” on page 6-16
• “Create LCD Add-on” on page 6-21

6-2
Custom Add-On Library Concepts

Custom Add-On Library Concepts


An add-on library is a collection of MATLAB and C++ code that provides a user easy access to
features on the Arduino hardware or attached shields. Without the need to directly program the
Arduino hardware work within the MATLAB environment, the exploration and development of
projects can proceed at an accelerated rate.

This schematic shows the construction of a custom Arduino add-on library and its relation to the
hardware.

The “Custom Arduino Libraries” provides the abstract matlabshared.addon.LibraryBase class


in MATLAB and the C++ librarybase.h library. You create a custom add-on library by extending
the MATLAB class and creating a C++ class that includes librarybase.h.

Command Handler
Communication between the Arduino hardware and MATLAB on the host computer operates in a
server-client relationship, respectively.

The sendCommand function issues a command, known as a commandID, from the MATLAB on the
host computer, which is acting as the client. A server object on the Arduino hardware, created by the
ArduinoServer.ino library, receives the command in the “Command Handler” on page 6-8
method in the “Create and Configure C++ Header File” on page 6-6. A switch statement
determines which code segment to execute on the Arduino device. When complete, the “Command
Handler” on page 6-8 uses the sendResponseMsg() to return any data and validate that the
specified commandID was executed.

Note Communication between MATLAB on the host computer and the Arduino hardware incurs a 20
ms time delay.

Required Knowledge
To create custom add-on libraries, you should have a working knowledge in the following areas

6-3
6 Custom Arduino Libraries

• MATLAB classes
• C++
• The functionality of your hardware device, and its associated application programming interfaces
(APIs)

See Also
“Create Custom Arduino Add-On Library” on page 6-2 | “Physical Terminals and Pin Numbers” on
page 6-35

6-4
Create Add-On Package Folder

Create Add-On Package Folder


The add-on library folder is a MATLAB package folder. The top-level package folder name must be the
name of your add-on library preceded by a + sign.

The package folder must contain two files: “Create and Configure C++ Header File” on page 6-6
and the “Create and Configure MATLAB Add-On Class” on page 6-11 file.

Note Use only ASCII characters in your MATLAB and C++ classes.

Create a folder package to contain all the files for your custom library, and add it to the MATLAB
path. For example:

1 Add a folder named +arduinoioaddons in your working folder.


2 In +arduinoioaddons, add a +ExampleAddon subfolder.

This folder contains the “Create and Configure MATLAB Add-On Class” on page 6-11 file.
3 In the +ExampleAddon subfolder, add a src folder that contains the “Create and Configure C++
Header File” on page 6-6.

See Also
“Create and Configure C++ Header File” on page 6-6 | “Create and Configure MATLAB Add-On
Class” on page 6-11

More About
• “Packages Create Namespaces”

6-5
6 Custom Arduino Libraries

Create and Configure C++ Header File


In this section...
“Install Third-Party Libraries” on page 6-6
“LibraryBase” on page 6-6
“Constructor” on page 6-7
“Command Handler” on page 6-8
“Setup” on page 6-9
“Loop” on page 6-9
“Debugging” on page 6-9

The C++ header requires several properties and methods that must be overridden from the base
class:

• “Install Third-Party Libraries” on page 6-6


• “LibraryBase” on page 6-6
• “Constructor” on page 6-7
• “Command Handler” on page 6-8
• “Debugging” on page 6-9

Note Use only ASCII characters for file include path, C++ class name, and variables.

Install Third-Party Libraries


If you have third-party Arduino libraries for your Arduino hardware that you will use with your add-
on, install it at the following locations:

• Windows and Linux - "arduinoio.IDERoot/portable/sketchbook/libraries/"


• Mac- "~/Documents/Arduino/libraries/"

LibraryBase
The LibraryBase class provides all the necessary functionality for executing the code from the
“Create and Configure MATLAB Add-On Class” on page 6-11. At the beginning of the file C++
header file, you must include the LibraryBase.h library:

#include "LibraryBase.h"

You can include additional libraries following LibraryBase.h. Typically, these libraries are third-
party Arduino libraries for your Arduino hardware that provide direct access to specific functionality.

Your base add-on class C++ header must extend the LibraryBase class:

class MyAddon : public LibraryBase {


...
};

6-6
Create and Configure C++ Header File

Note If you have included additional third-party libraries, make sure the name of your add-on class
(e.g. MyAddon) is not the same as the name of any of the classes defined in the third-party libraries.

Extending the LibraryBase.h class provides access to the appropriate methods and properties. The
following diagram shows the typical method inheritance for an add-on:

Constructor
The add-on constructor defines the name of your add-on library and registers the library with the
main Arduino program. Your add-on class must override the default constructor method of the
“LibraryBase” on page 6-6. The constructor uses the same name as your add-on class and takes a
reference to a MWArduinoClass object.

public:
MyAddon(MWArduinoClass& a)
{

libName = "MyAddonPackageFolder/MyAddon";

a.registerLibrary(this);
}

The library name property, libName, must be the same string defined in the “Library Specification”
on page 6-12 of the “Create and Configure MATLAB Add-On Class” on page 6-11:

<AddonFolderName>/<AddonName>

The add-on library is registered with the general MWArduinoClass object using the
registerLibrary method. For example, the constructor from the “Create HelloWorld Add-On” on
page 6-16 example uses the following constructor:

public:
HelloWorld(MWArduinoClass& a)
{
libName = "ExampleAddon/HelloWorld";
a.registerLibrary(this);
}

6-7
6 Custom Arduino Libraries

Command Handler
The commandHandler method is the entry point for the commands executed in your “Create and
Configure MATLAB Add-On Class” on page 6-11 that were executed by the sendCommand. Your add-
on class must override the default commandHandler method of the “LibraryBase” on page 6-6 class.

public:
void commandHandler(byte cmdID, byte* dataIn, unsigned int payloadSize)
{

switch (cmdID){

case 0x01:{

sendResponseMsg(cmdID, val, 13);
break;
}

… // Other cases with appropriate cmdIDs

default:{
// Do nothing
}
}
}

The switch statement uses the command identifiers, cmdID, to determine the segment of code to
execute. The cmdIDs must match those defined in the “Create and Configure MATLAB Add-On Class”
on page 6-11. At the end of each switch statement, the commandHandler must call the
sendResponseMsg function:

sendResponseMsg(byte commandID, byte* dataOut, unsigned int payloadSize)

The data assigned to the input arguments dataOut, and payloadSize returned to the output
arguments of the sendCommand function.

Note Execution of thesendCommand called within the “Create and Configure MATLAB Add-On Class”
on page 6-11 held until either a sendResponseMsg executes or the timeout condition is reached.

The commandHandler method from the “Create HelloWorld Add-On” on page 6-16 example shows
how a string, 'Hello World!', can be created in the C++ code and returned to the “Create and
Configure MATLAB Add-On Class” on page 6-11 through the commandHandler:

public:
void commandHandler(byte cmdID, byte* dataIn, unsigned int payloadSize)
{
switch (cmdID){

case 0x01:{
byte val [13] = "Hello World!";
sendResponseMsg(cmdID, val, 13);
break;
}

default:{

6-8
Create and Configure C++ Header File

// Do nothing
}
}
}

Setup
The setup method can be used to initialize and set the initial values. Your add-on class can override
the default setup method of the “LibraryBase” on page 6-6 class to initialize variables. The “Create
LCD Add-on” on page 6-21 example overrides the default setup method to reset the cursor to the
first row upon initialization as shown:

public:
void setup()
{
cursorRow=0;

Loop
The loop method can be used to perform certain repetitive tasks. Your add-on class can override the
default loop method of the “LibraryBase” on page 6-6 class. In the example below, if mcused is true,
the controller remains on.

void loop()
{
if(mcused)
{
controllerMW.ping();
}
}

Note Do not use any blocking operation in the loop method.

Debugging
The “LibraryBase” on page 6-6 also provides a convenient function, debugPrint, to display
messages to the MATLAB command line to help in development of your add-on.

The debugPrint function uses the same syntax as the C++ printf function:

debugPrint(MSG_EXAMPLE_DEBUG);

The debug message must be declared in the C++ header file using the following syntax:

const char MSG_EXAMPLE_DEBUG[] PROGMEM = "This is a debug message.\n";

where the string PROGMEM is the message displayed. Additional information can be included in the
debug message using format specifiers. To enable debugPrint messages to be displayed to the
MATLAB command line during run-time, you must set the additional Name-Value property ‘trace’ in
the arduino function:

6-9
6 Custom Arduino Libraries

The “Create HelloWorld Add-On” on page 6-16 example prints to the MATLAB command line a
sample debug message with the last commandID that was included using a format specifier:

const char MSG_EXAMPLE_DEBUG[] PROGMEM = "Example debug message: cmdID %d\n";

...

debugPrint(MSG_EXAMPLE_DEBUG, cmdID);

See Also
“Create Add-On Package Folder” on page 6-5 | “Create and Configure MATLAB Add-On Class” on
page 6-11

6-10
Create and Configure MATLAB Add-On Class

Create and Configure MATLAB Add-On Class


In this section...
“Command Identifiers” on page 6-12
“Library Specification” on page 6-12
“Constructor” on page 6-13
“Destructor” on page 6-14
“Resource Ownership” on page 6-15

The MATLAB class for your library must inherit from the matlabshared.addon.LibraryBase
class:

classdef MyAddon < matlabshared.addon.LibraryBase



end

Note Use only ASCII characters for class, package, function, script, and variable names in your
MATLAB class.

The matlabshared.addon.LibraryBase class includes a variety of properties and methods. The


following diagram shows a typical class inheritance for your add-on:

To implement your MATLAB add-on class, you must override the following properties and method:

• “Command Identifiers” on page 6-12


• “Library Specification” on page 6-12
• “Constructor” on page 6-13

Depending on the design of your add-on, you may also be required to override the following property
and method:

6-11
6 Custom Arduino Libraries

• “Resource Ownership” on page 6-15


• “Destructor” on page 6-14

Command Identifiers
The command identifiers, typically named commandID, are 8-bit hexadecimal values. The commandID
is used in the sendCommand to provide a consistent mapping to the commandHandler on page 6-8
method in the “Create and Configure C++ Header File” on page 6-6.

Use the following syntax to specify a commandID property in your MATLAB class:

properties(Access = private, Constant = true)


ADDON_OPERATION = hex2dec(cmdID)

end

The “Create LCD Add-on” on page 6-21 example shows the commandIDs in the LCDAddon.m
classdef file as:

properties(Access = private, Constant = true)


LCD_CREATE = hex2dec('00')
LCD_INITIALIZE = hex2dec('01')
LCD_CLEAR = hex2dec('02')
LCD_PRINT = hex2dec('03')
LCD_DELETE = hex2dec('04')
end

Similarly, the LCD.h defines the commandIDs:

#define LCD_CREATE 0x00


#define LCD_INITIALIZE 0x01
#define LCD_CLEAR 0x02
#define LCD_PRINT 0x03
#define LCD_DELETE 0x04

Note For consistent behavior, the command identifiers in the MATLAB class must match the
commandIDs used in the commandHandler on page 6-8 method from the C++ header file.

Library Specification
The library specification defines the name of the add-on and locations of the required C++ source
files and libraries. The library specification is a property set with this code:

properties(Access = protected, Constant = true)


LibraryName = 'MyAddonFolder/MyAddon'
DependentLibraries = {}
LibraryHeaderFiles = {}
CppHeaderFile = fullfile(arduinoio.FilePath(mfilename('fullpath')), 'src', 'MyAddon.h')
CppClassName = 'MyAddon'
end

The five library specification properties must be defined as in matlabshared.addon.LibraryBase


or as shown in the following table.

6-12
Create and Configure MATLAB Add-On Class

Property Description
LibraryName Name of your add-on library as a string. The
string uses the same syntax as your add-on folder
structure: <AddonFolder>/<AddonName>
DependentLibraries Other add-on libraries required by your add-on as
a cell array of strings.
LibraryHeaderFiles Any C++ header files needed by your add-on. See
“LibraryBase” on page 6-6 for details on
including header files.
CppHeaderFile Full path and name of your add-on C++ header
file as a string.
CppClassName Name of the class in your C++ header file as a
string.

The “Create LCD Add-on” on page 6-21 sample library shows a typical naming of these properties:

properties(Access = protected, Constant = true)


LibraryName = 'ExampleLCD/LCDAddon'
DependentLibraries = {}
LibraryHeaderFiles = 'LiquidCrystal/LiquidCrystal.h'
CppHeaderFile = fullfile(arduinoio.FilePath(mfilename('fullpath')), 'src', 'LCD.h')
CppClassName = 'LCD'
end

If your add-on has a C++ header file specified in LibraryHeaderFiles, make sure the
CppClassName is not the same as the name of any of the classes defined in the header file. In this
example, LCD is different from the C++ class defined in LiquidCrystal.h.

If your add-on requires I2C support, then

DependentLibraries = {'i2c'};

Constructor
The constructor for your add-on must initialize the add-on object in two ways:

• Parent the add-on object to the Arduino object.


• Define the set of hardware pins used by the add-on

Here is the minimum form of the constructor:

methods

function obj = AddonName(parentObj)


obj.Parent = parentObj;
end


end

Typically, the add-on constructor registers add-on resources with the parent Arduino object. Similarly,
checks can also be performed to ensure that add-ons do not generate resource usage conflicts. The

6-13
6 Custom Arduino Libraries

constructor in the “Create LCD Add-on” on page 6-21 example shows how a resource can be
checked and then acquired to prevent two LCD add-ons existing simultaneously:
% InputPins is user input and contains the pins that connect the LCD and the arduino
function obj = LCDAddon(parentObj,varargin)
if(nargin ~= 7)
matlabshared.hwsdk.internal.localizedError('MATLAB:narginchk:notEnoughInputs');
end

try
p = inputParser;
addParameter(p, 'RegisterSelectPin',[]);
addParameter(p, 'EnablePin', []);
addParameter(p, 'DataPins', []);
parse(p, varargin{1:end});
catch e
throwAsCaller(e);
end
obj.Parent = parentObj;
obj.RegisterSelectPin = p.Results.RegisterSelectPin;
obj.EnablePin = p.Results.EnablePin;
obj.DataPins = p.Results.DataPins;
inputPins = [cellstr(obj.RegisterSelectPin) cellstr(obj.EnablePin) obj.DataPins];
obj.Pins = inputPins;
count = getResourceCount(obj.Parent,obj.ResourceOwner);
% Since this example allows implementation of only 1 LCD
% shield, error out if resource count is more than 0
if count > 0
error('You can only have 1 LCD shield');
end
incrementResourceCount(obj.Parent,obj.ResourceOwner);
createLCD(obj,inputPins);
end

Destructor
By default, you do not need to write a destructor for your add-on. The destructor from the
matlabshared.addon.LibraryBase class is called implicitly. Add-ons that use hardware resources
from the parent Arduino object or allocate memory in the C++ header must call an add-on destructor
to release these resources.

Warning Not releasing resources in the destructor can cause memory leaks and failure during the
creation of a new instance of your add-on.

A destructor for your add-on class must:

• Override the delete method of the matlabshared.addon.LibraryBase class.


• Execute a command in your C++ commandHandler on page 6-8 method to deallocate any memory
resources used by your library.
• Not throw an error or exception. To prevent errors or exceptions being thrown during the
destructor, wrap the contents in a try-catch statement.

The destructor in the “Create LCD Add-on” on page 6-21 example shows how resource can be
checked and released safely:

6-14
Create and Configure MATLAB Add-On Class

methods(Access = protected)
function delete(obj)
try
parentObj = obj.Parent;
% Clear the pins that have been configured to the LCD shield
inputPins = [cellstr(obj.RegisterSelectPin) cellstr(obj.EnablePin) obj.DataPins];
for iLoop = inputPins
configurePinResource(parentObj,iLoop{:},obj.ResourceOwner,'Unset');
end
% Decrement the resource count for the LCD
decrementResourceCount(parentObj, obj.ResourceOwner);
cmdID = obj.LCD_DELETE;
inputs = [];
sendCommand(obj, obj.LibraryName, cmdID, inputs);
catch
% Do not throw errors on destroy.
% This may result from an incomplete construction.
end
end
end

Resource Ownership
Your add–on can optionally specify certain hardware resources that are unique and cannot be shared.
The“Create LCD Add-on” on page 6-21 can only have a single instance since only one LCD shield
can be attached to the Arduino device at a time.

Note Explicitly defining hardware resource ownership of your add-on prevents resource acquisition
and usage conflicts during runtime.

You can specify the resource ownership through the following set of properties in your add-on class:

properties(Access = private)
ResourceOwner = 'ExampleLCD/LCDAddon';
end

See Also
“Create Add-On Package Folder” on page 6-5 | “Create and Configure C++ Header File” on page 6-6

6-15
6 Custom Arduino Libraries

Create HelloWorld Add-On


In this section...
“Create Folder Structure” on page 6-16
“Create C++ Code” on page 6-17
“Create MATLAB Wrapper” on page 6-18
“Register Add-On” on page 6-19
“Run MATLAB Code” on page 6-20

This example shows how to send a string from an Arduino Uno board to the MATLAB command line
and create all the necessary files in your custom library using MATLAB and C++.

In this section...
“Create Folder Structure” on page 6-16
“Create C++ Code” on page 6-17
“Create MATLAB Wrapper” on page 6-18
“Register Add-On” on page 6-19
“Run MATLAB Code” on page 6-20

Create Folder Structure

Create a folder package to contain all the files for your custom library, and add it to the MATLAB
path. To access all the library files for this example click on 'Open Example' and download the
'CreateFolderStructureExample/SDKExampleHelloWorld' folder attached with this example.

For this example:

1. Add a folder named +arduinoioaddons in your working folder.

2. In +arduinoioaddons, add a +ExampleAddon subfolder to contain your MATLAB class file. For
example C:\Work.

3. In the +ExampleAddon subfolder, add a src folder to contain your C++ header files.

6-16
Create HelloWorld Add-On

Create C++ Code

For this example, create a C++ header file named HelloWorld.h, and save it in the
+arduinoioaddons/+ExampleAddon/srcfolder. This file wraps methods to expose to the Arduino
library.

You can access the library files from 'CreateFolderStructureExample/SDKExampleHelloWorld' folder


downloaded in “Create Folder Structure” on page 6-16.
1 Include header files, including LibraryBase.h and any other third-party header file that the
add-on library depends on.
#include "LibraryBase.h"
2 Create an add-on class that inherits from the LibraryBase class, which defines all the
necessary interfaces.
3 In the constructor, define the library name, and register the library to the server.
class HelloWorld : public LibraryBase
{
public:
HelloWorld(MWArduinoClass& a)
{
libName = "ExampleAddon/HelloWorld";
a.registerLibrary(this);
}

The custom class and library names must have this format:
shield(vendor)/device(library)
4 Determine the command calls to issue from MATLAB.
5 Override the command handler, and create a switch case for each command that the add-on
executes on the Arduino device:
public:
void commandHandler(byte cmdID, byte* inputs, unsigned int payload_size)
{
switch (cmdID){
case 0x01:{
byte val [13] = "Hello World";
sendResponseMsg(cmdID, val, 13);
break;

6-17
6 Custom Arduino Libraries

}
default:{
// Do nothing
}
}
}
};

The command IDs must match up with the operations that you add to the MATLAB add-on library.
For more information, see “Command Handler” on page 6-3.
6 (Optional) Use debugPrint to pass additional messages from the Arduino device to the MATLAB
command line.

Create MATLAB Wrapper


The MATLAB add-on wrapper class that defines your library must inherit from
matlabshared.addon.LibraryBase. The matlabshared.addon.LibraryBase class defines
several constant properties that you must override in your MATLAB class. The class also contains
internal utility functions that enable you to send and retrieve data from the server running on the
Arduino board.

You can access the library files from 'CreateFolderStructureExample/SDKExampleHelloWorld' folder


downloaded in “Create Folder Structure” on page 6-16.

1 Create a MATLAB class, and define the command ID for each command that is sent to the server
on the board.

classdef HelloWorld < matlabshared.addon.LibraryBase


properties(Access = private, Constant = true)
READ_COMMAND = hex2dec('01')
end
...
end
2 Override constant properties in the class to specify the location of source header files.

classdef HelloWorld < matlabshared.addon.LibraryBase


...
properties(Access = protected, Constant = true)
LibraryName = 'ExampleAddon/HelloWorld'
DependentLibraries = {}
LibraryHeaderFiles = {}
CppHeaderFile = fullfile(arduinoio.FilePath(mfilename('fullpath')), 'src', 'HelloWorl
CppClassName = 'HelloWorld'
end
...
end

Define the class constructor, set the methods to call the class constructor, and set the parent
property.

classdef HelloWorld < matlabshared.addon.LibraryBase


...
methods
function obj = HelloWorld(parentObj)

6-18
Create HelloWorld Add-On

obj.Parent = parentObj;

end
...
end
end

Always assign the first input argument to obj.Parent.

The support package auto-detects the class only if you have redefined all the properties. If you do
not need a value, leave the field empty.
3 Define the method to read the data back.

classdef HelloWorld < matlabshared.addon.LibraryBase


...
methods
...
function out = read(obj)
cmdID = obj.READ_COMMAND;
inputs = [];
output = sendCommand(obj, obj.LibraryName, cmdID, inputs);
out = char(output');
end
end

end

For help on using MATLAB programming language, see “Classes”.

Register Add-On
To register your add-on library, add the working folder that contains +arduinoioaddons to the
MATLAB path:

You can access the library files from 'CreateFolderStructureExample/SDKExampleHelloWorld' folder


downloaded in “Create Folder Structure” on page 6-16.

addpath C:\Work

Once you add the folder to the path, you should see the files listed in the MATLAB Current Folder
browser.

Make sure the ExampleAddon/HelloWorld library is available.

6-19
6 Custom Arduino Libraries

listArduinoLibraries

listArduinoLibraries

ans =

'Adafruit/MotorShieldV2'
'I2C'
'SPI'
'Servo'
'ExampleAddon/HelloWorld'

Tip If you do not see your add-on library in the list, see “Custom Arduino Library Issues” on page 7-
25 for more information.

Run MATLAB Code


This example shows how to return data from the Arduino library commandHandler to the MATLAB
command line.

Create an arduino object and include the new library. Set ForceBuildOn to true to reprogram the
board.

arduinoObj = arduino('COM3', 'Uno', 'Libraries', 'ExampleAddon/HelloWorld', 'ForceBuildOn', true)

Arduino devices reuse cached code if the specified library matches a library name in the source code.
Reprogramming forces the device to newly download the header file, ensuring current and accurate
information.

Create an add-on object using the ExampleAddon library.

dev = addon(arduinoObj,'ExampleAddon/HelloWorld');

Execute the command on the server, and read the data back into MATLAB.

read (dev)

ans =

Hello World

6-20
Create LCD Add-on

Create LCD Add-on


This example shows how to create an LCD add-on library and display “Hello World!” on an LCD. For
more information on LCDs, see RGB Backlit LCDs.

In this section...
“Connect Arduino to LCD” on page 6-21
“Connect Arduino to LCD” on page 6-24
“Create C++ Header and Include Third-Party Source Files” on page 6-25
“Create MATLAB Add-On Wrapper” on page 6-29
“Register Custom Library and Run MATLAB Code” on page 6-32

Connect Arduino to LCD


This example shows you how to wire up an LCD display to your Arduino Uno board. You need:

• An Arduino Uno board


• 16x2 LCD similar to this device from Sparkfun.
• 10k potentiometer
• Breadboard
• Jumper cables

Connect the LCD as shown in the schematic:

6-21
6 Custom Arduino Libraries

Make sure that you wire your pins as follows:

LCD Pin Arduino Pin


1 (VSS) Ground
2 (VDD) 5V
3 (V0) Mid pin on potentiometer
4 (RS) D7
5 (R/W) Ground

6-22
Create LCD Add-on

6 (E) D6
11 (DB4) D5 (PWM)
12 (DB5) D4
13 (DB6) D3 (PWM)
14 (DB7) D2
15 (LED+) 5V
16 (LED-) Ground

When done, your setup looks similar to this:

6-23
6 Custom Arduino Libraries

Connect Arduino to LCD

You can connect an LCD display to your Arduino® Uno board.

Required Hardware

• An Arduino Uno board

6-24
Create LCD Add-on

• 16x2 LCD similar to this device from Sparkfun.

• 10k potentiometer

• Breadboard

• Jumper cables

To access all the library files for this example click on 'Open Example' and download the
'ConnectArduinoToLCDExample/SDKExampleLCD' folder attached with this example.

Connect the LCD as shown in the schematic:

Create C++ Header and Include Third-Party Source Files


For this example, create a header file named LCDAddon.h and save it in the +arduinoioaddons/
+ExampleLCD/src folder. This file wraps all the methods in the library.

You can access the library files from 'CreateFolderStructureLCDExample/SDKExampleLCD' folder


downloaded in “Connect Arduino to LCD” on page 6-24.

Include LibraryBase.h and the third-party header fileLiquidCrystal.h.

6-25
6 Custom Arduino Libraries

#include "LibraryBase.h"
#include "LiquidCrystal.h"

Declare debug strings using const char. Use PROGMEM to store the debug strings to the device flash
memory, to save SRAM.

const char MSG_pLCD_CREATE_LCD_SHIELD[] PROGMEM = "Arduino::pLCD = new LiquidCrystal(%d, %d


const char MSG_pLCD_INITIALIZE_LCD_SHIELD[] PROGMEM = "Arduino::pLCD->begin(%d, %d);\n";
const char MSG_pLCD_CLEAR_LCD_SHIELD[] PROGMEM = "Arduino::pLCD->clear();\n";
const char MSG_pLCD_PRINT[] PROGMEM = "Arduino::pLCD->print(%s);\n";
const char MSG_SET_CURSOR_LCD_SHIELD[] PROGMEM = "Arduino::pLCD->setCursor(%d, %d);\n";
const char MSG_pLCD_DELETE_LCD_SHIELD[] PROGMEM = "Arduino::delete pLCD;\n";

Define command IDs to match those defined in your MATLAB class.

#define LCD_CREATE 0x00


#define LCD_INITIALIZE 0x01
#define LCD_CLEAR 0x02
#define LCD_PRINT 0x03
#define LCD_DELETE 0x04

byte cursorRow = 0;

Create the constructor that defines the library name. Declare the debug strings and register the
library to the server.

class LCD : public LibraryBase


{
public:
LiquidCrystal *pLCD;
public:
LCD(MWArduinoClass& a)
{
libName = "ExampleShield/LCD";
a.registerLibrary(this);
}

Override the setup method to reset the cursor to the first row upon initialization.

void setup()
{
cursorRow = 0;
}

Override commandHandler, and map each command to its corresponding methods. For this example,
map the commands:

Case Command Description


0x00 LCD_CREATE Define pins used by the LCD
0x01 LCD_INITIALIZE Set up columns and rows
0x02 LCD_CLEAR Clear the LCD screen
0x03 LCD_PRINT Print the message on the LCD
0x04 LCD_DELETE Delete the LCD object

6-26
Create LCD Add-on

Create an LCD object. Initialize the LCD and assign rows and columns of the inputs. Use
debugPrint to print trace messages to the MATLAB command line to help you debug code running
on the Arduino device.

To understand more about command handlers see “Command Handler” on page 6-3.

public:
void commandHandler(byte cmdID, byte* dataIn, unsigned int payloadSize)
{
switch(cmdID)
{
case LCD_CREATE: //createLCD
{
byte* pinNumbers = new byte [6];
for (byte i=0; i<6; i=i+1)
{
pinNumbers[i] = dataIn[i];
}
createLCDObject(pinNumbers[0],pinNumbers[1],pinNumbers[2],pinNumbers[3],pinNumber
sendResponseMsg(cmdID, 0, 0);
break;
}
case LCD_INITIALIZE: //initializeLCD
{
unsigned int rows = dataIn[0];
unsigned int cols = dataIn[1];
initializeLCD(rows,cols);
clearLCD();
sendResponseMsg(cmdID, 0, 0);
break;
}

Clear the LCD screen.

case LCD_CLEAR: //clearLCD


{
clearLCD();
cursorRow = 0;
setCursor(0, cursorRow);
sendResponseMsg(cmdID, 0, 0);
break;
}

Create a command that takes an input and prints it on the LCD screen.

case LCD_PRINT: //printLCD


{
byte* val = {dataIn};
// last byte is the number of rows initialized
// last 2nd byte is the number of columns initialized
char message[payloadSize-1];
for(byte k=0; k<(payloadSize-2); k=k+1)
{
message[k]=val[k];
}
message[payloadSize-2] = '\0';

byte cols = val[payloadSize-2];

6-27
6 Custom Arduino Libraries

byte rows = val[payloadSize-1];

if(cursorRow+1 > rows){


cursorRow = 0;
clearLCD();
}
setCursor(0,cursorRow);
printLCD(message);
cursorRow++;

sendResponseMsg(cmdID, 0, 0);
break;
}

Delete the LCD object.

case LCD_DELETE: //delete


{
deleteLCDobject();
//reset the cursor position to the first row on deletion
cursorRow = 0;
sendResponseMsg(cmdID, 0, 0);
break;
}
default:
{
// Do nothing
break;
}

Wrap the LiquidCrystal methods to add debug messages.

public:
void createLCDObject(unsigned int rs,unsigned int enable,unsigned int d0,unsigned int d1,unsi
{
pLCD = new LiquidCrystal(rs, enable, d0, d1, d2, d3);
debugPrint(MSG_pLCD_CREATE_LCD_SHIELD,rs,enable,d0,d1,d2,d3);
}
void initializeLCD(unsigned int cols,unsigned int rows)
{
pLCD->begin(cols, rows);
debugPrint(MSG_pLCD_INITIALIZE_LCD_SHIELD, cols, rows);
}
void clearLCD()
{
pLCD->clear();
debugPrint(MSG_pLCD_CLEAR_LCD_SHIELD);
}
void printLCD(char message[])
{
pLCD->print(message);
debugPrint(MSG_pLCD_PRINT, message);
}
void setCursor(byte column, byte row)
{
pLCD->setCursor(column, row);
debugPrint(MSG_SET_CURSOR_LCD_SHIELD,column,row);
}

6-28
Create LCD Add-on

void deleteLCDobject()
{
delete pLCD;
debugPrint(MSG_pLCD_DELETE_LCD_SHIELD);
}
};

Create MATLAB Add-On Wrapper


This example shows how to create LCDAddon.m MATLAB wrapper class file and save it in the
C:\Work\+arduinoioaddons\+ExampleLCD folder.

You can access the library files from 'CreateFolderStructureLCDExample/SDKExampleLCD' folder


downloaded in “Connect Arduino to LCD” on page 6-24.

Create MATLAB class, LCDAddon, that inherits from matlabshared.addon.LibraryBase.

classdef LCDAddon < matlabshared.addon.LibraryBase

Define custom command IDs for all public methods of the LCD class sent to the server on the board.

properties(Access = private, Constant = true)


LCD_CREATE = hex2dec('00')
LCD_INITIALIZE = hex2dec('01')
LCD_CLEAR = hex2dec('02')
LCD_PRINT = hex2dec('03')
LCD_DELETE = hex2dec('04')
end

Override constant properties in the class to include necessary header and third-party source files.

properties(Access = protected, Constant = true)


LibraryName = 'ExampleLCD/LCDAddon'
DependentLibraries = {}
LibraryHeaderFiles = 'LiquidCrystal/LiquidCrystal.h'
CppHeaderFile = fullfile(arduinoio.FilePath(mfilename('fullpath')), 'src', 'LCDAddon.h')
CppClassName = 'LCD'
end

properties(Access = private)
ResourceOwner = 'ExampleLCD/LCDAddon';
Rows
Columns
end

• DependentLibraries must contain all other libraries you need to use your custom library.
• LibraryHeaderFiles must be a string, starting with the library name, followed by a slash (/),
and then header file name. If you need multiple header files, specify a cell array of strings.
• CppHeaderFile must be the LCDAddon.h with the full path. Replace LCDAddon.h with your
custom file name after you create it, and save it to the src folder in the ExampleLCD folder.
• CppClassName must be the exact class name defined in LCDAddon.h.

Specify command IDs supported by the add-on for each method you create. Specify the pins that
connect to the LCD, and define an error if the resource count is more than 0. In this example, you can
add only one LCD, and therefore it is imperative that you manage your pin resource count.

6-29
6 Custom Arduino Libraries

methods(Hidden, Access = public)


% InputPins is user input and contains the pins that connect the LCD Data Pins and the ardui
function obj = LCDAddon(parentObj,varargin)
if(nargin < 7)
matlabshared.hwsdk.internal.localizedError('MATLAB:narginchk:notEnoughInputs');
elseif nargin > 7
matlabshared.hwsdk.internal.localizedError('MATLAB:narginchk:tooManyInputs');
end

try
p = inputParser;
addParameter(p, 'RegisterSelectPin',[]);
addParameter(p, 'EnablePin', []);
addParameter(p, 'DataPins', []);
parse(p, varargin{1:end});
catch e
throwAsCaller(e);
end
obj.Parent = parentObj;
obj.RegisterSelectPin = p.Results.RegisterSelectPin;
obj.EnablePin = p.Results.EnablePin;
obj.DataPins = p.Results.DataPins;
inputPins = [cellstr(obj.RegisterSelectPin) cellstr(obj.EnablePin) obj.DataPins];
obj.Pins = inputPins;
count = getResourceCount(obj.Parent,obj.ResourceOwner);
% Since this example allows implementation of only 1 LCD
% shield, error out if resource count is more than 0
if count > 0
error('You can only have 1 LCD shield');
end
incrementResourceCount(obj.Parent,obj.ResourceOwner);
createLCD(obj,inputPins);
end

Devices such as the Arduino Uno have a limited number of pins and require you to manage the
resource allocation. Therefore, you are limited to creating only one LCD object at a time. For more
information, see getResourceOwner.

Write a createLCD method to perform the following functions:

• Reserve the pins on the Arduino connected to the LCD and used by the library. Reserving prevents
other functions from using these pins, giving your library exclusive use of the pins.
• Send commands, including pin data, to the server using sendCommand.

function createLCD(obj,inputPins)
try
cmdID = obj.LCD_CREATE;

for iLoop = inputPins


configurePinResource(obj.Parent,iLoop{:},obj.ResourceOwner,'Reserved');
end

terminals = getTerminalsFromPins(obj.Parent,inputPins);
sendCommand(obj, obj.LibraryName, cmdID, terminals);
catch e
throwAsCaller(e);
end

6-30
Create LCD Add-on

end
end

Overload destructor delete method for LCD class to free up the reserved pins and decrement LCD
resource count.

methods(Access = protected)
function delete(obj)
try
parentObj = obj.Parent;
% Clear the pins that have been configured to the LCD shield
inputPins = [cellstr(obj.RegisterSelectPin) cellstr(obj.EnablePin) obj.DataPins];
for iLoop = inputPins
configurePinResource(parentObj,iLoop{:},obj.ResourceOwner,'Unset');
end
% Decrement the resource count for the LCD
decrementResourceCount(parentObj, obj.ResourceOwner);
cmdID = obj.LCD_DELETE;
inputs = [];
sendCommand(obj, obj.LibraryName, cmdID, inputs);
catch
% Do not throw errors on destroy.
% This may result from an incomplete construction.
end
end
end

Note Do not throw errors when you destroy the object.

Initialize the LCD with specific number of columns and rows, and clear the LCD screen.

methods(Access = public)
function initializeLCD(obj,varargin)
p = inputParser;
p.PartialMatching = true;

addParameter(p, 'Rows', 2);


addParameter(p, 'Columns', 16);
parse(p, varargin{:});
output = p.Results;

obj.Rows = output.Rows;
obj.Columns = output.Columns;
inputs = [output.Columns output.Rows];

cmdID = obj.LCD_INITIALIZE;
sendCommand(obj, obj.LibraryName, cmdID, inputs);
end

Clear the LCD.

function clearLCD(obj)
cmdID = obj.LCD_CLEAR;
inputs = [];
sendCommand(obj, obj.LibraryName, cmdID, inputs);
end

6-31
6 Custom Arduino Libraries

Print the message on the LCD. This example uses a 16x2 LCD screen and cannot print more than 16
characters.

function printLCD(obj,message)
cmdID = obj.LCD_PRINT;

if numel(message) > 16
error('Cannot print more than 16 characters')
end

inputs = [double(message) obj.Columns obj.Rows];


sendCommand(obj, obj.LibraryName, cmdID, inputs);
end
end
end

Register Custom Library and Run MATLAB Code


Use the header files you have created to register the custom library and run the example.

You can access the library files from 'CreateFolderStructureLCDExample/SDKExampleLCD' folder


downloaded in “Connect Arduino to LCD” on page 6-24.

Add the location of the working folder that contains +arduinoioaddons to the MATLAB path. For
example:

addpath ('C:\Work');

Make sure the ExampleLCD/LCDAddon library is available.

listArduinoLibraries

ans =

'Adafruit/MotorShieldV2'
'ExampleLCD/LCDAddon'
'I2C'
'SPI'
'Servo'

Tip If you do not see your add-on library in the list, see “Custom Arduino Library Issues” on page 7-
25 for more information.

6-32
Create LCD Add-on

Create an arduino object specifying the ExampleLCD/LCDAddon library. Set ForceBuildOn to


true to reprogram the board.

a = arduino('com5','uno','libraries','ExampleLCD/LCDAddon','ForceBuildOn',true);

a =

arduino with properties:

Port: 'COM5'
Board: 'Uno'
AvailablePins: {'D2-D13', 'A0-A5'}
AvailableDigitalPins: {'D2-D13', 'A0-A5'}
AvailablePWMPins: {'D3', 'D5-D6', 'D9-D11'}
AvailableAnalogPins: {'A0-A5'}
AvailableI2CBusIDs: [0]
Libraries: {'ExampleLCD/LCDAddon'}

Create the LCD object, and specify the pins you configured on the Arduino device.

lcd = addon(a,'ExampleLCD/LCDAddon','RegisterSelectPin','D7','EnablePin','D6','DataPins',{'D5','D

Initialize the LCD.

initializeLCD(lcd);

Print a string to the LCD.

printLCD(lcd,'Hello World!');

If you do not see a display on your LCD, try turning the knob on your potentiometer to adjust the
contrast.

Clear the LCD.

clearLCD(lcd);

6-33
6 Custom Arduino Libraries

Add-On Resources
In this section...
“Counted” on page 6-34
“Shared” on page 6-34

An Arduino add-on library resource can exist only as a limited or single instance. Resources can be
pins, properties, or add-on instances themselves. By specifying and acquiring resources in your add-
on library, you protect the resource from being acquired or altered by another add-on. For example, a
pin set by add-on library to act as an analog input must not be allowed to be changed to a digital
output by another add-on library. Two types of resources exist for an add-on library: “Counted” on
page 6-34 and “Shared” on page 6-34

Counted
A counted resource is limited to certain number of instances due to pin usages or application
constraints. The incrementResourceCount and decrementResourceCount enable you to
increment and decrement the number or instances of the resource. When a counted resource
increments, the next available resource is always taken in order. Similarly, when decremented, the
last acquired resource is released.

For example, an LCD shield can be a counted resource since only one LCD shield can exist in
MATLAB at the same time.

Shared
A shared resource is used by multiple objects of the same class. In a shared resource, when any
object modifies a property of that resource, the change is applied to all other objects that use the
resource. To modify a shared resource, use the getSharedResourceProperty and
setSharedResourceProperty functions.

For example, all instances of an add-on library class using a shared communication resource must set
the properties of the bus to be the same. Once the first add-on library instance acquires the resource,
any later instance must query and set the bus property to the same value as the first instance.

See Also
incrementResourceCount | decrementResourceCount | getSharedResourceProperty |
setSharedResourceProperty

More About
• “Custom Add-On Library Concepts” on page 6-3
• “Physical Terminals and Pin Numbers” on page 6-35

6-34
Physical Terminals and Pin Numbers

Physical Terminals and Pin Numbers


Arduino boards have physical terminals that can correspond to pin numbers that may not be same as
terminal numbers. Here is a terminal-pin mapping of an Arduino Uno Rev3.

See Also
getTerminalsFromPins | getPinsFromTerminals | validatePin | isTerminalDigital |
isTerminalAnalog | getPinAlias | getTerminalMode

More About
• “Custom Add-On Library Concepts” on page 6-3
• “Add-On Resources” on page 6-34

6-35
6 Custom Arduino Libraries

Register Add-On Library


To register your custom MATLAB Arduino add-on library, add the working folder that contains the
Arduino add-on library to the MATLAB path. For “Create LCD Add-on” on page 6-21 example, add the
+arduinoioaddons folder to the MATLAB path 'C:\Work'.

addpath ('C:\Work');

The files are now listed in the MATLAB Current Folder browser. Make sure that your Add-on library is
available. Use listArduinoLibraries to check if the add-on library is available. The available add-
on libraries in the “Create LCD Add-on” on page 6-21 example are as follows.

listArduinoLibraries

ans =

'Adafruit/MotorShieldV2'
'ExampleLCD/LCDAddon'
'I2C'
'SPI'
'Servo'

You can now write your MATLAB code by incorporating the new add-on library.

Create an arduino object, include the new add-on library, and set ForceBuildOn to true to
reprogram the board. Arduino devices reuse cached code if the specified library matches a library
name in the source code. Reprogramming forces the device to newly download the header file,
ensuring current and accurate information. For “Create LCD Add-on” on page 6-21 example, create
an arduino object by including the add-on library.

a = arduino('com5','uno','libraries','ExampleLCD/LCDAddon','ForceBuildOn',true);

a =

arduino with properties:

Port: 'COM5'
Board: 'Uno'
AvailablePins: {'D2-D13', 'A0-A5'}
AvailableDigitalPins: {'D2-D13', 'A0-A5'}
AvailablePWMPins: {'D3', 'D5-D6', 'D9-D11'}
AvailableAnalogPins: {'A0-A5'}
AvailableI2CBusIDs: [0]
Libraries: {'ExampleLCD/LCDAddon'}

6-36
Register Add-On Library

Create an add-on object by specifying the add-on library and other arguments based on your
requirements.

For “Create LCD Add-on” on page 6-21 example, create an LCD add-on object by specifying the add-
on library and the pins configured on the Arduino device.

lcd = addon(a,'ExampleLCD/LCDAddon','RegisterSelectPin','D7','EnablePin','D6','DataPins',{'D5','D

You can write the relevant commands based on your requirement and then run your MATLAB code.

See Also
listArduinoLibraries | arduino | addon

More About
• “Custom Add-On Library Concepts” on page 6-3
• “Create LCD Add-on” on page 6-21
• “Create HelloWorld Add-On” on page 6-16

6-37
7

Troubleshooting in MATLAB Support


Package for Arduino Hardware

• “Find Arduino Port on Windows, Mac, and Linux” on page 7-2


• “Find ESP32 Port on Windows, Mac, and Linux” on page 7-4
• “Arduino Bluetooth Setup Tips” on page 7-6
• “Arduino USB, Bluetooth, and Wi-Fi Connection Failure” on page 7-8
• “ESP32 Board Setup Tips” on page 7-12
• “Lost Connection and Data Issues” on page 7-13
• “Board Specific Issues” on page 7-15
• “Serial Device Issues” on page 7-21
• “Arduino Resource Conflicts” on page 7-22
• “Adafruit Motor Shields and Servo Issues” on page 7-23
• “Custom Arduino Library Issues” on page 7-25
• “Troubleshooting Sensors” on page 7-26
• “Limitations” on page 7-27
• “Connect Arduino to MATLAB over Bluetooth” on page 7-28
• “Connect Arduino to MATLAB over Wi-Fi” on page 7-29
• “Connect Arduino to MATLAB over USB” on page 7-30
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

Find Arduino Port on Windows, Mac, and Linux

In this section...
“Find Port Number on Windows” on page 7-2
“Find Port Number on Macintosh” on page 7-2
“Find Port Number on Linux” on page 7-2

Find Port Number on Windows


1 Open Device Manager, and expand the Ports (COM & LPT) list.
2 Note the number on the USB Serial Port.

Find Port Number on Macintosh


1 Open terminal and type: ls /dev/*.
2 Note the port number listed for /dev/tty.usbmodem* or /dev/tty.usbserial*. The port
number is represented with * here.

Find Port Number on Linux


1 Open terminal and type: ls /dev/tty*.

7-2
Find Arduino Port on Windows, Mac, and Linux

2 Note the port number listed for /dev/ttyUSB* or /dev/ttyACM*. The port number is
represented with * here.
3 Use the listed port as the serial port in MATLAB. For example: /dev/ttyUSB0.

7-3
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

Find ESP32 Port on Windows, Mac, and Linux


In this section...
“Find Port Number on Windows” on page 7-4
“Find Port Number on Macintosh” on page 7-4
“Find Port Number on Linux” on page 7-5

Find Port Number on Windows


1 Open Device Manager, and expand the Ports (COM & LPT) list.
2 Note the COM port number corresponding to Silicon Labs CP210x USB to UART Bridge.

Find Port Number on Macintosh


1 Open terminal and type: ls /dev/*.
2 Note the port number listed for /dev/tty.usbmodem* or /dev/tty.usbserial*. The port
number is represented with * here.

7-4
Find ESP32 Port on Windows, Mac, and Linux

Find Port Number on Linux


1 Open terminal and type: ls /dev/tty*.
2 Note the port number listed for /dev/ttyUSB* or /dev/ttyACM*. The port number is
represented with * here.
3 Use the listed port as the serial port in MATLAB. For example: /dev/ttyUSB0.

7-5
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

Arduino Bluetooth Setup Tips


Try these tips to troubleshoot issues that you face while configuring Arduino Bluetooth setup.

Note From R2020a release of MATLAB Support Package for Arduino Hardware, the support for
Adafruit Bluefruit EZ-Link shield for Bluetooth connectivity has been removed.

Failure to Program Arduino Board


Connect Arduino hardware to your computer using an USB cable. Make sure that you do not have
your Bluetooth device connected to Arduino hardware when you Program the board.

Configure a 5 V HC-05 or HC-06


When you configure your 5 V HC-05 or HC-06, use a 5 V FTDI adaptor and connect them, as shown:

Find FTDI Serial Port

Windows

On Windows, find the FTDI serial port listed as USB Serial Port under Ports (COM & LPT) in the
Device Manager, as shown:

Mac

On Mac, type ls /dev/cu.* in the Terminal to find the FTDI serial port, as shown:

7-6
Arduino Bluetooth Setup Tips

See Also

More About
• “Arduino USB, Bluetooth, and Wi-Fi Connection Failure” on page 7-8

7-7
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

Arduino USB, Bluetooth, and Wi-Fi Connection Failure

In this section...
“Arduino USB Connection Failure” on page 7-8
“Arduino Bluetooth Connection Failure” on page 7-10
“Arduino Wi-Fi Connection Failure” on page 7-10

Arduino USB Connection Failure


Arduino Object Creation Error

When you try to create an arduino object as shown here,

a = arduino()

you see the following error message,

Cannot detect Arduino hardware. Make sure original Arduino hardware is properly plugged in. Other

Steps to Resolve the Error


Specify Board Type and Port

If you see the error Cannot detect Arduino hardware. Make sure original Arduino
hardware is properly plugged in. Otherwise, please specify both port and
board type, specify the board and type as shown here,

a = arduino('COM4','Uno')

Specify Board Type and Port Correctly

If you see the error Cannot program board Uno (COM4). Please make sure the board is
supported and the port and board type are correct with both board type and port
specified:

1 Make sure that you specify the correct board type.


2 Make sure the board type is supported. See the full list.
3 Make sure you are using an FTDI converter to connect the board to computer, if you are using
the old ATmega328p board.
4 Make sure that you specify the correct port. See the “Find Arduino Port on Windows, Mac, and
Linux” on page 7-2 for more information.
5 Open Arduino IDE (any version supports the board). Make sure you can program the same board
under the same port successfully.

If you are using official Arduino boards such as Uno, Mega, Due, Micro and Leonardo, MATLAB can
autodetect the port connected to the hardware on Windows. However, some Arduino devices are not
automatically recognized, especially those that require external FTDI adaptors. In those cases,
specify both the port and board type to create a connection.

7-8
Arduino USB, Bluetooth, and Wi-Fi Connection Failure

Remove Bluetooth Device

If you want the Arduino hardware to communicate with the host computer via a USB cable, remove
any Bluetooth devices connected to your Arduino hardware, and then call the arduino function with
appropriate parameters to create your Arduino object.
Install Device Driver

If you cannot connect to official Arduino hardware, you may be missing the device driver.
Manual Disconnect

If you manually disconnect the board before clearing the arduino object from the MATLAB
workspace, MATLAB will not recognize the Arduino serial port if you reconnect. Restart MATLAB,
and try reconnecting the board.
Turn On the Trace Log

If you have checked for “Manual Disconnect” on page 7-9 and the issue still persists, turn on the
trace log by executing the following command in MATLAB.

a = arduino('COM4','Uno','Trace',true);

The trace log gives a much more detailed output of the compilation and upload results. There are
some common possible causes of the error. Depending on what you see in your trace log, try the one
that applies.

• If you see either of these errors in the log, try the appropriate action for your release. For R2015a
update the support package to the latest version, or uninstall WINAVR. For R2014a and R2014b,
follow these workarounds.

• C:/MATLAB/SupportPackages/R2015a/arduino-1.5.6-r2/hardware/arduino/sam/cores/arduino/WInter
C:/MATLAB/SupportPackages/R2015a/arduino-1.5.6-r2/hardware/arduino/sam/cores/arduino/Arduin
fatal error: avr/pgmspace.h: No such file or directory
compilation terminated.
cs-make: *** [C:/Users/maciej/AppData/Local/Temp/ArduinoServer/WInterrupts.c.o] Error 1
• C:/MATLAB/SupportPackages/R2014b/arduino-1.5.6-r2/hardware/arduino/avr/cores/arduino/WInter
C:/Users/ecsadmin/AppData/Local/Temp/ArduinoServer/WInterrupts.c.o
In file included from C:/MATLAB/SupportPackages/R2014b/arduino-1.5.6-r2/hardware/arduino/av
from C:/MATLAB/SupportPackages/R2014b/arduino-1.5.6-r2/hardware/arduino/avr/cores/arduino/W
C:/MATLAB/SupportPackages/R2014b/arduino-1.5.6-r2/hardware/arduino/avr/cores/arduino/Arduin
No such file or directory
make: *** [C:/Users/ecsadmin/AppData/Local/Temp/ArduinoServer/WInterrupts.c.o] Error 1"
• If you see the following error in the log, reinstall the support package. If error still exists, report
the bug to MathWorks® technical support.

In file included from C:/Users/Tom/AppData/Local/Temp/ArduinoServer/Dynamic.cpp:1,


from C:/MATLAB/SupportPackages/R2015a/arduinoio/toolbox/matlab/hardware/supportpackages/arduin
C:/MATLAB/SupportPackages/R2015a/arduinoio/toolbox/matlab/hardware/supportpackages/arduinoio/+
error: Adafruit_PWMServoDriver.h: No such file or directory
make: *** [C:/Users/Tom/AppData/Local/Temp/ArduinoServer/MWArduino.cpp.o] Error 1
• If you see the following error in the log, remove or rename the user-installed Firmata folder that is
conflicting with the shipping Firmata library the support package downloads,

In file included from


C:\Users\Max\Documents\Arduino\libraries\Firmata\utility\SerialFirmata.cpp:20:0:
C:\Users\Max\Documents\Arduino\libraries\Firmata\utility\SerialFirmata.h:30:28: fatal error:

7-9
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

SoftwareSerial.h: No such file or directory


#include<SoftwareSerial.h>

compliation terminated.

Look for the location of the Firmata folder to change in the error log. For example, this error
above indicates that the Firmata folder to change is "C:\Users\Max\Documents\Arduino
\libraries\Firmata". Remove or rename this Firmata folder. Then call arduino in MATLAB
again.

If you still have the same issues, after trying these steps, contact MathWorks Technical Support.

Arduino Bluetooth Connection Failure


Test Connection Fails

If the Test connection fails while you are setting up Arduino hardware to use Bluetooth connection
in the arduinosetup interface, try the following steps:

• To ensure that testing connection did not fail intermittently, try to click the Test connection
again.
• If Test connection fails consistently, check that the Bluetooth device appears on the host
computer and that it is paired correctly. If not, follow the instructions on “Pair a Bluetooth Device
and Retrieve the Bluetooth Device Address” on page 1-27 to pair your device.
• If you are using HC-05 or HC-06, use the bluetoothlist in the MATLAB Command Window, and
check that the Bluetooth device address appears on the RemoteIDs properties of the object.
• For information on troubleshooting, Bluetooth 4.0 for the boards: Nano 33 BLE, Nano 33 BLE
Sense, Nano 33 IoT, MKR1010, ESP32-DevKitV1, and ESP32-DevKitC see “Troubleshooting
Bluetooth Low Energy”.

Arduino Wi-Fi Connection Failure


If you have configured your Arduino Wi-Fi connection using arduinosetup interface, and if Test
connection fails, try the following steps:

• Select the Retrieve last configuration from Arduino board in the arduinosetup
interface, and obtain configuration information from the board.

• If you are unable to retrieve the IP address from the board, check whether your Wi-Fi network
is up and running. Restart and reconfigure the connection using the arduinosetup user
interface in MATLAB Command Window. Check that the Wi-Fi connection settings that you
specify in the arduinosetup are accurate.
• Ping the IP address and check whether the address is reachable. To ping the IP address, open a
shell window on Windows or a terminal on Linux/Mac and type, ping followed by the IP address of
the device.

• If the ping test fails, check whether your Wi-Fi network is up and running. Restart and
reconfigure the connection using arduinosetup in the MATLAB Command Window. Check
that the Wi-Fi connection settings that you specify in arduinosetup are accurate.
• If you are using static IP address and if the ping test fails, make sure that the specified IP
address is available and your network settings allow communication with that IP address.

7-10
Arduino USB, Bluetooth, and Wi-Fi Connection Failure

If you are still experiencing Arduino hardware connection issues, contact MathWorks Technical
Support.

See Also

More About
• “Arduino Bluetooth Setup Tips” on page 7-6
• “Lost Connection and Data Issues” on page 7-13

7-11
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

ESP32 Board Setup Tips


In this section...
“ESP32 Hardware Detection” on page 7-12
“ESP32 Hardware Configuration” on page 7-12

ESP32 Hardware Detection


During the Hardware Setup workflow on Windows, if the ESP32 board is not detected or if a warning
sign appears against the CP2102 USB to UART Bridge Controller device in Device Manager,
try these steps:

1 Download the CP210x Universal Windows Driver from Silicon Labs CP210x USB to UART
Bridge VCP Drivers.
2 Extract the contents of the zipped folder that you downloaded.
3 Go to Device Manager, double click the CP2102 USB to UART Bridge Controller device,
and click Update Driver.
4 Browse for the folder in which you extracted the CP210x driver, and complete the update of the
driver.
5 Launch the arduinosetup interface again, reconnect the ESP32 board to USB port, and
proceed with the setup.

ESP32 Hardware Configuration


If you are facing issues while configuring your ESP32 board connection using arduinosetup
interface, try the following steps:

• Ensure that your computer is connected to the internet to download the necessary third-party files
required for the ESP32 setup.
• Ensure that you have write permissions to the Arduino IDE root folder
(arduinoio.getIDERoot).

If you are still experiencing Arduino hardware connection issues, contact MathWorks Technical
Support.

See Also

More About
• “Lost Connection and Data Issues” on page 7-13

7-12
Lost Connection and Data Issues

Lost Connection and Data Issues


In this section...
“Lost Connection with Arduino Hardware” on page 7-13
“Data Issues” on page 7-14

Lost Connection with Arduino Hardware


Unplugged Hardware

The most common cause of a lost connection is an unplugged cable. Check the cable and make sure
that it is firmly plugged in.

Board with Low Data Memory

If your Arduino board has low data memory, you may lose connection while working with large data
sets. If this occurs, remove all libraries that you are not using from the board to free up some space.
For example, create an arduino object with no libraries.
a = arduino('COM3','Uno','Libraries','');

Too Many Device Objects

If you have created too many add-on objects for your Arduino hardware, those objects may use up
memory on the board and cause a lost connection. Clear all objects and reconnect. Make sure that
you use fewer peripheral devices.

Communication Loss When Writing to I2C Device

Make sure that the power line is always connected. With I2C devices, the server code can stop
working if the power line is disconnected.

Connection Lost When Using Timer

You can lose connection to your Arduino board when you use it with a timer. The callback timer on
your system runs between lines of MATLAB code. This can cause the timer to issue a call to the
device at the same time you issue a read, write, or configuration change on the Arduino board, or
click a button in the interface. The operation throws an error with a re-entrancy exception. For
example, consider a timer function that polls Arduino pins.
t = timer('Name','PinSniffer','BusyMode','Drop','ExecutionMode','fixedSpacing','Period',1,'TimerF
function tester(src,event,a)
try
value = 1:10;
for iloop = 2:13
if strcmpi(configurePin(a,iloop),'D3')
value(iloop-1) = readDigitalPin(a,iloop);
end
end
catch e
stop(src);
rethrow(e);
end

7-13
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

In this situation, you issue a command to configure pins on your Arduino board and read the value.

configurePin(a,'A0','DigitalOuput');
value = readDigitalPin(a,'A0');

If your read command and the poll run simultaneously, the timer can interrupt your calls before it has
completed. This results in a re-entrancy exception.

To work around this situation, stop the timer before you manually issue a command.

stop(t);
configurePin(a,'A0','DigitalOuput');
value = readDigitalPin(a,'A0');
start(t);

Connection Lost when Using Encoders

You can lose connection between the Arduino board and MATLAB, when the encoder shaft is rotating
fast or the A/B signal rate of the encoder crosses the threshold of 17–18 kHz. When one of these
situations happens, the interrupts used by A/B channels completely block the serial communication
on the Arduino board which also relies on interrupts. Therefore, it can stop the Arduino board from
sending a response back to MATLAB, and you see the following error message:

Host and client connection is lost. Make sure the board is plugged in, and recreate arduino and r

However, once the shaft stops rotating or rotates slower, the serial communication works as usual.

Data Issues
Pin Not Receiving Data

Make sure devices that have floating or high impedance pins have proper pull-up or pull-down
resistors. Use configurePin to set the mode to pull-up internally.

Pin Not Receiving Proper Signal

Make sure that your pins are properly configured. For example, a pull-up or a pull-down resistor is
being used for reading data. Use configurePin to set the mode to pull-up internally.

Strange Data

If your Arduino hardware has low data memory, you may see strange data. If this occurs, delete all
libraries that you are not using from the board to free some space. To delete libraries, create an
arduino object with no libraries.

a = arduino('COM3','Uno','Libraries','');

Incorrect Input or Output

You can get incorrect readings if you are using the wrong pin. For example, if you are writing to a pin
configured as input or reading from a pin configured as a pull-up.

7-14
Board Specific Issues

Board Specific Issues

In this section...
“Arduino ATmega328p Boards Does Not Work on Mac 10.9” on page 7-15
“Arduino Due” on page 7-15
“Arduino Leonardo and Micro” on page 7-16
“Arduino Nano 33 IoT” on page 7-16
“Arduino Nano 33 BLE and Nano 33 BLE Sense” on page 7-17
“Arduino MKR CAN Shield” on page 7-17
“Arduino Uno and Mega” on page 7-17
“Arduino MKR1000 or MKR1010” on page 7-17
“Boards Not Listed in Interactive Hardware Setup” on page 7-19
“Arduino to FTDI Adaptor Connection” on page 7-19

Arduino ATmega328p Boards Does Not Work on Mac 10.9


On systems running on Mac 10.9, the built-in FTDI driver can be problematic. To fix the problem:

1 Type these commands into the terminal:

cd /System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns
sudo mv AppleUSBFTDI.kext AppleUSBFTDI.disabledjobdsavjlo'pfbvdajpo'
sudo touch /System/Library/Extensions
2 Restart your computer.
3 Install the original FTDI Virtual Com Port drivers.

Arduino Due
SPI Pins on Arduino Due Not Functioning Correctly

To use SPI pins on an Arduino Due board, configure the board as follows:

• Use SPI header, not the ICSP header on the Due.


• Wire the CS pin to one of three pins on the Due, [4, 10, 52].
• When using an EEPROM, add decoupling capacitor, 1 uF, between Vcc and Gnd as close to SPI
EEPROM as possible.
• When using an EEPROM, connect /WP to Vcc through a 22K pull-up resistor.
• When using an EEPROM, wire Vcc to /HOLD.

Read/Write to Servo on Arduino Due Incorrect

readPosition on servo object might not give back the value you write to it using writePosition
when you use an Arduino Due. The value could be off by 1.

7-15
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

Error creating I2C device object from the output of scanI2Cbus() function on Bus 1 of
Arduino Due

Creating an I2C device object using the addresses received from the scanI2CBus function on Bus 1
of the Arduino Due board errors out. This is because, Arduino Due does not have internal pull-up
resistors. Connect the pull-up resistors to be able to create the device object.

SPIMode 3 of Arduino Due works sporadically.

On the Arduino Due, when you set the SPI Mode in Mode 3, the first write works sporadically. See
this link for more details.

Serial pins configured as digital pins cannot be used as serial peripherals

Serial pins configured as DigitalInput or DigitalOutput using configurePin, cannot be used


as serial peripherals. To workaround this issue, clear the existing arduino and recreate the arduino
and serial device object.

Limited I2C write size on Arduino Due

You cannot write more than 32 bytes of data to I2C EEPROM attached to an Arduino Due board in a
single transmission.

Arduino Leonardo and Micro


Cannot See Leonardo Board Port

If you are using an Arduino Leonardo device on a Windows machine, and the board was left in a bad
state during upload, the COM port may briefly show up in the Device Manager and then quickly
disappear.

To use Arduino IDE to see the COM port again:

1 Open Arduino IDE from the folder returned by the arduinoio.IDERoot in MATLAB command
window.
2 Plug the board in again, or press the reset button to make the serial COM port appear again.
3 With the port still visible in Device Manager, select the port in Arduino IDE, and select
Leonardo as the Board type.

Alternatively, you can also try pressing and holding the reset button on the board while clicking
Upload in Arduino IDE. When IDE displays the 'Uploading...' message, release the reset button and
make sure that the upload was successful.

Once reset, the Leonardo serial port appears correctly on Windows.

Arduino Nano 33 IoT


D0 and D1 pins are reversed

The serial pins D0 and D1 are reversed on the Arduino Nano 33 IoT board. D0 pin corresponds to TX
and the D1 pin corresponds to RX. Ensure you use the correct pins.

7-16
Board Specific Issues

Arduino Nano 33 BLE and Nano 33 BLE Sense


Arduino object creation fails

If the arduinoio.IDERoot has a path length more than 50 characters , arduino object creation
fails. Ensure that the path length is less than 50 characters.

Arduino MKR CAN Shield


CAN-H and CAN-L pins are marked incorrectly

The markings for CAN-H and CAN-L may be swapped on the silkscreen on an Arduino MKR CAN
SHIELD board. Use the schematic of the board to identify the correct pins.

Arduino Uno and Mega


Incorrect readVoltage results

On Arduino Uno and Mega boards, readVoltage gives incorrect values when the
AnalogReferenceMode is internal, the AnalogReference value is 1.1V, and an external
reference voltage is connected to the AREF pin through a 5K resistor. See this link for more details.

Limited I2C EEPROM write size

You cannot write more than 32 bytes of data to I2C EEPROM attached to an Arduino Uno or Mega
boards in a single transmission.

Arduino MKR1000 or MKR1010


Bootloader Mode

If you are using an Arduino MKR1000 or MKR1010 boards, the board may occasionally get stuck in
bootloader mode, which shows up in the Windows Device Manager.

To retrieve the MKR1000 board from bootloader mode:


1 Open Arduino IDE from the folder path returned by the arduinoio.IDERoot in the MATLAB
Command Window.
2 Select the port in Arduino IDE, and select Arduino/Genuino MKR1000 as the board type.
3 Press and hold the reset button on the board while clicking Upload in Arduino IDE. When IDE
displays the 'Uploading...' message, release the reset button, and make sure that the upload
was successful.

Alternatively, you can unplug the board and plug it in again, or press the reset button on the board.

Once reset, the Arduino MKR1000 successfully comes out of bootloader mode. Follow the same steps
for the Arduino MKR1010board as well.

7-17
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

Arduino MKR1010 programmed as MKR1000

If you program the Arduino MKR1010 board accidentally as the MKR1000, you need to reconfigure it.

To reconfigure the board:

1 Open Arduino IDE from the folder path returned by the arduinoio.IDERoot in the MATLAB
Command Window.
2 Select the port in Arduino IDE, and select Arduino WiFi MKR1010 as the board type.
3 Upload an Example Sketch.

Arduino MKR1010 Static IP doesn't work with default firmware

From the Hardware Setup window for Arduino boards, you must be able to specify an IP address
over which the Arduino connection is made. To do this, check Use static IP address and input the IP
address as shown below.

Issue: The connection is made at a different ‘Device Address’ than mentioned or sometimes a “Test
connection failed” error message is received.

7-18
Board Specific Issues

Solution: Update MKR Wi-Fi 1010 board to Wi-Fi NINA firmware version 1.2.0 or higher

Follow the steps to update firmware:

1 Download the ‘WiFi101-Updater-ArduinoIDE-Plugin-0.10.7.zip’ from this link and extract the file.
2 Type the following command in MATLAB Command Window: arduinoio.IDERoot.
3 Outside of MATLAB, go to the location output from Step 2 and navigate inside the folder titled
tools.
4 In this new location, copy and paste the WiFi101 folder from the extracted zip file (Step 1) to
replace existing folder.

Example new path: C:\ProgramData\MATLAB\SupportPackages\R2019a\3P.instrset


\arduinoide.instrset\arduino-1.8.1\tools\WiFi101
5 Go back to the location output from Step 2 and open the Arduino application.
6 Go to Tools > Board and Tools > Portto confirm the board and port number matches that of
your MKR Wi-Fi 1010 board.
7 Go to File > Examples > WiFiNINA > Tools > FirmwareUpdater
8 Upload this sketch to your Arduino MKR Wi-Fi 1010
9 After you get the Done Uploading message, click on Tools > WiFi101/WiFiNINA Firmware
Updater.
10 Select the port that matches your MKR Wi-Fi 1010 board and confirm that the firmware pre-
selected is NINA firmware (1.2.0 or higher) and then click Update Firmware
11 You should get The firmware has been updated! confirmation message.
12 Close Arduino IDE; go to MATLAB and try setting your Static IP address.

Boards Not Listed in Interactive Hardware Setup


The following boards, though supported, are not listed in the interactive hardware setup screen for
the support package installed on macOS 10.15 Catalina:

• Arduino Nano 3.1


• Arduino Pro Mini
• Sparkfun Red Board Uno
• Sparkfun Digital Sandbox

To workaround this issue, specify the port and board while creating an arduino object.

Arduino to FTDI Adaptor Connection


To align the TX and RX pins correctly, as shown in the diagram, connect the TX on the FTDI device to
RX on the Arduino board and RX on the FTDI device to TX on the Arduino board. If these are
misaligned, the FTDI can go undiscovered.

7-19
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

7-20
Serial Device Issues

Serial Device Issues

Data Issues
Incorrect values of NumBytesAvailable

NumBytesAvailable shows incorrect values:

• At the time of object creation, the value of NumBytesAvailable is non-zero.


• Although, there is no device connected to the RxPin, the value on NumBytesAvailable changes
after writing data from the device

This is caused if the serial device connections are changed after the arduino object is created in the
workspace. If you do not change the connections, you will not see this issue.

If you continue to see the issue, create the arduino object again with ForceBuildOn set to true,
and do not disturb the connections.

7-21
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

Arduino Resource Conflicts


When using Arduino boards in MATLAB, you might get an error saying there is a hardware resource
conflict. For example, if you use I2C pins A4 and A5 on an Arduino Uno as digital inputs, then using
I2C classes throws an error. To resolve the conflict, call configurePin to explicitly change the pin
mode.

Note If the modes are compatible, MATLAB converts the mode automatically for you without
throwing an error.

7-22
Adafruit Motor Shields and Servo Issues

Adafruit Motor Shields and Servo Issues

In this section...
“Adafruit Motor Shields” on page 7-23
“Servo Issues” on page 7-24

Adafruit Motor Shields


Cannot Stack Motor Shields

Stacking multiple motor shields is not supported for an Arduino Due board. To be able to stack
shields, use an Uno board or any other Arduino hardware that supports motor shields.

Motor Not Rotating

If your motor is not rotating,

1 Check that your device has enough power.


2 Check that the jumper is missing.
3 Check the operating voltage and current of the motor to ensure that the power requirements are
met. For example, an Arduino Due board supports only the voltage range 0V to 3.3V.

Refer to the Adafruit FAQ page for more troubleshooting tips.

Connection Loss When Using DC Motor

When you are using a DC motor and get this error:

The host and client connection is lost. Make sure the board is plugged in and
recreate arduino and its related objects.

• Make sure that you have an external power supply to meet the power requirement of the motor.
• If you are powering the motor via the USB connection, do not run the motor at high speeds.

Connection Loss When Using a Stepper Motor

When you are using a stepper motor, you might get an error if you have specified a large number of
StepsPerRevolution and RPM. The move function throws this error:

The host and client connection is lost. Make sure the board is plugged in and
recreate arduino and its related objects.

You also see a connection-lost error if you are using a step type that produces more precision, such as
Microstep.

To work around this issue, specify small StepsPerRevolution and RPM values. As a best practice,
do not run the motor at a speed higher than 1200 steps per second. The stepper motor speed is
constrained by I2C communication and the Arduino serial I/O processing time, and this constraint
slows down the stepper.

7-23
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

Servo Issues
Servo Not Working

If the pulse duration settings on a servo are incorrect, you can get errors or unexpected behavior.
Check the settings on the minimum and maximum pulse duration values. Refer to your servo device
specification for appropriate values.

7-24
Custom Arduino Library Issues

Custom Arduino Library Issues

Custom Library Class Not Detected


If the MATLAB class of your custom library is not detected by listArduinoLibraries, you are
unable to create an arduino object with the new custom library. To overcome this issue, try these
steps:

1 Make sure that the folder with the custom library is added to the MATLAB path.
2 Run the following commands:

a Clear all classes.

clear classes
b Rehash toolbox cache.

rehash toolboxcache

Then try to list available libraries,

lib = listArduinoLibraries();

After defining the required properties in the custom class, try to instantiate the class directly to check
if the class is properly recognized by MATLAB. This action ensures that there is no syntax error in the
class.

7-25
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

Troubleshooting Sensors

In this section...
“Error: Unable to receive data from the target hardware” on page 7-26
“Unexpected response from IMU sensor” on page 7-26

Error: Unable to receive data from the target hardware


1 If you are getting this error:

a Clear both the arduino and sensor objects.


b Ensure that the connections to the sensor are intact. It is recommended to use a bread board
shield(prototype shield) or solder the sensor to the Arduino board to prevent loose contact
while moving the board.
c Recreate the objects and try again.

If you continue to face the issue with IMU sensors, it is likely that it is due to the loose
connections between the sensor and Arduino board. This causes the code to get stuck while
performing the I2C operation.

On AVR based Arduino boards, you can avoid this by doing the following:

a Replace the I2C library files from this location.


b Navigate to ArduinoCore-avr > libraries > Wire > src > utility in the downloaded folder.
c Copy the “twi.c’ and ‘twi.h’ and replace the files in the folder which opens up after executing
the following commands in MATLAB command prompt:

>> path = fullfile(arduinoio.IDERoot,'hardware','arduino','avr','libraries','Wire','src',


>> cd(path)
d Reflash the Arduino server using the command:

a = arduino(‘com4’,’Uno’,'ForceBuild',true)

Use the sensor functions again. This will refrain the hardware from getting stuck due to a loose
connection and will throw appropriate error if there is any.
2 Avoid using multiple add-on libraries with Arduino Uno when using sensor functions. Arduino
Uno and other ATmega328P based boards have limited RAM memory(2KiB.) You may get this
error when you use sensor objects with multiple add-on libraries on Arduino Uno. To verify this
create an arduino object with minimum libraries required and try again. For more details, see
“Lost Connection and Data Issues” on page 7-13.

Unexpected response from IMU sensor


Trace messages can be used to view the commands which are being executed on the hardware board
when you are using sensor functions. To view the trace messages, create the arduino object with
the TraceOn parameter set as true and use sensor functions. Note that the TraceOn is not
supported for read function.

7-26
Limitations

Limitations
• For uninterrupted real-time sensor data reading, do not use other Arduino functions while you are
using the read function. Calling other functions clears the stored data when the ReadMode
property is set to Oldest, and does not return the oldest data stored when you read data.
• The function read is not supported if the TraceOn parameter of the arduino object is set to
true while creating the IMU sensor object. Set TraceOn to false to use the read function.
• TraceOn is not supported for gpsdev.
• In order to ensure latest data is obtained in ReadMode is Latest, MATLAB buffers are flushed if
the delay between subsequent read is above a threshold value. For IMU sensors the threshold is
3s and for GPS this is 120s.

7-27
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

Connect Arduino to MATLAB over Bluetooth


Check if the Arduino board is connected to MATLAB and configured. If the board needs configuration,
click Hardware Setup and follow the onscreen instructions to upload the Arduino server and set up
the Arduino to communicate with MATLAB.

• Board — Select the Arduino Board


• Bluetooth Address — Enter the Bluetooth device name or address. Use blelist or
bluetoothlist command to scan nearby Bluetooth devices for the address and enter your
device's address.
• Custom Name — You may select a custom name for your Arduino.

After you have specified values for these parameters, click Confirm Parameters. If the connection is
successful, your Arduino board appears in the Device List. Go back to the Devices tab at any time by
clicking Cancel.

If the connection fails:

• Ensure that the Arduino board is connected to host system. Use blelist or bluetoothlist
commands to check if your Arduino device is discoverable.
• Ensure that the Bluetooth server has been successfully uploaded into the Arduino board.
• Ensure that the Board and Bluetooth address are correct.

For further information, see “Arduino USB, Bluetooth, and Wi-Fi Connection Failure” on page 7-8.

7-28
Connect Arduino to MATLAB over Wi-Fi

Connect Arduino to MATLAB over Wi-Fi


Check if the Arduino board is connected to MATLAB and configured. If the board needs configuration,
click Hardware Setup and follow the onscreen instructions to upload the Arduino server and set up
the Arduino to communicate with MATLAB.

• Board — Select the Arduino Board


• IP Address — Select the Wi-Fi IP address.
• TCP/IP Port — Select the TCP/IP port to connect to the Arduino.
• Custom Name — You may select a custom name for your Arduino.

After you have specified values for these parameters, click Confirm Parameters. If the connection is
successful, your Arduino board appears in the Device List. Go back to the Devices tab at any time by
clicking Cancel.

If the connection fails:

• Ensure that the Arduino board is connected to host system by pinging its IP Address.
• Ensure that the Wi-Fi server has been successfully uploaded into the Arduino board.
• Ensure that the Board, IP Address and TCP/IP port fields are correct.

For further information, see “Arduino USB, Bluetooth, and Wi-Fi Connection Failure” on page 7-8.

7-29
7 Troubleshooting in MATLAB Support Package for Arduino Hardware

Connect Arduino to MATLAB over USB


Check if the Arduino board is connected to MATLAB and configured. If the board needs configuration,
click Hardware Setup and follow the onscreen instructions to upload the Arduino server and set up
the Arduino to communicate with MATLAB.

• Board — Select the Arduino Board


• Port — Select the USB port.
• Custom Name — You may select a custom name for your Arduino.

After you have specified values for these parameters, click Confirm Parameters. If the connection is
successful, your Arduino board appears in the Device List. Go back to the Devices tab at any time by
clicking Cancel.

If the connection fails:

• Ensure that the Arduino board is connected to host system.


• Ensure that the USB server has been successfully uploaded into the Arduino board.
• Ensure that the Board and the Port fields are correct.

For further information, see “Arduino USB, Bluetooth, and Wi-Fi Connection Failure” on page 7-8.

7-30
8

AEK

• “Using Arduino Engineering Kit Rev 2 with Pre-Configured Projects in Support Package”
on page 8-2
• “Webcam Controlled Rover Using Arduino Engineering Kit Rev 2” on page 8-5
• “Drawing Robot Using Arduino Engineering Kit Rev 2” on page 8-7
• “Self-Balancing Motor Cycle Using Arduino Engineering Kit Rev 2” on page 8-9
8 AEK

Using Arduino Engineering Kit Rev 2 with Pre-Configured


Projects in Support Package
The Arduino Engineering Kit is directed towards engineering students who want to learn engineering
concepts with the help of Arduino, MATLAB, Simulink, and Stateflow®. This kit was developed by
Arduino in collaboration with MathWorks. The kit contains all the components needed to build three
complete projects, along with educational materials that elaborate on the project assembly as well as
the Physics and Engineering concepts behind the projects, such as Control Systems, Image
Processing, Mechatronics and Robotics. You will be introduced to programming in Arduino, MATLAB
and Simulink, and learn all these topics discussed above while making three challenging engineering
projects.

License and Installation Requirements


You can access the license and installation requirements at https://engineeringkit.arduino.cc/.

The kit includes a one-year individual user MATLAB license that includes all of these products with
version R2021a:

• MATLAB Support Package for Arduino Hardware


• Simulink®
• Simulink Support Package for Arduino Hardware
• Control System Toolbox™
• Curve Fitting Toolbox™
• DSP System Toolbox™
• Image Processing Toolbox™
• Instrument Control Toolbox™
• Optimization Toolbox™
• Signal Processing Toolbox™
• Simscape™
• Simscape Multibody™
• Stateflow®
• Symbolic Math Toolbox™

If you have an existing MATLAB license, you can use that too if you have the required products and
access to release R2021a or later.

You can see if you have the required products installed by typing the following command at the
MATLAB prompt:

ver

If you have version R2020b or earlier releases, Arduino Engineering Kit Rev 2 project files are not
available with the support package. For those releases, you can use the Arduino Engineering Kit Rev
1 project files, which are available in MATLAB Central™ File Exchange.

8-2
Using Arduino Engineering Kit Rev 2 with Pre-Configured Projects in Support Package

Pre-Configured Projects Available with the Support Package


When you install MATLAB Support Package for Arduino Hardware, the project files for these three
projects are downloaded and installed:

Self-Balancing Motorcycle

Featuring inverted pendulum dynamics using a reaction wheel and movement gyro, the Self-
Balancing Motorcycle can move around and balance by itself. The motorcycle is using Simulink to
monitor and control the movements, by performing inertial sensing and filtering to make the
motorcycle balance. In this project, the Nano Motor Carrier from Arduino will be used to control the
inertia wheel in the center of the motorcycle. It will also command a geared DC motor in the back
wheel to move forward or backward, and a servo in the front to steer the motorcycle.

Webcam Controlled Rover

The Webcam Controlled Rover features position tracking via a webcam and onboard sensing features
for obstacle avoidance and movement. The rover uses a mix between MATLAB and Simulink
programs to move around and interact with the world. In the rover, the Nano Motor Carrier from
Arduino will be used to control the two DC geared motors at the rear end and a servo motor in the
front of the vehicle, providing the rover with a lifting mechanism.

Drawing Robot

Using image processing techniques for extraction of geometries and path planning, the Drawing
Robot recreates a picture on a whiteboard from an image captured through a webcam with the help
of MATLAB. The robot utilizes pure MATLAB code to convert an image into set of motor commands
that moves the markers across a whiteboard in order to duplicate the picture on the canvas. In this
project, the Nano Motor Carrier from Arduino will be used to position the two DC geared motors on
the whiteboard. Additionally, it will be used to control a servo motor that lowers the markers on the
whiteboard, and helps to select between two different marker colors.

Required Products for the Pre-Configured Projects


Self-Balancing Motor Cycle Webcam Controlled Rover Drawing Robot
MATLAB MATLAB MATLAB
Simulink Simulink Control System Toolbox
Simscape Stateflow Image Processing Toolbox
Simscape Multibody Image Processing Toolbox MATLAB Support Package for
USB Webcams
Simulink Support Package for MATLAB Support Package for MATLAB Support Package for
Arduino Hardware Arduino Hardware Arduino Hardware
Simulink Support Package for
Arduino Hardware

8-3
8 AEK

See Also

Related Examples
• “Drawing Robot Using Arduino Engineering Kit Rev 2” on page 8-7
• “Self-Balancing Motor Cycle Using Arduino Engineering Kit Rev 2” on page 8-9
• “Webcam Controlled Rover Using Arduino Engineering Kit Rev 2” on page 8-5

8-4
Webcam Controlled Rover Using Arduino Engineering Kit Rev 2

Webcam Controlled Rover Using Arduino Engineering Kit Rev 2

This example shows how to use Arduino® Engineering Kit Rev 2 to program a differential drive robot
that can be remotely controlled by MATLAB® over Wi-Fi® to perform operations such as path
following and moving objects with a forklift along with obstacle avoidance.

The rover is controlled by an Arduino Nano 33 IoT board, that is interfaced to the Arduino Nano
Motor Carrier, two DC motors with encoders, and a micro-servo motor. On top of the rover, you will
install a color-coded sticker that will serve as a marker and assist the image processing algorithm
that uses a webcam to detect the location and orientation of the robot, and thereby assist the rover in
overall trajectory tracking.

Required Products

• MATLAB Support Package for Arduino Hardware


• Simulink® Support Package for Arduino Hardware
• Stateflow®
• Image Processing Toolbox™

Prerequisites

Before you start exploring the Webcam Controlled Rover project, complete these steps:

1. Understand the basics of Arduino Engineering Kit Rev 2 and install the tools as described in
Unboxing and Installation. Because you have already installed the MATLAB add-on for Arduino
hardware (MATLAB Support Package for Arduino Hardware), you can proceed with the installation of
the other tools.

2. Learn how to get started with Arduino environment and the tools, as described in Arduino,
MATLAB and Simulink.

8-5
8 AEK

3. Learn the basics of DC motors, servo motors, IMU (Inertial Measurement Unit), and motor control
system, as described in Basics of Mechatronics.

Assemble the Webcam Controlled Rover

To assemble the webcam controlled rover from the components included in Arduino Engineering Kit
Rev 2, watch the video in the Project Overview section of Project Webcam Controlled Rover.

Project files for Webcam Controlled Rover

The required files for Webcam Controlled Rover project are downloaded and installed as part of the
MATLAB Support Package for Arduino Hardware installation. You can find these files in the folder
aekrev2projectfiles.instrset. Use this MATLAB command to view and access the files:

fullfile(matlabshared.supportpkg.getSupportPackageRoot, '3P.instrset', 'aekrev2projectfiles.instr

The MobileRover subfolder in this main folder (aekrev2projectfiles.instrset) contains the files
described in the detailed workflow at Project Webcam Controlled Rover.

See also

• “Using Arduino Engineering Kit Rev 2 with Pre-Configured Projects in Support Package” on page
8-2

8-6
Drawing Robot Using Arduino Engineering Kit Rev 2

Drawing Robot Using Arduino Engineering Kit Rev 2

This example shows how to use Arduino® Engineering Kit Rev 2 to build and program a robot that
extracts line traces from an image and reproduces it as a drawing on a whiteboard. The project uses
MATLAB® code to capture an image using a webcam, and then convert it into a set of motor
commands using image processing techniques, which drive the robot across a whiteboard and
reproduce the captured image as a drawing.

The drawing robot is controlled by an Arduino Nano 33 IoT board, interfaced with the Arduino Nano
Motor Carrier, two DC motors with encoders, and a micro-servo motor. The drawing robot has two
different colored markers that can be raised and lowered by means of the servo motor. The two DC
motors helps the drawing robot navigate over the whiteboard.

Required Products

• MATLAB Support Package for Arduino Hardware


• MATLAB Support Package for USB Webcams
• Image Processing Toolbox™
• Control System Toolbox™

Prerequisites

Before you start exploring the Drawing Robot project, complete these steps:

1. Understand the basics of Arduino Engineering Kit Rev 2 and install the tools as described in
Unboxing and Installation. Because you have already installed the MATLAB add-on for Arduino
hardware (MATLAB Support Package for Arduino Hardware), you can proceed with the installation of
the other tools.

2. Learn how to get started with Arduino environment and the tools, as described in Arduino,
MATLAB and Simulink.

3. Learn the basics of DC motors, servo motors, IMU (Inertial Measurement Unit), and motor control
system, as described in Basics of Mechatronics.

8-7
8 AEK

Assemble the Drawing Robot

To assemble the drawing robot from the components included in Arduino Engineering Kit Rev 2,
watch the video in the Project Overview section of Project Drawing Robot.

Project files for Drawing Robot

The required files for Drawing Robot project are downloaded and installed as part of the MATLAB
Support Package for Arduino Hardware installation. You can find these files in the folder
aekrev2projectfiles.instrset. Use this MATLAB command to view and access the files:

fullfile(matlabshared.supportpkg.getSupportPackageRoot, '3P.instrset', 'aekrev2projectfiles.instr

The DrawingRobot subfolder in this main folder (aekrev2projectfiles.instrset) contains the files
described in the detailed workflow at Project Drawing Robot.

See also

• “Using Arduino Engineering Kit Rev 2 with Pre-Configured Projects in Support Package” on page
8-2

8-8
Self-Balancing Motor Cycle Using Arduino Engineering Kit Rev 2

Self-Balancing Motor Cycle Using Arduino Engineering Kit Rev


2

This example shows how to use Arduino® Engineering Kit Rev 2 to build and program a motorcycle
bot that self-balances and maneuvers by itself using a flywheel. The project models the motorcycle
with the help of inverted pendulum dynamics and performs inertial sensing to balance the motorcycle
by controlling the flywheel, located at the center of the motorcycle.

The motorcycle is controlled by an Arduino Nano 33 IoT board, that is interfaced with the Arduino
Nano Motor Carrier, a DC motor to move the back wheel, DC motor with Encoder to control the
inertia wheel and a standard servo motor to steer the motorcycle handle.

Required Products

• Simulink® Support Package for Arduino Hardware


• Simscape™
• Simscape™ Multibody™

Prerequisites

Before you start exploring the Self-Balancing Motor Cycle project, complete these steps:

1. Understand the basics of Arduino Engineering Kit Rev 2 and install the tools as described in
Unboxing and Installation. Because you have already installed the Simulink add-on for Arduino
hardware (Simulink Support Package for Arduino Hardware), you can proceed with the installation of
the other tools.

2. Learn how to get started with Arduino environment and the tools, as described in Arduino,
MATLAB and Simulink.

8-9
8 AEK

3. Learn the basics of DC motors, servo motors, IMU (Inertial Measurement Unit), and motor control
system, as described in Basics of Mechatronics.

Assemble the Motor Cycle

To assemble the motor cycle from the components included in Arduino Engineering Kit Rev 2, watch
the video in the Project Overview section of Project Self-balancing Motorcycle.

Project files for Self-Balancing Motor Cycle

The required files for Self-Balancing Motor Cycle project are downloaded and installed as part of the
MATLAB Support Package for Arduino Hardware installation. You can find these files in the folder
aekrev2projectfiles.instrset. Use this MATLAB command to view and access the files:

fullfile(matlabshared.supportpkg.getSupportPackageRoot, '3P.instrset', 'aekrev2projectfiles.instr

The Motorcycle subfolder in this main folder (aekrev2projectfiles.instrset) contains the files described
in the detailed workflow at Project Self-Balancing Motor Cycle.

See also

• “Using Arduino Engineering Kit Rev 2 with Pre-Configured Projects in Support Package” on page
8-2

8-10
9

Arduino Explorer

• “Using Arduino Explorer App” on page 9-2


• “IoT-Based Automatic Cooling Fan Control Using ThingSpeak and Arduino Hardware”
on page 9-20
• “IoT-Based Temperature Monitoring Using ThingSpeak and Arduino Hardware” on page 9-32
9 Arduino Explorer

Using Arduino Explorer App


Launch the Arduino Explorer app using any of these methods:

• In the MATLAB Command Window, enter arduinoExplorer.


• On the Apps tab on the MATLAB Toolstrip, under Test and Measurement, click the app icon.

After launching the app, select the device card corresponding to the Arduino board you want to
work with.

If the app does not detect your device automatically and it does not appear in the All Hardware
section, use one of the configuration cards on the top to manually add your device based on
connection type.

• On the Apps tab of MATLAB Toolstrip, under Test and Measurement, click the Hardware
Manager app icon. In the All Hardware section, click the device card of the detected Arduino
board. This launches the Arduino Explorer app.

Set Up and Connect to Official Arduino Boards and Clone Boards


The Arduino Explorer app can automatically detect official Arduino boards that are connected to your
computer. The app also detects and displays other unofficial (clone) Arduino boards if they were
previously set up and configured using the app.

If you don't see your connected Arduino board in the All Hardware section, use one of the
configuration cards on the app home screen to manually add your Arduino board:

9-2
Using Arduino Explorer App

• Configure USB Arduino


• Configure Bluetooth Arduino
• Configure Wi-Fi Arduino

To connect to the board for the first time, follow the instructions that appear when you click any of
the (name the UI element).

Tip The All Hardware section displays all unofficial (clone) Arduino boards, even the ones added
manually, with a close button X. You can remove an unofficial board from the list by clicking the X
button.

Manage Required Libraries

After launching a new app session, you can manage the required libraries by completing the following
steps.

1 Ensure that the Arduino board is connected to the computer over USB.

Note Installing Arduino libraries on to the board is supported only over a USB connection.
2 Click Libraries in the Configure section of the app.

9-3
9 Arduino Explorer

3 The Manage Libraries window displays the installed libraries. To install a new set of libraries on
to the board, select the required libraries and click Install Libraries. To remove a library which
was installed on the Arduino board, but not required for the current session, you can clear the
corresponding library selection and then click Install Libraries.

9-4
Using Arduino Explorer App

Configure Read and Write for GPIO Pins


You can use the Pin Explorer pane and Pin Configuration panel in the Arduino Explorer app to
configure each pin to read and write data.

1 In the Pin Explorer pane, click the row corresponding to the pin that you want to configure. The
Pin Configuration panel displays the options you can use to configure the selected pin.
2 In the Pin Configuration panel, select the Mode from the list, and if required specify a Label to
uniquely identify the pin.

After you select the mode, the columns are automatically updated with the values. For example, if
you set the mode to Analog Input, the app starts reading data from the corresponding pin and
displays it in the Read Value column.

9-5
9 Arduino Explorer

3 If you select a mode that allows you to write data to the pin, specify a value in the Write Value
column, and the app writes the specified data to the pin.

Tip The Arduino Explorer app displays the pinout diagram of the selected board in a panel at the
bottom right corner of the app window.

To view the pinout diagram more efficiently:

• Increase the area of the Pinout panel — Maximize the panel by double-clicking it and collapse the
other adjacent panels.
• Open pinout panel in another window — Click the icon that appears at the top of the pinout
panel.

9-6
Using Arduino Explorer App

For details regarding recording and visualizing data, see “Visualize and Record Data from Arduino
Pins” on page 9-14.

Note Clicking New Session in the app resets all Arduino pin configurations and sets them to the
Unset mode.

Connect to SPI Device


Arduino Explorer app lets you configure the SPI communication interface, which you can then use to
read and write data to SPI devices connected to the Arduino hardware.

To do this, click the SPI icon in the Configure section of the app. Use the Set Up SPI Device window
to select the pins and configure the SPI communication properties.

After you set the values, click OK. All the pins that support SPI are configured for communicating
using the protocol and they all are displayed in one row in the Pin Explorer.

9-7
9 Arduino Explorer

To control the precision in read and write operations, set the Precision value in the Pin
Configuration panel.

This automatically updates the values in the columns in the Pin Explorer window. In the SPI interface,
writing data to the device, in a cell under the Write Value column, also reads equal bytes of data from
the device into the Read value column.

For more information on Add Decode Logic option, see “Decode Read Data” on page 9-13.

For more information on recording and visualizing data, see “Visualize and Record Data from Arduino
Pins” on page 9-14.

Connect to I2C Device


You can also use the Arduino Explorer app to configure the I2C communication interface and use the
interface to read and write data to I2C devices connected to the Arduino hardware.

Click theI2C icon in the Configure section of the app and use the Set Up I2C Device window to
select the I2C Bus (if your board supports more than one bus) and modify the I2C properties.

Tip Click Scan I2C to scan the I2C interface for all the available I2C device addresses.

9-8
Using Arduino Explorer App

Once you set the I2C properties, click OK. The Pin Explorer window now displays a row for I2C
communication.

Configure Read and Write for I2C

Use the Pin Configuration panel corresponding to the I2C interface to perform one of these
operations.

• Read or write

9-9
9 Arduino Explorer

• Register read or write

The value you specify in the Precision parameter must match the size of the device register.

Once you set the parameter values (in the read and register read operations), click Read. The
Read Value column corresponding to the I2C row in the Pin Explorer pane displays the value as
read by the SDA pin or the register address.

Once you set the parameter values (in the write and register write operations), edit the
corresponding cell in the Write Value column and enter the value to be written to the SDA pin or
the register address.
• Perform continuous reading of data.

9-10
Using Arduino Explorer App

Select the Read Continuously option and then click Start Reading to continuously read data
from the I2C device. The value displayed in Read Value column changes continuously based on the
data being read. Click Stop Reading to stop reading the data from the I2C device.

For more information on the Add Decode Logic option, see “Decode Read Data” on page 9-13.

For more information on recording and visualizing data, see “Visualize and Record Data from Arduino
Pins” on page 9-14.

Connect to Serial Device


The Arduino Explorer app lets you configure the serial communication interface and use the interface
to read and write data to serial devices connected to the Arduino hardware.

Click the Serial icon in the Configure section of the app and use the Set Up Serial Device window to
select the Serial Port and modify serial communication properties.

9-11
9 Arduino Explorer

After you set the values, click OK. The Pin Explorer displays the row specific to serial pin.

You can perform read and write using serial pins by following the same procedure as described in
“Configure Read and Write for I2C” on page 9-9.

9-12
Using Arduino Explorer App

Decode Read Data


The Arduino Explorer app lets you decode raw data from the communication protocol interfaces of
the Arduino board and view the decoded data in the app. In the Pin Explorer pane, select the row
corresponding to a communication interface (I2C, SPI or Serial) then click Add Decode Logic in the
Pin Configuration panel.

In the Add Decode Logic window, specify a MATLAB function or use the Browse button to select a
MATLAB function that contains the logic to decode the data. Click OK after selecting the file.

Note Ensure that you use the syntax as suggested in the Add Decode Logic window and that the
function is saved on the MATLAB path.

The Decode Logic field in the Pin Configuration panel updates to show the name of the file.

9-13
9 Arduino Explorer

Once you provide the decode logic:

• The Read Value column in the Pin Explorer window displays the decoded data instead of raw
values from the interface.
• The Log panel of the app now displays a new column named Decoded Data with the decoded
values.

Visualize and Record Data from Arduino Pins


You can use the Plot and Log panels in the app to visualize and analyze data from the Arduino board.
The app also provides an option to record data from multiple pins to a Workspace variable for further
analysis.

Plot Panel

The Plot panel of the app enables you to interactively view data read from the Arduino board. Using
the Plot panel, you can:

• Visualize data from all read pins.


• Use Plot Settings to further customize the display (grid, axes, and so on).
• Toggle visibility of signals in the plot by interactively clicking the corresponding signal in the
legend.

9-14
Using Arduino Explorer App

Log Panel

The Log panel of the app provides a table with data communication details such as time stamp, type
of operation, data value, value of decoded data, size of data, and the data type. This table is
particularly useful when you are continuously reading data from communication protocol interfaces
(I2C, SPI, and Serial).

You can select the Display Format to display data values in the appropriate format in the table. You
can set the data format to Default, Hexadecimal, ASCII, and Binary. If you set data format to
Default, the log displays raw data from pins.

9-15
9 Arduino Explorer

The app also provides an option to export the entire log as a timetable into the Workspace. To do this,
click Export Log in the Export section of the app.

Record Data

The Arduino Explorer app lets you record the data from Arduino pins to a Workspace variable for a
specified duration. To do this:

1 Select the check box in the Record Pin column in the Pin Explorer window corresponding to the
pins.
2 In the Record section of the app, specify the Workspace Variable name and Duration, and
then click Record.

9-16
Using Arduino Explorer App

You can view the status of the data recording process in the app's status bar.

9-17
9 Arduino Explorer

If you want to stop recording before the specified duration, click Stop in the Record section of
the app.

The recorded data is saved to the workspace variable and the updated status displays in the app's
status bar.

Once the data recording is complete, you can click Signal Analyzer in the Analyze section of the
app to analyze the recorded data.

Generate MATLAB Script


You can use the Generate Script option in the Export section of the Arduino Explorer app to
generate MATLAB code in a live script. Use this option to perform the same operations as performed
in the app by using objects and functions provided in the MATLAB Support Package for Arduino
Hardware. You can also use this code to add additional logic and create your own custom functions or
applications.

Customizable Views in the App


You can customize some of the user interface elements in the app.

9-18
Using Arduino Explorer App

User Interface Element Customization


Pin Explorer • Determine pins to display by using one of the
four options in the top right of the Pin
Explorer window: All, Analog, Digital, or In
use.
• Increase window size by collapsing the Pin
Configuration panel on the right or the Plot
and Log panels at the bottom.
Pin Configuration, Plot, Log Increase the panel area by maximizing the panel
by double-clicking it and collapsing the other
panels.
Legend Drag the legend to change its location.
Plot Settings Use the Plot Settings button to:

• Show legend
• Show grid
• Display multiple Y-axes
• Scale Y-axes

9-19
9 Arduino Explorer

IoT-Based Automatic Cooling Fan Control Using ThingSpeak


and Arduino Hardware

This example shows how to create a ThingSpeak™ channel and use the MATLAB® functions to
collect the temperature data from a BMP280 sensor connected to your Arduino® board, and then use
MATLAB Analysis in ThingSpeak to trigger the automatic control of a CPU cooling fan kept in the
room and then monitor the usage of the fan by calculating the runtime. This example also shows you
how to set up an email alert if the fan turns on, by using MATLAB functions in ThingSpeak.

Hardware Setup

This example uses:

• Arduino Uno
• Arduino Sensor Kit - Base
• BMP280 sensor
• CPU cooling fan (12V DC)
• 5V General Purpose Relay Module
• XL6009 DC-DC Step-Up Converter
• Input power source (5V)

Hardware Connection

1 Place the Base Shield that is part of the Arduino Sensor Kit, on top of Arduino Uno board.
2 Connect the BMP280 sensor to one of the I2C grove connectors on the Base Shield.
3 Connect the Arduino Uno to the computer running MATLAB via USB.
4 Connect the Vcc pin of the relay to 5V pin of Arduino Uno, and connect the GND pin of relay to
GND pin of Arduino Uno.
5 Connect the IN pin of the relay to D2 pin of Arduino Uno.
6 Connect the output pins of relay to the + and - power inputs of XL6009 DC-DC Step-Up
Converter. Make the connections such that the LED on the relay glows till it receives input signal
from Arduino board (NC - Normally Closed condition).
7 Connect the + and - terminals of the fan to the output of the XL6009 DC-DC Step-Up Converter.

9-20
IoT-Based Automatic Cooling Fan Control Using ThingSpeak and Arduino Hardware

Create ThingSpeak Channel and Add Widgets

ThingSpeak is an IoT analytics platform service that allows you to aggregate, visualize, and analyze
live data streams in the cloud. For more details, refer to Get Started with ThingSpeak. You need to
first create a new channel in ThingSpeak by defining multiple fields, which help you to collect the
data and then write the analyzed data to the same channel.

1 Sign In to ThingSpeak™ using your MathWorks® Account credentials, or create a new account.
2 Click Channels > MyChannels.
3 On the Channels page, click New Channel.
4 In Channel Settings, select the check boxes next to Fields 1–4. Enter these values for the field
names (the unit of temperature in this example is assumed to be degree celsius):

• Name: Automatic Fan Control


• Field 1: Temperature
• Field 2: Status
• Field 3: Runtime
• Field 4: Overall Runtime

9-21
9 Arduino Explorer

Click Save Channel to save the settings. The Channel Stats area of the new channel displays four
charts (which correspond to the four fields that you configured). However, for this example, we use
only Field 1 Chart, and use widgets for the other three fields.

Add Widgets

In the window that displays the saved channel (Automatic Fan Control), click Add Widgets,
select Lamp Indicator and then click Next.

9-22
IoT-Based Automatic Cooling Fan Control Using ThingSpeak and Arduino Hardware

Configure the widget by specifying the name as Status and by selecting Field 2.

9-23
9 Arduino Explorer

For Field 3 and Field 4, add Numeric Display widgets with the names Runtime and Overall
Runtime respectively. The updated widgets look like this in the Channel Stats area.

9-24
IoT-Based Automatic Cooling Fan Control Using ThingSpeak and Arduino Hardware

Identify API Keys in ThingSpeak

Before you write the MATLAB code, it is required that you identify the API Keys of the ThinkSpeak
channel because these will be used in the code.

To identify the API Keys, click API Keys among the options available for configuring the channel.

9-25
9 Arduino Explorer

Run MATLAB Code to Obtain Temperature Data from BMP280 Sensor

You can run the MATLAB code on the Arduino board that has BMP280 sensor connected. The
MATLAB code uses channel ID and its Write API Key to publish data over IoT to the ThingSpeak
channel.

The bmp280 object in MATLAB Suport Package for Arduino Hardware establishes a connection to the
connected BMP280 sensor and reads the temperature data.

In this example, we use a custom MATLAB code that reads temperature data from the channel (the
data which is originally obtained from the BMP280 sensor) and triggers a signal when temperature
crosses a threshold, and then writes the result back to the channel.

To explore the data from the sensor and find the temperature using ThingSpeak, we use the Read API
Key. After comparing the temperature against a threshold (26 degree celsius), we use the Write API
Key to send the signal that triggers the fan control on pin D2 of Arduino board that is connected to
the relay, and also to send the calculated run time values to the same channel.

Run these commands, one after the other, in the MATLAB command window (it is assumed that
Arduino board is connected to COM9 port). Replace the values of ChannelID, ReadAPI and WriteAPI

9-26
IoT-Based Automatic Cooling Fan Control Using ThingSpeak and Arduino Hardware

variables to match the actual values corresponding to your channel. In this example, we set the
threshold to 26 degree celsius (you can change it, if required).
a=arduino('COM9','Uno','Libraries','I2C')

sensorObj=bmp280(a);

%Setting to trigger relay


configurePin(a,'D2','DigitalOutput');

writeDigitalPin(a,'D2',1); % Writing 1 to D2 disconnects the relay switch

temp=readTemperature(sensorObj);

%Setting up ThingSpeak Parameters


ChannelID=XXXXXXXX;
threshold=26;
ReadAPI='XXXXXXXXXXX';
WriteAPI='XXXXXXXXXXX';
flag=0; % start/stop the timer based on this variable
Runtime=0;
overallRuntime=0;
thingSpeakWrite(ChannelID,[temp,0,0,0],'WriteKey',WriteAPI,'Fields',[1,2,3,4]);
pause(1);

while 1
% Read Data
temp=readTemperature(sensorObj);
if (temp>threshold)
if flag==0
tic;
flag=1;

% Switching on the relay and turning on the fan


writeDigitalPin(a,'D2',0);

% Read previous entry


y=thingSpeakRead(ChannelID,'ReadKey',ReadAPI,'Fields',[3,4]);

%Update all the fields


thingSpeakWrite(ChannelID,[temp,1,y(1),y(2)],'WriteKey',WriteAPI,'Fields',[1,2,3,4]);
pause(1);
end
else
if flag==1
Runtime=toc;
flag=0;

%Turn off the fan


writeDigitalPin(a,'D2',1);

% Read previous entry


x=thingSpeakRead(ChannelID,'ReadKey',ReadAPI,'Fields',4);

%Calculate overall runtime


overallRuntime = Runtime + x;
end
% Update all the fields

9-27
9 Arduino Explorer

thingSpeakWrite(ChannelID,[temp,0,Runtime,overallRuntime],'WriteKey',WriteAPI,'Fields',[1

end
pause(5);
end

Note: To stop the while loop and stop executing the code (to stop sending data to the ThingSpeak
channel), press Ctrl+C in the MATLAB Command Window.

The data from BMP280 sensor is sent to the channel. You can view the Channel Stats in ThingSpeak
and observe the live temperature, the status of the fan, and the runtime values. This figure shows an
example of recorded data based on live temperature sent from BMP280 sensor over IoT using
ThingSpeak. The figure shows the plot of temperature variation, the status of the fan (ON), and the
display in the two Numeric Display widgets that you added.

Set Up Email Alert for Temperature Beyond Threshold Using ThingSpeak

After the data from the BMP280 sensor connected to Arduino board is available in the ThinkSpeak
channel, you can set up an email alert that triggers an email. The email will be sent to the email ID
registered with your ThinkSpeak account, whenever the temperature exceeds a threshold.

To set up the email alert:

1 In ThingSpeak, click Apps > MATLAB Analysis.


2 Click New to get started with your code.
3 Under Examples, select Read channel to trigger email, and then click Create.

9-28
IoT-Based Automatic Cooling Fan Control Using ThingSpeak and Arduino Hardware

4 In the MATLAB Code area, customize the code as shown below. Ensure that you change the
values assigned to readChannelID and readAPIKey fields to match the actual values
corresponding to your channel. The alertAPIKey is the one associated with your profile in
ThingSpeak. After you write the code, click Save and Run.

% Enter your MATLAB Code below


readChannelID = XXXXXXXX;
% Temperature Field ID
TemperatureFieldID = 1;

% Channel Read API Key


% If your channel is private, then enter the read API Key between the '' below:
readAPIKey = 'XXXXXXXXXXXX';

% Read temperature data for the last 24 hours

[tempF,timeStamp] = thingSpeakRead(readChannelID,'Fields',TemperatureFieldID, ...

'numDays',1,'ReadKey',readAPIKey);

% Calculate the maximum and minimum temperatures


[maxTempF,maxTempIndex] = max(tempF);
[minTempF,minTempIndex] = min(tempF);

alertApiKey='XXXXXXXXXXXXXXXX';
alertURL = "https://api.thingspeak.com/alerts/send";
options = weboptions("HeaderFields", ["ThingSpeak-Alerts-API-Key", alertApiKey ]);
alertBody = sprintf("The temperature is %0.2f°F.Turning on the Fan", maxTempF);
alertSubject = sprintf("Temperature exceeded threshold");
try
webwrite(alertURL, "body", alertBody, "subject", alertSubject, options);
catch
% Code execution will end up here when a 429 (error due to frequent request) is caught
end

Next, let's set up a React app that triggers the email alert, as configured above, when the
temperature exceeds 26 degree celsius.

To do this, click Apps > Actions > React, and then configure the app as shown in this image (the
MATLAB Analysis app that you configured as shown above is saved with the name, Alert).

9-29
9 Arduino Explorer

Click Save React. Whenever the room temperature, as read by the BMP280 sensor, exceeds 26
degree Celsius, an email is sent to the ThingSpeak-registered email ID. This figure shows a sample

9-30
IoT-Based Automatic Cooling Fan Control Using ThingSpeak and Arduino Hardware

email based on the alertBody and alertSubject fields that you configured in the MATLAB
Analysis app.

9-31
9 Arduino Explorer

IoT-Based Temperature Monitoring Using ThingSpeak and


Arduino Hardware

This example shows how to create a ThingSpeak™ channel and use MATLAB® functions to collect
the temperature data from a BMP280 sensor connected to your Arduino® board, and then use
MATLAB Analysis in ThingSpeak to analyze the maximum and minimum temperature. This example
also shows you how to set up an email alert if the room temperature exceeds a threshold value, by
using MATLAB functions in ThingSpeak.

Hardware Setup

This example uses:

• Arduino Uno
• Arduino Sensor Kit - Base
• BMP280 sensor

Hardware Connection

1 Place the Base Shield that is part of the Arduino Sensor Kit, on top of Arduino Uno board.
2 Connect the BMP280 sensor to one of the I2C pin grove connectors on the Base Shield.
3 Connect the Arduino Uno to the MATLAB computer via USB.

Create ThingSpeak Channel and Add Widgets

ThingSpeak is an IoT analytics platform service that allows you to aggregate, visualize, and analyze
live data streams in the cloud. For more details, refer to Get Started with ThingSpeak. You need to

9-32
IoT-Based Temperature Monitoring Using ThingSpeak and Arduino Hardware

first create a new channel in ThingSpeak by defining multiple fields, which help you to collect the
data and then write the analyzed data to the same channel.
1 Sign In to ThingSpeak™ using your MathWorks® Account credentials, or create a new account.
2 Click Channels > MyChannels.
3 On the Channels page, click New Channel.
4 In Channel Settings, select the check boxes next to Fields 1–3. Enter these values for the field
names (the unit of temperature in this example is assumed to be degree celsius):

• Name: Temperature
• Field 1: Live Temperature
• Field 2: Min Temperature
• Field 3: Max Temperature

Click Save Channel to save the settings. The Channel Stats area of the new channel displays three
charts (which correspond to the three fields that you configured).

9-33
9 Arduino Explorer

Add Widgets

In the window that displays the saved channel (Temperature), click Add Widgets, select Numeric
Display and then click Next.

9-34
IoT-Based Temperature Monitoring Using ThingSpeak and Arduino Hardware

Configure each widget by specifying the name and its corresponding field. For example, the Max
Temperature widget can be configured like this:

9-35
9 Arduino Explorer

The new Numeric Display widgets that you configured appear for each of the fields, along with the
charts in the Channel Stats area.

Identify API Keys

Before you write the MATLAB code, it is required that you identify the API Keys of the ThinkSpeak
channel because these will be used in the code in the MATLAB Analysis app.

To identify the API Keys, click API Keys among the options available for configuring the channel.

9-36
IoT-Based Temperature Monitoring Using ThingSpeak and Arduino Hardware

To explore the data from the sensor and find the maximum and minimum temperature using
ThingSpeak, in MATLAB Analysis app, we use the Read API Key. After obtaining the result, we send
the same to the channel using the Write API Key.

Add Code for MATLAB Analysis in ThingSpeak

The MATLAB Analysis app in ThingSpeak lets you explore the data stored in ThingSpeak channels
and do further analysis. In this example, we use a custom MATLAB code that reads temperature data
from the channel (the data which is originally obtained from the BMP280 sensor) and calculates the
minimum and maximum temperature, and then writes the result back to the channel.

9-37
9 Arduino Explorer

To create the code for MATLAB Analysis in ThingSpeak:


1 Click Apps > MATLAB Analysis.
2 Click New to get started with your code.
3 Under Examples, select Calculate high and low temperatures, and then click Create.
4 In the MATLAB Code area, customize the code as displayed below. Ensure that you change the
values assigned to readChannelID, readAPIKey and writeAPIKey fields to match the actual values
corresponding to your channel. After you write the code, click Save and Run.
readChannelID = xxxxxx;
TemperatureFieldID = 1;
readAPIKey = 'XXXXXXX';
[tempF,timeStamp] = thingSpeakRead(readChannelID,'Fields',TemperatureFieldID, ...
'numDays',1,'ReadKey',readAPIKey);
[maxTempF,maxTempIndex] = max(tempF);
[minTempF,minTempIndex] = min(tempF);

timeMaxTemp = timeStamp(maxTempIndex);
timeMinTemp = timeStamp(minTempIndex);

display(maxTempF,'Maximum Temperature for the past 24 hours is');


display(minTempF,'Minimum Temperature for the past 24 hours is');

writeAPIKey = 'XXXXXXXX';

thingSpeakWrite(readChannelID,[minTempF,maxTempF],'WriteKey',writeAPIKey,'Fields',[2,3]);

pause(1)

Run MATLAB Code to Obtain Temperature Data from BMP280 Sensor

After you configure ThingSpeak channel, you can run the MATLAB code on the Arduino board that
has BMP280 sensor connected. The MATLAB code uses channel ID and its Write API Key to publish
data over IoT to the ThingSpeak channel.

The bmp280 object in MATLAB Suport Package for Arduino Hardware establishes a connection to the
connected BMP280 sensor and reads the temperature data.

Run these commands, one after the other, in the MATLAB command window (it is assumed that
Arduino board is connected to the COM9 port). Replace channel ID (first argument in
thingSpeakWrite function) and the Write API Key to match the actual values corresponding to your
channel.
a=arduino('COM9','Uno','Libraries','I2C')

sensorObj=bmp280(a);

while 1
temp=readTemperature(sensorObj);
thingSpeakWrite(xxxxxx,temp,'WriteKey','XXXXXXXXX','Fields',1);
pause(300); %sending data every 5 minutes

end

Note: To stop the while loop and stop executing the code (to stop sending data to the ThingSpeak
channel), press Ctrl+C in the MATLAB Command Window.

9-38
IoT-Based Temperature Monitoring Using ThingSpeak and Arduino Hardware

The data from BMP280 sensor is sent to the channel every 5 minutes. You can view the Channel
Stats in ThingSpeak and observe the live temperature and the maximum and minimum recorded
temperature till that time. This figure shows an example of recorded data based on live temperature
sent from BMP280 sensor over IoT using ThingSpeak. The figure shows the plot of temperature
variation and displays the two Numeric Display widgets that you added.

Set Up Email Alert for Temperature Beyond Threshold Using ThingSpeak

After the data from the BMP280 sensor connected to Arduino board is available in the ThinkSpeak
channel, you can set up an email alert that triggers an email. The email will be sent to the email ID
registered with your ThinkSpeak account, whenever the temperature exceeds a threshold.

To set up the email alert:

1 Click Apps > MATLAB Analysis.


2 Click New to get started with your code.
3 Under Examples, select Read channel to trigger email, and then click Create.
4 In the MATLAB Code area, customize the code as shown below. Ensure that you change the
values assigned to readChannelID and readAPIKey fields to match the actual values
corresponding to your channel. The alertAPIKey is the one associated with your profile in
ThingSpeak. After you write the code, click Save and Run.

% Enter your MATLAB Code below


readChannelID = xxxxxxx;

9-39
9 Arduino Explorer

% Temperature Field ID
TemperatureFieldID = 1;

% Channel Read API Key


% If your channel is private, then enter the read API Key between the '' below:
readAPIKey = 'XXXXXXXXXX';

% Read temperature data for the last 24 hours.

[tempF,timeStamp] = thingSpeakRead(readChannelID,'Fields',TemperatureFieldID, ...


'numDays',1,'ReadKey',readAPIKey);

% Calculate the maximum and minimum temperatures


[maxTempF,maxTempIndex] = max(tempF);
[minTempF,minTempIndex] = min(tempF);

alertApiKey='XXXXXXXXX';
alertURL = "https://api.thingspeak.com/alerts/send";

options = weboptions("HeaderFields", ["ThingSpeak-Alerts-API-Key", alertApiKey ]);


alertBody = sprintf("It's hot here and the temperature is %0.2f°F!.", maxTempF);
alertSubject = sprintf("Temperature exceeded threshold!");
try
webwrite(alertURL, "body", alertBody, "subject", alertSubject, options);
catch
% Code execution will end up here when an error 429 (error due to frequent request) is ca
end

You can set up a React app that triggers the email alert, as configured above, when the temperature
exceeds a particular temperature.

To do this, click Apps > Actions > React, and then configure the app as shown in this image (the
MATLAB Analysis app that you configured as shown above is saved with the name, Alert).

9-40
IoT-Based Temperature Monitoring Using ThingSpeak and Arduino Hardware

9-41
9 Arduino Explorer

Click Save React. Whenever the room temperature, as read by the BMP280 sensor, exceeds 26
degree Celsius, an email is sent to the ThingSpeak-registered email ID. This figure shows a sample
email based on the alertBody and alertSubject fields that you configured in the MATLAB
Analysis app.

9-42

You might also like