There is Intelligent Life
Out There
After five months of sitting on a breadboard with
mere LEDs and switches for company, your ATmega328P
microcontroller has likely started to develop a deep
longing for intelligent conversation. Sure, it has spoken
with your PC over a USB-serial connection, but that is still
the only component with any form of intelligence on the
breadboard. You can reassure your MCU that this month,
things are about to change!
From your experience with the Arduino environment,
you’ll be familiar with some of the intelligent components
we can add to our projects: a host of digital sensors; real
time clocks (RTCs); EEPROM modules; modules that
enable wireless/Bluetooth/LAN communication; GPS
modules ... the list is a very long (and exciting) one — and
one that can inflict long-lasting damage on your credit
card!
As these modules can provide some fairly complex
functionality, it follows that there has to be some degree
of complexity in the way we communicate with them — a
simple high or low voltage on a microcontroller pin simply
won’t cut it any longer.
The two most popular protocols used to communicate
with these kinds of modules are: SPI (Serial Peripheral
Interface); and I2C (Inter-Integrated Circuit). These two
protocols achieve the same basic result — communication
between modules — but as with most things have their
own strengths and weaknesses.
At a summarized level, SPI allows faster and simpler
communication, but needs four wires (plus GND) to
achieve this. I2C is slower, but only requires two wires
(plus GND) and allows you to daisy-chain multiple
modules (up to 128 of them) on the same pair of wires.
The I2C simplicity at a hardware level is, however, a trade-off on the software side — it is a more complicated
protocol.
Making a Choice
So, how do you decide whether to use SPI or I2C on
your projects — assuming, of course, that both versions of
your module are available (some manufacturers are kind
to us and do offer both versions)? The simple answer is
there isn’t a simple answer — your choice will depend on
what constraints you face in your particular project; what
trade-offs you’re prepared to make; and what aspects you
aren’t prepared to compromise on.
The first stand-alone AVR project I completed that had
any level of complexity was the irrigation controller I’ve
mentioned in previous articles. In addition to the
microcontroller itself, I had an EEPROM chip, an RTC, and
an LCD display (as well as various buttons, LEDs, relays,
and a rotary encoder). My constraints were budget and
the number of I/O pins I had on my MCU (I was using the
same ATmega328P we’re using here). I had no
requirement for response times or volume/speed of data
transfer, so I could afford to compromise on that.
The decision I ended up making at the time was to
manage my budget by avoiding a serial LCD and instead
using a shift register to address the LCD in a “traditional”
way. I then opted for an I2C EEPROM and I2C real time
clock as I could use the same two pins to communicate
with both — I had no need for the SPI speed, and could
not spare the I/O pins I would have needed to use SPI
versions of the modules. A simple example perhaps, but
nevertheless it illustrates the point.
Diving into Detail on I2C
If you’ve been following this series, you’ll know that I
like to get into a little theory before we apply power to a
project. Let’s take a quick look under the hood of I2C.
Beyond the
Arduino
To the Power of I2C
6
The components we’ve included in
our projects so far have been
relatively simple. This month, we
raise the bar and connect our AVR
microcontroller to modules with a
little more intelligence, using the I2C
protocol.
52 September 2015