You are on page 1of 24

Subscribe to DeepL Pro to edit this document.

Visit www.DeepL.com/Pro for more information.

Specialized Master in Smart Industry

Project: Industrial Communication


- Inter Integrated Circuit Bus (I2C Bus)-

Presented by:
EL AMRANI YOUSSEF
Tuesday Fatima zahra

Supervisor : Prof. Mohammed Nabil Kabbaj


Academic Year: 2018/2019

Executive Summary
Introduction

I. Generality on the I2C bus.…………………………………………………………… 4

1) Definitions…………………… .……..………… 4

2) Characteristics and operating principle of the I2C……… bus.…… 4

II. The I2C 6 protocol

1) The takeover of the bus.………………………… 6

2) Single-byte……………………………
transmission..……...…………….............................................................................
..................................................................... 6

3) The transmission of an address..............………………… 7

4) Writing a data 8

5) Reading a data...………................... 9

6) Arbitration between masters………………………………………….………………….. 10

III. Realization of the I2C bus with Arduino………………… cards .………..…… .. . 11


Objective
.……………………………………………………….......…….................................................................
.............................................

1) Ultrasonic sensor HC-SR04…… .…………… . . .…… . 12

2) I2C Arduino : Wire Library……………… .……………..………… .……. ...14

3) Principle of data…… exchange...……………… 15

4) I2C protocol with two Arduino basses.………………………………… 16

1
5) Distance………………… measurement result.…………..…………… 17

Conclusion 18

References…… 19

Appendix ..…………………………………………………………………….20…………………

List of figures :

Figure 1 : The takeover of the bus……………………............ 6

Figure 2: Transmission of an address.………………......... …. 8

Figure 3: Writing a data……………………….………........... 9

Figure 4: Reading a data………………………...…… .. . 10

Figure 5: Arbitration between masters……………………...…… .. . 11

Figure 6: Wiring ………………………diagram ……. . 12

Figure 7: Ultrasonic sensor HC-SR04 with Arduino……... .. . 13

Figure 8: I2C protocol at bass of two Arduino……………... 16

2
Introduction

The I2C bus (Inter Integrated Circuit Bus) is the historical bus, developed by Philips
for home automation and home electronics applications in the early 1980s, in
particular to enable the various circuits of a modern television set to be easily
connected to a microprocessor.

It is the bus that has emerged from the war of standards launched by all the actors of
the electronic world. Thus, in televisions, all the units are on an I2C bus (Remote
control receiver, BF amplifier settings, tuner, clock, SCART management...)

There are countless devices operating this bus, it is even software implantable in any
of the microcontrollers. The weight of the consumer electronics industry has imposed
very low prices on many components.

Our project is part of this context, and it consists on the one hand in the study of the
operating principle of the I2C bus, and on the other hand in the realization of this bus
using Arduino cards. The work presented here is organized as follows
In the first part, we propose generalities on the operating principle of the I2C bus

In the second part, we will make this bus using Arduino cards

3
I. Generality on the I2C bus:

1) Definitions :
Subscriber: any element connected to the bus.
sender: any subscriber who sends data to DID.
Receiver: any subscriber who receives data from DID.
Master: any subscriber who starts and ends an exchange.
Slave: any subscriber addressed by a master.
Address: number assigned to a slave.
Exchange: dialogue between a master and a slave, it starts with an address issued by
the master, followed by one or more data issued by the master or the slave, a master
can chain several exchanges in a row.
Arbitration: resolution of the conflict of simultaneous access by two masters

2) Characteristics and operating principle of the I2C bus :

To connect to an I²C bus you need a ground, and two communication wires. The first
wire, SDA (Signal DAta), is used to transmit the data. The other wire, SCL (Signal
CLock) is used to transmit a synchronous clock signal (signal that indicates the
evolution rate of the DID line). The voltages associated with the logic levels will
depend on the technology of the circuits present (CMOS, TTL). All circuits connected
to the I2C bus will have to use the same potentials to define the high and low levels. In
the end, this means that all components connected to the same bus must be supplied
with the same power. This does not mean that the components must use the same
source to power themselves; it is sufficient if the supply voltage is at the same value
for all components, the ground wire allowing the references to be unified.
There is now a crucial problem. How to allow several logic circuits to connect their
outputs together, knowing that some circuits will want to impose a high level while
others will want to impose a low level, so use open collector (or open drain outputs for
CMOS circuits). The resulting level on the line is then an "AND" function of all
connected outputs.
4
The I2C bus is controlled by a master (it is usually a microcontroller, for example a
PIC 16F876A), it can have several masters (we speak then of multi-master mode) but
at a given moment such that only one master controls the I2C bus, it has one or several
slaves

