Sunteți pe pagina 1din 35

Tutorial 8.

Reading of MPU6050 sensor (Accelerometer and Gyroscope) in


Microcontroller of STM32F4 series.
Start Tutorial 8. Reading of MPU6050 sensor (Accelerometer and Gyroscope) in
Microcontroller of STM32F4 series.

The objective of this tutorial is to show how to configure our Ophyra development
card to read the MPU6050 sensor. This sensor is an integrated Accelerometer and
Gyroscope with I2C communication. To demonstrate its operation we will make an
example where we will send the data read from the sensor to the RS232 port to
visualize them in the compiler terminal.

Configure Hardware using STM32CubeMX.

The first thing we will do is the corresponding configuration of the resources of


our card in STM32CubeMX as follows:

We created a new project (Image 1) and selected the STN32F407VG


microcontroller, as we already know, which is the one corresponding to our Ophyra
card.
Image 1. New Project in STM32CubeMX.

Image 2. Selection of the microcontroller.

As already mentioned, the RS232 communication will be used to display the


information coming from the MPU6050 sensor. So we will use the resource
"USART 3", so we look for it in the left part of the "Pinout" window, we select it
and we enable it. Then, in the part where it says "Mode" we select the
"Asynchronous" option, and in the section that says "Hardware Flow Control
(RS232)" we leave it in the "Disable" option, that is, disabled. Now we can see the
pins corresponding to "TX" and "RX", ie the corresponding pins to transmit and
receive are enabled and put green as you can see in image 3.

Image 3. Enabling the RS-232 port number 3.

The next step is to enable the I2C port number 1. The MMPU6050 sensor is
connected to this port. As you know this port uses two pins or ports to perform the
communication:
 SDA: Bidirectional synchronous serial port, through which data is
transmitted from device to device.

 SCL: Synchronous data serial port, this generates a clock signal with the
speed of data transfer to the sensor.

In the section "pinout" we enable the port I2C1 and put it in "I2C" mode, as shown
in Figure 4. Also in the image seen in the microcontroller pins ports are
enabled PB7 = I2C_SDA and PB6 = I2C_SCL . These ports are connected by
default to the sensor, therefore it is not necessary to move or rename them.

An additional device (an EEPROM memory) is also connected to port I2C1, as


detailed in table 1. Both devices have their ID or slave identification address
configured as hardware, as shown in the table. In the I2C protocol, the ID is always
sent at the beginning of a communication between master-slave devices. These
addresses are used to control which slave device the master device will
communicate with. When a slave device recognizes its ID, it responds to the
master device through a recognition signal (acknowledgemt in English), it is at that
moment when communication is established between them.

Table 1. Devices connected to the I2C1 port of Ophyra.

If we want to use another device with I2C protocol, it will not be possible to use
the I2C1 bus , since it is not mapped to any physical pin of the expansion ports
CN1, CN2 and CN3; however the Ophyra microcontroller has 2 additional I2C
ports, which are possible to enable (I2C2 or I2C3). We recommend reviewing
the Ophyra manual in section 5.14 Expansion ports to identify in which connector
we have an additional I2C port available.
Image 4. Enabling the I2C port and devices connected to the same port.

Then we click on the "Configuration" tab and enter the configuration windows of
each activated resource (see image 5). In the picture 6 the configuration window of
the RS-232 protocol is observed. We make sure that the settings are properly
activated and we click on the accept button. Now we do the same with the
configuration of the I2C port.

Image 5. Buttons to select.


Image 6. Parameters of the RS-232 port and the I2C port.

In the configuration tab we find in connectivity "Conecctivity" the I2C


protocol. Clicking on this button shows some configurations:

 I2C Speed Mode: Speed mode.

 I2C Clock Speed (Hz): Speed frequency.

 Clock No Strech Mode: Mode that encourages communication speed.


 Primary Address Length selection: Primary communication address.

 Dual Address Acknowledge: Recognize the address.

 Primary slave address: Primary slave address.

 General Call Adreess detection: Detection of address recognition.

Image 7 . Generation of code .

