≡ Menu

Communicating with I2C devices with the LinkM


I was recently looking for a USB to I2C adapter and mostly I found rather expensive ($100-300) development kits which tend to be large-ish boards. Considering I2C communication can be done with a fairly basic microcontroller, I thought these were poor solutions. I eventually tripped across the LinkM, which is, on the surface, a USB controller/programmer for the BlinkM programmable LED devices. However, the BlinkM uses I2C as it’s communications bus and the LinkM is essentially a USB to I2C adapter. It’s pretty cheap ($30) and small, with a nice plastic housing and a simple female header connection. All the code is open source, from the client-side API to the firmware on the LinkM microcontroller. In addition, the client-side code is cross platform, in C, Java and Processing, working on Mac OS X, Windows, and Linux. Since the the USB interface is implemented as a simple HID device, it’s probably pretty easy to write code for any platform, really.

That said, while the software can talk to generic I2C devices, it’s really geared towards supporting the BlinkM. As such, there is little documentation about how to talk to generic I2C devices. The simplest thing to to is compile the linkm-tool application located in the c_host folder. Note that this depends on linkmbootloadlib, so you’ll need to build that first.

Windows notes:

  1. If compiling on a Windows platform, you’ll need MinGW – the LinkM developers recommend the TDM-GCC compiler suite, which integrates MinGW and GCC.
  2. In the Makefile for linkmbootloadlib, you’ll need to comment/remove line 98: rm -f lib$(PROGNAME).a # FIXME. You could replace it with the proper del command as well.

Once you have linkm-tool compiled you can do the following:

  1. Scan the I2C bus:
    linkm-tool -v --i2cscan
  2. Read/Write to an I2C device:
    linkm-tool -v --linkmcmd "0x01,<# bytes to write>,<# bytes to read>,<write byte 1>,<write byte 2>,...,<write byte n>"
    For example, if you need to write “0x50,0x11,0x20” (I2C address 0x50, command 0x11, data 0x20):
    linkm-tool -v --linkmcmd "0x01,3,0,0x50,0x11,0x20"
    Or to read 3 bytes: “0x50,0x12” (I2C address 0x50, command 0x12):
    linkm-tool -v --linkmcmd "0x01,2,3,0x50,0x12"

This is fine for simple testing, later when you put together an app, you can simply include hiddata.h and call the relevant functions.

{ 2 comments… add one }
  • Andy July 28, 2015, 2:13 pm

    Ultra useful, especially the last bit, there’s literally no documentation. Many thanks.

  • RoboGourmet July 28, 2015, 6:45 pm

    Andy – I’m glad you found it helpful!

Leave a Comment