How to talk to I2C sensors, displays from… Linux

T’other week, I wrote about my work on building a Raspberry Pi RP2040-based I²C host device and some macOS client software to control it. I mentioned that I might get the latter running under Linux too. I now have, and it does.

The matrix display client and the CPU activity display example running on a Raspberry Pi 400
The matrix display client and the CPU activity display example running on a Raspberry Pi 400

The original repo has been updated with a linux directory. Just hop in there and use cmake to compile the three client apps and then copy the binaries to a location of your choice.

cd linux
cmake -S . -B build
cmake --build build
sudo cp build/cli2c /usr/local/bin/cli2c

While I’m on the subject of the cli2c client app, it’s had some work done too. If you’re fed up of the LED heartbeat, you can turn if off with

cli2c /dev/ttyACM0 l off

More usefully, you can specify which I²C bus, and SDA and SCL pins your I²C Host will use, using the updated c command. For example, to use pins 22 (SDA) and 23 (SCL) on i2c0, just run:

cli2c /dev/cu.usbmodem101 c 0 22 23

The pin numbers are the official GPIO designations, not the the count of the pin from the USB end of the board.

An experimental feature to try is GPIO control, with the g command. For example to set GPIO 22 to digital out with a state of logic high, run:

cli2c  /dev/ttyACM0 g 22 hi out

You can use 1 or 0 in place of hi or lo, and for in or out. Pins configured as inputs can be subsequently read with:

cli2c /dev/cu.usbmodem101 g 22 read

The app will drop the value as two hex characters to stdout.

As you’ll see from the examples above, I’ve mixed macOS device paths (/dev/cu.usb...) with Linux ones (/dev/ttyACM0) for cross-platform users.

There’s still some work to be done with GPIO: allowing a pin’s pull (up or down) to be set, and possibly a mechanism to interrupt the client when a sensor with an alert pin asserts that pin for some reason. Temperature sensors often do, for example, when the sensed temperature rises above or falls below thresholds you’ve set.

I compiled and tested the Linux clients on a Raspberry Pi, and you might very will wonder what’s the point of them when the Pi supports I²C and other buses directly. To be fair, you’re right: there isn’t as much benefit as there is with a Mac, which doesn’t include bus-muxed GPIO pins. However, there are instances where the client is useful. For example:

A cased, headless Raspberry Pi using segment to drive a CPU utilisation display
A cased, headless Raspberry Pi using segment to drive a CPU utilisation display

This is the Pi I have tucked alongside a NAS and behind my router, and which runs my Pi-Hole and a couple of other services 24×7. It’s headless and stays cased to keep the dust out, so having an I²C breakout the works over USB rather than GPIO is, in this rare case, rather handy.

You can find full usage details on my website.

More in this Series