What tradeoffs should I consider when deciding to use an SPI or I2C interface?

This accelerometer/gyro breakout board is available in two models, one for each interface. Would either one be easier to integrate into an Arduino project?


enter image description here

  • 11
    I2C and SPI have their strenghts. I2C is more complex to set-up, once stable you can so easily extend (as long as your bus wiring doesn't get too long or large). SPI is easy to set-up.. you can bitbang it very easily if required. Expansion eats I/O with all the chip selects. If I have the luxury of I/O and connector space and don't need busses, I'd always go with SPI. – Hans Mar 31 '12 at 15:18
  • How is I2C more complex? I have used both buses on different micros (small PICs and decent sized ARMs) and in every case I2C setup was simpler (i.e. less registers to write). If anything, SPI is more complex because of the clock polarity and data sampling options. – Armandas Mar 31 '12 at 18:31
  • 5
    @Armandas -- no way! SPI has 4 possible modes for clock/data polarity, and two of them dominate -- almost all SPI devices update their MISO output on the falling edge of a clock and read their MOSI input on the rising edge of a clock. You can figure out which one in a few minutes by looking at the data sheet, and then you're done. If you pick the wrong mode by mistake, you'll figure it out quickly once you look at oscilloscope traces. SPI data errors are rare and don't get you stuck in weird states the way I2C does. – Jason S Apr 1 '12 at 1:40
  • 5
    I say I2c is way more complex because I have once had to write an I2C driver at an ARM proccesor. I followed the state machine of NXP documents, and it was about 20 states long. It took me a decent time to figure out the acknowledge, when the last byte is read/written, etc. I've never had any of these issues with SPI, just have to get the clock & data lined up. – Hans Apr 1 '12 at 11:09
  • 1
    @JonL, well frankly, I am the only one to have provided a complete answer so far, since I am the only one to discuss the issue of the particular breakout board the OP wants to use, and point out that it is not available in both SPI and I2C, but only I2C -- so he has to use I2C if he wants to use this particular board. The others only dealt with which interface (SPI or I2C) is easier to interface, which I also covered. – tcrosley Apr 2 '12 at 18:44
up vote 90 down vote accepted


  • SPI is faster.
  • I2C is more complex and not as easy to use if your microcontroller doesn't have an I2C controller.
  • I2C only requires 2 lines.

I2C is a bus system with bidirectional data on the SDA line. SPI is a point-to-point connection with data in and data out on separate lines (MOSI and MISO).

Essentially SPI consists of a pair of shift registers, where you clock data in to one shift register while you clock data out of the other. Usually data is written in bytes by having each time 8 clock pulses in succession, but that's not an SPI requirement. You can also have word lengths of 16 bit or even 13 bit, if you like. While in I2C synchronization is done by the start sequence in SPI it's done by SS going high (SS is active low). You decide yourself after how many clock pulses this is. If you use 13 bit words the SS will latch the last clocked in bits after 13 clock pulses.
Since the bidirectional data is on two separate lines it's easy to interface.

SPI in standard mode needs at least four lines: SCLK (serial clock), MOSI (Master Out Slave In), MISO (Master In Slave Out) and SS (Slave Select). In bideroctional mode needs at least three lines: SCLK (serial clock), MIMO (Master In Master Out) which is one of the MOSI or MISO lines and SS (Slave Select). In systems with more than one slave you need a SS line for each slave, so that for \$N\$ slaves you have \$N+3\$ lines in standard mode and \$N+2\$ lines in bidirectional mode. If you don't want that, in standard mode you can daisy-chain the slaves by connecting the MOSI signal of one slave to the MISO of the next. This will slow down communication since you have to cycle through all slaves data.

Like tcrosley says SPI can operate at a much higher frequency than I2C.

I2C is a bit more complex. Since it's a bus you need a way to address devices. Your communication starts with a unique start sequence: the data line (SDA) is pulled low while the clock (SCL) is high, for the rest of the communication data is only allowed to change when the clock is low. This start sequence synchronizes each communication.
Since the communication includes the addressing only two lines are required for any number of devices (up to 127).

It's obvious that the data line is bidirectional, but it's worth noting that this is also true for the clock line. Slaves may stretch the clock to control bus speed. This makes I2C less convenient for level-shifting or buffering. (SPI lines in standard mode are all unidirectional.)

After each byte (address or data) is sent the receiver has to acknowledge the receipt by placing an acknowledge pulse on SDA. If your microcontroller has an I2C interface this will automatically be taken care of. You can still bit-bang it if your microcontroller doesn't support it, but you'll have to switch the I/O pin from output to input for each acknowledge or read data, unless you use an I/O pin for reading and one for writing.

At 400kHz standard I2C is much slower than SPI. There are high-speed I2C devices which operate at 1MHz, still much slower than 20MHz SPI.

  • 4
    I have not yet met a microcontroller which handles all the corner cases of I2C need to handle proper error detection and recovery in a way that is useable without having to be an I2C expert. I've always had to drop back down from a "smart" I2C peripheral to bitbanging temporarily to handle the missed-clock case when SDA is being held low, which is a complete pain./ – Jason S Apr 1 '12 at 0:44
  • (but +1 since I agree with the rest of your answer) – Jason S Apr 1 '12 at 2:44
  • There are even I2C devices around that work at 3.4MHz, but I am uncertain whether these can be combined with slower devices (as all devices need to be able to follow the bus addressing). I also believe the timings of 3.4MHz I2C is little bit different. – Hans Apr 1 '12 at 11:10
  • @Hans - HS I2C seems to be downwards compatible with the more common 400kbit devices. Frankly, (without thorough research) I've never seen a microcontroller which supports HS (yet), that's why I didn't want to mention it. – stevenvh Apr 1 '12 at 11:18
  • @stevenvh: Some controllers' two-wire implementations (e.g. Cypress PSOC) require that SCK be low for at least one or two cycles of an internal clock before they will latch it, and will malfunction badly it isn't. I don't know why they can't detect and clock-stretch an I2C start condition without a system clock pulse, but such behaviors mean that when such a chip is running at a low system clock speed, all I2C transactions on the bus must be run slowly). Even 400Khz operation is too fast for a PSOC running at 3MHz. – supercat Apr 2 '12 at 17:06

