I²C Support
This page details the I²C driver and client-code that makes use of it.
The current version is 1.3.0. Read the release notes.
The I²C driver is located in the repo’s /client/i2c
directory. It depends on the Depot serial driver and utility libraries, which are found in the repo’s /client/common
directory. Consult the header files for details of the public functions.
The driver enables the following client apps. You can find the source code for these apps in the /client
directory.
cli2c
cli2c
has the the following syntax:
cli2c {device_port} [command] ... [command]
Note
Arguments in braces { }
are required; those in square brackets [ ]
are optional.
device_port
is the USB-connected I²C host’s Unix device path.
On a Mac, this will be something like/dev/cu.usbmodem-101
.
On a Raspberry Pi or other Linux b, this will be/dev/ttyACM0
.[command]
is an optional command block, comprising a single-character command and any required data as described in the following table.
Command |
Args |
Description |
---|---|---|
|
|
Choose the host’s I²C bus (0 or 1) and the SDA and |
|
|
The I²C bus frequency in multiples of 100kHz. |
|
Initialise the target I²C bus. The bus is not initialised |
|
|
|
Write the supplied data to the I²C device at |
|
|
Read |
|
Issue an I²C STOP. Usually used after multiple writes |
|
|
Reset the I²C bus |
|
|
Display devices on the I²C bus. |
|
|
Display I²C host device information |
|
|
|
Set a GPIO pin |
|
|
Turn the I²C Host LED on or off |
|
Display help information |
Error and Data Output
All message output is routed via stderr
. All data read back from a device is output to stdout
so it can be captured to a file. Returned data is currently presented as hexadecimal strings. For example:
cli2c /dev/cu.usbmodem-101 r 0x18 16 > data.bin
cat data.bin
A0FF123B5C5FAA5F010304
Device Defaults
Board |
I2C Bus |
SDA Pin |
SCL Pin |
---|---|---|---|
Pico |
1 |
2 |
3 |
QTpy |
1 |
22 (26) |
23 (27) |
Trinkey |
0 |
16 |
17 |
ProMicro |
1 (0) |
2 (16) 3 (17) |
|
Tiny |
1 |
6 |
7 |
Nano |
0 |
0 |
1 |
Note
The QTpy and ProMicro both have a STEMMA-QT port as well as pins. The values in brackets are the bus and pins used when the STEMMA-QT is set to be the default. This can be done uncommenting the set(USE_STEMMA 1)
line in the board’s CMakeLists.txt
file. But don’t forget that you can use the c
command to choose an alternative I²C bus and pins.
GPIO
You can use cli2c
to set a GPIO pin. Provide the GPIO number and its initial state (hi
or lo
) and its mode: whether it is an input or output (in
or out
).
Setting a pin to an output immediately sets its state to the provided value. To change the state, just pass in the opposite value. There’s no need to specify its mode again unless you wish to change it.
cli2c /dev/cu.usbmodem-101 10 hi out
cli2c /dev/cu.usbmodem-101 10 lo
Setting a pin to an input does nothing immediately, and the supplied state value is ignored unless it is r
, for read. To read an input pin, pass r
in place of a state: cli2c
will output the pin’s current value as a two-digit hex number:
cli2c /dev/cu.usbmodem-101 10 lo in
cli2c /dev/cu.usbmodem-101 10 r 1
Again, you don’t need to restate the pin’s mode unless you’re changing it.
matrix
matrix
is a specific driver for HT16K33-based 8x8 LED matrices. Use it with this command-line call:
matrix {device} [I2C address] [commands]
Note
Arguments in braces { }
are required; those in square brackets [ ]
are optional.
{device}
is the path to the multi-bus adaptor, eg./dev/cu.usbserial-DO029IEZ
.[I2C address]
is an optional I²C address. By default, the HT16K33 uses the address0x70
.[commands]
are a sequence of command blocks as described below.
Command |
Arguments |
Description |
---|---|---|
|
|
Activate or deactivate the display. |
|
|
Set the brightness to a value between |
|
|
Plot the specified character, by code, on the display. |
|
|
Plot a user-generated glyph on the display. The glyph |
|
|
Plot a point as the co-ordinates |
|
|
Scroll the specified string. |
|
Clear the screen |
|
|
|
Rotate the display by the specified multiple of 90 degrees |
|
Display help information |
Multiple commands can be issued by sequencing them at the command line. For example:
matrix /dev/cu.usbserial-DO029IEZ 0x71 w r 3 p 0 0 p 1 1 p 2 2 p 3 3 p 4 4 p 5 5 p 6 6 p 7 7
Note
The client-side display buffer is not persisted across calls to matrix
, so building up an image across calls will not work. While the display retains its own image data, the local buffer is implicitly cleared with each new call. This may be mitigated in a future release.
Examples
Draw a dot at 1,1
matrix /dev/cu.usbserial-DO029IEZ p 1 1
Draw T, centred
matrix /dev/cu.usbserial-DO029IEZ c 123 true
Draw a smiley
matrix /dev/cu.usbserial-DO029IEZ g 0x3C,0x42,0xA9,0x85,0x85,0xA9,0x42,0x3C
Scroll “Hello, World!” across the display
matrix /dev/cu.usbserial-DO029IEZ t "Hello, World! "
Note
The four spaces (two matrix columns each) ensure the text disappears of the screen at the end of the scroll.
segment
segment
is a specific driver for HT16K33-based 4-digit, 7-segment LEDs. Use it with this command-line call:
segment {device} [I2C address] [commands]
Note
Arguments in braces {}
are required; those in square brackets \[\]
are optional.
{device}
is the path to the multi-bus adaptor’s device file, eg./dev/cu.usbserial-DO029IEZ
.[I2C address]
is an optional I²C address. By default, the HT16K33 uses the address0x70
.[commands]
are a sequence of command blocks as described below.
Command |
Arguments |
Description |
---|---|---|
|
|
Activate or deactivate the display. |
|
|
Set the brightness to a value between |
|
Flip the display vertically. |
|
|
|
Write a user-generated glyph on the display |
|
|
Write a single-digit number (0-9, |
|
|
Write the character on the display at |
|
|
Write a number between -999 and 9999 |
|
Light the segment’s central colon symbol |
|
|
Clear the screen |
|
|
Write the buffer to the screen immediately |
|
|
Display help information |
Multiple commands can be issued by sequencing them at the command line. For example:
segment /dev/cu.usbserial-DO029IEZ 0x71 w f n 7777
Note
The display buffer is not persisted across calls to segment
, so building up an image across calls will not work. While the display retains its own image data, the local buffer is implicitly cleared with each new call. This may be mitigated in a future release.
Examples
Draw 42.4 degrees
segment /dev/cu.usbserial-DO029IEZ n 4240 d 1 c '*' 3