Guide to Arduino GIGA USB Features

Learn how you can turn your USB device into a mouse or keyboard, how to read & write to a USB mass storage, and connecting a keyboard via the USB-A connector.

The GIGA R1 comes with a great range of supported USB features, including USB HID, USB Host and Mass Storage. It also comes with a USB-A connector that allow you to plug devices directly to your GIGA R1 board.

It can easily be configured to act as a mouse or keyboard (HID device) or as a USB Host (connect a keyboard, USB stick). This makes it possible to create powerful interfaces, and build complex interactive projects.

In this guide, we will take a look at the available features, how to enable them in a sketch and what circuit (if any) is required.

Hardware & Software Needed

Libraries

USB features on the GIGA R1 is currently enabled through three separate libraries.

These libraries each provides a set of methods to access the USB features on the board. This includes using the GIGA R1 as a mouse/keyboard (HID), reading & writing to mass storage devices & connecting external keyboards.

The examples provided in this guide are based on these libraries.

USB Overview

The GIGA R1 has two USB connectors:

  • USB-C - for powering, programming & HID communication.
  • USB-A - for USB-Host (connecting keyboards, USB sticks etc).

USB ports on GIGA R1.
USB ports on GIGA R1.

Note: do NOT connect the USB-A connector to your computer. This is not a programming port and if the

PA15
pin is enabled, it can damage your computer's USB port.

Below is an example of how you should use the USB-C / USB-A connectors.

Keyboard connected to USB-A port.
Keyboard connected to USB-A port.

Enable/Disable USB-A Port

To enable the USB-A port, you will need to define it as an output. You can also disable it inside of a sketch by writing a LOW state to it.

1void setup(){
2 pinMode(PA_15, OUTPUT); //enable the USB-A port
3}
4
5void loop(){
6 digitalWrite(PA_15, HIGH); //write a high state
7 digitalWrite(PA_15, LOW); //write a low state
8}

Please note that connecting devices to the USB-A that draw high amounts of current may cause the board to reset.

USB Mass Storage

The USB-A connector onboard the GIGA R1 can be used to connect USB mass storage devices, for example, a USB stick. This can be used for a number of applications, including:

  • Accessing large files such as images & audio files,
  • Logging large amounts of data,
  • Storing images or videos captured with a camera.

USB mass storage devices connected needs to be formatted with the FAT32 as a file system, using the MBR partitioning scheme. This is a requirement, and reading & writing will not work otherwise.

The USB mass storage features are based on the Arduino_USBHostMbed5 library.

USB Designation

To access the correct USB mass storage device, we need to specify the designation in the code.

1mbed::FATFileSystem usb("USB_DRIVE_DESIGNATION")

This is so that our GIGA R1 can target the right USB device. In addition, when reading & writing to files, please ensure that the designation is included in the path.

The below line of code is an example of how you need to use the designation in the path,

/usb/
before accessing the file.

1FILE *f = fopen("/usb/text.txt", "r+");

The designation is essential to consider when using the examples in this guide. All examples are based on the designation =

usb
. You will need to change this in the code, or else it will not work.

List File Directory

Below is an example sketch that can be used to list files in a USB mass storage device.

