0:09
hello and welcome to controllers Tech
0:12
this is the second video in the ESB 32
0:15
i2c Series in the previous video we saw
0:19
how to interface the LCD
0:21
1602 which was connected using the
0:24
pcf8574 i2c extender today we will see
0:28
how to read the data from a sensor and
0:31
we will also check the functions
0:32
available in the es32 i2c library I am
0:39
accelerometer sensor for today's video
0:43
let me be clear that this video does not
0:45
cover the full functionality of the
0:47
sensor rather we will only read the
0:50
acceleration data and focus more on how
0:53
to read data using the i2c in ESB
0:56
32 this is how the sensor is connected
1:00
b32 the clock pin is connected to pin 18
1:04
and data is connected to pin
1:07
19 the sensor is powered with 3.3 volts
1:10
from the ESB 32 itself that is all for
1:14
the connection let's open the ID and
1:17
create a new expressive IDF Project
1:20
Check the section for using the template
1:23
scroll down to peripherals then expand
1:26
the i2c peripheral and select the i2c
1:29
simple project let's rename the project
1:33
and click finish all right the project
1:36
has been generated and here is the main
1:39
file let me delete all these definitions
1:42
first also delete the mpu
1:47
functions and leave only the i2c
1:50
initialization in the main function
1:53
let's build the project once and then we
1:56
will start dealing with the errors all
1:58
right let's define this i2c instance
2:01
first we will use the i2c 0 in this
2:05
tutorial next we need to define the data
2:08
and clock pins the clock pin is number
2:12
18 and the data pin is
2:15
19 let's change the variables here
2:21
too let's set the i2c clock speed to 400
2:25
khz you can also set 100 khz the sensor
2:30
works fine with it also the TX and RX
2:34
buffers are not used in the master mode
2:36
so let's set them to zero all right
2:39
let's build the code again we still have
2:42
some errors and they are because of
2:45
definitions I am using the stm32
2:48
definition here all right the errors are
2:51
gone now and we can proceed with the
2:54
video the i2c master in it initializes
2:57
the i2c in the master mode
3:00
note here that the internal pull-ups are
3:02
enabled for both clock and data
3:05
pins after setting the configuration we
3:08
call the function i2c parameter config
3:11
and pass the configuration to it then
3:14
the function i2c driver install will
3:16
finally initialize the i2c instance in
3:19
the master mode here the i2c mode is set
3:22
to master the TX and RX buffer are
3:25
disabled in the master mode and the
3:27
interrupt flag is set to zero as we not
3:31
interrupts inside the main function we
3:33
will call the master in it to initialize
3:36
the i2c in the master mode and if there
3:38
are no errors a success message will be
3:42
console the sensor we are interfacing
3:47
slave now before we start writing the
3:50
function for the sensor we need to know
3:52
its slave address here is the data sheet
3:55
of the mpu6050 here you can find the
3:59
slave address in the i2c interface
4:02
section here is the 7bit slave address
4:05
for the sensor but if you note here the
4:08
least significant bit is marked X as
4:12
they have mentioned here the LSB depends
4:14
on the logic of the pin
4:16
a0 you can find this pin on the breakout
4:19
Board of the sensor the address is
4:22
configured in this way so as to allow
4:24
two sensors to be connected to the same
4:26
i2c bus since we have not connected the
4:30
ad0 the logic will be treated as zero
4:33
and hence the address will be 68 hex if
4:37
you want to interface another sensor to
4:39
the same bus you can connect the ad0 to
4:42
a 3.3v signal and use the address 69 hex
4:46
for it all right let's define the slave
4:49
address 68 hex in our
4:52
code since we are not covering the full
4:54
functionality of this sensor we will not
4:57
dig too deep into the data sheet
5:00
rather let's just focus on the bare
5:02
minimum to get the acceleration values
5:05
sensor let's check out the sb32 i2c
5:10
file here mainly we have three functions
5:14
available Master right to device Master
5:16
read from device and master right read
5:20
device there are other functions as well
5:22
like i2c start stop write read Etc but
5:27
they are the low-level functions
5:30
at a high level we only have these three
5:34
available let's understand why I am
5:37
calling them high level
5:39
functions the function right to device
5:41
is used to send the data to the slave it
5:45
parameters the i2c instance the slave
5:49
address pointed to the data that you
5:51
want to write the size of the data and
5:54
timeout this function will first issue
5:57
the start condition the then it will
6:01
address then all the data bytes are
6:04
sent and finally it will issue the stop
6:08
condition this is a standard i2c
6:13
master next we have the master read from
6:16
device this function is used to read the
6:19
data from the slave device and it also
6:23
parameters the i2c instance the slave
6:26
address pointed to the data where you
6:28
want to store the received data the size
6:33
timeout this function will first issue
6:36
the start condition and then it will
6:39
address note that the slave address is
6:42
shifted to the left by one place and
6:44
then it adds the read bit to it actually
6:48
the slave address for any device is 8
6:50
bit wide where the seven bits are the
6:52
actual address and the least significant
6:55
bit decides whether it is a write or
6:58
operation the SB is set to zero for a
7:01
right operation and it is set to one for
7:05
operation in our main function we Define
7:07
a seven-bit address and the library
7:10
takes care of the read and write bit by
7:13
itself after sending the slave address
7:16
the function starts reading the data
7:19
once the required number of data bytes
7:21
has been read the master will issue a
7:23
negative acknowledgement to indicate the
7:27
transfer finally it will issue view the
7:29
stop condition the next function is the
7:35
device this is the most important of
7:37
them especially when we are dealing with
7:39
a sensor that has data arranged in
7:43
locations this function will first write
7:46
the data to the device and then start
7:48
reading the data it takes seven
7:51
parameters in total the i2c instance the
7:55
slave address pointed to the data that
7:57
you want to write the size of the data
8:00
to write point it to the data where you
8:02
want to store the received data the size
8:04
of the data to read and the
8:07
timeout this function will first issue
8:09
the start condition then it will send
8:13
the slave address with a right bit then
8:16
it will write the required number of
8:19
device next it will again issue a start
8:23
condition this is called repeated start
8:26
in terms of i2c communication
8:29
now it will send the slave address with
8:31
a read bit then it will start reading
8:35
the data once the required number of
8:38
data bytes has been read the master will
8:40
issue a negative acknowledgement to
8:42
indicate the slave to stop the
8:44
transfer finally it will isue the stop
8:48
condition as I mentioned earlier you can
8:51
even directly use these start stop write
8:54
read conditions without the use of these
8:59
but remember that you need to follow the
9:04
communication we will use these
9:06
highlevel functions as they will serve
9:08
our purpose for any kind of
9:10
requirement mostly all the sensors have
9:13
data arranged in memory locations inside
9:15
them and mpu6050 is no
9:19
different we need to write the data
9:22
inside these memory locations and
9:25
similarly read from them let's write a
9:28
function to read the data from a
9:32
6050 the parameters of the function are
9:35
the register address inside the sensor
9:37
where we want to read from the pointer
9:39
to the buffer where we want to store the
9:41
received data to and the number of bytes
9:45
read here we will call the function
9:50
device pass the i2c instance and the
9:54
address the master needs to First send
9:57
the address of the register inside the
9:59
slave save device so pass the register
10:02
address and the address is one bite in
10:05
size now the master will store the
10:08
received data into this buffer and the
10:10
size of the data to be read will be
10:12
passed from the functions parameter
10:14
itself let's set the time out to 2
10:18
seconds before we can read the
10:20
acceleration data from this sensor we
10:22
will read the ID of the
10:24
device here I have the register map for
10:29
Zer it contains the details of all the
10:33
sensor here the last register is who am
10:36
I this is a readon register and it
10:40
stores a unique ID the register address
10:43
is 75 hex and the data stored in the
10:46
register is 68 hex when we read this
10:50
register we should get this data and
10:52
that will verify that the sensor is
10:54
responding fine inside the main function
10:58
let's call the function mpu read from
11:00
the register we want to read the
11:03
register 75 hex the received data will
11:07
be stored in the data array and we are
11:10
reading only one bite we will log this
11:13
received data to the
11:16
console here x is used for displaying
11:23
hexadecimal all right let's build the
11:25
project now we don't have any errors
11:29
make sure that the correct device is
11:32
configured here it has found the target
11:35
so we are good to go let's Flash the
11:42
board now open the terminal and connect
11:45
the serial Port here you can see we have
11:49
received the data 68 hex from the sensor
11:52
so the sensor is responding fine and we
11:55
can proceed with reading acceleration
11:57
data from it let's write another
11:59
function to write the data into a
12:01
particular register of the slave device
12:04
the parameters of the function will be
12:06
the register we want to write and the
12:09
data bite itself here we will call the
12:12
function Master right to device pass the
12:15
i2c instance and the slave address to
12:19
parameters now we need to pass the right
12:22
buffer basically we will first send the
12:24
register bite followed by the data bite
12:28
so let's Define an array of two bytes
12:31
first then store the register data into
12:34
this array followed by the data B now
12:37
pass the array to the parameter the size
12:40
is 2 bytes and let's set the time out to
12:43
1 second if you want to write multiple
12:46
bytes starting from a fixed register you
12:48
can create the right buffer with a size
12:50
one greater than the number of data
12:53
bytes then store the register data at
12:55
the first position and then copy the
12:57
rest of the data into the right buffer
13:01
all right let's check the register map
13:04
sensor here we are interested in this
13:07
power management register one the
13:10
register address is 6bx and it is
13:13
responsible for configuring many
13:15
things we will reset all the bits of
13:20
zero thus setting the clock source as an
13:25
oscillator also the temperature sensor
13:28
is not disabled the sleep is not
13:30
disabled but the sensor is also not in
13:33
the sleep mode Let's call the function
13:36
mpu right register and set all the bits
13:39
of the register 6 beex to zero the next
13:43
register we are interested in is sample
13:46
divider the address of this register is
13:49
19 hex and all the bits are used to
13:52
configure the sample rate
13:54
divider the value we input here is used
13:57
in this formula to generate the output
13:59
sample rate the gyroscope output rate is
14:03
fixed at 8 khz when the digital low pass
14:06
filter is disabled we will keep it
14:09
disabled so the rate is definitely at 8
14:12
khz if we use the sample rate divid a
14:15
value as 7 the sample rate will be 1
14:19
khz let's set the value 7 to the
14:22
register 19 hex next we have the
14:25
configuration register which is by
14:28
default reset to to zero with this
14:30
configuration the digital low pass
14:33
filter is disabled and the gyroscope
14:37
khz next is the gyroscope configuration
14:41
register which we are not interested in
14:44
then we have the accelerometer
14:46
configuration which is also reset to
14:48
Zero by default in this configuration
14:52
the accelerometer full scale range is
14:56
2G just keep this in mind as it will be
15:01
calculation next we are interested in
15:05
measurements the accelerometer data
15:08
stored in the six registers starting
15:10
from the address 3B hex the acceleration
15:14
data for each axis is 16bit wide and it
15:17
is split into two 8bit
15:20
registers after reading the data we will
15:23
combine these two bytes to make a single
15:25
16bit value similarly we will combine
15:29
registers to make 16bit data in other
15:31
axes as well we want to continuously
15:34
read this data so let's write the rest
15:37
of the code in the while loop Now call
15:40
the function mpu read from register
15:43
again here we will read six bytes of
15:46
data starting from the register 3B hex
15:50
we will store the data in the data array
15:53
let's define this array for 10 bytes so
15:56
that we can store the acceleration data
15:58
in into it now we have the data so let's
16:02
combine it for each axis let's define
16:05
assigned 16bit integer raw X which will
16:09
store the combined data the higher bite
16:12
is sent first so we will shift it to the
16:15
left by8 places and then the lower bite
16:17
with it similarly combine the data bytes
16:21
for the Y and Z axis as well now we have
16:24
the raw 16bit raw data for all axes so
16:28
we will convert convert it to gravity
16:30
form to do so we will divide the 16bit
16:40
16,384 depends on the full scale range
16:43
selected in the accelerometer
16:45
configuration here you can see for the
16:48
range of plusus 2G there are
16:52
16,384 lsbs for 1G this means that a
16:56
value of 16,3 84 is equivalent to
17:01
1G so to get the gravity data we will
17:05
divide our raw value by
17:09
16,384 similarly we will get the gravity
17:11
data in other axes as well now we have
17:15
the data so let's log it on the
17:17
console here I am using the format point
17:20
2f so that the data will be displayed in
17:27
places let's give a delay of 1 second
17:31
measurements all right let's build the
17:34
project there are no errors so let's
17:37
flash it to the board let's check the
17:40
console for the logs the sensor is kept
17:43
stationary so there should be
17:45
acceleration in The Zed axis actually
17:48
there is a small error in the code here
17:51
T should be the fourth element of the
17:53
array and we are shifting by eight
17:56
places let's build and Flash it again
17:59
all right now we have the Zed
18:03
1G please keep track of the sensor's
18:06
position so you will understand how the
18:08
acceleration changes with alignment
18:11
let's flip the sensor upside down you
18:14
can see the acceleration in the Z AIS is
18:21
G now if we change the alignment towards
18:24
the left the acceleration in the x-axis
18:27
has been increased towards 1 G the other
18:31
X's are close to zero similarly if we
18:34
change the alignment towards the right
18:37
the acceleration in the x-axis increases
18:39
towards positive 1 G changing the
18:42
alignment vertically changes the
18:44
acceleration in the Y AIS as well so we
18:48
can write and read the data from the
18:53
i2c we saw how to use the i2c write and
18:56
read functions in es32 do as I mentioned
19:00
earlier this video was not about mpu6050
19:04
instead we will make a complete video in
19:07
near future covering all the
19:08
functionality of this sensor we will
19:11
cover some more sensors which use i2c in
19:15
videos this is it for
19:18
today I hope everything was clear you
19:21
can download the project from the link
19:24
description leave comments in case of
19:27
any doubt keep watching and have a nice