Lesson 03 - I2C

The lecture

This is the first of two lecturs about I2C and components on the I2C bus

I2C (or wire) is a very common local network or fieldbus within robotics and controlsystems.

It is widely used in many areas and types of sensors.

The goal for today is get insight and get hands on in using I2C.

So today we will develop our own drivers for I2C as well as I2C slaves using a standard Arduino platform.


The Inter-integrated Circuit (I2C) Protocol is a protocol intended to allow multiple “slave” digital integrated circuits (“chips”)
to communicate with one or more “master” chips.
Like the Serial Peripheral Interface (SPI), it is only intended for short distance communications within a single device.
Like Asynchronous Serial Interfaces (such as RS-232 or UARTs), it only requires two signal wires to exchange information.

Preparation for the lecture

  1. Read litterature

  2. See movies

  3. Find two Arduinos and three wires

  4. Identify I2C pins (SDA , SCL) and ground

    1. Maybe do it together with one more from your studygroup

Exercise 1

Implement and test an I2C scanner: (See lecti2c01-rawcode) just to get started

Exercise 2

Design and implement a simple protocol which can

  • carry out ADC on channel 0,1,2 and return the conversion as 16 bit signed int (which is default)

    • hint: decide a master code for ADC and a minor code for channel selection

    • hint: design return telegram so master can see what is contained

    • hint: dont forget we can have more than one slave so ID maight be interesting in response.

    • or maybe not

Exercise 3

Design and code an arduino based I2C slave with following functonallity

  • Run the examples on two Arduinos connected by sda,slk and gnd

    • If you are runing them from one PC remember set set Arduino type and USB port every time your are reprogramming

  • Instead of the master try to run the scanner to see if you can see your slave

  • Construct a I2C slave device

    • Here is the spec seen from master side

    • has address 8 or whatever you want

    • has two digital outputs (pin 12,13)

    • has one digital input (11) known as no 11 pin

    • Command to set a digital pin: <id><0 or 1)

    • id 12,13,14

    • Command to read digital pin

    • pin nr 11 has id 11

    • And of course a master that can test it

    • hint attach a button to pin 11 so you can see high or low

    • hint 2 let master running cyclic at 1 Hz

Exercise 4

Performance and Quality

  • Measure signal on I2c by use of oscilloscope. Is the builtin pull-up resistors suifficient

  • In exercise 2 configure it to run as fast as possible

    • Do you loose packages - might be observed by the system locks up or is hanging

  • What is max speed (pkg pr sec)

  • Observe on oscilloscope and identify busy as wells as non busy periodes (no traffic)

Litterature and slides

Slides

Litt

Reading hints and order

First Priority


Secondary priority litt

A simple Arduino to Arduino setup for a single master and single slave experiment

You need

  1. Two Arduinos

  2. Three wires to interconnect them (sda, sdl and ground)

Movies

  • Good video about I2C here

  • A video for master/slave arduino to arduino here

After today - you should (at least) be able to …

  1. Understand I2C protocol

  2. Be able to design a master slave protocol on top of I2C

  3. Code it and get it running

  4. Understand timing and performance on the I2C bus

Tips

3.3V versus 5V

Some devices like Arduino UNO, Mega,… is powered by 5V.

See more here (a practical viewpoint)
Other devices like esp32, m5stack etc is running on 3.3V

This might give problems when having a mix of 3.3V and 5V devices on the bus

You might damage 3.3V devices by having a 5V device on the canbus.

meaning you might be lucky or … not.

citing from element14.com

2C devices have open-drain drivers, which only pull the SCL and SDA lines low to 0V.
Each I2C line should have a single pull-up resistor: make sure they pull up to 3.3V and not 5V.
Also make sure that each 5V part has a reasonable Vih (Input voltage high) threshold.
Many 5V chips use TTL Vih which is 2.0V, which works.
Others may have Vih = 0.7 x 5.0 = 3.5V, which means you'll have to do something else.

A hack

  • disable internal pullup resistors in the 5V based device and use eternal pullup resistors connected to a 3.3V source. You might be lucky because


citing hackaday (link above)

3.3V TTL logic shares the 0.8V and 2V thresholds for logic 0 and logic 1 transitions with 5V TTL logic,
so a 3.3V TTL output can drive a 5V TTL input without any extra hardware required.

But I dont give any guarantee

Ground

When wiring up always start with ground so all devices has same reference

I2C recover

If your I2C locks up this code might help you lect03-i2c-recover

Some Example Code

lecti2c01-rawcode