1#include <DigitalOut.h>
2#include <FATFileSystem.h>
3#include <Arduino_USBHostMbed5.h>
4
5USBHostMSD msd;
6mbed::FATFileSystem usb("usb");
7
8
9void setup()
10{
11 Serial.begin(115200);
12
13 pinMode(PA_15, OUTPUT); //enable the USB-A port
14 digitalWrite(PA_15, HIGH);
15
16 while (!Serial)
17 ;
18
19 Serial.println("Starting USB Dir List example...");
20
21 // if you are using a Max Carrier uncomment the following line
22 // start_hub();
23
24 while (!msd.connect()) {
25 //while (!port.connected()) {
26 delay(1000);
27 }
28
29 Serial.print("Mounting USB device... ");
30 int err = usb.mount(&msd);
31 if (err) {
32 Serial.print("Error mounting USB device ");
33 Serial.println(err);
34 while (1);
35 }
36 Serial.println("done.");
37
38 char buf[256];
39
40 // Display the root directory
41 Serial.print("Opening the root directory... ");
42 DIR* d = opendir("/usb/");
43 Serial.println(!d ? "Fail :(" : "Done");
44 if (!d) {
45 snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
46 Serial.print(buf);
47 }
48 Serial.println("done.");
49
50 Serial.println("Root directory:");
51 unsigned int count { 0 };
52 while (true) {
53 struct dirent* e = readdir(d);
54 if (!e) {
55 break;
56 }
57 count++;
58 snprintf(buf, sizeof(buf), " %s\r\n", e->d_name);
59 Serial.print(buf);
60 }
61 Serial.print(count);
62 Serial.println(" files found!");
63
64 snprintf(buf, sizeof(buf), "Closing the root directory... ");
65 Serial.print(buf);
66 fflush(stdout);
67 err = closedir(d);
68 snprintf(buf, sizeof(buf), "%s\r\n", (err < 0 ? "Fail :(" : "OK"));
69 Serial.print(buf);
70 if (err < 0) {
71 snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
72 Serial.print(buf);
73 }
74}
75
76void loop()
77{
78}

File Read

Below is an example sketch that can be used to read files from a USB mass storage device.

1#include <Arduino_USBHostMbed5.h>
2#include <DigitalOut.h>
3#include <FATFileSystem.h>
4
5USBHostMSD msd;
6mbed::FATFileSystem usb("usb");
7
8// If you are using a Portenta Machine Control uncomment the following line
9mbed::DigitalOut otg(PB_14, 0);
10
11void setup() {
12 Serial.begin(115200);
13
14 pinMode(PA_15, OUTPUT); //enable the USB-A port
15 digitalWrite(PA_15, HIGH);
16
17 while (!Serial);
18
19 delay(2500);
20 Serial.println("Starting USB File Read example...");
21
22 // if you are using a Max Carrier uncomment the following line
23 //start_hub();
24
25 while (!msd.connect()) {
26 delay(1000);
27 }
28
29 Serial.println("Mounting USB device...");
30 int err = usb.mount(&msd);
31 if (err) {
32 Serial.print("Error mounting USB device ");
33 Serial.println(err);
34 while (1);
35 }
36 Serial.print("read done ");
37 mbed::fs_file_t file;
38 struct dirent *ent;
39 int dirIndex = 0;
40 int res = 0;
41 Serial.println("Open file..");
42 FILE *f = fopen("/usb/Arduino.txt", "r+");
43 char buf[256];
44 Serial.println("File content:");
45
46 while (fgets(buf, 256, f) != NULL) {
47 Serial.print(buf);
48 }
49
50 Serial.println("File closing");
51 fflush(stdout);
52 err = fclose(f);
53 if (err < 0) {
54 Serial.print("fclose error:");
55 Serial.print(strerror(errno));
56 Serial.print(" (");
57 Serial.print(-errno);
58 Serial.print(")");
59 } else {
60 Serial.println("File closed");
61 }
62}
63
64void loop() {
65
66}

File Write

Below is an example sketch that can be used to write files from a USB mass storage device.

