Arduino MKR IoT Carrier

post hero image

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:

  1. RGB LEDs
  2. Capacitive touch buttons
  3. Rounded 1.3” TFT display
  4. Grove connectors
  5. IMU Accelerometer & Gyroscope
  6. Humidity & Temperature
  7. Pressure
  8. RGB and Gesture
  9. Relays
  10. Buzzer
  11. Battery holder for a 18650 Li-Ion battery
  12. 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:

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.

Arduino MKR IoT 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:

  1. r: the red component of the read color,
  2. g: the green component of the read color,
  3. b: the blue component of the read color,
  4. 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.

zoom of input

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:

    1. GND pin is connected to GND pin
    2. VCC pin is connected to VCC pin
    3. IN pin receives the signal from Arduino through a digital input
  • high voltage group are connected to a high voltage device:

    1. COM pin (Common),
    2. NO pin (Normally open),
    3. 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.

schema 1

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:

  1. musical-notes.h filled with the notes constants from B0 to D#8 (and a couple of bonus constants: END and PAUSE)
  2. musical-constants.h filled with the notes’ duration (i.e. semibreve, minim, crotchet)
  3. songs.h that contains bi-dimensional arrays filled with the notes (in a row) and their duration (in the other row).

The 4th 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:

Adafruit libraries:

Other libraries: