Arduinoio Ug
Arduinoio Ug
Arduinoio Ug
Hardware
User’s Guide
R2023b
How to Contact MathWorks
Phone: 508-647-7000
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
I2C Sensors
2
Arduino I2C Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2
iii
Measure Temperature from I2C Device on Arduino Hardware . . . . . . . . . 2-5
SPI Sensors
3
Arduino and SPI Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-2
Servo Motors
4
Servo Motors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-2
iv Contents
Calibrate BNO055 Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-50
Calibrate Magnetometer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-50
Calibrate Accelerometer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-50
Calibrate Gyroscope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-51
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
v
Custom Add-On Library Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-3
Command Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-3
Required Knowledge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-3
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
Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-27
vii
Connect Arduino to MATLAB over Wi-Fi . . . . . . . . . . . . . . . . . . . . . . . . . . 7-29
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
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
viii Contents
1
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:
This support package supports Arduino Uno, Arduino Mega 2560 and Arduino Due hardware.
1-2
Install Support for Arduino Hardware
Install the MATLAB Support Package for Arduino Hardware to add support for Arduino devices.
• 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.
• 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.
• 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.
• 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
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.
1-6
Set up and Configure Arduino Hardware
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.
1-10
Set up and Configure Arduino Hardware
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
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
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.
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.
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).
1-15
1 Setup and Configuration
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
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.
• 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.
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).
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
1-20
Set up and Configure ESP32 Hardware
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
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
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.
1-28
Pair a Bluetooth Device and Retrieve the Bluetooth Device Address
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
Make sure the Arduino or ESP32 hardware is connected to the computer. If the device is unofficial,
note the port and the board name.
a = arduino()
a =
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
If you are using an unofficial (clone) Arduino hardware, specify port and board name to establish
connection.
a = arduino('COM4','Uno')
a =
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
1-32
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
• 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.
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
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.
a = arduino;
Write data to the digital pin to turn the LED on and off repeatedly for 10 seconds.
Change the brightness from maximum to minimum using the digital pin's PWM duty cycle.
clear a
1-38
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
If you have more than one Arduino board connected, specify the port and board type.
clear a;
a = arduino('COM4', 'Uno');
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);
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
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.
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.
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.
time = time - 1;
pause(0.1);
end
Clean up
clear a
1-43
2
I2C Sensors
• 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.
2-2
Communicate with an I2C EEPROM Device
a = arduino('COM22','Uno','Libraries','I2C');
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(eeprom,[8 'rld!']);
Write 0 in order to read from the first byte of the first page.
write(eeprom,0);
char(read(eeprom,12))
ans =
Hello World!
2-3
2 I2C Sensors
writeRegister(eeprom,80,5);
readRegister(eeprom,80)
ans =
2-4
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.
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-5
2 I2C Sensors
addrs = scanI2CBus(a)
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
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.
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
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
Clean Up
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
% Temperature in °C
T = double(digitalT) * resolution;
end
2-8
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.
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.
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
Read acceleration.
acceleration = readAcceleration(lsmObj)
acceleration = 1×3
This function returns one sample of acceleration data. For more information, see
readAcceleration.
angularVelocity = readAngularVelocity(lsmObj)
angularVelocity = 1×3
This function returns one sample of angular velocity data. For more information, see
readAngularVelocity.
magneticField = readMagneticField(lsmObj)
magneticField = 1×3
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
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
3-3
3 SPI Sensors
It is also recommended that you place a 1uF decoupling capacitor between VCC and Gnd.
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.
Cspin = 'D10';
eeprom =
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
readCmd = 0b00000011;
writeCmd = 0b00000010;
writeEnable = 0b00000110;
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];
ans =
0 0 0 0 0 0 0 0
returnedData =
disp(char(returnedData(4:end)));
Hello
3-5
3 SPI Sensors
This example shows how to use the MATLAB® Support Package for Arduino® Hardware to use SPI
interface to communicate with 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.
If you are using a different board, make sure you connect to the correct pins.
3-6
Communicate with SPI Device on Arduino Hardware
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
Clean up
clear d_pot a
3-8
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
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.
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
This example shows how to use the MATLAB® Support Package for Arduino® Hardware to control a
hobby servo motor.
Hardware setup
4-4
Control Servo Motors
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');
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)
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.
Clean up
clear s a
4-6
5
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
5-2
Push Button Control with 74HC165 Shift Register
5-3
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
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'
Monitor the states of the four push buttons, and print out a message if at least one button 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
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
5-5
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
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
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.
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" ;
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.
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.
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.
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
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
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.
%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
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
5-16
Classify and Count Fruits Using Arduino Nano 33 BLE Sense, ThingSpeak, and Machine Learning
while(proximReadings <0.1)
proximReadings = readProximity(apds9960Obj);
end
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
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.
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
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
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
5-27
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
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.
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 shapes_training_data
5-28
Identify Shapes Using Machine Learning on Arduino Nano 33 BLE Sense Hardware
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.
To set up a connection with the Arduino board, create an arduino object and specify name of the
board.
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.
Specify the number of frames to be captured per gesture in the while loop. For this example, set that
value to 100.
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;
Extract
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
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
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
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:
5-34
Control 7-Segment Display with 74HC595 Shift Register
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,
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
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
Hardware Setup
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
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: []
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.
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
5-39
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
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
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
Hardware Setup
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);
rpm = readSpeed(encoder1);
fprintf('Current motor speed is: %.2f\n',rpm);
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));
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.
5-44
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
2. Connect an FS5106B motor to servo motor port 1, labeled 'Servo 1' 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.
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)
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
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);
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
5-47
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
5-48
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:
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
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:
5-51
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
5-52
Create Standalone Applications for Arduino Hardware
LCD Add-on
To create the LCD add-on, see “Create LCD Add-on” on page 6-21.
Required Products
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.
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.
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:
5-55
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
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).
• 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:
>> 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.
• 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.
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
• 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.
5-59
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
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.
• 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.
Updating server code on board Uno (COM9). This may take a few minutes.
5-61
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
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:
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
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
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.
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.
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
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.
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
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
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
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.
• 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:
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.
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.
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.
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
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.
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
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
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
• 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
5-77
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
a = arduino('COM6','Mega2560','Libraries','Serial');
gps = gpsdev(a)
gps =
gpsdev with properties:
SerialPort: 1
BaudRate: 9600 (bits/s)
SamplesPerRead: 1
ReadMode: "latest"
SamplesRead: 0
SamplesAvailable: 0
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 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.
5-78
Plot Position Using GPS Connected to Arduino Hardware
Clean Up
delete(gps);
clear gps;
clear a;
5-79
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
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.
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.
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.
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
• “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
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.
5-81
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
Configure and Run Models on the Arduino Board and the Android Device
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
References
5-83
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
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
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 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: []
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 =
Channel with properties:
5-85
5 Shift Registers, Quadrature Encoders, Adafruit Motor Shield V2 and CAN
readMsg = read(rxObj)
readMsg=1×8 timetable
Time ID Extended Name Data Length Signa
________________________ ___ ________ __________ ___________ ______ _______
readMsg.Data
readMsg.Data{:}
ans =
1 2 3 4 5 6 7 8
Clean Up
clear txObj;
clear arduinoUnoObj;
clear rxObj;
clear arduinoMKRObj;
5-86
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
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 a CAN channel connected to the VN1610 device using the canChannel function from the
Vehicle Network Toolbox.
Create a connection to the CAN channel linked to the Arduino Mega2560 board using canChannel
from the MATLAB Support Package for Arduino Hardware.
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, 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
________________________ ___ ________ _____________ ___________ ______ ____
arduinoRx.Signals{1}.EngineRPM
ans = 2000
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
____________ ___ ________ _____________ ___________ ______ ____________
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
____________ ____________ _________
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=2×8 timetable
Time ID Extended Name Data Length Signal
____________________ ___ ________ _____________ ___________ ______ ________
Clean Up
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
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
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 transmit CAN channel object on which you can use the automatic message transmit
commands using the canChannel function from Vehicle Network Toolbox™.
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 CAN messages for periodic transmit using the database information.
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
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);
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(rxCh, 100)
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);
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);
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.
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])
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
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
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.
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
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));
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
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:
This table shows the steps required to create a custom Arduino add-on library.
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
This schematic shows the construction of a custom Arduino add-on library and its relation to the
hardware.
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
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:
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
The C++ header requires several properties and methods that must be overridden from the base
class:
Note Use only ASCII characters for file include path, C++ class name, and variables.
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:
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;
}
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:
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();
}
}
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:
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:
...
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
The MATLAB class for your library must inherit from the matlabshared.addon.LibraryBase
class:
Note Use only ASCII characters for class, package, function, script, and variable names in your
MATLAB class.
To implement your MATLAB add-on class, you must override the following properties and method:
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
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:
The “Create LCD Add-on” on page 6-21 example shows the commandIDs in the LCDAddon.m
classdef file as:
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:
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:
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.
DependentLibraries = {'i2c'};
Constructor
The constructor for your add-on must initialize the add-on object in two ways:
methods
…
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.
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
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 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.
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
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.
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.
1 Create a MATLAB class, and define the command ID for each command that is sent to the server
on the board.
Define the class constructor, set the methods to call the class constructor, and set the parent
property.
6-18
Create HelloWorld Add-On
obj.Parent = parentObj;
end
...
end
end
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.
end
Register Add-On
To register your add-on library, add the working folder that contains +arduinoioaddons to the
MATLAB path:
addpath C:\Work
Once you add the folder to the path, you should see the files listed in the MATLAB Current Folder
browser.
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.
Create an arduino object and include the new library. 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.
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
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
6-21
6 Custom Arduino Libraries
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
6-23
6 Custom Arduino Libraries
Required Hardware
6-24
Create LCD Add-on
• 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.
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.
byte cursorRow = 0;
Create the constructor that defines the library name. Declare the debug strings and register the
library to the server.
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:
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;
}
Create a command that takes an input and prints it on the LCD screen.
6-27
6 Custom Arduino Libraries
sendResponseMsg(cmdID, 0, 0);
break;
}
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);
}
};
Define custom command IDs for all public methods of the LCD class sent to the server on the board.
Override constant properties in the class to include necessary header and third-party source files.
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
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.
• 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;
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
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;
obj.Rows = output.Rows;
obj.Columns = output.Columns;
inputs = [output.Columns output.Rows];
cmdID = obj.LCD_INITIALIZE;
sendCommand(obj, obj.LibraryName, cmdID, inputs);
end
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
Add the location of the working folder that contains +arduinoioaddons to the MATLAB path. For
example:
addpath ('C:\Work');
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
a = arduino('com5','uno','libraries','ExampleLCD/LCDAddon','ForceBuildOn',true);
a =
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
initializeLCD(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.
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
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
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 =
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
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
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
7-4
Find ESP32 Port on Windows, Mac, and Linux
7-5
7 Troubleshooting in MATLAB Support Package for Arduino Hardware
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.
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
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
a = arduino()
Cannot detect Arduino hardware. Make sure original Arduino hardware is properly plugged in. Other
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')
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:
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
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.
7-9
7 Troubleshooting in MATLAB Support Package for Arduino Hardware
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.
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”.
• 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
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.
• 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
The most common cause of a lost connection is an unplugged cable. Check the cable and make sure
that it is firmly plugged in.
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','');
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.
Make sure that the power line is always connected. With I2C devices, the server code can stop
working if the power line is disconnected.
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);
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.
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','');
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
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
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:
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.
On the Arduino Due, when you set the SPI Mode in Mode 3, the first write works sporadically. See
this link for more details.
You cannot write more than 32 bytes of data to I2C EEPROM attached to an Arduino Due board in a
single transmission.
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.
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.
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
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.
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.
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.
You cannot write more than 32 bytes of data to I2C EEPROM attached to an Arduino Uno or Mega
boards in a single transmission.
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.
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
If you program the Arduino MKR1010 board accidentally as the MKR1000, you need to reconfigure it.
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.
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
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.
To workaround this issue, specify the port and board while creating an arduino object.
7-19
7 Troubleshooting in MATLAB Support Package for Arduino Hardware
7-20
Serial Device Issues
Data Issues
Incorrect values of NumBytesAvailable
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
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
In this section...
“Adafruit Motor Shields” on page 7-23
“Servo Issues” on page 7-24
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.
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.
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
1 Make sure that the folder with the custom library is added to the MATLAB path.
2 Run the following commands:
clear classes
b Rehash toolbox cache.
rehash toolboxcache
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
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 = 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.
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
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.
• 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
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.
• 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
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.
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
The kit includes a one-year individual user MATLAB license that includes all of these products with
version R2021a:
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
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.
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.
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
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
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.
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.
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:
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
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
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
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.
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:
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
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
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.
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.
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:
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
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.
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
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.
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
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.
• 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.
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.
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.
Use the Pin Configuration panel corresponding to the I2C interface to perform one of these
operations.
• Read or write
9-9
9 Arduino Explorer
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.
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
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
• 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.
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:
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.
9-18
Using Arduino Explorer App
• Show legend
• Show grid
• Display multiple Y-axes
• Scale Y-axes
9-19
9 Arduino Explorer
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
• 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
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):
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
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
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);
temp=readTemperature(sensorObj);
while 1
% Read Data
temp=readTemperature(sensorObj);
if (temp>threshold)
if flag==0
tic;
flag=1;
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.
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.
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.
'numDays',1,'ReadKey',readAPIKey);
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
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
• 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.
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.
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.
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
timeMaxTemp = timeStamp(maxTempIndex);
timeMinTemp = timeStamp(minTempIndex);
writeAPIKey = 'XXXXXXXX';
thingSpeakWrite(readChannelID,[minTempF,maxTempF],'WriteKey',writeAPIKey,'Fields',[2,3]);
pause(1)
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.
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.
9-39
9 Arduino Explorer
% Temperature Field ID
TemperatureFieldID = 1;
alertApiKey='XXXXXXXXX';
alertURL = "https://api.thingspeak.com/alerts/send";
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