Click on "Apply" and then "Ok". Now we can proceed to generate the code, by
clicking on the "Generate Source Code ..." icon, located at the top of the main
window, where the following window will be displayed:
Picture 8 . Proyect settings window .

Once in this window we proceed to configure the following parameters:


1. Project Name , a name is placed for the project, which in our case will
be Tutorial_AccGyro_Serial .
2. In Project Location , in this field you only have to make sure that the
address where your Workspace is located is located for Atollic
TrueSTUDIO, in our example the Wokspace is located in C: \ Users \
Fernando \ Atollic \ TrueSTUDIO \ ARM_workspace_7.1. Once the location
is selected automatically, the "Toolchain Folder Location" section will be
filled.
3. In the Toolchain / IDE , here we must select our software that we will use to
program, that being a free Software, we will use Atollic TrueSTUDIO,
therefore we select TrueSTUDIO.
4. Select the Code Generator tab and click on the option shown in the image.
5. By clicking on this option we configure the STM32 CubeMX to generate the
configuration files separated from the "main" file . This step is optional
and depends on the programmer's preference.

Finally we click on "OK", and then the window that shows the generation of the
project will be displayed, in which we will click on "Open Project".

Perform program in Atollic TrueSTUDIO.

Once STM32CubeMx opens TrueStudio, we go to the project explorer where the


current project is shown as shown in the following image. We display the folder of
our project, and in the directory "Src" we look for the file "main.c" and we double
it to be displayed in the text window.
Image 9. Selecting the "main" file.

Within the "USER CODE BEGIN Includes" section we add the directives that are
observed in image 10. The first two lines correspond to standard C libraries, while
the third line corresponds to the slave address or ID of the MPU6050 sensor (see
table 1). It should be noted that the address 0x68 is shown in table 1 and 0xD0 is
shown in the image. This is so, because the number 0x68 was previously made a
shift to the left remaining at the value of 0xD0. This shift is necessary because in
the I2C protocol, the least significant bit of the ID is used as a write / read
command. This bit is manipulated by the master device, setting it to 1 when you
want to read information and 0 when you want to write to the slave device.

Image 10. Initial directives to include in the program.

Next write the code that shows the following image.


Figure 11. Variables and sensor configuration sections.

The section marked with number 1 corresponds to the variables used to transmit
and receive data from the MPU6050 sensor.

Section 2 sends the first sensor configuration data. The data that is sent is 0x6B
and 0x00; the first is the address of the sensor configuration record. The second
data corresponds to the data to be written to the sensor. According to the sensor
specification sheet when a zero is written to the 0x6B register, the sensor exits the
standby or standby state and begins to perform the acceleration and rotation
measurements. The instruction used to send data is:

HAL_I2C_Master_Transmit ( Arg1 , Arg2 , Arg3 , Arg4 , Arg5 );

As you can see, this instruction requires 5 parameters:

 Arg1: The I2C port with which you are working is specified.

 Arg2: Is the ID or address of the slave device.

 Arg3: Buffer or array of data to be sent to the slave device.

 Arg4: Amount of data to send .

 Arg5: Maximum waiting time.

Section 3 configures the sampling frequency of the sensor at 1KHz, writing the
data 0x07 in the internal register 0x19 of the sensor.

Now we write the code shown in figure 12. This section of code in general reads
the data coming from the Accelerometer, Gyroscope and temperature; and sends
them to the USB-Serial port, for viewing on any serial terminal. In this particular
case we will use the serial terminal that is integrated with Atollic-TrueStudio.
Image 12. Program section to be executed in infinite while loop .

Next we will describe each section of the code:

Section 1 sends only one data (0x3B) to the sensor. This causes the sensor to
position its pointer in the 0x3B register. This register corresponds to the most
significant byte of the X axis of the Accelerometer. The sensor data sheet specifies
that all readings made by the sensor are stored in stacked records in its internal
memory. In addition, each reading is 16 bits in length, so it uses 2 bytes for each
axis sensed. Therefore, there are 6 bytes for the Accelerometer data (ie 2 bytes for
each Cartesian axis: X, Y, Z), 6 bytes for the Gyroscope data and 2 bytes for the
temperature sensor data. In total there are 14 bytes that have to be read to obtain
the complete sensor information.