(edit: To be clear, many of the following concerns have to do with signal integrity caused by board-to-board use of I2C/SPI devices, as Olin correctly points out.)

Unless you have constraints that strongly push you towards fewer wires (we had one project with a hermetically-sealed connector that each additional contact was rather expensive), avoid I2C when possible, and stick with SPI.

SPI is fairly easy to deal with on a hardware and a software basis. In hardware, there are two shared data lines, Master In Slave Out (MISO or SOMI) and Master Out Slave In (MOSI or SIMO), a shared clock generated by the master, and one chip select per device. The CS line goes low, the clock cycles and essentially shifts in input bits and shifts out output bits, until the transaction finishes, at which point the CS line goes high. When their CS line is high, slave devices don't communicate: they ignore the CLK and MOSI lines, and put their MISO pin into a high-impedance state to let someone else use it.

If you have a microcontroller using several SPI devices, and it has a built-in SPI peripheral, send the microcontroller's CS output to a demultiplexer (e.g. 74HC138) and control the address lines to select the device between SPI transactions; you write words to a register to queue them up for output, and read them back after the CS pin is raised high.

Because SPI signals are all unidirectional, they can be buffered, used across an isolation barrier with digital isolators, and can be sent from board to board using line drivers like LVDS. The only thing you have to worry about is the round-trip propagation delay, which will limit your maximum frequency.

I2C is a completely different story. While it's much simpler from a wiring standpoint, with only two wires SCL and SDA, both these lines are shared bidirectional lines that use open-drain devices with an external pullup. There's a protocol for I2C that starts by transmitting a device address, so that multiple devices can be used if each has their own address.

From a hardware standpoint, it is very difficult to use I2C in systems that have any significant noise. In order to buffer or isolate I2C lines, you have to resort to exotic ICs -- yes, they exist, but there aren't many: we used one on one project and realized that you could use one isolator, but you couldn't use two in series -- it used small voltage drops to figure out which side was the driving end of things, and two series drops were two much.

The logic level thresholds of I2C depend on Vcc so you have to be really careful if you use 3V/3.3V and 5V devices in the same system.

Any signals that use a cable of more than a foot or two have to worry about cable capacitance. Capacitance of 100pf/meter isn't out of the ordinary for multiconductor cable. This causes you to have to slow down the bus, or use lower pullup resistors, to be able to handle the extra capacitance properly and meet the rise time requirements.

So let's say you have a system that you think you've designed well, and you can deal with most of the signal integrity issues, and noise is rare (but still present). What do you have to worry about?

There are a bunch of error conditions you have to be prepared to handle:

  • Slave device doesn't acknowledge a particular byte. You have to detect this and stop and restart the communications sequence. (With SPI, you can usually read back the data you send if you want to make sure it was received without error.)

  • You're reading a byte of data from a slave device, and the device is "hypnotized" because of noise on the clock line: You have sent the requisite 8 clocks to read that byte, but because of noise, the slave device thinks it has received 7 clocks, and is still transmitting a 0 on the data line. If the device had received the 8th clock, it would have released the data line high so that the master could raise or lower the data line to transmit an ACK or NACK bit, or the master could transmit a stop (P) condition. But the slave is still holding the data line low, waiting in vain for another clock. If a master is not prepared to try extra clocks, the I2C bus will be stuck in deadlock. While I have used several microcontrollers that handle the normal ACK/NACK conditions, I have never used one that handles this missed clock bit (or extra clock bit) condition successfully, and I've had to exit automatic I2C mode, enter into bit-banging mode, add clocks until the data line is high, and re-enter automatic I2C mode.

  • The really awful case is when a master is writing data to one slave device, and another slave interprets the device address incorrectly and thinks that the data transmitted is meant for it. We've had I2C devices (I/O expanders) that occasionally have registers set incorrectly because of this. It is nearly impossible to detect this case, and to be robust to noise, you have to periodically set all registers, so that if you do run into this error, at least it will be fixed after a short period of time. (SPI never has this problem -- if you happen to have a glitch on the CS line, it will never persist for long and you won't get data accidentally read by the wrong slave device.)

A lot of these conditions could be handled properly in the protocol if there were error detection (CRC codes), but few devices have this.

I find that I have to build complex software in my I2C master device to handle these conditions. In my opinion, it's just not worth it unless the constraints on wiring force us to use I2C and not SPI.

  • 5
    Your religious dislike of IIC has no place here. Both IIC and SPI are good at what they do and each have their place. Most of your objections to IIC come from inappropriate use of it. IIC should be thought of as on-board only, although it is used routinely in the power supply industry for controlling intelligent supplies. If you find yourself wanting IIC buffers, then that's a strong indication IIC isn't the right solution. However, IIC works very well for low speed devices all on the same board. – Olin Lathrop Apr 1 '12 at 12:08
  • 2
    The logic level thresholds of I2C depend on Vcc so you have to be really careful if you use 3V/3.3V and 5V devices in the same system. No, this is wrong. IIC logic thresholds are at fixed voltages. You can trivially mix 5 V and 3.3 V systems by pulling up the lines to only 3.3 V. – Olin Lathrop Apr 1 '12 at 12:10
  • 5
    It's not a religious dislike of I2C, it's a practical dislike of I2C. You're right about it being much easier with on-board systems; I'll use it when it makes sense, but it adds software cost, and too many hardware engineers just stick an I2C device on a board without discussing the tradeoffs that cause more software headaches. – Jason S Apr 1 '12 at 13:19
  • 3
    IIC is a little easier to implement electrically, and SPI perhaps a little easier in the firmware. Both are however pretty easy and straight forward in both respects. – Olin Lathrop Apr 1 '12 at 14:37
  • 2
    @Olin - the fixed 1.5 V threshold seems to be used in the past, but according to the latest version of the spec thresholds are indeed 0.3 Vcc and 0.7 Vcc. This quotation from the spec mentions the 1.5 V for legacy devices. – stevenvh Jul 7 '12 at 4:56

In general, SPI is a faster bus - the clock frequency can be in a range of MHz. However, SPI requires at least 3 lines for bi-directional communication and an additional slave select for each device on the bus.

I2C only requires 2 lines, regardless of how many devices you have (within limits, of course). The speed, however, is in the range of kHz (100-400kHz is typical).

Most microcontrollers, nowadays, have hardware support for both buses, so both are equally simple to use.

  • 4
    @Jason: You seem to have some predjudice against IIC, but it's unfair to ding other people on account of it. Both IIC and SPI are "easy", with each having their own wrinkles. SPI needs extra lines, which can be not easy. IIC is a little more complicated, but it's still easy to do all firmware implementations, which I have done may times. It doesn't take all that much code. Both have their place and both are easy enough for that not to be a factor to anyone that knows what they are doing. – Olin Lathrop Apr 1 '12 at 12:00
  • 1
    Not unfair. I'm happy to upvote when the statement of "equally simple to use" is corrected or at least clarified. I challenge anyone to write software on a microprocessor with intelligent I2C and SPI peripherals to interface with an IC series that has both I2C and SPI variants, and show me the software complexity via any objective measure (lines of code, # of states, cyclomatic complexity, etc.) to show that they're equally simple to use. Examples: Microchip 24LC256/25LC256 EEPROM, MCP23017/23S17 I/O expander. – Jason S Apr 1 '12 at 13:27
  • 5
    @Jason: I just checked, and my generic IIC code for firmware implementation of IIC on 8 bit PICs is only 311 lines, and probably over half of that are comments. That gets you a procedural interface to the IIC bus at the level of routines for start, put, get, stop, etc. Big deal. A module calling that to drive a simple EEPROM is 272 lines, again 1/2 comments probably, and that includes some high level management like default data, UART debug interface, etc. This is all so trivial that arguing whether it take 10 instructions less than SPI is pointless. – Olin Lathrop Apr 1 '12 at 14:44
  • 2
    @Andrew Kohlsmith - I2C is designed for on-board applications. - Apparently I2C device manufacturers disagree with you. Take the TMP100. The product page explicitly states: The TMP100 and TMP101 are ideal for extended temperature measurement in a variety of communication, computer, consumer, environmental, industrial, and instrumentation applications. The same is true for the TMP75 – Connor Wolf Apr 3 '12 at 1:59
  • 4
    @FakeName You're incorrect; I spent 13 years doing industrial power electronics. (starting and monitoring LARGE three phase mtors is a VERY noisy environment) It's not about SPI being more reliable, it's about designing the system with all failure modes planned and accounted for, and having recovery options built in to the system where needed. I've never, ever had a noise spike kill my I2C (or SPI for that matter) comms, but I also never relied exclusively on the I2C controller to do everything for me. It's a matter of planning and design, not of one bus being better. – akohlsmith Apr 3 '12 at 14:07

The breakout board for device at SparkFun is actually for the I2C version only (MPU-6500). The MPU-6000 version has both SPI and I2C interfaces on the same chip, and I don't see that SparkFun has a board with that chip. So I believe you are limited to using I2C if you want to use that particular board. But I was going to recommend using I2C anyway in your situation for the following reasons.

In general, you will find that the I2C bus is easier to use from a hardware standpoint than the SPI bus. I2C is a 2 wire bus (SCL/SDA):

SCL – Serial clock.
SDA – Serial data (bidirectional).

SPI is a 4 wire bus (SCLK/MOSI/MISO/CS):

SCLK– Serial clock.
MOSI – Master-out, Slave-in. Data from the CPU to the peripheral.
MISO – Master-in, Slave out. Data from the peripheral back to the CPU.
CS – Chip select.

You can have several devices connected to one I2C bus. Each device has its own set of address(es) built-in to the chip. The address is actually broadcast over the bus as the first byte of every command (along with a read/write bit). This, along with some other overhead, requires more bits to be sent over an I2C bus vs SPI for the same functionality.

Different classes of devices (memory, I/O, LCD, etc.) have different address ranges. Some devices, which are commonly used more than once in a system (such as the PCF8574 I/O expander), use one or more address lines (AD0-2 for the PCF8574) which can be tied high or low to specify the low bits of the address. The MPU-6500 has one such address line (AD0), so two of them can be used in the same system.

You can also have multiple devices on an SPI bus, but each device must have its own chip-select (CS) line. Therefore the 4-wire description is a bit of a misnomer -- it is really a three wire interface + one additional wire per device. I am not experienced with the Arduino series of boards, but I believe this would make using SPI more difficulty on the Arduino, since if you needed lots of chip select lines this would start to get cumbersome with the common pin assignments used by the various shields.

I believe most Arduino boards run at 5 volts, with some newer ones running at 3.3v. The MPU-6500 runs at 3.3v. If the minimum input "high" voltage for a the I2C bus on a 5v CPU is 3v or below, you could avoid level conversion issues by just providing 10K pullup resistors to 3.3v on the SCL and SDA lines, since the bus is open-collector. Make sure any 5v internal pullups on an CPU are disabled.

However I checked the datasheet for the ATmega2560 (using the ADK 5v Arduino as an example), and its minimum input 'high" voltage is 0.7*Vcc, or 3.5v which is greater than 3.3v. So you need some sort of active level conversion. The TI PCA9306, which requires pullups resistors on both 5v and 3.3v sides of the chip, costs just 78 cents in single quantities.

Why then ever pick SPI over I2C? Mainly because SPI can be run much much faster -- up to many 10's of MHz in some cases. I2C is generally limited to 400 KHz. But this is not really an issue for the MPU-6050/6000 accelerometer, since it runs at 400 KHz for I2C, and only 1 MHz for SPI -- not that much of a difference.

  • 2
    Another reason to pick SPI over I2C: All the lines are unidirectional, which makes things like level shifters a bit easier. – markrages Mar 31 '12 at 19:27
  • @markrages, I checked the datasheet for a 5v Arduino CPU and discovered my simple pullup solution doesn't work since the minimum input for the I2C is 0.7*Vcc, or 3.5v. So a level shifter would be needed. I modified my answer to indicate this, and recommend a chip to use. I agree the level shifting for SPI is simpler, since you only have one CPU input line to deal with (MISO) -- the outputs can be handled with voltage dividers. – tcrosley Mar 31 '12 at 23:47
  • 2
    I2C is easier than SPI?! The only thing about I2C that's easier is the connectivity if you can just hook everything together. Otherwise the signal integrity is tougher in I2C, and robust software implementation is way tougher in I2C. – Jason S Apr 1 '12 at 0:42
  • 2
    @JasonS, I have completed dozens of embedded software projects using I2C, and have never run into the lock-up problems you mention in your post. I can understand your not liking it due to your bad experiences. I currently have a product out in the marketplace using an I2C DAC to output audio, while simultaneously reading the next buffer of data off of an SD card over SPI. Works great. I couldn't use SPI for both the DAC and SD card since I was getting bus contentions and the audio broke up. The micro (a low-end one) only has one SPI and one I2C port. – tcrosley Apr 1 '12 at 5:52
  • 1
    I'm impressed that you can output audio to an I2C DAC! (what's the max clock rate?) If you're using onboard IC's with short runs, the probability of running into lockup is extremely small, but it still exists. (Also you'd never run into it if you're just writing data to I2C. It requires you to read from a device that is willing to wait forever for what it thinks is a missing / extra clock.) – Jason S Apr 1 '12 at 13:41

