Arduino Tutorial

By LiterallyTheOne

7: I2C: Part 1

Arduino Tutorial, I2C: Part 1

Introduction

  • Previous tutorial: Interrupt
  • This tutorial: I2C
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

I2C Communication

  • Inter-Integrated Circuit
  • 2 Wire
  • Short-distance
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

I2C Pins

  • SDA: Serial Data
  • SCL: Serial Clock
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

Master and Slave

  • Master: 1
  • Slave: multiple
  • We can connect multiple components to the same pins
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

Master's privileges

  • Controls the clock on SCL
  • Decides that if it wants to communicate with slaves
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

Communication structure

Field Bit Count Description
START SDA goes LOW while SCL is HIGH → begins communication
Slave Address 7 bits Unique address of target device (0–127)
R/W Bit 1 bit 0 = Write, 1 = Read
ACK/NACK 1 bit Receiver pulls SDA LOW to acknowledge (ACK), HIGH for no-ack (NACK)
Data Byte 1 8 bits First byte of data to write or read
ACK/NACK 1 bit Receiver acknowledges the byte
Data Byte 2…N 8 bits Additional data bytes (optional, depends on protocol)
ACK/NACK 1 bit Acknowledge after each data byte
STOP SDA goes HIGH while SCL is HIGH → ends communication
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

I2C pins in Arduino Uno

signal pin
SDA A4
SCL A5
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

Wire

  • Library to control I2C Communication in Arduino
  • Include Wire:
#include <Wire.h>
  • Initilize Wire:
Wire.begin();
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

Different communication with an slave

  • Read
  • Write
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

Write

// start the communication in order to write
// with the slave with the address of `addr`
Wire.beginTransmission(addr);   
Wire.write(data);               // write data
Wire.endTransmission();         // finish transmission
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

Read

// start a read communication with the slave
// with the address of `addr` and read `number` bytes
Wire.requestFrom(addr, number);
Wire.read();                    // read bytes
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

Connect a Clock to an Arduino

  • DS1307: Micro/Peripherals/DS1307

By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

Code to scan

#include <Arduino.h>
#include <Wire.h>

void setup()
{
  Wire.begin();
  Serial.begin(9600);
}

void loop()
{
  for (int i = 0; i < 127; i++)
  {
    Wire.beginTransmission(i);
    if (Wire.endTransmission() == 0)
    {
      Serial.println("Device found at address: 0x" + String(i, HEX));
    }
  }
  delay(2000);
}
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

Connect OLED

  • SSD1306: Outputs/Displays/SSD1306

By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

Clock: DS1307

  • Real-Time Clock (RTC) integrated circuit
  • keeps track of the current time and date
  • Battery
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

DS1307 registers

Register Address
Seconds 0x00
Minutes 0x01
Hours 0x02
Day of Week 0x03
Day of Month 0x04
Month 0x05
Year 0x06
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

Way that it stores data

  • Storing: 0x22 -> 22
  • Not 2*16+2
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

DS1307: Define Clock Adress

#define CLOCK_ADDRESS 0x68
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

DS1307: Jump to the minutes register

Wire.beginTransmission(CLOCK_ADDRESS);
Wire.write(0x01); // Address that we want to jump to
Wire.endTransmission();
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

DS1307: Request bytes

Wire.requestFrom(CLOCK_ADDRESS, 2);

byte minutes = Wire.read();
byte hours = Wire.read();

Serial.println("Minutes: " + String(minutes, HEX));
Serial.println("Hours: " + String(hours, HEX));

delay(1000);
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

DS1307: Read output

By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

DS1307: Read all 7 registers

By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

DS1307: Convert decimal to hex in order to write

  • We want to write: 25
  • If we send 25
    • It would store: 0x19
    • 25/16=1, 25%16=9
  • We should send 0x25
    • which is: 37
    • 2*16+5=37
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

DS1307: Code for converting

byte minutes_to_write = 25;
// convert 25 to 0x25
minutes_to_write = (minutes_to_write / 10) * 16 + minutes_to_write % 10;
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

DS1307: Code for writing

// Write minutes
Wire.beginTransmission(CLOCK_ADDRESS);
Wire.write(0x01); // Address that we want to jump to
Wire.write(minutes_to_write);
Wire.endTransmission();
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

DS1307: Write output

By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

OLED: SSD1306

  • OLED (Organic Light Emitting Diode)
  • Graphic display modules
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

AdaFruit

  • Library to control graphics
  • Add to platfomIO
lib_deps =
    Adafruit SSD1306
    Adafruit GFX Library
  • Include
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

SSD1306: global variables

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

SSD1306: setup

if (!display.begin(SSD1306_SWITCHCAPVCC, SSD1306_ADDRESS))
{
Serial.println("SSD1306 failed!");
for (;;)
  ;
}

display.setTextSize(1);
display.setTextColor(WHITE, BLACK);
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

SSD1306: display

display.clearDisplay();
display.setCursor(0, 0);
display.print("Hello World!");
display.display();
By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

SSD1306: Show the clock

By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

OLED ball

By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

OLED ball line

By Ramin Zarebidoky (LiterallyTheOne)
Arduino Tutorial, I2C: Part 1

By Ramin Zarebidoky (LiterallyTheOne)