Section 2 , reads the 14 bytes of information, by means of the following


instruction:
HAL_I2C_Master_Receive ( Arg1, Arg2, Arg3, Arg4, Arg5 );

As you can see, this instruction requires 5 parameters:

 Arg1: The I2C port with which you are working is specified.

 Arg2: Is the ID or address of the slave device.

 Arg3: Buffer or data array where the information coming from the slave
device is stored .

 Arg4: Amount of data to be received .

 Arg5: Maximum waiting time.

Section 3 is responsible for assembling the data in floating 32-bit words. The first
thing you do is a concatenation (at 16 bits) of the most significant byte with the
least significant byte of each acceleration axis, temperature sensor and
gyroscope. Then divide each concatenation by a factor of sensitivity or conversion,
as specified in the data sheet of the sensor.

Section 4 is in charge of sending the obtained data to the USB-Serial port of


Ophyra, for its deployment in the serial terminal of Atollic. For more details on
sending and reading data through the serial port, see tutorial 7 .

Finally we compile our program to generate the * .HEX file and download it to our
card. To do this, follow steps 1 to 5 of this GUIDE .

Upload program to our Ophyra Development card.

The last step is to program your Ophyra card. If you have never done it, follow
steps 6 through 12 of this GUIDE .

Conclusions

After loading the program to the Ophyra card, we will open the terminal of the
serial port that is integrated in Atollic TRUESTUDIO. In the picture 13 the button
that we must press is shown so that we will have the terminal. Note : This button
can vary from location according to the configuration of your program, for it is
necessary that you identify it well.
Image 13. Button to open the serial terminal of Atollic.

Clicking on the button will open a configuration window like the one shown in
image 14.
Image 14. Configuration window of the Atollic serial terminal.

We select the COM port corresponding to our Ophyra card, the other parameters
are not modified as this was configured by default the Ophyra serial port; finally
we click on OK. Atollic will open a window in the lower part of the window, next
to the console. In this window we will observe the data sent by Ophyra (see image
15).

For this example, a chain of data corresponding to each reading of the axes of the
accelerometer-gyroscope and of the temperature sensor will be
observed. Accelerometer measurement units are configured in gravities or G ; for
the Gyroscope they are given in º / sec and for the thermometer in ºC . By default
the Accelerometer is configured for a range of 2G , but can be configured for
ranges of 4, 8 and 16G. Similarly, the Gyroscope is set to a sensitivity of 250 º /
sec , but can be configured for sensitivities of 500, 1000 and 2000 º / sec.

To end or close the communication with the serial port, we must press the button
that is highlighted in red in image 15.
Figure 15. Activated Atollic serial terminal. Deployment of data.
We have configured and programmed the MPU6050 sensor in Ophyra through the
I2C serial port. We also use the RS232 serial port, to visualize the information
coming from the sensor in the Atollic terminal.

We suggest you to do more complicated exercises such as the configuration of the


sensor at another sampling rate, Accelerometer measurement range and Gyroscope
sensitivity.
Amlaku yalew
Hi friends, In I wanted to present my project that I have tried using HAL libraries
only. I hope it's a useful sharing. Please do not hesitate to add your questions and
comments.
In this article, a friend asked me a question about the MPU6050 sensor related to
my project ( PICproje.org ).

Project creation phase, video description:


Let us define the variables we will use according to the project.
uint8_t TxBuffer [2];
uint8_t RxBuffer [7];
uint8_t DataBuffer [14];
int16_t DataBuffer16 [7];
uint8_t MPU6050_INT_State = 0;
int16_t gyro_x_temp, gyro_y_temp, gyro_z_temp, accel_x_temp, accel_y_temp,
accel_z_temp, temp_raw;
float temp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z;
Let's define the functions we will use later.
static void Error_Handler (void);
static void MPU6050_Extract_Readings (void);
The Error_Handler () function will be a function that we can use to detect any
errors. If I detect errors in the condition (if) controls that I have created, I can
direct this function to the program and insert the program into the infinite while
loop. This is a serious help in the development phase.
The MPU6050_Extract_Readings () function converts raw data from the sensor
into its final form.
Now we write the required values to the registers required for the MPU6050 to
work as we wish. I did not write the meaning of these values, you can see what
they do easily by looking at the Register Map of the module.
TxBuffer [0] = 0x80;
HAL_I2C_Mem_Write (& hi2c1, MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_PWR_MGMT_1, 1, TxBuffer, 1, 1000);
Hal_delay (200);
TxBuffer [0] = 0x00;
HAL_I2C_Mem_Write (& hi2c1, MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_PWR_MGMT_1, 1, TxBuffer, 1, 1000);
Hal_delay (200);
TxBuffer [0] = 0xF8;
HAL_I2C_Mem_Write (& hi2c1, MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_FIFO_EN, 1, TxBuffer, 1, 1000);
Hal_delay (200);
TxBuffer [0] = 0x10;
HAL_I2C_Mem_Write (& hi2c1, MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_FIFO_EN, 1, TxBuffer, 1, 1000);
Hal_delay (200);
HAL_I2C_Mem_Read (& hi2c1, MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_ACCEL_CONFIG, I2C_MEMADD_SIZE_8BIT, RxBuffer, 1,
1000);
Hal_delay (200);
RxBuffer [0] | = 0x18;
HAL_I2C_Mem_Write (& hi2c1, MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_ACCEL_CONFIG, 1, RxBuffer, 1, 1000);
HAL_I2C_Mem_Read (& hi2c1, MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_INT_ENABLE, I2C_MEMADD_SIZE_8BIT, RxBuffer, 1,
1000);
Hal_delay (200);
RxBuffer [0] | = 0x11;
HAL_I2C_Mem_Write (& hi2c1, MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_INT_ENABLE, 1, RxBuffer, 1, 1000);
HAL_I2C_Mem_Read (& hi2c1, MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_INT_PIN_CFG, I2C_MEMADD_SIZE_8BIT,
RxBuffer, 1, 1000);
Hal_delay (200);
RxBuffer [0] | = 0x30;
HAL_I2C_Mem_Write (& hi2c1, MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_INT_PIN_CFG, 1, RxBuffer, 1, 1000);
HAL_I2C_Mem_Read (& hi2c1, MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_CONFIG, I2C_MEMADD_SIZE_8BIT, RxBuffer, 1, 1000);
Hal_delay (200);
RxBuffer [0] | = 0x06;
HAL_I2C_Mem_Write (& hi2c1, MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_CONFIG, 1, RxBuffer, 1, 1000);
From this point on, the processor will read and convert data continuously in the
main while loop. You can use the incoming data as desired.
/ * Infinite loop * /
/ * USER CODE BEGIN WHILE * /
while (1)
{
while (MPU6050_INT_State == 1)
{
HAL_GPIO_WritePin (GPIOD, LD4_Green_Pin, GPIO_PIN_SET);
// MPU6050_I2C_Mem_Read_Multi (MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_ACCEL_XOUT_H, DataBuffer, 14);
HAL_I2C_Mem_Read (& hi2c1, MPU6050_DEFAULT_ADDRESS,
MPU6050_RA_ACCEL_XOUT_H, I2C_MEMADD_SIZE_8BIT, DataBuffer, 14,
10000);
for (int i = 0; i <7; i ++)
{
DataBuffer16 [i] = (int16_t) (((uint16_t) DataBuffer [2 * i] << 8) | DataBuffer [2 *
i + 1]);
}
MPU6050_Extract_Readings ();
MPU6050_INT_State = 0;
}
HAL_GPIO_WritePin (GPIOD, LD4_Green_Pin, GPIO_PIN_RESET);
}
/ * USER CODE END WHILE * /
Our function to work when cutting occurs.
void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_5)
{
MPU6050_INT_State = 1;
}
}
Our debugging function. (Not used in this application.)
static void Error_Handler (void)
{
while (1)
{
HAL_GPIO_TogglePin (GPIOD, LD5_Red_Pin);
Hal_delay (250);
}
}
The function in which we process raw data. In this function, the letters ar F at are
added to the end of the numbers to perform the operations with float numbers by
the FPU unit. Otherwise, the process would be done software with a floating-point
number, which would seriously slow down the program. Friends who work with
different processors should pay attention to this issue.
void MPU6050_Extract_Readings ()
{
// Extract accel readings
accel_x_temp = DataBuffer16 [0];
accel_x = (float) accel_x_temp / 2048.0F;
accel_y_temp = DataBuffer16 [1];
accel_y = (float) accel_y_temp / 2048.0F;
accel_z_temp = DataBuffer16 [2];
accel_z = (float) accel_z_temp / 2048.0F;
// Extract temperature readings
temp_raw = DataBuffer16 [3];
temp = temp_raw / 340.0F;
// Extract gyro readings
gyro_x_temp = DataBuffer16 [4];
gyro_x = (float) gyro_x_temp / 131.0F;
gyro_y_temp = DataBuffer16 [5];
gyro_y = (float) gyro_y_temp / 131.0F;
gyro_z_temp = DataBuffer16 [6];
gyro_z = (float) gyro_z_temp / 131.0F;
// Set accel offset
accel_x + = Accelx_offset;
accel_y + = Accely_offset;
accel_z + = Accelz_offset;
// Set temp offset
temp + = Temp_offset;
// Set gyro offset
gyro_x + = Gyrox_offset;
gyro_y + = Gyroy_offset;
gyro_z + = Gyroz_offset;
}
Finally, you can download the header file of the sensor including the offset map
and the offset values in our data processing function .
If you include this file at the top of your main.c file, you won't have any problems.
Good luck with.
Accelerometer and Gyroscope data
It works with the mpu9255 sensor (such mpu6050 only with a few additions) and stm32 f103
microcontroller.