The potential return resistors VCC allow the SDA and SCL signals to be at 1 if all
open collector outputs are also at level 1 (result of the "AND" function). If one or more
outputs attempt to impose a low level on a line, the associated transistor(s) will drive,
resulting in a low level on the corresponding line (which is consistent with the result of
the "AND" function).

As far as the reading of the DID and SCL signals is concerned, this is not a problem.
The signals can be read continuously without risk of interfering with the line level

At rest, all connected circuits must impose a high level on their respective outputs. If
the SDA and SCL lines are at high level in these conditions, it means that no circuit is
trying to take control of the bus. If one of the DID or SCL lines goes to a low level
under the same conditions, it means that one of the circuits wants to take control of the
bus. But there can also be two circuits trying to take control of the bus at the same time
5
(or a few nanoseconds apart). A protocol must therefore be put in place to manage
possible conflicts.

II. The I2C protocol:

1) The takeover of the bus:


Before attempting to take control of the bus, a circuit must check that the SDA and
SCL lines are at rest, i. e. in the high state. If this is the case, the circuit indicates that it
takes control of the bus by setting the DID line to 0. From that moment on, the other
circuits know that the bus is busy and they should not try to take control of it. The
circuit that has just taken control of the bus becomes the master, it is it that generates
the clock signal, whatever the direction of the transfer (figure 1)

Figure 1 : Taking control of the bus

2) The transmission of a byte:

Before setting the bits that form the byte to be transmitted on the bus, the master must
set the SCL clock line to 0. As long as the SCL line is at the high level, the DID line
must not change state, otherwise this condition will be interpreted as the stop
condition. The stop condition can occur even in the middle of the one-byte
transmission, to abandon the transmission and free the bus for the other circuits. To
correctly transmit the bits on the DID line, the master must therefore first set the SCL
line to 0, then the master can set the DID line to the level corresponding to the bit to be
transmitted and return the SCL line to level 1 to indicate that the bit is present on the

6
DID line. The same operation will be repeated as many times as necessary to transmit
the 8 data bits. Note that it is the high weight bit that is transmitted first.

Once the 8 bits have been transmitted, the circuit that has just received the data must
impose an ACK acknowledgement bit on the DID line. To do this, while the SCL line
is at the low level, the master places its own output at the high level, while the receiver
(also called the slave) places its output at the low level. Since the outputs are open
collector, the DID line will remain at the low level because of the slave. The master
then rereads the DID line once he has passed the SCL line at the high level. If the
value read for the ACK bit is 0, it means that the slave has successfully executed the
received byte, otherwise there is an error and the master must generate the stop
condition.

3) The transmission of an address:


Since the number of components that can be connected to an I²C bus is well over two,
the master must be able to choose which slave is supposed to receive the data. For this
purpose, the first byte transmitted by the master is not a data but an address. The
format of the address byte is a bit special since bit D0 is reserved to indicate whether
the master requests a reading from the slave or whether the master imposes a write to
the slave (figure2)

Figure 2: Transmission of an address

7
4) Write a data:
If the R/W bit previously sent was 0, it means that the master must transmit one or
more bytes of data. After each valid ACK bit, the master can continue to send bytes to
the slave or it can decide to terminate the dialog with a stop condition (figure 3)

Figure 3: Writing a data

5) Reading a data:

If the R/W bit transmitted together with the address is at 1, it means that the master
wants to read data from the slave. It is always the master who will generate the SCL
clock signal. On the other hand, after the ACK bit of the address, it is the slave who
will keep control of the DID line. To do this, the master will set its own DID output at
the high level to allow the slave to take control of the DID line. The slave must then

8
scan the SCL line and wait for the low level to change the state of the DID line,
otherwise the master will detect a stop condition and abandon the transfer (the
electronics integrated in the slave must also detect that there has been a stop condition,
of course).

After the slave has transmitted the 8 data bits, this time the master will generate an
acknowledgement bit. If the master wishes to read additional bytes, he will set the
acknowledgement bit to 0, but if the master decides that the reading is complete, he
will set the ACK bit to level 1. The slave will then understand that the transfer is
complete. This time, although the ACK bit is at level 1, this does not correspond to an
error condition but to the end of the transfer (figure 4).

Figure 4: Reading a data

