5 ms·
Probably one of the least painful digital buses. If anyone is wondering how to access an I2C bus from a Linux computer, say, a raspberry pi: int fd = open("/d
by inamberclad 7y ago
Probably one of the least painful digital buses.
If anyone is wondering how to access an I2C bus from a Linux computer, say, a raspberry pi:
int fd = open("/dev/i2c-1", O_RDWR);
ioctl(fd, I2C_SLAVE, [slave address here]);
Then you can read() and write() to the device with the kernel taking care of all the transmission details. Usually all that's exposed is a few bytes for the registers. To set a register, write two bytes: first the register address, and then the value. To read a register, write the register address and then read a byte. Most of the devices have linear address spaces, so reading out multiple registers is as simple as reading multiple bytes.
The i2c-tools package has some very handy CLI tools for exploring an I2C bus.
Electrically, the bus is an open-collector design on both ends, so devices can only pull the lines to low, and they release them to set them high. Don't forget pull-up resistors!
- dws 7y agoTo avoid clock-stretching problems, using one of the small Arduinos that support USB serial to handle the I2C bus can help considerably, at the expense of a bit more programming complexity.
- zeta0134 7y agoI'm not at all familiar with this space, but I'm a bit surprised the kernel isn't wrapping the I2C transmission and helping to work around clock stretching issues anyway. Can someone who's more familiar with this implementation weigh in? It seems like that'd be the primary feature of writing to the /dev/i2c* device instead of manually bit-banging the GPIO pins from userland.
- opencl 7y agoThe Pi's hardware i2c has buggy silicon and does not handle clock stretching properly. There's also a kernel driver to bitbang i2c over the GPIO pins and clock stretching does work properly with that.
- BubRoss 7y agoDoes the PI 4 also have this problem?
- opencl 7y agoI'm not sure about the 4, though it was present at least from the original up through the 3B+.
- davidf560 7y agoThere's a claim that it was fixed here: https://www.raspberrypi.org/forums/viewtopic.php?p=1484482#p1484482 https://www.raspberrypi.org/forums/viewtopic.php?p=1484482#p... Apparent confirmation here (by mapping a different I2C bus?): https://www.raspberrypi.org/forums/viewtopic.php?p=1544123&sid=9893879e086f80a2c71987dc6a564089#p1544123 https://www.raspberrypi.org/forums/viewtopic.php?p=1544123&s...
- inamberclad 7y agoA quick note: buy one of the really cheap (~$10) logic analyzers on ebay and use Sigrok/Pulseview to to watch the bits get sent over the wire! It's an absolutely invaluable tool for the price. The hardware inside those logic analyzers is fascinating in its own right, too!
- hartzell 7y agoI've found the [I2CDriver](https://www.adafruit.com/product/4267 https://www.adafruit.com/product/4267) device to be really useful with debugging, poking, and otherwise prodding I2C devices.
- deleted 7y ago[deleted]
- justinclift 7y agoInteresting. This intro to Sigrok looks like it covers things pretty well too: https://www.youtube.com/watch?v=dobU-b0_L1I https://www.youtube.com/watch?v=dobU-b0_L1I That, and a cheapo Saldae clone might be all I need for learning how to use a logic analyser finally. :)
- chocolatebunny 7y agoNot all i2c devices can be read that way. There are several devices that require an address (on top of the device address) to be written before data can be read, but without a second stop bit after writing the address. You end up with like double start condition. These require either using the smbus stuff or I2C_RDWR ioctl.