My problem is that with a higher frequency of data downloading, the microcontroller hangs right
after the start.

But one by one, it communicates with the sensor via I2C. The configuration of the gyroscope and
accelerometer looks like this:

HAL_I2C_Mem_Write (& hi2c2, 0xD0, GYRO_CONFIG, I2C_MEMADD_SIZE_8BIT, &


SETTINGS_GYRO, 1.1000); gyro config
HAL_I2C_Mem_Write (& hi2c2, 0xD0, ACC_CONFIG, I2C_MEMADD_SIZE_8BIT, &
SETTINGS_ACC, 1.1000); // acc config

The data reading itself triggers an interrupt from the timer with the frequency of 1kHz (allowing
the accelerometer enough)

HAL_I2C_Mem_Read (& hi2c2, ADDR_MPU, ACCEL_XOUT_H,


I2C_MEMADD_SIZE_8BIT, & buf_mpu [0], 14,1000);

where:

ACC_CONFIG = 28

GYRO_CONFIG = 27

SETTINGS_ACC = 0x00

SETTINGS_GYRO = 0x00

ACCEL_XOUT_H = 0x3B

I download the data from the accelerometer, thermometer and gyroscope.

Well, just at such a frequency, the microcontroller often hangs and nothing happens right after
the start (it reads data using stmStudio), usually it will catch after a few resets.

By reducing the frequency of interruption, the problem occurs less often, until at a certain level it
completely disappears. The problem also disappears when commenting on the lines to read the
value.

What could be the reason for this?


[Edit] I have misidentified the problem, regardless of the frequency of data interruption and
reading, uC hangs on the first call to the HAL_I2C_Mem_Read function. Suspension occurs
randomly, sometimes a dozen times is ok and sometimes the same has to be reset.

Veeeeeeefugehwfk

Radio Frequency Weather Systems


Today’s modern airborne weather radar systems are lightweight, multicolor, digital systems designed
to provide flight crew with weather location and analysis. The intent is to detect and avoid storms
along the flight path of the aircraft. Most modern airborne weather radar systems are X-band
systems that radiate anywhere between 18 watts and 10 kW of power.

Microsemi’s broad portfolio of RF and microwave technology is perfectly positioned to solve complex
engineering problems at the discrete, RFIC, MMIC, module and subsystem levels for these
application areas. It is also complemented by a wide variety of FPGA, analog mixed signal, and
discrete power technologies for an overall solution.
Hjg4tuiy45jiuj35i33tiu32

S-ar putea să vă placă și