9
6) Arbitration between masters
● When a master addresses a slave, the slave's
address is placed on SDA.
○ To put a 0 on SDA, so he activates the pull- transistordown○
To put a 1 on SDA, so he uses the pull-up of the line.
● When a master writes on SDA, he checks by rereading it
SDA● If SDA is 0 while the master has not activated his pull-down then it is because
another master communicates
aussi● The loser withdraws
aussitôt● As the addresses are given with the high weight bits first,
the smallest slave addresses have priority over the larger ones

If two masters try to start an exchange simultaneously, the first one who says 1 on DID
has lost as shown below.

Figure 5: Arbitration between masters

10
III. Application of the I2C bus:
Objective

The objective of this work is the communication between a master (Arduino Uno1)
and a slave (Arduino Uno2) based on the I2C Protocol. From where the slave is
connected to two ultrasonic sensors (HC-SR04) therefore the purpose is the reading of
the data (distances) given by the slave in the master, as shown in the following
diagram.

Figure 6: Wiring diagram


1) Ultrasonic sensor HC-SR04

Our sensor will use the popular HC-SR04 ultrasonic sensors.

These devices are inexpensive and easy to obtain from any electronic parts store. They
are reasonably accurate and have become an essential element in robotics projects.

As with most ultrasonic sensors, the HC-SR04 consists of a transmitter and a receiver.
The transmitter sends ultrasonic pulses to the target and the receiver receives the
reflected signal.

11
As the pulses move at the speed of sound, it is sufficient to measure the time between
sending and receiving the pulse. This can be used to calculate the distance

The HC-SR04 has four pins. Two are used for power and ground, the other two for
transmission (Trigger) and reception (Echo), as shown below.

12
Figure 7: Ultrasonic sensor HC-SR04 with Arduino

2) I2C Arduino: Wire Library :

The Wire.h library allows you to simply define the serial communication. The
functions are similar to the Serial library.

INITIALIZATION
● begin() :initializes communication with Arduino "master".
● begin(address) :initializes communication with Arduino "slave"
MASTER MODE
● beginTransmission(address) :starts communication with a slave
● endTransmission() :sends data to slave, makes 0 if successful
● write(< value|chain|pointer,size>) :writes data to be sent to slave
● requestFrom(address, size) :data request to a slave
● available() :makes the number of bytes available after a requestFrom
● read() :reads the byte received from the slave after a requestFrom
SLAVE MODE ●onReceive(function): defines the function to be called upon receipt
of data from the master
● onRequest(function): defines the function to be called at the request of the master

13
● write() :sends the data to the master after request
● available() :test if available data from the master (cfonReceive)
● read() :read data from master

14
3) Principle of data exchange:
The master:
● issues a condition of
démarrage● sends an address on 7
bits● sends the command r/w●
reads the accused and stops if
NACK● for writing, it loops
sur○ sends the 8 bits of
donnée○ reads the accused and stops if NACK●
for reading, it loops
sur○ reads the 8 bits of
donnée○ issues ACK, or NACK for
stopper● issues a stop condition
The slave:●
expects a condition of
démarrage● reads the address on 7
bits● reads the command r/w●
sends ACK if
concerné● for a writing, it loops
sur○ reads the 8 bits of
donnée○ puts ACK or NACK for
arrêter● for a reading, it loops
sur○ writes the 8 bits of
donnée○ reads the accused and stops if NACKle
master and slave can slow down the exchange by playing on SCL● It is
the master who drives the SCL clock by setting it to 0 and at
1● If the slave forces the clock to 0, the master can no longer set it to 1The
master understands that he must wait until the slave "releases" the clock

15
4) I2C protocol with two Arduino basses:

In order for the two cards to communicate with each other, they must be connected
correctly (A4 with A4 and A5 with A5) and the ground (GND) must be connected as
shown in the following diagram.

Figure 8: I2C protocol at bass of two Arduino

With only one I2C equipment connected to the Arduino, pull-up resistors are not
(normally) required, as the Arduino's ATmega328 microcontroller already integrates
them. If several devices are connected to the bus, two resistors of 10 kΩ each are used,

The maximum master-slave distance for an I2C bus is about one meter and depends on
several factors such as the electrical capacity of the bus or the transmission rate. This
distance can be significantly increased by using specific interfaces (an i2c-bus
extender amplifies the current flow through the SDA and SCL pins, which increases
the signal range).

Each device can be connected to the bus in any order, and some devices can even
change from master to slave status and vice versa

