Arduino Robotics Board Documentation
This board is a flexible platform with a variety of I/O for different applications and has been designed to be used either as a standalone platform or in conjunction with a Raspberry Pi.
Included are:
- Socketed Arduino Nano 33 BLE
- Socketed Pololu TB6612FNG Dual Motor Driver
- 2x Motor Header connectors, designed for use with the Pololu Magnetic Encoder Kit
- 2x 2x4-pin headers for use with up to 4 HC-SR04 ultrasonic range sensors. Can also be used for GPIO if not otherwise required
- 4x I2C buses to allow for multiple devices with the same address to be used
- These break out into both JST connections for direct connection to devices such as the Sharp GP2Y0E02B optical sensor, and regular 2.54mm pin headers for general use
- 1x SPI header for interfacing with other devices
- 1x UART header for connecting devices to the Arduino's UART pins
- This is also accessible through the secondary serial USB connection
- A row of general purpose headers, including GND, +5V, +3V and GPIO
- A 4-way button.
- 2 sets of DIP switches to configure parts of the board
- 5V power in via USB micro B
- A convenient reset switch
All headers and their pinouts are labelled on the board silkscreen.
The encoder input, SPI, ultrasonic signal, GPIO and UART pins have over-voltage and over-current protection on the board. Please avoid connection directly to the Arduino as this will bypass the included protection.
Hardware
This section gives the hardware details of the board to enable proper use of all the board features and assist in writing programming for the board.
Arduino Nano 33 BLE
The Arduino Nano 33 BLE is a derivative of the regular Arduino Nano based on a nRF52840 microcontroller that includes on-board support for Bluetooth Low-Energy. It also includes a 9-axis IMU and an onboard user programmable RGB LED. It has a pinout equivalent to the regular Arduino Nano, but is only 3V3 tolerant, as opposed to the regular Nano which operates at 5V, so care must be taken if using the two interchangeably. The Nano is programmed via its onboard micro USB B connector. This connector is for programming only, it will not supply power to the board, only to the Nano. For more information on the Arduino Nano 33 BLE see the Further Information section.
Pinout
This shows the pinout of the Nano as they are addressed from within the Arduino IDE.
This shows the pinout of how the Nano’s pins are used across the board. Note that pins in bold are pins which are connected through protection circuitry on the board (see below).
Any I/O pin can be used as an interrupt input or PWM output.
Pin Protection
Select I/O pins on certain connectors on the board have over-voltage and over-current protection on them through the use of a Zener diode and a current limiting resistor. If used as an input the Zener diode will clamp the voltage to 3V3, protecting the Nano from using 5V devices, and when used as an output the 330R resistor will limit the current to around 10mA max.
Protection is offered on:
- The encoder pins of both motor headers
- All I/O pins of the SPI header
- The SIG pins of the ultrasonic headers
- The four generic GPIO pins
- The TX and RX of the UART
Take care when connecting devices to non-protected pins to ensure that the correct voltage levels are in use. Please do not connect directly to the pins of the Nano as this will bypass the protection.
Pin Reuse
The following pins can be repurposed as GPIO pins if they are not required for their intended purpose. Pins in red do not have pin protection on them and should be used with extreme caution as to not damage the Arduino, 3.3V max.
- All 4 of the SPI pins
- TX and RX on the UART breakout (see UART section about the problem with RX)
- USONIC1-4 trigger pins
- Motor A and B encoder inputs
- Motor direction A and B, available from the motor driver socket on pins 3 and 5 (AIN1 and BIN1 on the Pololu motor driver)
- Motor PWM A and B, also on the motor driver socket, pins 1 and 7
Power
Power is supplied to the board via a USB micro B connector. It is expected that the board will be powered by a 5V 3A (max) USB powerbank. The motors drivers can supply a sustained 2A directly from the 5V rail, as well as the ultrasonic sensors (if used) and any other peripherals connected to the general use 5V header.
The 5V rail also feeds an LDO onboard the Arduino Nano to provide the 3V3 rail it requires. The LDO is capable of outputting up to 1A of 3V3 power, with around 900mA available for use external to the Nano. This will include I2C devices, the magnetic encoders and any devices connected to the general use 3V3 header.
Motor Headers
There are two 6-pin motor headers located on opposite sides of the board marked motor A and B. These headers are designed to connect to micro metal gearmotors equipped with a Pololu Magnetic Encoder, and therefore have a matching pinout. The Pololu Magnetic Encoder has a 2mm pitch header, so a 2mm to 2.54mm cable will be required to connect to the board. The encoder board has two outputs for the encoder itself, but for this application only output A is connected. The magnetic encoder is used to calculate the distance travelled. The output is connected to a digital input pin on the Nano with the intention of using interrupts to catch the pulses.
The outputs of the motor header is driven by the motor driver board. This is connected to the board with four pins, direction A and B, and PWM A and B. Setting the direction output to either 0 or 1 will change the direction of rotation for that motor. The PWM pin is used to set the speed of rotation. Setting this to 0 will stop the motor.
For more information on the Pololu Magnetic Encoder and the Pololu Motor Driver see the Further Information section.
Ultrasonic Sensor Headers
Along the front of the board are 4 headers for connecting HC-SR04 (or compatible) ultrasonic distance sensors. When using 3-pin versions of the sensor, SIG should be connected to the TRIG pin, and the uSonic DIP switch for should be off. For 4-pin versions connect to the relevant pins and the DIP switch should be on. This will bridge together the TRIG and ECHO pins with a 4k7 resistor, allowing them to be used in 3-pin mode to save pins on the Arduino.
The headers output 5V for power and the input is protected to allow 5V signals in to remain compatible with the older 5V only versions of the sensor. Many newer versions are both 3V3 and 5V compatible, but please ensure that they do support 5V before connecting.
To use the sensor, the pin must first be set as an output. Then a pulse is sent out on that pin for a minimum of 10uS. After the pulse has been sent, the pin must be switched to an input to read and measure the returning pulse which is then used to calculate the distance. Once the returning pulse has been captured the pin can be returned to an output, ready for the start of the next measurement.
Serial
The Arduino Nano 33 BLE has two serial ports, Serial and Serial1. Serial is the port provided by over the USB micro-B connector on the Arduino itself. This is how the Arduino is programmed and can also be used to send debug messages to the programming PC. The second serial port, Serial1, is available on the UART pins of the Arduino. This pins are broken out to a connector on the front of the ARB, but are also connected to an onboard serial ↔ USB converter, so is available on the top most USB micro-B connector on the board. This is intended to be connected to a Raspberry Pi to enable communications between the Pi and the ARB. A library will be provided to enable this communication. For more information see the Software section below.
There is a physical bug with the UART breakout on the ARB. The serial port accessible through those pins is shared with the USB ↔ UART chip, used for connecting to a Raspberry Pi, but there is an unforeseen conflict between the pin protection used by the UART breakout and the USB ↔ UART chip which results in the UART chip always overriding the RX pin of the UART breakout. This can be temporarily fixed by soldering a wire between the RX pin and pin 17 of the Arduino socket, bypassing the pin protection, allowing the serial port to work as intended. Please ask a technician if you require help with this.
SPI
A SPI header is provided on the front of the board. This can be used for connecting SPI peripherals or used for GPIO.
COPI and CIPO were previously known as MOSI and MISO.
I2C
Along the front of the board also are 4 JST-SH connectors that each provide a separate I2C bus, allowing use of multiple devices with the same device ID by connecting them to separate buses. The separate buses are provided by an I2C mux chip which connects the main I2C bus (SDA and SCL) from the Nano to one of 4 sub-buses (SD0-SD3 and SC0-SC3). The mux chip itself is controlled through I2C, and is located at address 0xEE, which is therefore reserved. The Arduino Wire
library used for I2C communication only supports 7-bit addresses, so this would be at address 0x77
in the Arduino code. These connectors have been designed to be used with the GP2Y0E02B optical distance sensor, and have a pinout to match. They will require the use of JST-SH to JST-SH cables to connect directly to the sensors.
The 4 I2C sub-buses are also broken out to regular 2.54mm headers in the centre of the board for use with other devices.
A wrapper function will be provided for ease of use of the mux chip.
GPIO
A selection of pins are broken out at 2.54mm headers along the top of the board. These include 5 pins each of 3V3, GND & 5V, and 4 GPIO pins. The GPIO pins are all protected. The GPIO are shared with the joystick buttons; see below.
Joystick
On the top left of the board there is a 4-way + push joystick button. This means it can be pushed in all four directions, up, down, left and right, and also pushed in. This shares its connections with some of the pins broken out in the headers along the top of the board:
Direction | Shared Pin |
Right | GPIO1 |
Up | GPIO2 |
Down | GPIO3 |
Left | GPIO4 |
This pin sharing can be controlled using DIP1. Turing the relevant DIP switch on will connect the direction of the button to its GPIO pin. Disable this if you require use of the GPIO pins.
Software
Several libraries and example pieces of code have been provided:
Arduino
The provided ARB.zip
file contains the libraries and example code for the Arduino Nano 33 BLE side of things. This can be imported into the Arduino IDE and accessed the same as any other library you might download through the libraries manager.
To import the library you go to ‘Sketch’ -> ‘Include Library’ -> ‘Add .ZIP library …’ in the Arduino IDE menu, then select the ARB.zip file. Alternatively you can manually add the library by extracting the ARB.zip file to the Arduino/libraries directory in your Documents directory.
Once the library is imported you will have some example sketches under ‘File’ -> ‘Examples’ -> ‘ARB’.
To use the library in your own sketches, #include
it like you would any other library:
#include <ARB.h>
When using the ARB library, there is a function called ARBSetup
that should be called at the start of your setup function. This sets up things like the I2C and Serial communications.
I2C
The I2C multiplexer chip sits on the I2C bus of the Nano and connects the main I2C bus to one of 4 separate sub-buses. This is useful for when you want to use multiple of a device that has a fixed I2C address, such as the GPY0E02B IR range sensor, as each device can be placed on a separate bus, and therefore properly addressed individually without conflicting with the other devices at the same ID.
The mux chip is configured over I2C, and, in the configuration on this board, sits at the address 0xEE
. The standard Arduino Wire library, which is used for I2C communications, uses 7-bit addressing, which requires an 8-bit address to be bit-shifted right by one place, so 0xEE
is accessed at 0x77
instead.
To control which bus is selected a single byte is written to the mux’s address.
Bus | X | X | X | X | 3 | 2 | 1 | 0 |
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
When the bit corresponding to a bus is 1, that bus is active. When it is 0 it is deactivated. The top 4 bits do not relate to a bus, and are ignored.
In the provided library there is a function called setI2Cbus
. This is an easy to use function to make it simple to switch between buses. Simply call the function and pass the number of the sub-bus you want to access, 0, 1, 2 or 3. Pass any other value and all sub-buses will be deactivated.
Once the desired bus has been activated then the devices on that bus can be accessed using the standard Arduino Wire
library functions, as they will now be connected to the main I2C bus via the multiplexer.
See the Further Information section for more information on the Arduino Wire
library.
Serial
Included with the given libraries are functions to enable convenient communication between the Raspberry Pi and the Arduino Nano using the secondary USB serial on the ARB. This means the main Arduino serial is still available for programming and debug output, and the Raspberry Pi serial GPIO is available for shell access.
To enable this feature on the Nano side pass true
to the ARBSetup()
function:
ARBSetup(true);
The communications protocol is register based. On the Nano there is an array of 128 bytes/chars that can be accessed with the getRegister
and putRegister
commands. These are then accessible from the Raspberry Pi using similar commands, once the serial comms have been activated. By placing information into the registers on the Nano side and reading them from the Pi side and vice versa, you can exchange information and commands between the two.
See the included serialComms
example and the Raspberry Pi section for more information on this communication system. See the Further Information section for more information on the Arduino serial library.
Motor Control
Provided is an example way of controlling the included motor driver and reading the motor encoders, called motorControl
. The direction of the motors is controlled by setting the output of the corresponding direction pin to either 0 or 1, where 0 is clockwise and 1 is counter-clockwise. The speed of the motor is set by controlling the PWM pins using the Arduino analogWrite
function. Setting the PWM output to 0 stops the motors, whereas 255 is maximum speed.
To read the encoders, it is recommended to use interrupts. An interrupt can be attached to a pin using the Arduino function attachInterrupt
. We will use the CHANGE
interrupt type to fire the interrupt on either edge, to count all the edges coming from the encoder. The encoder gives a quadrature output, but in this case we are only reading one channel of the output as we can determine direction from what we have set it to, so there should be 6 counts per revolution when counting both edges of the output. The number of revolutions of the output of the motor will therefore be 6 times the gear ratio of the gearbox in use. The ISR in the example program simply counts the number of steps, adding when moving clockwise and subtracting when moving counter-clockwise.
See the Further Information section for more information on the mentioned Arduino functions.
Ultrasonic Sensors
Provided is an example of how to read the distance from an ultrasonic sensor in 3-pin mode called uSonic
. The pin is first set as an output. The pin is toggled high for at least 10uS, then back to low, to generate the pulse. The pin is then reconfigured to be an input to read the incoming return pulse. The Arduino function pulseIn
is then used to record the duration of the incoming pulse in uS. This time can then be (approximately) converted to cm using the ARB
library helper function uSecToCM
.
See the Further Information section for more information on the mentioned Arduino functions.
Joystick
Also provided is an interrupt-based example of how to read the onboard joystick buttons, called pushButton
. Internal pull-ups in the Nano are used to pull the inputs high when the buttons are open. When the buttons are closed they connect the pin to ground, therefore we tell the interrupt to look for FALLING
edges. When a falling edge is detected a flag is raised so that the main program loop can handle the event, in this example printing the name of the button pressed.
See the Further Information section for more information on the mentioned Arduino functions.
SPI
A breakout for the SPI bus is provided on the board for user purposes. The Arduino Nano 33 BLE only supports SPI controller mode, and therefore can be used to control other SPI peripheral devices, but cannot become a peripheral itself, so will not be able to communicate with other controllers. SPI can be accessed using the standard Arduino SPI library.
See the Further Information section for more information on the Arduino SPI library.
Bluetooth Low Energy (BLE)
Please see the separate document for more information.
Raspberry Pi
The provided ARBPi.zip
file contains the libraries and example code to be run on the Raspberry Pi (if required). This should be extracted to a directory of your choosing on the Pi. It provides both C++ and Python libraries with equivalent functions, and the Python library provides bindings to the C++ library.
The ARBPi.zip
file should be extracted to a suitable directory on the Raspberry Pi. Its contents are as follows:
ARBPi.cpp
- The main C++ library file
ARBPi.h
- The matching header file for the above file
serialTest.cpp
- A test program to be ran in conjunction with the serialComms example on the Nano
libARBPi.so
- A shared library file that allows the ARBPi
C++ functions to be accessible from Python
ARBPi.py
- The Python 3 library that contains the Python bindings for the C++ library
serialTest.py
- An equivalent test program to serialTest.cpp
but in Python
For C/C++ programs the required files are ARBPi.cpp
, ARBPi.h
and your program files. To compile a program using the ARBPi
C++ library use the following command:
g++ -o ./serialtest -l wiringPi ./ARBPi.cpp ./serialTest.cpp
Where ./serialtest
is the name of the output file and ./serialTest.cpp
is the name of your source file.
For Python programs the required files are libARBPi.so
and ARBPi.py. To use the ARBPi
library in Python, simply import the ARBPi
library. If changes have been made to the ARBPi
C++ library, the libARBPi.so
file can be recompiled to update the Python library using the command:
g++ -fPIC -shared -o ./libARBPi.so -l wiringPi ./ARBPi.cpp
There are 3 functions available in the ARBPi
library:
ARBPiSetup
- should be called once at the start of the program.
getRegister
- used to read a value from a register on the Nano. Takes one argument, an int
which is the number of the register to read and returns a char
(or an int
in Python) of the contents of the register. This is a blocking function as it waits for a reply from the Nano before progressing, so will halt the execution of the program until the reply is received.
putRegister
- used to put a value into a register on the Nano. Takes two arguments, an int
of the number of the register to write to and a char
(or an int
in Python) which is the value to write to the register. It returns no value. This function is non-blocking as it writes the required values into the transmit buffer of the serial device and then continues execution without needing a reply. As Python has no char
datatype an int
is used instead, so take care that it does not overflow a single byte, as the underlying C code still deals with chars
.
Serial communication in Linux required the user to be part of the dialout
group. The user raspberry
can be added to the dialout
group using the command:
sudo usermod -a -G dialout raspberry
Further Information
Arduino Nano 33 BLE documentation
Pololu Magnetic Encoder documentation
Pololu Motor Driver documentation
GP2Y0E02B IR Range Sensor documentation
Arduino Wire library reference
Arduino Serial library reference
Arduino digitalWrite function reference
Arduino analogWrite function reference
Arduino attachInterrupt function reference