1#include <Arduino_USBHostMbed5.h>
2#include <DigitalOut.h>
3#include <FATFileSystem.h>
4
5USBHostMSD msd;
6mbed::FATFileSystem usb("usb");
7
8// mbed::DigitalOut pin5(PC_6, 0);
9mbed::DigitalOut otg(PB_8, 1);
10
11void setup() {
12 Serial.begin(115200);
13
14 pinMode(PA_15, OUTPUT); //enable the USB-A port
15 digitalWrite(PA_15, HIGH);
16
17 while (!Serial);
18
19 msd.connect();
20
21 while (!msd.connected()) {
22 //while (!port.connected()) {
23 delay(1000);
24 }
25
26 Serial.println("Mounting USB device...");
27 int err = usb.mount(&msd);
28 if (err) {
29 Serial.print("Error mounting USB device ");
30 Serial.println(err);
31 while (1);
32 }
33 Serial.print("read done ");
34 mbed::fs_file_t file;
35 struct dirent *ent;
36 int dirIndex = 0;
37 int res = 0;
38 Serial.println("Open /usb/numbers.txt");
39 FILE *f = fopen("/usb/numbers.txt", "w+");
40 for (int i = 0; i < 10; i++) {
41 Serial.print("Writing numbers (");
42 Serial.print(i);
43 Serial.println("/10)");
44 fflush(stdout);
45 err = fprintf(f, "%d\n", i);
46 if (err < 0) {
47 Serial.println("Fail :(");
48 error("error: %s (%d)\n", strerror(errno), -errno);
49 }
50 }
51
52 Serial.println("File closing");
53 fflush(stdout);
54 err = fclose(f);
55 if (err < 0) {
56 Serial.print("fclose error:");
57 Serial.print(strerror(errno));
58 Serial.print(" (");
59 Serial.print(-errno);
60 Serial.print(")");
61 } else {
62 Serial.println("File closed");
63 }
64}
65
66void loop() {
67
68}

Datalogger Example

In the example below, we are reading logging the

A0
pin, where we are defining two parameters:

  • interval
    - how long between each reading.
  • number_of_readings
    - how many readings we should take.

This is useful if you e.g. want to log a specific amount of samples for a specific amount of time.

1#include <Arduino_USBHostMbed5.h>
2#include <DigitalOut.h>
3#include <FATFileSystem.h>
4
5USBHostMSD msd;
6mbed::FATFileSystem usb("usb");
7
8int err;
9int count;
10int number_of_readings = 100; //how many readings you want to take
11int interval = 10; //how long between readings (milliseconds)
12
13void setup() {
14 Serial.begin(115200);
15
16 pinMode(PA_15, OUTPUT); //enable the USB-A port
17 digitalWrite(PA_15, HIGH);
18
19 while (!Serial); //stop program from executing until serial port opens
20
21 msd.connect();
22
23 while (!msd.connected()) {
24 Serial.print("MSD not found.");
25 delay(1000);
26 }
27
28 Serial.println("Mounting USB device...");
29
30 err = usb.mount(&msd);
31 if (err) {
32 Serial.print("Error mounting USB device ");
33 Serial.println(err);
34 while (1)
35 ;
36 }
37 Serial.print("read done ");
38
39 //function to write to file
40 WriteToFile();
41}
42
43void loop() {
44}
45
46void WriteToFile() {
47 mbed::fs_file_t file;
48 struct dirent *ent;
49 int dirIndex = 0;
50 int res = 0;
51
52 Serial.println("Opening file..");
53 FILE *f = fopen("/usb/log.txt", "w+");
54
55 for (int i = 0; i < number_of_readings; i++) {
56 count += 1;
57
58 Serial.print("Reading Nr: ");
59 Serial.print(count);
60 Serial.print(", Value: ");
61 Serial.println(analogRead(A0));
62
63 fflush(stdout);
64
65 int reading = analogRead(A0);
66
67 err = fprintf(f, "%s", "Reading Nr: ");
68 err = fprintf(f, "%d", count);
69 err = fprintf(f, "%s", ", Value: ");
70 err = fprintf(f, "%d\n", reading);
71
72 if (err < 0) {
73 Serial.println("Fail :(");
74 error("error: %s (%d)\n", strerror(errno), -errno);
75 }
76 delay(interval);
77 }
78
79 Serial.println("File closing");
80 fflush(stdout);
81 err = fclose(f);
82
83 if (err < 0) {
84 Serial.print("fclose error:");
85 Serial.print(strerror(errno));
86 Serial.print(" (");
87 Serial.print(-errno);
88 Serial.print(")");
89 } else {
90 Serial.println("File closed");
91 }
92}

