News: Now with lcd4linux driver. I recently purchased 10 SLM1608 (SLM1606) LED matrix display units from Ebay (you might also contact the seller directly at op16@gmx.de). These are 16x16 LED matrix units with a green and a red LED per pixel allowing each pixel to be switched to either green, red, amber or off. It uses code from the xu1541 by Till Harbaum and the LUFA USB library by Dean Camera. A commercial version called the ZoomFloppy is now available from Jim Brain. It is quite nice and only slightly more expensive than a bare Atmel developer board, so I no longer recommend building your own hardware. CiteSeerX - Document Details (Isaac Councill, Lee Giles, Pradeep Teregowda): Todays FPGA technology allows reconfigurable hardware to be integrated into standard PC hardware. With this kind of hardware it is possible to change hardware functionality on-the-fly and to remove and insert complete subsystems just by rebooting the configurable parts. Till Harbaum - Open Source - The i2c-tiny-usb is a open source/open hardwareproject. It is meant to replace those i2c printerport interfaces often used to connect i2c sensorchips (e.g. Temperature sensors) to a Linux PC.
Introduction
Several routers and embedded devices with OpenWRT-support are equipped with one or more USB ports. In order not to risk your warranty by opening your device and soldering an I²C bus to the GPIOs, you can use an USB-I²C adapter to connect to your I²C-devices (e.g. temperature sensors, RTCs, AD-converters, GPIO-expanders, LCD-Drivers). One of those adapters is called i2c-tiny-usb, developed by Till Harbaum. Biggest advantage is the low price (though not as cheap as the GPIO mod) and the support in the Linux kernel (thus making it possible to connect it to your computer running a recent Linux distribution and test it). Though you need some basic soldering skills, and at the moment you need to build OpenWRT from source.
Compiling the kernel module
Note: This module is now in trunk, called kmod-i2c-tiny-usb. You can use a snapshot and install this kernel module with opkg. |
Follow the build instructions until you reach the topic building images. At that point you have to edit you kernel configuration:
Make sure the following items are selected:
- Device Drivers > I2C support > I2C device interface <*> (to get access through /dev/i2c-X)
- Device Drivers > I2C support > I2C Hardware Bus support > Tiny-USB adapter <*>
Continue with the build instructions.
Using the I²C bus - kernel module
Since the module is compiled into the kernel, the I2C-Tiny-USB adapter can be plugged in. The successful registration can be tested:
The same results are achieved by loading the kernel module by insmod. The current trunk module within kmod-i2c-tiny-usb package works just fine (requiring also kmod-i2c-core package).
Using the I²C bus - using the bus
First install the i2c-tools package.This will provide all necessary tools for you to work with the bus.
Searching for the bus
As you already can see in the dmesg listing, the i2c-0 device was created. The device node is visible under /dev/i2c-0.First of all, check the device is also visible for i2c tools.Running
i2cdetect -l
should print something like
i2c-0 i2c i2c-tiny-usb at bus 001 device 004 I2C adapter
This is a good sign.We can show the implemented functions by running
i2cdetect -F 0
and it will print something like
Functionalities implemented by /dev/i2c-0:I2C yesSMBus Quick Command yesSMBus Send Byte yesSMBus Receive Byte yesSMBus Write Byte yesSMBus Read Byte yesSMBus Write Word yesSMBus Read Word yesSMBus Process Call yesSMBus Block Write yesSMBus Block Read noSMBus Block Process Call noSMBus PEC noI2C Block Write yesI2C Block Read yes
Searching for the devices
Now, we can search for devices, connected to the bus:
i2cdetect 0
will scan the bus and show available devices, similar to this:
WARNING! This program can confuse your I2C bus, cause data loss and worse!I will probe file /dev/i2c-0.I will probe address range 0x03-0x77.Continue? [Y/n] 0 1 2 3 4 5 6 7 8 9 a b c d e f00: – – – – – – – – – – – – – 10: – – – – – – – – – – – – – – – – 20: 20 – – – – – – – – – – – – – – – 30: – – – – – – – – – – – – – – – – 40: – – – – – – – – – – – – – – – – 50: – – – – – – – – – – – – – – – – 60: – – – – – – – – – – – – – – – – 70: – – – – – – – –
Should you be anoyed by the Y/n question, you can use the -y switch to avoid it ;)
As you can see, I have an i2c device accessible on address 0x20 on the bus number 0.
Accessing the example device
My device is actually a MCP23017 - 16 port GPIO expander.First I have to set the directions of the inputs and outputs - as this device possess 2 ports (A and B), I have to set the direction for both of them - setting a bit to 0 will cause it to switch to output, setting the bit to 1 will cause to switch to input. The address to set the direction for port A is 0x00, for port B it's 0x01.Therefore to set the first 8 channels (port A) to output, I'd run
i2cset -y 0 0x20 0x00 0
That means use the device at the address 0x20 on the bus /dev/i2c-0, set its address 0x00 to zero value. The -y
switch is there just to avoid the Y/n question.Also, to set the port B to input, I'd issue following command:
i2cset -y 0 0x20 0x01 0xff
This will set all the pins for port B to input.To set the actual value for port A, the address 0x12 is utilized. Similar, for port B, the address is 0x13.Therefore to set first bit to logical 1, I'd issue (assuming I already set the port's bit for output):
i2cset -y 0 0x20 0x12 1
Should you have some LED connected to the port, it will shine bright now.To turn it off, simply issue the following:
i2cset -y 0 0x20 0x12 0
Should some input be set on the port B, one can read its value by using following command:
i2cget -y 0 0x20 0x13
The result will be something like 0x00
(corresponding to the logical values presented to the actual pins).
Using this approach, you can enrich the OpenWRT device with multiple I/O channels.
I've already tested MCP23017, MCP23008, some i2c temperature sensors and EEPROM - all working just fine.
Till Harbaum Driver Ed
Precaution
This I²C bus operates at 5V. Make sure not to connect I²C devices incompatible with this voltage level!