You will probably be familiar with I²C, a serial bus typically used for not-very-fast communication with microcontroller peripherals. It’s likely though that unless you are an I²C wizard you won’t be intimately familiar with the intricacies of its operation, and each new device will bring a lengthy spell of studying data sheets and head-scratching.
If the previous paragraph describes you, read on. [Clint Stevenson] wrote a library for interfacing I²C EEPROMs to Arduino platforms, and when a user found a bug when using it on an ATtiny85, he wrote up his solution. The resulting piece is a clear explanation of how I²C EEPROMs talk to the bus, the various operations you can perform on them, and the overhead each places on the bus. He then goes on to explain EEPROM timing, and how since it takes the device a while to perform each task, the microcontroller must be sure it has completed before moving to the next one.
In the case of [Clint]’s library, the problem turned out to be a minor incompatibility with the Arduino Wire library over handling I²C start conditions. I²C has a clock and a data line, both of which are high when no tasks are being performed. A start condition indicates to the devices on the bus that something is about to happen, and is indicated by the data line going low while the clock line stays high for a while before the clock line starts up and the data line carries the I²C command. He’s posted samples of code on the page linked above, and you can find his library in his GitHub repository.
If you want to know more about I²C, take a look at Hackaday Editor [Elliot Williams’] masterclasses on the subject: What could go wrong, I²C edition, and Embed With Elliot, I²C bus scanning.
Serial EEPROM die picture, By Epop (Own work) [CC0], via Wikimedia Commons.
Sometimes there’s just no substitute for the right diagnostic tool. [Ankit] was trying to port some I2C code from an Arduino platform to an ARM chip. When the latter code wasn’t working, he got clever and wrote a small sketch for the Arduino which would echo each byte that came across I2C out to the serial line. The bytes all looked right, yet the OLED still wasn’t working.
Time to bring out the right tool for the job: a logic analyzer or oscilloscope. Once he did that, the problem was obvious (see banner image — Arduino on top, ARM on bottom): he misunderstood what the ARM code was doing and was accidentally sending an I2C stop/start signal between two bytes. With that figured, he was on the right track in no time.
We just ran an epic post on troubleshooting I2C, and we’ll absolutely attest to the utility of having a scope or logic analyzer on hand when debugging communications. If you suspect that the bits aren’t going where they’re supposed to, there’s one way to find out. It’s conceivable that [Ankit] could have dug his way through the AVR’s hardware I2C peripheral documentation and managed to find the status codes that would have also given him the same insight, but it’s often the case that putting a scope on it is the quick and easy way out.
[Folkert van Heusden] sent us in his diabolical MIDI device. Ardio is a MIDI synthesizer of sorts, playing up to sixteen channels of square waves, each on its separate Arduino output pin, and mixed down to stereo with a bunch of resistors. It only plays square waves, and they don’t seem to be entirely in tune, but it makes a heck of a racket and makes use of an interesting architecture.
Ardio is made up of three separate el cheapo Arduino Minis, because…why not?! One Arduino handles the incoming MIDI data and sends note requests out to the other modules over I2C. The voice modules receive commands — play this frequency on that pin — and take care of the sound generation.
None of the chips are heavily loaded, and everything seems to run smoothly, despite the amount of data that’s coming in. As evidence, go download [Folkert]’s rendition of Abba’s classic “Chiquitita” in delicious sixteen-voice “harmony”. It’s a fun exercise in using what’s cheap and easy to get something done.
I should really like I2C more than I do. In principle, it’s a brilliant protocol, and in comparison to asynchronous serial and SPI, it’s very well defined and clearly standardized. On paper, up to 127 devices can be connected together using just two wires (and ground). There’s an allowance for multiple clock-masters on the same bus, and a way for slaves to signal that the master to wait. It sounds perfect.
In reality, the tradeoff for using only two wires is a significantly complicated signalling and addressing system that brings both pitfalls and opportunities for debugging. Although I2C does reduce the number of signal wires you need, it gets dangerous when you have more than a handful of devices on the same pair of wires, and you’re lucky when they all conform to the same standard. I’ve never seen twenty devices on a bus, much less 127.
But still, I2C has its place. I2C was designed to connect up a bunch of slower, cheaper devices without using a lot of copper real estate compared to its closest rival protocol: SPI. If you need to connect a few cheap temperature sensors to a microcontroller (and their bus addresses don’t clash) I2C is a great choice. So here’s a guide to making it work when it’s not working.
Continue reading “What Could Go Wrong? I2C Edition”
[Andrew Sowa] wanted to use an off-the-shelf relay board from Numato Labs. The board lacks a suitable computer interface, which meant that [Andrew] would have to build one, and its input connectors are screw terminals, which meant a lot of wiring. Undeterred, he created an i2c expansion board using an MCP23017 I/O port expander, and with a novel card-edge designed to mate with the screw terminals, solving both problems at once.
Continue reading “i2c Relay Expander Uses Nifty Card-Edge Connection”
PJON, pronounced like the iridescent sky rats found in every city, is a cool one wire protocol designed by [gioblu].
[gioblu] wasn’t impressed with the complications of I2C. He thought one-wire was too proprietary, too complicated, and its Arduino implementations did not impress. What he really wanted was a protocol that could deal with a ton of noise and a weak signal in his home automation project with the smallest amount of wiring possible.
That’s where is his, “Padded Jittering Operative Network,” comes in. It can support up to 255 Arduinos on one bus and its error handling is apparently good enough that you can hold an Arudino in one hand and see the signals transmitted through your body on the other. The fact that a ground and a signal wire is all you need to run a bus supporting 255 devices and they’ll play nice is pretty cool, even if the bandwidth isn’t the most extreme.
Aside from the cool of DIY protocols. We really enjoyed reading the wiki describing it. Some of the proposed uses was running your home automation through your ducting or water pipes (which should be possible if you’re really good at isolating your grounds). Either way, the protocol is neat and looks fun to use. Or check out PJON_ASK if you want to do away with that pesky single wire.