Introduction
The Arduino® MKR IoT Carrier is equipped with a lot of different sensors, actuators and also a little display to let your IoT device communicate with the outside world in the easiest way possible. It only works if an Arduino board from the MKR family it attached on its top.
The MKR IoT Carrier comes equipped with:
- RGB LEDs
- Capacitive touch buttons
- Rounded 1.3” TFT display
- Grove connectors
- IMU Accelerometer & Gyroscope
- Humidity & Temperature
- Pressure
- RGB and Gesture
- Relays
- Buzzer
- Battery holder for a 18650 Li-Ion battery
- SD Card slot
I’ll talk about each one of those I/O devices later on this post!
Compatible Boards
The MKR family boards offers different features but share a common pinout so that they can all be easily connected to the MKR IoT Carrier.
Here is a list of the MKR boards:
- MKR WiFi 1010
Basic IoT and pico-network application design - MKR Zero
Made for music makers: provides an SD Card slot and dedicated SPI interfaces - MKR 1000 WiFi
Basic IoT and pico-network application design (just like MKR WiFi 1010) - MKR FOX 1200
Entry point to start working with the European Sigfox networks. - MKR GSM 1400
Build IoT projects connected to GSM / 3G network - MKR NB 1500
Communicates over NB-IoT and LTE-M networks - MKR Vidor 4000
The only board with FPGA chip, camera & HDMI connector - MKR WAN 1300
First LoRa® board released by Arduino - MKR WAN 1310
Connects to Arduino LoRa® PRO Gateway, existing LoRaWAN® infrastructure like The Things Network, or even other boards
Mount the Carrier
The chosen Arduino MKR board needs to be mounted on top of the MKR IoT Carrier and connected to a computer using a USB cable of type B-mini.
Pinout
The official image clearly shows the Carrier pinout.
Carrier library
All the code snippets used below assume that you include Arduino_MKRIoTCarrier
library and instantiate an object of type MKRIoTCarrier
.
For these reasons, this sketch could be used as template for all your projects with the Carrier:
// include the library
#include <Arduino_MKRIoTCarrier.h>
// instantiate the object
MKRIoTCarrier carrier;
void setup() {
// CARRIER_CASE refers to the plastic casing in the kit
// and the capacitive buttons on the carrier.
// set to 'true' when the plastic casing is used
// set to 'false' when not (default).
CARRIER_CASE = false;
// initialize the object
carrier.begin();
// ...
}
void loop() {
// ...
}
Moreover, Arduino_MKRIoTCarrier
library includes lots of other libraries to control the I/O devices.
Those libraries are all mentioned in the Quoted Libraries section of this post.
RGB LEDs
The Carrier comes with 5 digital RGB LEDs placed on the top side of the carrier in front of the buttons.
The LEDs are controlled with the Adafruit’s DotStar
library.
You can control the LEDs with those methods:
// update the new state of the LEDs
carrier.leds.show();
// set the color of the index's LED
carrier.leds.setPixelColor(index, green, red, blue);
// set the overall brightness, from 0 (no brightness) to 255 (maximum brightness)
carrier.leds.setBrightness(0-255);
// clear the buffer of the LEDs
carrier.leds.clear();
// fill a given amount of the LEDs with the same color
carrier.leds.fill(color, firstLedToCount, count);
// save a custom color
uint32_t myColor = carrier.leds.Color(green, red, blue);
Take a look at RGB-LEDs
directory from arduino-projects
GitLab repository.
Capacitive touch buttons
The Carrier has five capacitive qTouch buttons on its top, numbered from 00
to 04
.
The buttons are sensitive to direct touch and detect wireless touch.
You can control the buttons with those methods:
// replace X with a number from 0 to 4
// reads the state of the pads
// put this on the top of 'void loop()' method
carrier.Buttons.update();
// get if the pad is getting touched
// it's value is 'true' until it gets released
carrier.Buttons.getTouch(TOUCHX);
carrier.ButtonX.getTouch();
// i.e. carrier.Buttons.getTouch(TOUCH0);
// i.e. carrier.Button0.getTouch();
// get when have been a touch down
carrier.Buttons.onTouchDown(TOUCHX);
carrier.ButtonX.onTouchDown();
// get when the button has been released
carrier.Buttons.onTouchUp(TOUCHX);
carrier.ButtonX.onTouchUp();
// get both, touched and released
carrier.Buttons.onTouchChange(TOUCHX);
carrier.ButtonX.onTouchChange();
Take a look at touch
directory from arduino-projects
GitLab repository.
Rounded 1.3” TFT display
The screen on the Carrier has a 240 x 240
resolution and a diameter of 36 x 40 mm
.
The display is controlled through the Adafruit-ST7735-Library
.
Every color with the prefix 'ST77XX_'
(i.e. 'ST77XX_BLACK'
) can be used without having to know its hexadecimal value.
Colors available from the library are BLACK
, WHITE
, RED
, GREEN
, BLUE
, CYAN
, MAGENTA
, YELLOW
and ORANGE
.
You can configure and control the display with those methods:
// set the display background using hexadecimal codes
carrier.display.fillScreen(color);
// set the angle of the screen, 0 is the starting position with no rotation
// the screen can only be rotated 90, 180 or 270 degrees by replacing the 0 with 1, 2 or 3
carrier.display.setRotation(0);
// print the text inside the string at the current cursor position
display.print("Hello World!");
// display a bitmap visual. 'x' and 'y' are the top left coordinates where the visual is drawn
// 'w' and 'h' are the width and height of the visual. The data for the 'bitmap_visual' graphic
// can be stored as a byte array and used as the 'bitmap_visual'
carrier.display.drawBitmap(x, y, bitmap_visual, w, h, color);
// set the color of the text using hexadecimal codes
carrier.display.setTextColor(color);
// set the text size
carrier.display.setTextSize(number);
// indicate the position, given in pixel, where printing starts
carrier.display.setCursor(x, y);
Take a look at display
directory from arduino-projects
GitLab repository.
Grove connectors
The Carrier comes with three grove connectors (2
analog and 1
I2C) that enables you to easily connect external sensors.
The type of the connector is labeled clearly on the back of the carrier.
IMU & Gyroscope
The LSM6DSOXTR microcontroller from STM is an IMU (Inertial Measurement Unit) that features a 3D digital accelerometer and a 3D digital gyroscope. It also features a machine learning core, which is useful for any motion detection projects, such as free fall, step detector, step counter, pedometer.
The unit is placed underneath the Carrier’s display. It connects to the mounted Arduino MKR board through an I2C interface, and acquires Low power consumption (0.55mA at most).
Accelerometer range is set at ±4 g
with a resolution of 0.122 mg
.
Gyroscope range is set at ±2000 dps
with a resolution of 70 mdps.
Output data rate is fixed at 104 Hz
.
You can find some code examples in IMU-accelerometer-and-gyroscope
directory from arduino-projects
GitLab repository.
Humidity & Temperature
The HTS221 Humidity Sensor is mounted on the top side of the carrier under the display, marked with a drop icon.
The sensor uses capacitive sensing with a humidity sensing range of 0-100%
and accuracy of ± 3.5% rH
(20
to +80% rH
), and a temperature sensing range of -40
to 120° C
, with an accuracy of ± 0.5 °C
, 15
to +40 °C
.
The sensor uses a low power consumption (2μA
at 1 Hz
sampling rate) and connects to the mounted Arduino MKR board through a I2C
interface.
The values from those sensors can be stored in float
variables, as shown below:
// get temperature value in Celsius
carrier.Env.readTemperature();
// get relative humidity (rH) in percentage
carrier.Env.readHumidity();
float temperature = carrier.Env.readTemperature();
float humidity = carrier.Env.readHumidity();
Pressure
The LPS22HBTR Pressure Sensor is mounted on the top side of the carrier under the display, marked with a meter icon.
The sensor measures absolute pressure range of 26
to 126
kPa
(kilopascal) which is equivalent to 0.25
to 1.24
atm
(Atmosphere) and connects to the mounted Arduino MKR board through a I2C
interface.
The values from the pressure sensor can be stored in float
variables, as shown below:
// returns pressure value in Kilopascal (kPa)
float pressure = carrier.Pressure.readPressure();
RGB and Gesture
The Carrier contains a Broadcom APDS-9660 RGB and Gesture sensors, placed under the display and marked with a bulb icon. It is very useful for ambient light, and RGB color sensing, proximity sensing, gesture detection and even more.
Moreover, it defines the enumerator below to easily control which type of gesture has been performed:
// Arduino_MKRIoTCarrier.h
// [around line 80]
//Gesture change for APDS9960
enum {
NONE = -1,
DOWN = 3,
UP = 2 ,
LEFT = 1,
RIGHT = 0
};
Take a look at gesture
directory from arduino-projects
GitLab repository.
Moreover, by using the same sensor, you can also interact with the RGB sensor: its color values can be stored into int
variables.
The function below requires 3 or 4 integer variables as arguments where the read color will be stored:
r
: the red component of the read color,g
: the green component of the read color,b
: the blue component of the read color,a
: the ambient light intensity.
int r, g, b, a;
carrier.Light.readColor(r, g, b, a);
Take a look at color-test
sketch from gesture
directory.
Relays
The Carrier has two 5V
Coil voltage KEMET EE2-5NU-L relays, located on its back side.
The relays are non-latching with the following contacts:
COM
(Common),NO
(Normally open),NC
(normally closed)
They can take up a max of 2A
(Ampere) and 24V
(Volt) of input each.
Once the cables are introduced inside the connectors, they will automatically be locked inside. To unlock a cable and remove it from the connector, you need to insert a tool through the top rectangular hole (a flat screwdriver, a hard piece of plastic or something similar). As you can see in the picture below, the wires must be places inside the round holes stroked in blue. While to unlock the wires you need to insert the flat screwdriver inside the red-stroked rectangular holes.
Moreover, the L1
and L2
LEDs on the front of the Carrier are visual indicators of the relays’ state: if the LED
is ON
, it means that relay’s COM
and NO
terminal are connected, while if the LED
is OFF
it means that COM
and NC
are connected.
How it works
Relay has two groups of pins: low voltage group and high voltage group.
low voltage group are connected to Arduino:
GND
pin is connected toGND
pinVCC
pin is connected toVCC
pinIN
pin receives the signal from Arduino through a digital input
high voltage group are connected to a high voltage device:
COM
pin (Common),NO
pin (Normally open),NC
pin (normally closed)
In the following schema, the Arduino Uno controls the DC Motor without having to dealt with the high voltage of the motor. Note that the schema is purely illustrative since when using the Arduino MKR IoT Carrier, you not need to care about the low-voltage group.
The relay works with two modes: normally open mode (NO
) and normally closed mode (NC
). These modes are the opposite.
To use the Normally Open mode, connect the high voltage device to the COM
and NO
open just like above.
// control the relays with
carrier.RelayX.open();
carrier.RelayX.close();
// reads the status of the relays
carrier.RelayX.getStatus();
You need to replace the placeholder X
with the numbers 1
or 2
.
// swap to the Normally Open (NO) circuit of relay 1 (turns it on)
carrier.Relay1.open();
// swap to the Normally Closed (NC) circuit of relay 2 (turns it off), default mode on power off
carrier.Relay2.close();
// boolean variable, returns the status: LOW means NC and HIGH means NO
bool relayStatus = carrier.Relay2.getStatus();
You can find some examples in relays-test
from arduino-projects
GitLab repository.
Buzzer
The Carrier is equipped with a sound buzzer on the bottom side of it, under the housing of the Arduino MKR board.
There are a couple of methods to control the buzzer:
Equivalent to tone()
: it will make the tone with the selected frequency.
carrier.Buzzer.sound(freq)
Equivalent to noTone()
: it will stop the tone signal.
carrier.Buzzer.noSound()
playMelody
Despite you could think to use a buzzer only to trigger the user’s attention, you could also use it for playing songs and let it accompany you as a counterpoint when you play an instrument.
That’s what I made in play_melody_on_carrier! Let’s drive into the major steps.
Define the header files:
musical-notes.h
filled with the notes constants fromB0
toD#8
(and a couple of bonus constants:END
andPAUSE
)musical-constants.h
filled with the notes’ duration (i.e. semibreve, minim, crotchet)songs.h
that contains bi-dimensional arrays filled with the notes (in a row) and their duration (in the other row).
The 4
th step is, off course, to write the script that brings it all together, but the code is already very well self-documented with lots of comments all around. So jump right into play_melody_on_carrier.ino to learn it all!
Battery holder for a 18650 Li-Ion battery
The Carrier can be either powered through a USB cable connected to the mounted MKR board, or through a battery. The battery used should be a LI-ION 18650 3.7 v
battery, which can be mounted to the carrier via the battery holder on the bottom side.
A cable with JST
connectors on both ends are needed to connect the MKR IoT Carrier and the MKR board. The Battery can then be recharged via a USB connection through the MKR Board (Runs up to 48h
with a 3.7v 2500mAh
).
SD Card slot
The Carrier contains a SD Card slot that can hold a Micro SD, with which you can locally store data recorded from the sensors.
The SD
library supports FAT16
and FAT32
file systems on standard SD
cards and SDHC
cards. It uses short 8.3
names for files. The file names passed to the SD
library functions can include paths separated by forward-slashes, /
, e.g. "home/sunrise.txt"
.
Since the working directory is always the root of the SD
card, a name refers to the same file whether it includes a leading slash (e.g. "/file.txt"
is equivalent to "file.txt"
). As of version 1.0, the library supports opening multiple files.
The communication between the microcontroller and the SD
card uses SPI
, which takes place on digital pins 11
, 12
and 13
(on most Arduino boards). Additionally, another pin must be used to select the SD
card.
This can be the hardware SS
pin - pin 10
(on most Arduino boards) - or another pin specified in the call to SD.begin()
. Note that even if you don’t use the hardware SS
pin, it must be left as an output or the SD
library won’t work.
Conclusion
This is one of the very first steps to jump right into IoT development. I know this blog post is very complex and could be difficult to read and understand, but the I/O devices that the MKR IoT Carrier gives you are very complex too.
I tried to write the paragraphs and the code snippets as readable as possible!
Documentation
I took inspiration from Arduino Docs’ MKR IoT Carrier Cheat Sheet article to write this blog post.
You can also take a look at official MKR Datasheet.
Quoted Libraries
Here is the full list of libraries I quoted within this article:
Arduino libraries:
Arduino_MKRIoTCarrier
Arduino_MCHPTouch
Arduino_LSM6DS3
Arduino_HTS221
Arduino_LPS22HB
Arduino_APDS9960
SD
Adafruit libraries:
Other libraries:
MKR-IoT-Carrier
directory ofarduino-projects
GitLab repository