After logging data, remove the USB stick from your board, and insert it in your computer to see the data logged:

Data logged in .txt file.
Data logged in .txt file.

USB Host Keyboard

It is possible to connect generic USB keyboards to the GIGA R1's USB-A connector without any additional circuitry.

The library used for this can be downloaded through Github.

Please note that this library is in Alpha development stage. This means support is experimental and examples may not function as expected. Future versions of this library may break the example provided below.

The USBHostGiga library is not available in the Arduino IDE and needs to be installed manually. You can do so my navigating to

Sketch
>
Include Library
>
Add .ZIP Library
.

1#include "USBHostGiga.h"
2
3//REDIRECT_STDOUT_TO(Serial)
4Keyboard keyb;
5HostSerial ser;
6
7void setup() {
8 // put your setup code here, to run once:
9 Serial.begin(115200);
10 while (!Serial);
11 pinMode(PA_15, OUTPUT);
12 keyb.begin();
13 ser.begin();
14}
15
16
17void loop() {
18 if (keyb.available()) {
19 auto _key = keyb.read();
20 Serial.println(keyb.getAscii(_key));
21 }
22 while (ser.available()) {
23 auto _char = ser.read();
24 Serial.write(_char);
25 }
26 //delay(1);
27}

USB HID

It is possible to turn your GIGA R1 board into a Human Interface Device (HID), aka mouse & keyboard, using the USBHID library which is included in the GIGA Board Package.

Among other things, you can:

  • Create a custom keyboard, or a keyboard accessory,
  • Create sophisticated game controllers,
  • Accessories for VR/AR applications.

Keyboard

Important! When using the GIGA as a keyboard, make sure to include some sort of delay. Otherwise, you may end up printing things very fast, which can be an annoyance. If this happens nonetheless, double tap the reset button and upload a blank sketch to reset the board.

To emulate a keyboard, we need to include

PluggableUSBHID.h
and
USBKeyboard.h
, and create an object using the
USBkeyboard
constructor.

1#include "PluggableUSBHID.h"
2#include "USBKeyboard.h"
3
4USBKeyboard Keyboard;

To send a single character, we can use the

putc()
method.

1Keyboard.putc(97); //prints the letter 'a'

See the

DEC
column at ascii-code.com to understand what number you need to print a specific character.

To print a whole string, use the

printf()
method.

1Keyboard.printf("Hello World!");

To use modifiers and function keys, use the

key_code()
method.

1Keyboard.key_code(KEY_F1);

To use media keys, use the

media_control()
method.

1Keyboard.media_control(KEY_NEXT_TRACK);

All modifiers, function and media control keys can be found in this header file.

Mouse

To emulate a mouse, we need to include

PluggableUSBHID.h
and
USBMouse.h
, and create an object using the
USBMouse
constructor.

1#include "PluggableUSBHID.h"
2#include "USBMouse.h"
3
4USBMouse Mouse;

To move the cursor, we can write the x and y coordinates directly, using the

move()
method.

1Mouse.move(100,100);

For clicking the mouse, use the

click()
method.

1Mouse.click(MOUSE_LEFT);
2Mouse.click(MOUSE_RIGHT);
3Mouse.click(MOUSE_MIDDLE);

For double clicking the mouse, use the

double_click()
method.

1Mouse.double_click(MOUSE_LEFT);

To press and release the buttons on the mouse, we can use the

press()
and
release()
methods. This way, we can define how long we want the button to be pressed for.

1Mouse.press(MOUSE_LEFT);
2Mouse.press(MOUSE_RIGHT);
3Mouse.press(MOUSE_MIDDLE);
4
5delay(1000);
6
7Mouse.release();

Summary

The goal with this guide was to provide a summary of all the GIGA R1's features, including:

  • Enabling and disabling the USB-A port.
  • Read & Write to a USB mass storage device (MSD).
  • Connecting keyboards and reading key presses.
  • Emulate a mouse/keyboard through the HID interface.

Suggest changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.