16
5) Distance measurement result :

After compiling and executing the programs, open the serial monitor for Arduino 1
(master) and measure the distances for sensor 0 and sensor 1 as shown in the
following diagram.

17
Conclusion

This project has been very beneficial and has given us the opportunity to enrich
our training on both theoretical and practical levels.

On the theoretical level, we had the opportunity to improve our skills by using
the Arduino software (IDE) and the programming language C adapted to the
Arduino.

In practical terms, it has enabled us to acquire knowledge about fieldbuses and


various electronic components.

18
References Bibliography/Webography :

http://fabrice.sincere.pagesperso-orange.fr/electronique1.htm#22

https://www.technologuepro.com/cours-systemes-embarques/cours-systemes-embarques-Bus-
I2C.htm

http://fabrice.sincere.pagesperso-orange.fr/cm_electronique/projet_pic/aide-
memoire/16F876A_bus_I2C/bus_I2C_16F876A.htm

https://www.aurel32.net/elec/i2c.php

https://f-leb.developpez.com/tutoriels/arduino/bus-i2c/

https://www.locoduino.org/spip.php?article77

https://howtomechatronics.com/tutorials/arduino/how-i2c-communication-works-and-how-to-use-
it-with-arduino/

https://www.aranacorp.com/fr/gerez-plusieurs-arduino-avec-un-bus-i2c/

19
Annex

Program for arduino1(master) :


// Include the Arduino Wire library for I2C
#include < Wire.h>
// Define the I2C address of the slave
#define SLAVE_ADDR 9
// Define the counter to count the bytes in response
int bcount;
// Define a table for the return data
byte distance[2];
void setup()
{
Wire.begin();
Serial.begin(9600);
}
byte readI2C(int address) {
// Define a variable to contain the data byte byte bval ;
long entry = millis();
// Read one byte at a time
Wire.requestFrom(address, 1);
// Wait 100 ms until the data stabilizes.
while (Wire.available() == 0 && (millis() - entry) < 100) Serial.print("Waiting");
// Place the data in byte
if (millis() - entry < 100) bval = Wire.read();
return bval;
}
void loop()
{
while (readI2C(SLAVE_ADDR) < 255) {
// Until the first byte has been received, print a Serial.print message ("Waiting");

20
}
for (bcount = 0; bcount < 2; bcount+++) {
distance[bcount] = readI2C(SLAVE_ADDR);
}
for (int i = 0; i < 2; i++) {
Serial.print(distance[i]);
Serial.print("\t");
}
Serial.println();
delay(200);
}
Program for arduino2 (slave) :
// Include the NewPing library for the HC-SR04 sensor
#include < NewPing.h>
// Include the Arduino Wire library for I2C
#include < Wire.h>
// Define the I2C address of the slave
#define SLAVE_ADDR 9
// Sensor 0
#define TRIGGER_PIN_0 10
#Define ECHO_PIN_0 10
// Sensor 1
#define TRIGGER_PIN_1 11
#Define ECHO_PIN_1 11
// The maximum distance is 260 cm.
#define MAX_DISTANCE 260
// Create objects for ultrasonic sensors
NewPing sensor0(TRIGGER_PIN_0, ECHO_PIN_0, MAX_DISTANCE);
NewPing sensor1(TRIGGER_PIN_1, ECHO_PIN_1, MAX_DISTANCE);
// Define the return data network, one element per sensor
int distance[2];

21
// Define the counter to count the bytes in response
int bcount = 0;
void setup() {
// Initiate I2C communications as a slave
Wire.begin(SLAVE_ADDR);
// Function to be executed when data is requested from the
Wire.onRequest(requestEvent) master;
}
void requestEvent() {
// Define a byte to contain the data
byte bval;
Browse data // Browse data
// The first answer is always 255 to mark the beginning.
switch (bcount) {
box 0:
bval = 255;
break;
box 1:
bval = distance[0];
break;
box 2:
bval = distance[1];
break;
}
// Return the answer to the Master
Wire.write(bval);
// Increment the byte counter
bcount = bcount + 1;
if (bcount > 2) bcount = 0;
}
void readDistance()

22
{
distance[0] = sensor0.ping_cm();
if (distance[0] > 254) {
distance[0] = 254;
}
delay(20);
distance[1] = sensor1.ping_cm();
if (distance[1] > 254) {
distance[1] = 254;
}
delay(20);
}
void loop()
{
// Refresh the readings every half second
readDistance();
delay(500);
}

23

You might also like