Arduino Microcontroller: How to Use I2C, SPI, and UART

The Arduino microcontroller is a versatile microcontroller, a true workhorse for many do it yourself projects. It has enough pins to connect several sensors and actuators. When building more complex system, you need to have a means for communicating with other microcontrollers or even single board computers.

In the last article, I explained the main protocols that are available on the Arduino and the Raspberry Pi: 1-Wire, I2C, SIP, UART. In this article, we will explore the libraries that are used to establish the connection with these protocols. Each library will be presented with its name, short description of its function, and a code example to get you up and running in minutes.

This article originally appeared at my blog.

I2C

Lets see an example. The following program starts an IC2 master node.

#include <Arduino.h>
#include <Wire.h>
#define IC2_CLIENT 0x23void setup() {
Wire.begin();
Serial.begin(9600);
}
void loop() {
Wire.beginTransmission(IC2_CLIENT);
Wire.write("Server Request");
Wire.endTransmission();
delay(3000);
}

The I2C client node will listen for incoming messages, and print them on the serial output.

#include <Arduino.h>
#include <Wire.h>
#define MY_I2C_ADDRESS 0x23void setup() {
Wire.begin(MY_I2C_ADDRESS);
Serial.begin(9600);
}
void loop() {
if (Wire.available()) {
char c = Wire.read();
Serial.print(c);
}
}

This is just a basic example. The library also provides a mean to define non-blocking handler methods that are executed when data is available. And there are also methods to govern how the server requests to read data from its connected clients.

SPI

Let’s take a look at an example, inspired by the official example.

#include <Arduino.h>
#include <SPI.h>
#define CLIENT_SELECT_PIN = 10
#define CLIENT_REGISTER_ADDRESS = 0x10;
void setup() {
pinMode(CLIENT_SELECT_PIN, OUTPUT);
SPI.begin();
}
void loop() {
delay(1000);
writeToSpiClient(0x10, millis());
}
void writeToSpiClient(char& buffer, int value) {
delay(100);
SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0));
SPI.transfer(buffer,value);
SPI.endTransaction();
digitalWrite(CLIENT_SELECT_PIN, HIGH);
delay(100);
}

The basic steps are:

  • Define the pin layout
  • Start the SPI server with SPI.begin()
  • Wrap any transaction in SPI.beginTransaction() and SPI.endTransaction()
  • Use SPI.transfer to send and receive data at the same time

UART

To open the UART connection, you need to define the baud rate, a technical term for the number of characters that can be send. Once established, you can read and write any character-based data.

The following program sends configures the baud rate to 9600. It will then send the "Hello UART" exactly one time to any connected client. Then, it will listen for any incoming data, and store it in a variable called msg.

#include <Arduino.h>
#include <stdbool.h>
string msg;
bool only_once = true;
void setup() {
Serial.begin(9600);
}
void loop() {
(if only_once) {
only_once = false;
Serial.send("Hello Client");
}
if (Serial.available()) {
char c;
while (c = Serial.read()) {
msg += c;
}
}
}

Conclusion

IT Project Manager & Developer