SPI can be run much faster than I2C (some SPI devices go over 60MHz; I don't know if the "official" I2C spec allows devices over 1MHz). Implementation of a slave device using either protocol requires hardware support, while both allow easy implementation of "software bit-bang" masters. With relatively minimal hardware, one can construct an I2C-compliant slave which will operate correctly even if the host may arbitrarily decide to ignore the bus for up to 500us at a time, without need for additional handshaking wires. Reliable SPI operation, however, even with hardware support, generally requires that one either add a handshake wire, or else that the host "manually" add a delay after each byte equal to the slave's worst-case response time.

If I had my druthers, controllers' SPI support would contain a few simple extra features to provide 8-bit-transparent bidirectional data transfers between controllers with handshaking and wake-up abilities, using a total of three unidirectional wires (Clock and MOSI [master-out-slave-in] from the master; MISO [master-in-slave-out] from the slave). By comparison, efficient and reliable communication between microcontrollers with "stock" SPI ports, when both processors might independently be delayed for arbitrary lengths of time, requires the use of a lot more wires (Chip-Select, Clock, MISO, and MOSI to start with, plus some sort of acknowledge wire from the slave. If the slave might asynchronously start having data to send (e.g. because someone pushed a button), then one must either use yet another wire as a "wakeup" signal or else have the master repeatedly poll the slave to see if it has data yet.

I2C does not provide all the abilities my "improved" SPI would have, but it does offer built-in handshaking abilities which SPI lacks, and in many implementations it can be kludged to provide wake-up as well, even if the master is a software bit-bang. For inter-processor communication, I would therefore strongly recommend I2C over SPI except when higher speeds are needed than SPI can supply, and the use of extra pins is acceptable. For inter-processor communications where low pin count is needed, UARTs have a lot to recommend them.

  • There's a high-speed version of I2C which allows 1MHz; normal I2C is 400kHz. – The Resistance Sep 4 '13 at 6:15
  • @TheResistance: I know that normal I2C was 400kHz, but versions were spec'ed up to 1MHz. What I don't know is whether faster versions have been specified. – supercat Sep 4 '13 at 6:25
  • According to the specification 400kbps (not kHz, I used the wrong units there) is Fast-mode, 1Mbps is Fast-mode Plus, and there's a High-speed mode up to 3.4Mbps. Ultra-fast goes up to 5Mbps, but is unidirectional. – The Resistance Sep 5 '13 at 7:23
  • @TheResistance: Thanks. I hadn't heard of those later versions. What exactly do you mean by 'unidirectional'? I know that the speed of SPI slave-to-master communication can go faster than master-to-slave because the slave is guaranteed to get its clock after the master, but I'm not sure of an equivalent concept for I2C. Got a linky? – supercat Sep 5 '13 at 14:44
  • Find the spec here. On page 23 it says that Ultra-fast can be used for devices which don't send data back (write only), not even ACK. – The Resistance Sep 6 '13 at 9:02

This question has been thoroughly explored in the excellent answers here, but perhaps there's one more point of view to I2C I could offer from a chip maker's point of view.

The I2C's electrical interface is an open collector. Now breathe and think of the implications. Using I2C, I can design a chip which is totally agnostic to the operating voltage of the bus. All that I need to be able to do is pull the SDA line low if it pleases me to do so, and compare the voltages of SCL and SDA to some ground-referenced threshold voltage, which I can choose. And if I leave out the normal high side protection structures and replace them with other structures, I can make a chip which can totally live its own life undependent from the rest of the system - SCL, SDA never feed any current to my chip and I certainly won't feed any current to those pins. That's why it's such a nice bus for real-time clocks and other low power stuff like that.

One thing I haven't seen mentioned in the other answers is that I2C supports multiple masters on the same bus. If you need bidirectional communication and don't want to use a polling-based method, I2C will get the job done.

Over longer distances, CAN has the same capability and is more robust. But CAN is an asynchronous protocol that requires hardware support and a transceiver, so it may not be an option in a low-cost system.

  • Good point (on multi master), I've also seen SPI devices with interrupt pins, while one device still is the master, both can instantiate (bi-directional) communication. For remote devices there, of course are more solid and better options (such as CAN). – Paul Mar 18 '16 at 11:28

Use the SPI protocol and write your bits directly to the device whenever the sync clock is rising. The xnor logic circuit can be used to match the "homemade" address from a memory to select the wanted device as if it was an i2c device.

The i2c is integrating the authorial circuit inside the format of the device, standard...etc are complex and different, with a spi you can use a spi memory to display a video on screen, but not i2c.

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.