I am starting to get into i2C, SPI, and other forms of communication. I have read about them and have a fuzzy idea of how they work electrically, but can someone explain how I would turn the electronic portion into the coding/controlling portion? I really want to get a great understanding of it.

  • If you have Arduino Uno, you can try my free I2C terminal. I2C communication is quite complex. Check out iobtoolkit.com/s/i2c and youtube.com/watch?v=4x3NNWLgtTU . The idea is that you hook up I2C device and you can chat with the device using a console, exploring the protocol and device functions, without writing a single line of C. – IOB Toolkit Team Feb 23 '16 at 19:29
  • I really want to get a great understanding of it. - reading the existing library would help (Wire.cpp and twi.c amongst other files). – Nick Gammon Feb 23 '16 at 22:03

The AVR microcontrollers that Arduino uses have built-in hardware support for the said protocols.

That means that you don't have to write program to control the transmission/reception process but you only need to configure the appropriate registers and the hardware will initiate transfer and inform you when it's done. I suggest you carefully read the datasheet of the microcontroller you are using with your Arduino and you should find all the information there. It even has code examples, so you can actually copy-paste functions and use them in your program, here is one of the examples:

void SPI_MasterInit(void)
    /* Set MOSI and SCK output, all others input */
    DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
    /* Enable SPI, Master, set clock rate fck/16 */
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);

void SPI_MasterTransmit(char cData)
    /* Start transmission */
    SPDR = cData;
    /* Wait for transmission complete */
    while(!(SPSR & (1<<SPIF)));

The keywords with the capital letters are usually register and bit names: you can look them up in the datasheet.


Can someone explain how to program i2C communications without using the library?

The AVR has hardware support for this but you can implement it with the pin functions. I2C is a lot about timing the signals and detecting the reply signal from the slave.

The hardware support for I2C requires understanding of a complex state-machine. If you have implemented the I2C protocol it becomes easy to understand the hardware support and how this help remove a lot of work from the processor core. The state machine, control and status registers and interrupts, are described in the AVR product specification. There are also lots of excellent descriptions on the web. Do not miss the AVR application notes for the I2C. Most of the code in the Arduino core originated from them.


  • So its based all on timing, and hardware application? Sounds like it has to almost be like clockwork – TL140 Feb 23 '16 at 12:58
  • I2C hardware is present in almost any modern microcontroller. It's all about writing a driver for it. Hardware interface will take care of low-level details, such as clock generation and timing. – IOB Toolkit Team Feb 23 '16 at 19:47

A good way to learn how to code for these interfaces is to look at the source code for the libraries themselves. In the PC world, these will be in the directory

Program files (x86)\Arduino\hardware\arduino\avr\libraries

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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