Vous êtes sur la page 1sur 91

AMLAKU FEB 2/27/2019 1

AMLAKU FEB 2/27/2019 2


ABSTRACT:
The performance of an autopilot controller has been an issue for industries, aircraft system over
these days as they make use of less effective microcontroller. This limitation can be overcome by
using SSM/GGM based implementation logic and by replacing less effective microcontroller with
STM32 microcontroller. The prime Objective of this paper is the development of SSM based
autopilot controller using STM32.This autopilot controller comprises of Global Positioning
System (GPS), Sensor Suite, external flash for data logging, Servo motor to control aileron, rudder
and elevator action IRF based transceiver in order to communicate between SSM and Ground
Control station (GCS).This system focuses not only on device monitoring but also controlling it.
The GCS comprises of Mission Planer software which is used to monitor the data received from
SSM/GGM and can also control the flight mode from it. The Radio Frequency (RF) joystick is
used for SSM‟s flight control.

CHAPTER ONE
1. INTRODUCTION
SSM is a missile designed to be launched from the ground or the sea and strike targets on land.
They usually have fins and/or wings for lift and stability, although hyper-velocity or short-range
missiles may use body lift or fly a ballistic trajectory. The V-1 flying bomb was the first
operational surface-to-surface missile.
Contemporary surface-to-surface missiles are usually guided. An unguided surface-to-surface
missile is usually referred to as a rocket (for example, an RPG-7 or M72 LAW is an anti-tank
rocket whereas a BGM-71 TOW or AT-2 Swatter is an anti-tank guided missile).
Since the concept of SSM was proposed a few decades ago, SSM have attracted a lot of interest
from researchers all over the world. Many kinds of SSM prototypes have been developed by
universities and research laboratories. The primarily goal is to make the SSM have as more
functions as possible and suitable for different missions. SSM can significantly reduce the risk to
one’s country life and minimize the economic damage in the scientific, military and civil
application. The vertical take- off and landing (VTOL) SSM are particularly useful in missions
such as surveillance and reconnaissance, precision target location, signals intelligence, digital
mapping, forest fire monitoring, and indoor rescuing. Autopilots are systems to guide the UAVs
in flight without Assistance from human operators. Nowadays, Technological advances in wireless

AMLAKU FEB 2/27/2019 3


networks and micro electromechanical systems (MEMS) make it possible to use Small autopilots
on SSM. The autopilot board has onboard processors and sensors. These sensors are usually
MEMS (Micro Electro-Mechanical Systems), because such size and weight is always a limiting
factor in SSM. These sensors collect the flight data like acceleration, velocity, altitude, pressure,
magnet and temperature. These parameters are fed to the onboard computer. The onboard
computer also has a data link to a ground station called Ground Control Station (GCS) from where
the user sends commands to the SSM. Based on these commands and the data collected the SSM
flies and complete its mission. It also finds use in space missions. SSM‟s usually carry a camera,
a night vision device, a GPS and if possible an autopilot.
1.1. SYSTEM DESIGN
1.2 Autopilot Controller
The arm core present in the STM32F4 microcontroller provides the platform for complete
Autopilot controller. Fig1 depicts the working of Autopilot controller. The Autopilot controller is
used to control the trajectory of the SSM without requiring constant control by a human operator.
Autopilot cannot replace human operator but help them in controlling the SSM and allowing them
to focus on other operations such as monitoring the weather, trajectory and so on. The gains for
autopilot were based on the flight parameters. Unfortunately mathematical model describing the
flight dynamics of the SSM does not exit, so a trial and error approach has been adopted. The block
diagram of autopilot controller is shown in Fig.1. The system is designed such that if there is any
deflection in the wings then the sensors detects and sends the signal to the autopilot controller.
Then the auto pilot computer detects the signal and determines that the wings are not level. The
autopilot controller generates PWM signal based on the sensor output and sends it to the servo
motors that controls the aircrafts ailerons, elevators and rudder. This PWM signals will guide the
servos in which direction and with which angle it has to rotate. The wings will move back to the
level position if the ailerons, elevators and rudder are adjusted based the input PWM data. The
autopilot controller removes the command to the servos when the position sensors detects that the
wings are once again level.

AMLAKU FEB 2/27/2019 4


AMLAKU FEB 2/27/2019 5
1.3 STM32F407vgtx Microprocessor
The STM32 F4-series is the first group of STM32 microcontrollers based on the ARM Cortex-
M4 core. It has Digital Signal Processing (DSP) and floating point Unit (FPU). ARM Cortex-M4
core runs at a maximum clock rate of 84 / 168 / 180 MHz Most often controller work well with
168 MHZ. It supports standard embedded memories (SRAM is up to 196 KB out of which
128KB on bus matrix and 64KB on data bus dedicated for CPU usage. and 4KB for battery
backup for RTC) Up to 1MB Flash.
The microprocessor chip STM32f407 based on high performance ARM 32-bit Cortex™-M4
RISC is selected as the core chip of the hardware system. The external 8 MHz crystal oscillator
is used, and the operating frequency is up to 168 MHz which is sufficient for the high-precision
real time data processing. It has 1M bytes of flash memory and 192k bytes of SRAM. The chip
has multiple general-purpose timers and communication interfaces including three I2Cs, three
SPIs and four USARTs. This is convenient to communicate with the peripheral circuits.

AMLAKU FEB 2/27/2019 6


The microprocessor real-timely collects and processes large amounts of data from the GPS
receiver, accelerometer, gyroscope, digital compass and barometer to determine the system.
It also features standard and advanced high performance communication interfaces,
 An USB OTG-HS (High Speed) and USB OTG – FS (Full Speed) with full speed
compatibility.
 Two UARTs and four USARTs.
 Three I2C (Inter Integrated Circuits).
 Three full duplex SPI (Serial Peripheral Interface)
 Three ADCS.

1.4. Digital Barometer Pressure Sensor (BMP180) using


STM32F407VGTX microcontroller
1.4.1 Principles of Digital Barometer Pressure Sensor
The definition of pressure is a force “pressing” on an area. A common unit of pressure is pounds
per square inch (psi). One pound, pressing on one square inch, equals one psi. The SI unit is newton
per square meter, which are called Pascal’s (Pa).
There are lots of situations in which pressure can be measured (gravity, pull, etc.), but right now
we’re interested in atmospheric pressure, which is the force that the air around you is exerting
on everything. The weight of the gasses in the atmosphere creates atmospheric pressure. One
doesn’t normally notice that air weighs anything, but if you took a one inch wide column of air
from sea level to the top of the atmosphere, it would weigh about 14.7 pounds. (A 1 cm wide
column of air would weigh about 1 kg.) This weight, pressing down on the footprint of that column,
creates the atmospheric pressure that we can measure with sensors like the BMP180.
1.4.2 Temperature Effects
Because temperature affects the density of a gas, and density affects the mass of a gas, and mass
affects the pressure (whew), atmospheric pressure will change dramatically with temperature.
Pilots know this as “density altitude”, which makes it easier to take off on a cold day than a hot
one because the air is denser and has a greater aerodynamic effect. To compensate for temperature,
the BMP180 includes a rather good temperature sensor as well as a pressure sensor. To perform a

AMLAKU FEB 2/27/2019 7


pressure reading, you first take a temperature reading, then combine that with a raw pressure
reading to come up with a final temperature-compensated pressure measurement.
This sensor is used to measure the pressure which will be used to measure the altitude. The
Temperature measurement can also be performed using this sensor. The sensor is designed to be
connected directly to a microcontroller of a mobile/computer device via the I2C bus. The
pressure and temperature data has to be compensated by the calibration data of the E2PROM of
the sensor. The pressure sensor consists of a piezo resistive Sensor, an analog to digital converter
(ADC) and a control unit with E2PROM and a serial I2C interface And USART.
It delivers the uncompensated value of pressure and temperature. The E2PROM has stored 176
bit of individual calibration data. The 176 bit E2PROM is partitioned in 11 words of 16 bit each.
These contain 11 calibration coefficients. Every sensor module has individual coefficients.
Before the first calculation of temperature and pressure, the master reads out the E2PROM data.
The BMP sensor will gives the Uncompensated Pressure (UP) and Uncompensated Temperature
(UT). Pressure data is a 16 to 19 bit and Temperature data is a 16 bit. The temperature data word
UT, the pressure data word UP and the calibration data read out from the sensor are used to
calculate the true pressure in steps of 1Pa (= 0.01hPa = 0.01mbar) and temperature in steps of
0.1°C.
1.4.3 Framework Map of Full BMP180 System using stm32f4 Microcontroller

BMP180 (Barometer pressure STM32F407VGTX


sensor (Microcontroller)

USART (SERIAL COMMUNICATION)

Figure: Framework Map of System Design

AMLAKU FEB 2/27/2019 8


BMP180 is a digital pressure sensor, with built in temperature sensor. Its range is between 300 and
1100 hPa (0.3 to 1.1Bar). In relating to the sea level, this is +9000 to -500 meters. Sensor works
with I2C communication at 100 kHz.
Sensor is quite bad created, because if you want to read pressure, you first need to read current
temperature for pressure calculation. To read temperature you have to wait at least 4.5ms. After
that, you first have to read temperature and then you can start with pressure measurement. Time
for pressure measurement depends on mode you select. After pressure is measured, you can read
uncompensated data from device. This is because device has one register for control temperature
and pressure, and also one register for data. So both, temperature and pressure cannot be measured
at same time. This takes about at least 10ms for every stuff to be done. At the end a lot of
calculations are needed to get valid pressure from device. Because very long time for STM32F4,
I split things into several functions, to start temp, read temp, start pressure, read pressure, etc.
I have also added possibility, that you calculate pressure right above the sea from known pressure
at known altitude.
 Sequence for reading useful data is:
 Start temperature measurement
 Wait 4.5ms at least
 Read temperature
 Start pressure measurement
 Delay depends on measurement mode you select
 Read pressure
 Use pressure data
1.4.4 Features of BMP180 SENSOR
 Read BMP180 temperature sensor
 Read BMP180 pressure sensor
 Calculate sea level pressure at from given know pressure and altitude
 If you are at ex 1000meters and there is pressure 98000Pascals, then you can calculate
pressure at sea level from this values.

AMLAKU FEB 2/27/2019 9


 Typical application circuits

AMLAKU FEB 2/27/2019 10


AMLAKU FEB 2/27/2019 11
AMLAKU FEB 2/27/2019 12
AMLAKU FEB 2/27/2019 13
1.4.5 Measurement of pressure and temperature
The microcontroller sends a start sequence to start a pressure or temperature measurement. After
converting time, the result value (UP or UT, respectively) can be read via the I2C interface. For
calculating temperature in °C and pressure in hPa, the calibration data has to be used. These
constants can be read out from the BMP180 E2PROM via the I2C interface at software
initialization. The sampling rate can be increased up to 128 samples per second (standard mode)
for dynamic measurement. In this case, it is sufficient to measure the temperature only once per
second and to use this value for all pressure measurements during the same period.

AMLAKU FEB 2/27/2019 14


1.4.6 The Flow Chart of the Bmp180

AMLAKU FEB 2/27/2019 15


1.4.6 Hardware pressure sampling accuracy modes
The mode (ultra low power, standard, high, ultra-high resolution) can be selected by the
variable oversampling setting (0, 1, 2, and 3) in the C code.
By using different modes the optimum compromise between power consumption, speed and
resolution can be selected, see below table.

Mode Parameter Internal Conversion Avg. RMS RMS


(Oversampling number of time current noise noise
setting) samples pressure @1 typ. typ. [m]
max. [ms] sample/s [hPa]
typ. [μA]

ultra low 0 1 4.5 3 0.06 0.5


power

standard 1 2 7.5 5 0.05 0.4

high 2 4 13.5 7 0.04 0.4


resolution

ultra high 3 8 25.5 12 0.03 0.25


resolution

1.4.7 Calibration coefficients


First what is an E2PROM?
EEPROM stands for electrically erasable programmable read-only memory. It is a non-volatile
flash memory device, that is, stored information is retained when the power is removed. EEPROM
generally offers excellent capabilities and performance. In EEPROM we can write and program
the IC for many times and these are acting as EPROM (UV erasable programming ROM).
However an EEPROM need not be taken out of the computer or electronic device of which it is
part when a new program or information or data needs to be written on it. Particular customizing
might be finished to an EEPROM chip. The 176 bit E2PROM is partitioned in 11 words of 16 bit
each. These contain 11 calibration coefficients. Every sensor module has individual coefficients.
Before the first calculation of temperature and pressure, the master reads out the E2PROM data.

AMLAKU FEB 2/27/2019 16


The data communication can be checked by checking that none of the words has the value 0 or
0xFFFF.

Figure shows calibration coefficients

AMLAKU FEB 2/27/2019 17


1.4.8 Calculation of pressure and temperature
The following figure shows the detailed algorithm for pressure and temperature measurement.

AMLAKU FEB 2/27/2019 18


This algorithm is available to customers as reference C source code (“BMP180_ API”) from Bosch
Sensor Tec.

Figure: Full Algorithm for pressure and temperature measurement

1.4.9 Calculating absolute altitude

AMLAKU FEB 2/27/2019 19


With the measured pressure p and the pressure at sea level P0 e.g. 1013.25hPa, the altitude in
meters can be calculated with the international barometric formula:
𝒑 𝟏
(𝟏 − 𝒑𝟎)
𝑨𝒍𝒕𝒊𝒕𝒖𝒅𝒆 = 𝟒𝟒𝟑𝟑𝟎 ∗ 𝟓. 𝟐𝟓𝟓
𝟓
1.5. Kiel C version codes for BMP180
#include "main. h"

#include "stm32f4xx_hal.h"
#include <math>
// BMP180 I2C address */
#ifndef BMP180_I2C_ADDRESS
#define BMP180_I2C_ADDRESS 0xEE
#end if
#define BMP180_ADDRESS 0x77<<1 // I2C address of BMP180, eight bit address on Kiel
#define AC1R 0xAA // R Calibration data (16 bits)
#define AC2R 0xAC // R Calibration data (16 bits)
#define AC3R 0xAE // R Calibration data (16 bits)
#define AC4R 0xB0 // R Calibration data (16 bits)
#define AC5R 0xB2 // R Calibration data (16 bits)
#define AC6R 0xB4 // R Calibration data (16 bits)
#define B1R 0xB6 // R Calibration data (16 bits)
#define B2R 0xB8 // R Calibration data (16 bits)
#define MBR 0xBA // R Calibration data (16 bits)
#define MCR 0xBC // R Calibration data (16 bits)
#define MDR 0xBE // R Calibration data (16 bits)*/
/* Multiple is faster than divide */
#define BMP180_1_16 ((float) 0.0625)
#define BMP180_1_256 ((float) 0.00390625)
#define BMP180_1_2048 ((float) 0.00048828125)
#define BMP180_1_4096 ((float) 0.000244140625)
#define BMP180_1_8192 ((float) 0.0001220703125)

AMLAKU FEB 2/27/2019 20


#define BMP180_1_32768 ((float) 0.000030517578125)
#define BMP180_1_65536 ((float) 0.0000152587890625)
#define BMP180_1_101325 ((float) 0.00000986923266726)
//
#define CONTROL 0x74 // W Control register
#define CONTROL_OUTPUT 0xF6 // R Output registers 0xF6=MSB,
0xF7=LSB, 0xF8=XLSB
#define READ_TEMPERATURE 0x2E

#define READ_PRESSURE 0x34


#define oss 1 //standard mode
* Default I2C pin */
#ifndef BMP180_I2C
#define BMP180_I2C I2C1
#define BMP180_I2C_PINSPACK TM_I2C_PinsPack_1
#end if
// Registers */

#define BMP180_REGISTER_CONTROL 0xF4

#define BMP180_REGISTER_RESULT 0xF6

#define BMP180_REGISTER_EEPROM 0Xaa

// Commands

#define BMP180_COMMAND_TEMPERATURE 0x2E

#define BMP180_COMMAND_PRESSURE_0 0x34

#define BMP180_COMMAND_PRESSURE_1 0x74

#define BMP180_COMMAND_PRESSURE_2 0xB4

#define BMP180_COMMAND_PRESSURE_3 0xF4

AMLAKU FEB 2/27/2019 21


// Minimum waiting delay, in microseconds */
#define BMP180_TEMPERATURE_DELAY 4500
#define BMP180_PRESSURE_0_DELAY 4500
#define BMP180_PRESSURE_1_DELAY 7500
#define BMP180_PRESSURE_2_DELAY 13000
#define BMP180_PRESSURE_3_DELAY 25000

I2C_HandleTypeDef hi2c1;

Int AC1, AC2, AC3, B1, B2, MB, MC, MD;

Unsigned int AC4, AC5, AC6;

Long int rawT, raw, B5;

Float Temperature, Pressure;

Float Altitude;

Unsigned char buffer [22];

Void SystemClock_Config (void);

Static void MX_GPIO_Init (void);

Static void MX_I2C1_Init (void);

Int main (void)

HAL_Init ();

SystemClock_Config ();

MX_GPIO_Init ();

AMLAKU FEB 2/27/2019 22


MX_I2C1_Init ();

While (1)

long int X1, X2, X3, B3, B6, P, Temp;

Unsigned long int B4, B7;

Buffer [0] = AC1R;

HAL_I2C_Master_Transmit (&hi2c1, 0xEE, buffer, 1,100);

HAL_Delay (20);

HAL_I2C_Master_Receive (&hi2c1, 0xEE, &buffer [0], 22, 100);

HAL_Delay (20);

AC1 = buffer [0] <<8 |buffer [1];

AC2 = buffer [2] <<8 |buffer [3];

AC3 = buffer [4] <<8 |buffer [5];

AC4 = buffer [6] <<8 |buffer [7];

AC5 = buffer [8] <<8 |buffer [9];

AC6 = buffer [10] <<8|buffer [11];

B1 = buffer [12] <<8|buffer [13];

B2 = buffer [14] <<8|buffer [15];

MB = buffer [16] <<8|buffer [17];

MC = buffer [18] <<8|buffer [19];

MD = buffer [20] <<8|buffer [21];

AMLAKU FEB 2/27/2019 23


HAL_Delay (1000);

//Write 0x2E to Register 0x74

Buffer [0] = 0xF4;

Buffer [1]= 0x2E;

HAL_I2C_Master_Transmit (&hi2c1, 0xEE, buffer, 2, 8);

HAL_Delay (8);

//Read data from 0x76 register address

Buffer [0] = 0xF6;

HAL_I2C_Master_Transmit (&hi2c1, 0xEE, buffer, 1,8);

HAL_I2C_Master_Receive (&hi2c1, 0xEE, &buffer [0], 2,100);

//MSB = 0xF6 LSB: 0xF7

RawT = buffer [0] <<8|buffer [1];

Buffer [0] = 0xF4;

Buffer [1] = 0x74;

HAL_I2C_Master_Transmit (&hi2c1, 0xEE, buffer, 2, 8);

HAL_Delay (8);

//Read data from 0x76 register address

Buffer [0] = 0xF6;

HAL_I2C_Master_Transmit (&hi2c1, 0xEE, buffer, 1, 8);

HAL_I2C_Master_Receive (&hi2c1, 0xEE, &buffer [0], 3,100);

RawP = (buffer [0] <<16|buffer [1] <<8|buffer [2])>> (8-oss);

AMLAKU FEB 2/27/2019 24


//Calculate Temperature
X1= (rawT - AC6)*AC5/(32768);
X2= MC*2048/(X1+MD);
B5= X1 + X2;
Temperature= (B5+8)/ (float) 256;
Temp = Temp/10.0f; // Temperature in Celsius and Divide by 10 because result is normally
in 0.1C
//Calculate Pressure

B6 = B5 - 4000;

X1 = (B2 * (B6 * B6 * BMP180_1_4096)) * BMP180_1_2048;


X2 = AC2 * B6 * BMP180_1_2048;
X3 = X1 + X2;
B3 = (((AC1 * 4 + X3) << (uint8_t) oss) + 2) * 0.25;
X1 = AC3 * B6 * BMP180_1_8192;
X2 = (B1 * (B6 * B6 * BMP180_1_4096)) * BMP180_1_65536;
X3 = ((X1 + X2) + 2) * 0.25;
B4 = AC4 * (uint32_t) (X3 + 32768) * BMP180_1_32768;
B7 = ((uint32_t) rawP - B3) * (50000 >> (uint8_t) oss);
If (B7 < 0x80000000) {
P = (B7 * 2) / B4;
} else {
P = (B7 / B4) * 2;
}
X1 = ((float) P * BMP180_1_256) * ((float) P * BMP180_1_256);
X1 = (X1 * 3038) * BMP180_1_65536;
X2 = (-7357 * P) * BMP180_1_65536;
Pressure = P + (X1 + X2 + 3791) * BMP180_1_16;

AMLAKU FEB 2/27/2019 25


P = (P + (X1 + X2 + 3791) * BMP180_1_16) / 100.0f; // Return pressure in mbar/ hPa and
convert to hPa
If (Pressure<=0)
{
Printf ("Low Pressure");
}
// calculate altitude
Altitude = (float) 44330.0 * (float)((float)1.0 - (float)pow((float)P * BMP180_1_101325,
0.19029495));
}}
Void SystemClock_Config (void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__HAL_RCC_PWR_CLK_ENABLE ();
__HAL_PWR_VOLTAGESCALING_CONFIG
(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
If (HAL_RCC_OscConfig (&RCC_OscInitStruct)! = HAL_OK)
{
_Error Handler (__FILE__, __LINE__);
}

AMLAKU FEB 2/27/2019 26


RCC_ClkInitStruct.ClockType =
RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
If (HAL_RCC_ClockConfig (&RCC_ClkInitStruct, FLASH_LATENCY_5)! = HAL_OK)
{
_Error_Handler (__FILE__, __LINE__);}
HAL_SYSTICK_Config (HAL_RCC_GetHCLKFreq ()/1000);
HAL_SYSTICK_CLKSourceConfig (SYSTICK_CLKSOURCE_HCLK);
HAL_NVIC_SetPriority (SysTick_IRQn, 0, 0);
}
Static void MX_I2C1_Init (void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
If (HAL_I2C_Init (&hi2c1)! = HAL_OK)
{
_Error_Handler (__FILE__, __LINE__);
}
}
Static void MX_GPIO_Init (void)
{
__HAL_RCC_GPIOA_CLK_ENABLE ();
__HAL_RCC_GPIOB_CLK_ENABLE ();
}
Void _Error_Handler (char *file, int line)
{
While (1)
{
}}
#ifdef USE_FULL_ASSERT
Void assert_failed (uint8_t* file, uint32_t line)
{ } #end if // USE_FULL_ASSERT

AMLAKU FEB 2/27/2019 27


1.5.1 ADC (Analog to Digital Converter) with STM32F4
In many embedded projects, we have to deal with signals directly from nature, like temperature,
pressure, current, etc. These signals are analog by default and in most of cases we use sensors that
converts these analog signals to analog electrical voltage to be injected in the microcontroller to
do some work. Unfortunately, microcontrollers are digital and just can't deal with analog signals
so these signals must be converted again to digital signals that is comprehensible by the
microcontroller. For this purpose, microcontroller's manufacturers usually incorporate an ADC
into the microcontroller. ADC is actually stands for Analog to Digital Converter. This module is
omnipresent in most of microcontrollers.
I'm going to use the STM32F4 discovery board to interface an analog input provided by a
potentiometer and visualize the received data with the watch feature while debugging the program.

Analog to Digital Converter


In this section the ADC is discussed for analog data interfacing.
A microcontroller, a digital device, can read, execute and transmit only digital signals. On the
contrary, the outputs of the most of the transducers are analog in nature. Thus it is hard to interface
these transducers directly with controllers. Analog-to-digital convertor (ADC) ICs are one way to
make the analog input compatible with the microcontroller.
Using an external ADC adds complexity to the circuit. To avoid this complexity, PIC
Microcontrollers have in-built ADC module which reduces the cost and connections of the circuit

AMLAKU FEB 2/27/2019 28


Since the Microcontroller has a built in analog pin to convert the analog output to digital which
have an 10 bit resolution which is 1024 (ranges from 0 to 1023) and the system input voltage is
5V. Then the ADC reading is evaluated according to the following equations.

An analog to digital converter (ADC) converts an analog signal into digital form, shown in Figure
below. An embedded system uses the ADC to collect information about the external world (data
acquisition system.) The input signal is usually an analog voltage, and the output is a binary
number. The ADC precision is the number of distinguishable ADC inputs (e.g., 4096 alternatives,
12 bits). The ADC range is the maximum and minimum ADC input (e.g., 0 to +3.3V). The
ADC resolution is the smallest distinguishable change in input (e.g., 3.3V/4096, which is about
0.81 mV). The resolution is the change in input that causes the digital output to change by 1.

Range(volts) = Precision(alternatives) • Resolution(volts)

AMLAKU FEB 2/27/2019 29


The measurand is a real world signal of interest like sound, distance, temperature, force, mass,
pressure, flow, light and acceleration. Figure 14.5 shows the data flow graph for a data acquisition
system or control system. The control system uses an actuator to drive a measurand in the real
world to a desired value while the data acquisition system has no actuator because it simply
measures the measurand in a nonintrusive manner.

Interfacing materials\

AMLAKU FEB 2/27/2019 30


ADC conversion using stm32f4xx cub mix microcontroller

#include"stm32f4xx_hal.h"

Void GPIO_Config (void);

Void ADC_Config (void);

Void Systick_Config (void);

ADC_HandleTypeDef myADCtypeDef;

Uint32_t myAdcvalue;

Int main (void)

HAL_Init ();

GPIO_Config ();

ADC_Config ();

Systick_Config ();

While (1)

{
// Read ADC value
HAL_ADC_Start (&myADCtypeDef);
If (HAL_ADC_PollForConversion (&myADCtypeDef, 5) ==HAL_OK)
{
MyAdcvalue = HAL_ADC_GetValue (&myADCtypeDef);
}
HAL_ADC_Stop (&myADCtypeDef);
//2.100ms delay
HAL_Delay (100);
} }

AMLAKU FEB 2/27/2019 31


Void GPIO_Config (void)

__HAL_RCC_GPIOD_CLK_ENABLE ();
GPIO_InitTypeDef myADCPin;
MyADCPin. Pin = GPIO_PIN_0;
MyADCPin. Mode = GPIO_MODE_ANALOG;
MyADCPin. Pull = GPIO_NOPULL;
HAL_GPIO_Init (GPIOA, &myADCPin);
}
Void ADC_Config (void)
{
__HAL_RCC_ADC1_CLK_ENABLE ();
MyADCtypeDef. Instance = ADC1;
myADCtypeDef.Init.Resolution = ADC_RESOLUTION8b;
myADCtypeDef.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
myADCtypeDef.Init.DataAlign = ADC_DATAALIGN_RIGHT;
HAL_ADC_Init (&myADCtypeDef);
ADC_ChannelConfTypeDef myADCchannelTypeDef;
myADCchannelTypeDef.Channel = ADC_CHANNEL_0;
MyADCchannelTypeDef. Rank = 1;
myADCchannelTypeDef.SamplingTime = ADC_SAMPLETIME_15CYCLES
HAL_ADC_ConfigChannel (&myADCtypeDef, &myADCchannelTypeDef);
}
Void Systick_Config (void) {
// set clock source and speed
HAL_SYSTICK_Config (HAL_RCC_GetHCLKFreq ()/1000);
// Configure the Systick
HAL_SYSTICK_CLKSourceConfig (SYSTICK_CLKSOURCE_HCLK);
// SysTick_IRQn interrupt priority configuration
HAL_NVIC_SetPriority (SysTick_IRQn, 0, 0);
HAL_NVIC_EnableIRQ (SysTick_IRQn);
}
Void SysTick_Handler (void)
{

AMLAKU FEB 2/27/2019 32


HAL_IncTick () ;}

ADC Result with Stm32f4xx

1.5.2 PWM (Pulse Width Modulation)


PWM, (Pulse Width Modulation), is a modulation technique used to control the analog circuits
via MCU digital outputs. It is widely applied, ranging from measurement and communication to
power control and conversion.

AMLAKU FEB 2/27/2019 33


The figure above shows a PWM signal. Figure b) shows the MCU digital signal. And figure a)
shows the corresponding analog signal when the digital output is connected to the power device,
like motor. For example, a pulse with PWM output at a 50% duty cycle, frequency at 10Hz and
high level of 3.3V, may have a 1.65V output analog signal result. PWM have two significant
parameters, one is output frequency, and the other is duty cycle. Duty cycle is used to change the
voltage of the output analog signal. A higher frequency will has a better analog result. And the
larger duty cycle will has the higher analog voltage.
Pulse width modulation mode allows you to generate a signal with a frequency determined by
the value of the TIMx_ARR register and a duty cycle determined by the value of the
TIMx_CCRx register. In PWM mode (1 or 2), TIMx_CNT and TIMx_CCRx are always
compared to determine whether TIMx_CCRx&TIMx_CNT or TIMx_CNT&TIMx_CCRx
(depending on the direction of the counter). The figure below shows the PWM edge-aligned
mode (up-counting configuration). CCRx is Capture/compare register, OCxREF is output
compare signal, and CCxIF is interrupt flag. ForCCRX=4, when the value in TIMx_CCRx is
lower than the counter, the output is in high level, or else in low level.
 In general PWM is a simple method of using a rectangular digital waveform to control an
analog variable.
 The duty cycle/D is the proportion of time i.e. pulse is ‘on’/high, &is expressed as a
percentage:
 Duty cycle = 100% * (pulse on time) / (pulse period)

AMLAKU FEB 2/27/2019 34


 If the on time is small, the average value is low; if the on time is large, the average value
is high
 By controlling the duty cycle, we control this average value
1.5.2.1 Use of PWM to run DC motor
 By adjusting the duty cycle /% of the signal(modulating the width of the pulses) i.e.
 The time fraction for w/c it is on, the average power can be varied & hence the motor
speed.
 In other words by varying the duty cycle we are getting d/t values of average voltage
(Vavg) across the motor resulting in d/t speeds.

 Low duty cycle corresponds to low power, because the power is off for most of the time.
 Duty cycle is expressed in percent, 100% being fully on.
 When a digital signal is on half of the time and off the other half of the time, the digital
signal has a duty cycle of 50% and resembles a "square" wave.
 When a digital signal spends more time in the on state than the off state, it has a duty
cycle of >50%.

AMLAKU FEB 2/27/2019 35


 When a digital signal spends more time in the off state than the on state, it has a duty
cycle of <50%.
 Here is a pictorial that illustrates these three scenarios below.

 PWM is the scheme in which the duty cycle of a square wave output from the
microcontroller is varied to provide a varying average DC output.
 By applying a PWM pulse is that the motor is switched ON and OFF at a given
frequency. In this way, the motor reacts to the time average of the power supply.

1.5.2.2 Uses of PWM Controlling servo motor position


 A servo is a small rotary position control device, used for example aero planes to position
controllers such as steering, elevators and rudders.
 The servo shaft positioned to specific angular positions by sending the servo a PWM signal.
 As long as the modulated signal exists on the input line, the servo will maintain the angular
position of the shaft.
 As the modulated signal changes, the angular position of the shaft changes.

AMLAKU FEB 2/27/2019 36


 The pulse width determines the position of the servomotor.
 Example:
 a pulse width of 1.25ms an angular position if 0 degrees,
 pulse width of 1.5ms an angular position if 90 degrees,
PWM timing requirements to control the servo between 0 & 180 degrees
1 Principle of Operation of Servo Motors
 It consists of dc motor, gear assembly and feedback control circuitry. PWM signal is used
to control the servo motor. It is applied on control signal pin.
 Servo feedback control circuitry contains comparator which compares the control signal
(PWM) and potentiometer reference signal to generate error signal which is later amplified
and given to the DC motor.
 DC motor shaft is connected to potentiometer shaft (knob) through gear assembly. So
rotating DC motor rotates potentiometer, which in term changes potentiometer reference
signal given to the comparator.
 At some position of shaft, both potentiometer signal and control signal strength match,
which produces zero error signal output. Hence rotation continues till comparator output
error signal becomes zero and DC motor stops

1.5.2.3 Servo Working Principles for the Given System

Servo motor position is controlled by pulse width modulation (PWM) signal. The width of the
control signal pulse is used to vary shaft position of servo motor. We can vary SG90 Micro servo
motor angular rotation in between 0° to 180° angle with PWM signal as shown in figure below.

AMLAKU FEB 2/27/2019 37


Above figure shows angular rotation of servo shaft. It uses PWM of 50Hz frequency with TON
variation from 1ms to 2ms. The servo motor rotates 90° in either direction from its middle position
i.e. it gives control over 180° of its rotation.

 At ~1ms (5% duty cycle) we get shaft position at -90° of its rotation.
 At 1.5ms (7.5% duty cycle) we get shaft position at 0° (neutral) of its rotation.
 At ~2ms (10% duty cycle) we get shaft position at +90° of its rotation.

1.5.2.4 Controlling servo position with PWM


 Connect the servo to the stm32f4 microcontroller as indicated.
 Set the PWM period to 20ms and try a number of d/t duty periods and observe the servo’s
motion.

 PWM to Drive Servo Motor

AMLAKU FEB 2/27/2019 38


 PWM produced by comparing TIMx_CNTto both TIMx_CCRyandTIMx_ARR
 Set TIMx_ARR= Period
 Set TIMx_CCRy= Duty
 TIMx_CCMRn(capture/compare mode)
 Set bit CCxE= 1 to configure the channel as output
 Set bits OCxM= 110 (PWM mode 1) –active if CNT < CCRy, inactive otherwise
OCxM= 111 (PWM Mode 2) -inactive if CNT < CCRy, active otherwise
 TIMx_CCER:
 Set bit CCxP= 0/1 to select active level high/low (output polarity) of OCx
 Set bit CCxE= 1 to enable Ox to drive the output pin
 Configure GPIO MODER and AF registers to select alt. function TIMx_CHn for the pin
FIGURE: shows edge aligned PWM wave form (ARR)

AMLAKU FEB 2/27/2019 39


1.5.2.4Using of Servo with Stm32f4discover
RC Servo receive digital signal to change the axis’s angle in the form of Pulse Width Modulation
(PWM). Position controlling module of RC Servo will check time of signal at state “ON” or pulse
width then adjust the position as programmed by its manufacturer. Figure 3-2 shows the estimated
width of ON signal for controlling the SG90 RC Servo with signal period 20ms. If user use other
model of RC Servo they should study its detail in datasheet especially its voltage and pulse width.

AMLAKU FEB 2/27/2019 40


2 PWM timer coding
#include "main.h"

#include "stm32f4xx_hal.h"

// Private variables

TIM_HandleTypeDef htim1;

/ /Private function prototypes

Void System Clock_Config (void);

Static void MX_GPIO_Init (void);

Static void MX_TIM1_Init (void);

Void HAL_TIM_MspPostInit (TIM_HandleTypeDef *htim);

AMLAKU FEB 2/27/2019 41


Int main (void)

Uint16_t duty cycle =10;

HAL_Init ();

// configure the system clock

SystemClock_Config ();

// Initialize all configured peripherals


MX_GPIO_Init ();
MX_TIM1_Init ();
HAL_TIM_PWM_Start (&htim1, TIM_CHANNEL_1);

// Infinite loop

While (1)

htim1.Instance->CCR1 = duty cycle;

Duty cycle+=10;
If (duty cycle>90) duty cycle =10;
HAL_Delay (1000);

}
}
Void SystemClock_Config (void)
{

AMLAKU FEB 2/27/2019 42


RCC_OscInitTypeDef RCC_OscInitStruct;

RCC_ClkInitTypeDef RCC_ClkInitStruct;

//Configure the main internal regulator output voltage

__HAL_RCC_PWR_CLK_ENABLE ();

__HAL_PWR_VOLTAGESCALING_CONFIG
(PWR_REGULATOR_VOLTAGE_SCALE1);

//Initializes the CPU, AHB and APB busses clocks

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.HSICalibrationValue = 16;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

_Error_Handler (__FILE__, __LINE__);

//Initializes the CPU, AHB and APB busses clocks

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

AMLAKU FEB 2/27/2019 43


if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
_Error_Handler (__FILE__, __LINE__);
}
//Configure the Systick interrupt time
HAL_SYSTICK_Config (HAL_RCC_GetHCLKFreq ()/1000);
//Configure the Systick
HAL_SYSTICK_CLKSourceConfig (SYSTICK_CLKSOURCE_HCLK);
// SysTick_IRQn interrupt configuration
HAL_NVIC_SetPriority (SysTick_IRQn, 0, 0);
}
// TIM1 init function
Static void MX_TIM1_Init (void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_OC_InitTypeDef sConfigOC;
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
htim1.Instance = TIM1;
htim1.Init.Prescaler = 16;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 100;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
If (HAL_TIM_Base_Init (&htim1)! = HAL_OK)
{
_Error_Handler (__FILE__, __LINE__);

AMLAKU FEB 2/27/2019 44


}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
If (HAL_TIM_ConfigClockSource (&htim1, &sClockSourceConfig) != HAL_OK)
{
_Error_Handler (__FILE__, __LINE__);
}
If (HAL_TIM_PWM_Init (&htim1)! = HAL_OK)
{
_Error_Handler (__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
If (HAL_TIMEx_MasterConfigSynchronization (&htim1, &sMasterConfig)! = HAL_OK) {
_Error_Handler (__FILE__, __LINE__); }

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 50;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) !=


HAL_OK)

AMLAKU FEB 2/27/2019 45


{

_Error_Handler(__FILE__, __LINE__);

sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;

sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;

sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;

sBreakDeadTimeConfig.DeadTime = 0;

sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;

sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;

sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;

if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)

_Error_Handler(__FILE__, __LINE__);

HAL_TIM_MspPostInit(&htim1);

static void MX_GPIO_Init(void)

// GPIO Ports Clock Enable

__HAL_RCC_GPIOE_CLK_ENABLE ();

AMLAKU FEB 2/27/2019 46


Void _Error Handler (char *file, int line)

// USER CODE BEGIN Error_Handler_Debug

// User can add his own implementation to report the HAL error return state

While (1)

// USER CODE END Error_Handler_Debug

CHAPTER TWO
SENSOR INTERFACING AND MODULE CONFIGURATION
2.1 MPU6050 Digital 6- DOF with Stm32f4 Microcontroller
MPU6050 is the world’s first integrated 6 axis motion sensor, it combines one 3 axis accelerometer
and one 3 axis gyroscope, and it has its own digital motion processor (DMP) which can process
the motion data with its inside algorithm. It can output 6 axis raw data as well as 6 axis data which
pass through the Kalman filter or processed by the Quaternion algorithm. However, access to the
filtered data as well as the DMP need specific permission, so only the raw data is used in this
project. This sensor can also attach a 3 axis compass through the I2C bus which makes it a 9 axis
inertial motion sensor. The chip itself has an internal 16 bit analog to digital converter (ADC), so

AMLAKU FEB 2/27/2019 47


the output data are 16 bit digital values. There are 117 registers in total inside the chip and all of
the registers are 8 bit, so it needs two registers to hold the value for one axis’ data. The detection
range of the accelerometer is +2g, 4g, 8g, 16g and that of the gyroscope is +250, 500, 1000,
2000º/s, the range can be chosen by setting the corresponding registers. MPU6050 is
communicated with microcontroller through the I2C data bus at the clock frequency of 100 kHz.
The InvenSense MPU6050 with embedded 3-axis MEMS accelerometer and gyroscope is chosen.
The acceleration along a particular axis induces a displacement on the corresponding proof mass
which is detected by the capacitive sensors and converted into a linear voltage signal. Figure shows
the break out board of MPU6050. The 16-bit sigma-delta ADC on each axis provides digital
outputs. The full scale range of the acceleration can be adjusted to ±2g, ±4g, ±8g, or ±16g. When
the gyroscope is rotated around the sense axis, the Coriolis force causes a vibration that is picked-
up by the sensing capacitors and converted into a voltage proportional to the angular rate by the
signal conditioning circuit. This voltage is digitized using on-chip 16-bit ADC. The full-scale
range of the gyroscope can be programmed to ±250, ±500, ±1000, or ±2000 degrees per second
The output value of the chip is not the actual acceleration or angular velocity. It has to be calibrated
according to the calibration value in the datasheet. For example, if the range of the accelerometer
is ±4g (or 18 ±500 for the gyroscope) according to the datasheet, its units is 8192 LSB/g (65.5
LSB/ (°/sec) for the gyroscope), which means that if the digital data we get from the chip is 9000,
the actual value should be 9000/8192=1.1g for the accelerometer and 9000/65.5=137.4°/sec for
the gyroscope.

AMLAKU FEB 2/27/2019 48


2.1.1 3-Axis Gyroscope

The MPU6050 consist of 3-axis Gyroscope with Micro Electro Mechanical System (MEMS)
technology. It is used to detect rotational velocity along the X, Y, Z axes as shown in below figure.
The MPU includes a 3-Axis vibratory MEMS rate gyroscope, which detect rotations about the X-
, Y-, and Z- Axes. When the gyro is are rotated about any of the sense axes, the Coriolis Effect
causes a vibration that is detected by a capacitive pickoff. The resulting signal is amplified,
demodulated, and filtered to produce a voltage that is proportional to the angular rate. This voltage
is digitized using individual on-chip 16-bit Analog to- Digital Converters (ADCs) to sample each

AMLAKU FEB 2/27/2019 49


axis. The full-scale range of the gyro sensor may be digitally programmed to ±250, ±500, ±1000,
or ±2000 degrees per second (dps). The ADC sample rate is programmable from 8,000 Samples
per second, down to 3.9 samples per second, and user selectable low pass filters enable a wide
range of Cut-off frequencies.
Gyroscope Features
The triple-axis MEMS gyroscope in the MPU-6050 includes a wide range of features:
 Digital-output X-, Y-, and Z-Axis angular rate sensors (gyroscopes) with a user-
programmable full-scale range of ±250, ±500, ±1000, and ±2000°/sec
 Sensitivity: 131 LSB/dps (±250 dps), 65.5 LSB/dps (±500 dps), 32.8
LSB/dps (±1000 dps), and 16.4 LSB (±2000 dps).
 External sync signal connected to the FSYNC pin supports image, video and GPS
synchronization
 Integrated 16-bit ADCs enable simultaneous sampling of gyros
 Enhanced bias and sensitivity temperature stability reduces the need for user
calibration
 Improved low-frequency noise performance
 Digitally-programmable low-pass filter(DPLF)
 Gyroscope operating current: 3.6mA
 Standby current: 5μA
 Factory calibrated sensitivity scale factor
 User self-test

AMLAKU FEB 2/27/2019 50


 MPU6050 orientation and polarity of rotation
 When the gyros are rotated about any of the sense axes, the Coriolis Effect causes a
vibration that is detected by a MEM inside MPU6050.
 The resulting signal is amplified, demodulated, and filtered to produce a voltage that is
proportional to the angular rate.
 This voltage is digitized using 16-bit ADC to sample each axis.
 The full-scale range of output are +/- 250, +/- 500, +/- 1000, +/- 2000.
 It measures the angular velocity along each axis in degree per second unit.

2.1.2 3-Axis Accelerometer


The MPU6050 consist 3-axis Accelerometer with Micro Electro Mechanical (MEMs) technology.
It used to detect angle of tilt or inclination along the X, Y and Z axes as shown in below figure.
The MPU‟s 3-axis accelerometer uses separate proof masses for each axis. Acceleration along a
Particular axis induces displacement on the corresponding proof mass, and capacitive sensors
detect the displacement differentially. The IMU‟s architecture reduces the accelerometer’s
susceptibility to fabrication Variations as well as to thermal drift. When the device is placed on a
flat surface, it will measure 0g on the X and Y-axes and +1g on the Z-axis. The accelerometer’s
scale factor is calibrated at the factory and is nominally independent of supply voltage. Each sensor
has a dedicated sigma-delta ADC for providing digital outputs. The full scale range of the digital
output can be adjusted to ±2g, ±4g, ±8g, or ±16g.

AMLAKU FEB 2/27/2019 51


Accelerometer Features
 The triple-axis MEMS accelerometer in MPU-6050 includes a wide range of
features:
 Digital-output triple-axis accelerometer with a programmable full scale range of
±2g, ±4g, ±8g and ±16g
 Sensitivity: 16.384 LSB/g (±2g), 8192 LSB/g (±4g), 4096 LSB/g (±8g), and
2048 LSB/g (±16g)
 Integrated 16-bit ADCs enable simultaneous sampling of accelerometers while
requiring no external multiplexer
 Accelerometer normal operating current: 500μA
 Low power accelerometer mode current: 10μA at 1.25Hz, 20μA at 5Hz, 60μA at
20Hz, 110μA at 40Hz
 Orientation detection and signaling
 Communication interfaces: I2C
 Tap detection and User self-test

Acceleration along the axes deflects the movable mass.

This displacement of moving plate (mass) unbalances the differential capacitor which results in
sensor output. Output amplitude is proportional to acceleration.

 16-bit ADC is used to get digitized output.


 The full-scale range of acceleration are +/- 2g, +/- 4g, +/- 8g, +/- 16g.
 It measured in g (gravity force) unit.

AMLAKU FEB 2/27/2019 52


 When device placed on flat surface it will measure 0g on X and Y axis and +1g on
Z axis

2.1.3 Accelerometer Working Principle

The figure 3 below shows a simplified diagram of a basic accelerometer structure. A simple mass
(m) is attached to a spring of stiffness (k) and the other end of the spring is then attached to the
casing. The dashpot with damping coefficient (B) is normally attached to the mass in parallel with
the spring. This provides desirable damping effect.

Figure 3. Simplified diagram of the accelerometer structure


Where: k=Stiffness (spring constant), m=Simple mass [also called seismic-mass or proof-mass in
accelerometers], B=Damping coefficient.

Operation
When the accelerometer is subjected to linear acceleration, a force equal to mass times acceleration
(F=ma), acts on the proof-mass, causing it to deflect. This deflection is sensed by a suitable means
and converted into an equivalent electrical signal. The amount of deflection is directly proportional
to the accelerometer’s acceleration. Some form of damping is required; otherwise the system
would not stabilize quickly under applied acceleration. To derive the motion equation of the system
Newton’s second law is used, where all real forces acting on the proof-mass are equal to the inertia
force on the proof-mass.

AMLAKU FEB 2/27/2019 53


Accordingly a dynamic problem can be treated as a problem of static equilibrium and the equation
of motion can be obtained by direct formulation of the equations of equilibrium. This damped
mass-spring system with applied force constitutes a classical second order mechanical system.
From the stationary observer’s point of view, the sum of all forces in the z direction is,

…….…………………….Eq (1)

………………………..Eq (2)

…………………………………………Eq (3)
Where: m= mass of the proof-mass, X= relative movement of the proof-mass with respect to frame,
B= damping coefficient, k= spring constant, F= force applied.
The equation of motion is a second order linear differential equation with constant coefficients.
The general solution x (t) is the sum of the complementary function XC (t) and the particular
integral Xp (t) [5].
…………………….Eq (4)
The complementary function satisfies the homogeneous equation

………………..……Eq (5)
The solution to XC (t) is

...........................................Eq (6)
Substituting equation (4) in equation (3)

……………………....Eq (7)
Called as the auxiliary or characteristic equation of the system.
The solution to this equation for values of S is

………...Eq (8)
From the above equation (9) the following useful formulae are derived

………………….………………………..Eq (9)

…………………………………………..….Eq (10)

AMLAKU FEB 2/27/2019 54


…………………………………….....Eq (11)

Where ωn = Undamped resonance frequency,


Calculations

Note that gyroscope and accelerometer sensor data of MPU6050 module consists of 16-bit raw
data in 2’s complement form.
Temperature sensor data of MPU6050 module consists of 16-bit data (not in 2’s complement
form). Now suppose we have selected,
- Accelerometer full scale range of +/- 2g with Sensitivity Scale Factor of 16,384 LSB (Count)/g.
- Gyroscope full scale range of +/- 250 °/s with Sensitivity Scale Factor of 131 LSB (Count)/°/s.
Then, to get sensor raw data, we need to first perform 2’s complement on sensor data of
Accelerometer and gyroscope.
After getting sensor raw data we can calculate acceleration and angular velocity by dividing sensor
raw data with their sensitivity scale factor as follows,
Accelerometer values into Gs (g force)
Raw Accelerometer value / 16384 (this is for +-2 G sensitivity
Acceleration along the X axis = (Accelerometer X axis raw data/16384) g.
Acceleration along the Y axis = (Accelerometer Y axis raw data/16384) g.
Acceleration along the Z axis = (Accelerometer Z axis raw data/16384) g.
Gyroscope values in °/s (degree per second)
In order to get degrees/sec form raw value;
Raw value of Gyro / 131 (this is for +-250 dps sensitivity)
Angular velocity along the X axis = (Gyroscope X axis raw data/131) °/s.
Angular velocity along the Y axis = (Gyroscope Y axis raw data/131) °/s.
Angular velocity along the Z axis = (Gyroscope Z axis raw data/131) °/s.
Temperature value in °/c (degree per Celsius)
Temperature in degrees C = ((temperature sensor data)/340 + 36.53) °/c.
For example,
Suppose, after 2’ complement we get accelerometer X axes raw value = +15454
Then Ax = +15454/16384 = 0.94 g.

AMLAKU FEB 2/27/2019 55


Registers 59 _ 64 – Accelerometer Measurements
ACCEL_XOUT_H, ACCEL_XOUT_L,
ACCEL_YOUT_H, ACCEL_YOUT_L,
ACCEL_ZOUT_H, and ACCEL_ZOUT_L
Type: Read Only

Each 16-bit accelerometer measurement has a full scale defined in ACCEL_FS (Register 28). For
each full scale setting, the accelerometers’ sensitivity per LSB in ACCEL_XOUT is shown in the
table below.

AMLAKU FEB 2/27/2019 56


Registers 65 _ 66 – Temperature Measurement

TEMP_OUT_H and TEMP_OUT_L


Type: Read Only

The temperature in degrees C for a given register value may be computed as:
Temperature in degrees C = (TEMP_OUT Register Value as a signed quantity)/340 + 36.53

Registers 67 _72 – Gyroscope Measurements


GYRO_XOUT_H, GYRO_XOUT_L,
GYRO_YOUT_H, GYRO_YOUT_L,
GYRO_ZOUT_H, and GYRO_ZOUT_L
Type: Read Only

Each 16-bit gyroscope measurement has a full scale defined in FS_SEL (Register 27). For each
full scale setting, the gyroscopes’ sensitivity per LSB in GYRO_XOUT is shown in the table below:

AMLAKU FEB 2/27/2019 57


Raw MPU6050 Data
The MPU6050 can be initialized to measure acceleration in Gs at any of the following sensitivities:
Full scale range of ±2g, ±4g, ±8g and ±16g
The gyroscope can also be configured to measure angular velocity in degree/s at one of the
following sensitivities:
Full-scale range of ±250, ±500, ±1000, and ±2000°/sec
The MPU6050 stores individual sensor outputs as 16 bit signed integers. This means that all values,
from the accelerometer or gyroscope, can be anywhere on the domain of ±16 bit range.
[-32768,32768] or 2^16.
This means that the data must be scaled in order for the raw data to have the proper units.
|Range|
Scalar = | 216 |
For +- 16g :
9.80665
SAcceleretaion = 32 ∗ 65536 = 0.00048828125 this implies the scaling factor ±8g
0.00048828125
For ±2000dg/s:
|range| 4000
SGyro = 216 = 65536 = 0.06103515625 This implies scaling factor ±2000 is
0.06103515625

You can change the sensitivity by writing different values to the MPU 6050s internal registers
via I2C. Below are a listing of the interested registers and their addresses:
FS_SEL - Register 1B, Bits 3 and 4 (gyroscope sensitivity)
Value written to FS_SEL - sensitivity:
0 - +-250
1 - +-500
2 - +-1000
3 - +-2000
AFS_SEL - Register 1C, Bits 3 and 4 (accelerometer sensitivity)
Value written to AFS_SEL - sensitivity:
0 - +-2G
1 - +-4G
2 - +-8G
3 - +-16G
A Gyroscope gives the values of degrees/sec in the three respective axis X, Y and Z (Yaw, Pitch
and Roll axes respectively).
But whatever raw value given first by these sensors should be converted to sensible acceleration
or angular velocity values by scaling.

AMLAKU FEB 2/27/2019 58


Intenseness Data Sheet of MPU-6050 says that we have to use different scaling factors for different
ranges of gyro values. I shall explain how to use these scaling factors in this section.

 Gyro full scale for X, Y and Z axis: +- 2000 degree/second. This means for example if the sensor
is rotated in X axis with maximum angular velocity of 2000 degrees per second, the gyro X data
will be maximum value of 16bit integer variable: 32768. In the other hand, the readout value
will be -32768 if the angular velocity is -2000 degrees per second. From here, we can come out
with the conversion ratio from raw sensor data to real angular velocity:
 R = 32768 / full scale value = 32768 / 2000 = 16.384.
 Therefore the Gyroscope can be set in the following form
Angular Velocity Sensitivity
250 131
500 65.5
1000 32.8
2000 16.4

 Accelerometer full scale: +- 16g.


Accelerometer Sensitivity
2g 16,384
4g 8,192
8g 4096
16g 2048

AMLAKU FEB 2/27/2019 59


MPU6050 STM32 connection

2.1.4 Mpu6050 I2C Communication using

Data on SDA must be stable during the high period of SCL as shown in Figure. The SDA signal
can only change when SCL is stable at low, otherwise it will generate the START or STOP
conditions. The master can issue a restart signal so that without first stopping a transfer, it can
change the direction of SDA data flow for either write or read, the restart signal contains the slave
address of the new data register as well as the direction specified by the R/W bit.
There are two types of operation on the I2C bus:
 Write operation: master writes START, address, data (the slave sends ACKs only)
 Read operation: master writes START, address. Slave sends data, master sends ACK /
NACK.

AMLAKU FEB 2/27/2019 60


In a "combined" write/read, there's still address overhead:
 Master sends Start, then slave address + write; slave acks
 Master sends data, slave acks
 Master sends Restart, then slave address + read; slave acks
 Slave sends data, master ACKs/NACKs
 Master sends Stop
2.2 Stm32f407vgtx Mpu6050 microcontroller full c Kiel code
#include "main.h"
#include "stm32f4xx_hal.h"
#include <string.h>
#include <math.h>
// defines
#define mpu6050Address 0xD0
#define XGOFFS_TC 0x00 // Bit 7 PWR_MODE, bits 6:1 XG_OFFS_TC, bit 0
OTP_BNK_VLD
#define YGOFFS_TC 0x01
#define ZGOFFS_TC 0x02
#define X_FINE_GAIN 0x03 // [7:0] fine gain
#define Y_FINE_GAIN 0x04
#define Z_FINE_GAIN 0x05
#define XA_OFFSET_H 0x06 // User-defined trim values for accelerometer
#define XA_OFFSET_L_TC 0x07
#define YA_OFFSET_H 0x08
#define YA_OFFSET_L_TC 0x09
#define ZA_OFFSET_H 0x0A
#define ZA_OFFSET_L_TC 0x0B
#define SELF_TEST_X 0x0D
#define SELF_TEST_Y 0x0E
#define SELF_TEST_Z 0x0F
#define SELF_TEST_A 0x10
#define XG_OFFS_USRH 0x13 // User-defined trim values for gyroscope; supported in MPU

AMLAKU FEB 2/27/2019 61


#define XG_OFFS_USRL 0x14
#define YG_OFFS_USRH 0x15
#define YG_OFFS_USRL 0x16
#define ZG_OFFS_USRH 0x17
#define ZG_OFFS_USRL 0x18
#define SMPLRT_DIV 0x19
#define CONFIG 0x1A
#define GYRO_CONFIG 0x1B
#define ACCEL_CONFIG 0x1C
#define FF_THR 0x1D // Free-fall
#define FF_DUR 0x1E // Free-fall
#define MOT_THR 0x1F // Motion detection threshold bits [7:0]
#define MOT_DUR 0x20 // Duration counter threshold for motion interrupt generation, 1
kHz rate, LSB = 1 ms
#define ZMOT_THR 0x21 // Zero-motion detection threshold bits [7:0]
#define ZRMOT_DUR 0x22
#define FIFO_EN 0x23
#define I2C_MST_CTRL 0x24
#define I2C_SLV0_ADDR 0x25
#define I2C_SLV0_REG 0x26
#define I2C_SLV0_CTRL 0x27
#define I2C_SLV1_ADDR 0x28
#define I2C_SLV1_REG 0x29
#define I2C_SLV1_CTRL 0x2A
#define I2C_SLV2_ADDR 0x2B
#define I2C_SLV2_REG 0x2C
#define I2C_SLV2_CTRL 0x2D
#define I2C_SLV3_ADDR 0x2E
#define I2C_SLV3_REG 0x2F
#define I2C_SLV3_CTRL 0x30
#define I2C_SLV4_ADDR 0x31

AMLAKU FEB 2/27/2019 62


#define I2C_SLV4_REG 0x32
#define I2C_SLV4_DO 0x33
#define I2C_SLV4_CTRL 0x34
#define I2C_SLV4_DI 0x35
#define I2C_MST_STATUS 0x36
#define INT_PIN_CFG 0x37
#define INT_ENABLE 0x38
#define DMP_INT_STATUS 0x39 // Check DMP interrupt
#define INT_STATUS 0x3A
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48
#define EXT_SENS_DATA_00 0x49
#define EXT_SENS_DATA_01 0x4A
#define EXT_SENS_DATA_02 0x4B
#define EXT_SENS_DATA_03 0x4C
#define EXT_SENS_DATA_04 0x4D
#define EXT_SENS_DATA_05 0x4E
#define EXT_SENS_DATA_06 0x4F
#define EXT_SENS_DATA_07 0x50

AMLAKU FEB 2/27/2019 63


#define EXT_SENS_DATA_08 0x51
#define EXT_SENS_DATA_09 0x52
#define EXT_SENS_DATA_10 0x53
#define EXT_SENS_DATA_11 0x54
#define EXT_SENS_DATA_12 0x55
#define EXT_SENS_DATA_13 0x56
#define EXT_SENS_DATA_14 0x57
#define EXT_SENS_DATA_15 0x58
#define EXT_SENS_DATA_16 0x59
#define EXT_SENS_DATA_17 0x5A
#define EXT_SENS_DATA_18 0x5B
#define EXT_SENS_DATA_19 0x5C
#define EXT_SENS_DATA_20 0x5D
#define EXT_SENS_DATA_21 0x5E
#define EXT_SENS_DATA_22 0x5F
#define EXT_SENS_DATA_23 0x60
#define MOT_DETECT_STATUS 0x61
#define I2C_SLV0_DO 0x63
#define I2C_SLV1_DO 0x64
#define I2C_SLV2_DO 0x65
#define I2C_SLV3_DO 0x66
#define I2C_MST_DELAY_CTRL 0x67
#define SIGNAL_PATH_RESET 0x68
#define MOT_DETECT_CTRL 0x69
#define USER_CTRL 0x6A // Bit 7 enable DMP, bit 3 reset DMP
#define PWR_MGMT_1 0x6B // Device defaults to the SLEEP mode
#define PWR_MGMT_2 0x6C
#define DMP_BANK 0x6D // Activates a specific bank in the DMP
#define DMP_RW_PNT 0x6E // Set read/write pointer to a specific start address in specified
DMP bank
#define DMP_REG 0x6F // Register in DMP from which to read or to which to write

AMLAKU FEB 2/27/2019 64


#define DMP_REG_1 0x70
#define DMP_REG_2 0x71
#define FIFO_COUNTH 0x72
#define FIFO_COUNTL 0x73
#define FIFO_R_W 0x74
#define WHO_AM_I_MPU6050 0x75 // should return 0x68

// using the GY-521 breakout board, I set ADO to 0 by grounding through a 4k7 resistor
// Seven-bit device address is 110100 for ADO = 0 and 110101 for ADO = 1
#define ADO 0
#if ADO
#define MPU6050_ADDRESS 0x69<<1 // Device address when ADO = 1
#else
#define MPU6050_ADDRESS 0x68<<1 // Device address when ADO = 0
#endif
#define MPU6050_GCONFIG_FS_SEL_BIT 4
#define MPU6050_GCONFIG_FS_SEL_LENGTH 2
#define MPU6050_GYRO_FS_250 0x00
#define MPU6050_GYRO_FS_500 0x01
#define MPU6050_GYRO_FS_1000 0x02
#define MPU6050_GYRO_FS_2000 0x03
#define MPU6050_ACONFIG_XA_ST_BIT 7
#define MPU6050_ACONFIG_YA_ST_BIT 6
#define MPU6050_ACONFIG_ZA_ST_BIT 5
#define MPU6050_ACONFIG_AFS_SEL_BIT 4
#define MPU6050_ACONFIG_AFS_SEL_LENGTH 2
#define MPU6050_ACONFIG_ACCEL_HPF_BIT 2
#define MPU6050_ACONFIG_ACCEL_HPF_LENGTH 3
#define MPU6050_ACCEL_FS_2 0x00
#define MPU6050_ACCEL_FS_4 0x01
#define MPU6050_ACCEL_FS_8 0x02

AMLAKU FEB 2/27/2019 65


#define MPU6050_ACCEL_FS_16 0x03
#define MPU6050_DHPF_RESET 0x00
#define MPU6050_DHPF_5 0x01
#define MPU6050_DHPF_2P5 0x02
#define MPU6050_DHPF_1P25 0x03
#define MPU6050_DHPF_0P63 0x04
#define MPU6050_DHPF_HOLD 0x07
/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;

UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
//I2C variables
uint8_t i2cBuf [14];
Uint16_t ax, ay, az; //Stores the 16-bit signed accelerometer sensor output
int16_t gx, gy, gz; //Stores the 16-bit signed gyroscope sensor output
int16_t temp;
float temperature;
Float aRes;
Float gRes;
Float Xaccel, Yaccel, Zaccel; // Stores the real accel value in g's
Float Xgyro,Ygyro, Zgyro; //// Stores the real gyro value in degrees per second
#define mpu6050Address 0xD0
// Set initial input parameters
Enum Ascale {
AFS_2G = 0,
AFS_4G,
AFS_8G,

AMLAKU FEB 2/27/2019 66


AFS_16G
};
enum Gscale {
GFS_250DPS = 0,
GFS_500DPS,
GFS_1000DPS,
GFS_2000DPS
};
// specify sensor full scale
int Gscale = GFS_250DPS;
int Ascale = AFS_2G;
float aRes, gRes; // scale resolutions per LSB for the sensors
// USER CODE END PV
// Private function prototypes
Void SystemClock_Config (void);
Static void MX_GPIO_Init (void);
Static void MX_I2C1_Init (void);
Static void MX_USART1_UART_Init (void);
//
Int main (void)
{
// MCU Configuration
// Reset of all peripherals, Initializes the Flash interface and the Systick
HAL_Init ();
// configure the system clock
SystemClock_Config ();
// USER CODE END SysInit
// Initialize all configured peripherals

MX_GPIO_Init ();

AMLAKU FEB 2/27/2019 67


MX_I2C1_Init ();
MX_USART1_UART_Init ();
/* USER CODE BEGIN 2 */
// char txBuf [22];
// char rxBuf [22];
// gyro config
//txBuf[1] = 0x1B; // GYRO_Config
//HAL_I2C_Mem_Write(&hi2c1,0xD0,GYRO_CONFIG,I2C_MEMADD_SIZE_8BIT,(uint8_t
*)&txBuf[1],1,100);
// HAL_Delay(500);
//HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,GYRO_XOUT_L,I2C_MEMADD_SIZE_8BIT,(ui
nt8_t*)&rxBuf[8],1,10); // for GYRO_XOUT_L
// HAL_Delay(1000);
//HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,GYRO_XOUT_H,I2C_MEMADD_SIZE_8BIT,(ui
nt8_t*)&rxBuf[9],6,10); //for GYRO_XOUT_H
//HAL_Delay(1000);
// // accelero config
// txBuf[1]= 0x1C; // ACCEL_Config
//HAL_I2C_Mem_Write(&hi2c1,0xD0,ACCEL_CONFIG,I2C_MEMADD_SIZE_8BIT,(uint8_t
*)&txBuf[1],1,100);
// HAL_Delay(500);
//HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,ACCEL_XOUT_L,I2C_MEMADD_SIZE_8BIT,(u
int8_t*)&rxBuf[1],1,10); // for GYRO_XOUT_L
// HAL_Delay(1000);
//HAL_I2C_Mem_Read
(&hi2c1,0xD0|0x01,ACCEL_XOUT_H,I2C_MEMADD_SIZE_8BIT,(uint8_t*)&rxBuf[0],6,10)
; //for GYRO_XOUT_H
//HAL_Delay (1000);
////* Gyro_Config settings... XG_ST --> 1 , YG_ST --> 1 , ZG_ST --> 1 , FS-SEL 10 (1000 dps)
// txBuf[0] = 0x81; //PWR_MGMT
// HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)&txBuf[0],1,200);

AMLAKU FEB 2/27/2019 68


// HAL_Delay(500);
// txBuf[0] = 0x07; // SMPLRT_DIV
// HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)&txBuf[0],1,200);
// HAL_Delay(50);
// txBuf[0] = 0x01; //,PWR_MGMT
// HAL_I2C_Master_Transmit(&hi2c1,mpu6050Address|0x01,(uint8_t*)&txBuf[0],1,200);
// HAL_Delay(500);
// txBuf[0] = 0x00; // CONFIG_REG
// HAL_I2C_Master_Transmit(&hi2c1,mpu6050Address|0x01,(uint8_t*)&txBuf[0],1,200);
// HAL_Delay(500);
// txBuf[0] = 0xF1;//GYRO_CONFIG
// HAL_I2C_Master_Transmit(&hi2c1,mpu6050Address,(uint8_t*)&txBuf[0],1,10);
// HAL_Delay(50);
// HAL_UART_Receive_DMA(&huart1,(uint8_t*)rxBuf,200);
//1. Scan the I2C adresses
for(uint8_t i=0; i<255; i++)
{
if(HAL_I2C_IsDeviceReady(&hi2c1 , i, 1, 10) == HAL_OK) //test for the slave address
{
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);
break;
}
}
i2cBuf[0] = 0x6B;
HAL_I2C_Mem_Write(&hi2c1,0xD0,PWR_MGMT_1,I2C_MEMADD_SIZE_8BIT,(uint8_t*)
&i2cBuf[0],1,10); // Device defaults to the SLEEP mode
HAL_Delay(50);
i2cBuf[0] = 0x19;
HAL_I2C_Mem_Write(&hi2c1,0xD0,SMPLRT_DIV,I2C_MEMADD_SIZE_8BIT,(uint8_t*)&i
2cBuf[0],1,10);
HAL_Delay(50);

AMLAKU FEB 2/27/2019 69


i2cBuf[0] = 0x6C;
HAL_I2C_Mem_Write(&hi2c1,0xD0,PWR_MGMT_2,I2C_MEMADD_SIZE_8BIT,(uint8_t*)
&i2cBuf[0],1,10);
HAL_Delay(50);
i2cBuf[0] = 0x1A;
HAL_I2C_Mem_Write(&hi2c1,0xD0,CONFIG,I2C_MEMADD_SIZE_8BIT,(uint8_t*)&i2cBuf
[0],1,10);
HAL_Delay(50);
i2cBuf[0] = 0x1B;
HAL_I2C_Mem_Write(&hi2c1,0xD0,GYRO_CONFIG,I2C_MEMADD_SIZE_8BIT,(uint8_t*)
&i2cBuf[0],1,10);
HAL_Delay(50);
i2cBuf[0] = 0x1C;
HAL_I2C_Mem_Write(&hi2c1,0xD0,ACCEL_CONFIG,I2C_MEMADD_SIZE_8BIT,(uint8_t*
)&i2cBuf[0],1,10);
HAL_Delay(50);
/* USER CODE END 2 */
//2. I2C Write example
//a) Set accelerometer range (reg28)
i2cBuf[0] = 28; //Register address: Accelerometer config 1
i2cBuf[1] = 0x00; //Data to write, +-2g range
i2cBuf[2] = 0x01; //Data to write, +-4g range
i2cBuf[3] = 0x02; //Data to write, +-8g range
i2cBuf[4] = 0x03; //Data to write, +-16g range
HAL_I2C_Master_Transmit(&hi2c1, 0xD0,i2cBuf, 2, 200);
HAL_Delay(1000);
//3. I2C Read example
//Request to read from a register (reg 28)
i2cBuf [0] = 28; //Register address: Accelerometer config 1
HAL_I2C_Mem_Write (&hi2c1, 0xD0, 0x00, I2C_MEMADD_SIZE_8BIT, i2cBuf, 1, 10);
//Read data

AMLAKU FEB 2/27/2019 70


i2cBuf [1] = 0x00; //Data to write, +-2g range
HAL_I2C_Mem_Read (&hi2c1, 0xD0, 0x00, I2C_MEMADD_SIZE_8BIT, &i2cBuf [1], 4, 10);
//2. I2C Write example
//a) Set gyroscope range (reg27)
i2cBuf [0] = 27; //Register address: Accelerometer config 1
i2cBuf [1] = 0x00; //Data to write, +-250 range
i2cBuf [1] = 0x01; //Data to write, +-500 range
I2cBuf [1] = 0x02; //Data to write, +-1000 range
i2cBuf [1] = 0x03; //Data to write, +-2000 range
HAL_I2C_Mem_Write (&hi2c1, 0xD0, 0x00, I2C_MEMADD_SIZE_8BIT, &i2cBuf [1], 1, 10);
HAL_Delay (100);
//3. I2C Read example
//Request to read from a register (reg 27)
i2cBuf [0] = 27; //Register address: gyroscope config 1
HAL_I2C_Mem_Write (&hi2c1, 0xD0, 0x00,I2C_MEMADD_SIZE_8BIT, &i2cBuf [0], 1, 10);
//Read data
i2cBuf [1] = 0x00;
HAL_I2C_Mem_Read (&hi2c1, 0xD0, 0x00, I2C_MEMADD_SIZE_8BIT, &i2cBuf [1], 4, 10);
HAL_Delay (100);

// Infinite loop

AMLAKU FEB 2/27/2019 71


While (1)
{
{
if(HAL_I2C_Mem_Read(&hi2c1,0xD0,WHO_AM_I_MPU6050,I2C_MEMADD_SIZE_8BIT,i
2cBuf,1,100) == HAL_OK ) {
// Return error
}
//WakeupMPU6050
HAL_I2C_Mem_Write(&hi2c1,0xD0,PWR_MGMT_1|0x00,I2C_MEMADD_SIZE_8BIT,i2cB
uf,1,100);
// Config accelerometer
temp=HAL_I2C_Mem_Read(&hi2c1,0xD0,ACCEL_CONFIG,I2C_MEMADD_SIZE_8BIT,i2c
Buf,1,100);
temp = (temp & 0xE7) | (uint8_t)Ascale << 3;
HAL_I2C_Mem_Write(&hi2c1,0xD0, ACCEL_CONFIG,
I2C_MEMADD_SIZE_8BIT,i2cBuf,6,100);
/* Config gyroscope */
HAL_I2C_Mem_Read(&hi2c1,0xD0,GYRO_CONFIG,I2C_MEMADD_SIZE_8BIT,i2c
Buf,1,100);
temp = (temp & 0xE7) | (uint8_t)Gscale << 3;
HAL_I2C_Mem_Write(&hi2c1,0xD0,
GYRO_CONFIG,I2C_MEMADD_SIZE_8BIT,i2cBuf,6,100 );
Switch (AScale)
{
// Possible accelerometer scales (and their register bit settings) are:
// 2 Gs (00), 4 Gs (01), 8 Gs (10), and 16 Gs (11).
// Here's a bit of an algorith to calculate DPS/(ADC tick) based on that 2-bit value:
case AFS_2G:
aRes = 2.0/32768.0;
break;
case AFS_4G:

AMLAKU FEB 2/27/2019 72


aRes = 4.0/32768.0;
break;
case AFS_8G:
aRes = 8.0/32768.0;
break;
case AFS_16G:
aRes = 16.0/32768.0;
break;
}
{
switch (Gscale)
{
// Possible gyro scales (and their register bit settings) are:
// 250 DPS (00), 500 DPS (01), 1000 DPS (10), and 2000 DPS (11).
// Here's a bit of an algorith to calculate DPS/(ADC tick) based on that 2-bit value:
case GFS_250DPS:
gRes = 250.0/32768.0;
break;
case GFS_500DPS:
gRes = 500.0/32768.0;
break;
case GFS_1000DPS:
gRes = 1000.0/32768.0;
break;
case GFS_2000DPS:
gRes = 2000.0/32768.0;
break;
}
//4.Read accelerometer data
//Request to read from a register
i2cBuf[0] = 0x3B; //ACCEL_XOUT_H //Register address: X_axis H

AMLAKU FEB 2/27/2019 73


HAL_I2C_Mem_Write(&hi2c1, 0xD0,ACCEL_XOUT_H,I2C_MEMADD_SIZE_8BIT,
i2cBuf, 1, 200);
HAL_Delay(200);
//Read data
i2cBuf[1] = 0x3C;//ACCEL_XOUT_L
HAL_I2C_Mem_Write(&hi2c1, 0xD0,ACCEL_XOUT_H,I2C_MEMADD_SIZE_8BIT, i2cBuf,
1, 200);
HAL_I2C_Mem_Read(&hi2c1, 0xD0,ACCEL_XOUT_L,I2C_MEMADD_SIZE_8BIT,
&i2cBuf[0],14,200);

ax= (i2cBuf[0]<<8 | i2cBuf[1]); // Turn the MSB and LSB into a signed 16-bit value
ay= (i2cBuf[2]<<8 | i2cBuf[3]);
az= (i2cBuf[4]<<8 | i2cBuf[5]);
temp = (i2cBuf [0] << 8 | i2cBuf [1]); // Turn the MSB and LSB into a signed 16-bit value
gx= (i2cBuf[0]<<8 | i2cBuf[1]);
gy= (i2cBuf[2]<<8 | i2cBuf[3]);
gz= (i2cBuf[4]<<8 | i2cBuf[5]);
Xaccel = ax/4096.0;
Yaccel = ay/4096.0;
Zaccel = az/4096.0;
Xgyro = gx/32.8;
Ygyro = gy/32.8;
Zgyro = gz/32.8;
HAL_Delay(1000);
}

// USER CODE END WHILE

AMLAKU FEB 2/27/2019 74


//5.write temprature data
i2cBuf[0] = 0x41; //Register address: X_axis H
HAL_I2C_Mem_Write(&hi2c1,0xD0,TEMP_OUT_H,I2C_MEMADD_SIZE_8BIT,i2cBuf, 1,
200);
HAL_Delay(200);
//Read temprature data
i2cBuf[1] = 0x42;
HAL_I2C_Mem_Write(&hi2c1, 0xD0,TEMP_OUT_H,I2C_MEMADD_SIZE_8BIT, i2cBuf, 1,
200);
HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,TEMP_OUT_H,I2C_MEMADD_SIZE_8BIT,
&i2cBuf[0], 2, 200);
temp = (i2cBuf [0] << 8 | i2cBuf [1]);
temprature = (float)((float)((int16_t)temp)/(float)340.0 + (float)36.53);
HAL_Delay(1000);
/* USER CODE BEGIN 3 */
// Write groscope data
i2cBuf[8] = 0x43; //Register address: X_axis H
HAL_I2C_Mem_Write(&hi2c1, 0xD0,GYRO_XOUT_H,I2C_MEMADD_SIZE_8BIT, i2cBuf,
1, 200);
HAL_Delay(200);
//Read groscope data
i2cBuf[0] = 0x44;
HAL_I2C_Mem_Write(&hi2c1,0xD0|0x01,GYRO_XOUT_H,I2C_MEMADD_SIZE_8BIT,
i2cBuf, 1, 200);
HAL_I2C_Mem_Read(&hi2c1, 0xD0|0x01,GYRO_XOUT_L,I2C_MEMADD_SIZE_8BIT,
&i2cBuf[0], 6, 200);
gx= (i2cBuf[0]<<8 |i2cBuf[1]);
gy= (i2cBuf[2]<<8 |i2cBuf[3]);
gz= (i2cBuf[4]<<8 |i2cBuf[5]);
Xgyro = gx/32.8;
Ygyro = gy/32.8;

AMLAKU FEB 2/27/2019 75


Zgyro = gz/32.8;
}
// usart data taransmit and receive
//ax= (rxBuf[0]<<8 | rxBuf[1]); // Turn the MSB and LSB into a signed 16-bit value
//ay= (rxBuf[3]<<8 | rxBuf[2]);
//az= (rxBuf[5]<<8 | rxBuf[4]);
//temp = (rxBuf [7] << 8 | rxBuf [6]); // Turn the MSB and LSB into a signed 16-bit value
//gx= (rxBuf[9]<<8 | rxBuf[8]);
//gy= (rxBuf[11]<<8 | rxBuf[10]);
//gz= (rxBuf[13]<<8 | rxBuf[12]);
// // ACCELERO CONFIG
//HAL_I2C_Mem_Read(&hi2c1,mpu6050Address|0x01,ACCEL_XOUT_L,I2C_MEMADD_SI
ZE_8BIT,(uint8_t*)&rxBuf[0],1,200);
//HAL_I2C_Mem_Read(&hi2c1,mpu6050Address|0x01,ACCEL_XOUT_H,I2C_MEMADD_SI
ZE_8BIT,(uint8_t*)&rxBuf[1],1,200);
//ax = (rxBuf[1]<<8 | rxBuf[0])*0.060975F;
//HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,ACCEL_YOUT_L,I2C_MEMADD_SIZE_8BIT,(u
int8_t*)&rxBuf[2],1,200);
//HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,ACCEL_YOUT_H,I2C_MEMADD_SIZE_8BIT,(u
int8_t*)&rxBuf[3],1,200);
//ay = (rxBuf[3]<<8 | rxBuf[2])*0.060975F;
//HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,ACCEL_ZOUT_L,I2C_MEMADD_SIZE_8BIT,(ui
nt8_t*)&rxBuf[4],1,200);
//HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,ACCEL_ZOUT_H,I2C_MEMADD_SIZE_8BIT,(u
int8_t*)&rxBuf[5],1,200);
//
az = (rxBuf[5]<<8 | rxBuf[4])*0.060975F;
// GYRO_CONFIG
//HAL_I2C_Mem_Read(&hi2c1,mpu6050Address|0x01,GYRO_XOUT_L,I2C_MEMADD_SIZ
E_8BIT,(uint8_t*)&rxBuf[8],1,200);

AMLAKU FEB 2/27/2019 76


//HAL_I2C_Mem_Read(&hi2c1,mpu6050Address|0x01,GYRO_XOUT_H,I2C_MEMADD_SI
ZE_8BIT,(uint8_t*)&rxBuf[9],1,200);
//gx = (rxBuf[1]<<8 | rxBuf[0])*0.060975F;
//HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,GYRO_YOUT_L,I2C_MEMADD_SIZE_8BIT,(ui
nt8_t*)&rxBuf[10],1,200);
//HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,GYRO_YOUT_H,I2C_MEMADD_SIZE_8BIT,(ui
nt8_t*)&rxBuf[11],1,200);
//gy = (rxBuf[3]<<8 | rxBuf[2])*0.060975F;
//HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,GYRO_ZOUT_L,I2C_MEMADD_SIZE_8BIT,(ui
nt8_t*)&rxBuf[12],1,200);
//HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,GYRO_ZOUT_H,I2C_MEMADD_SIZE_8BIT,(ui
nt8_t*)&rxBuf[13],1,200);
//gz = (rxBuf[5]<<8 | rxBuf[4])*0.060975F;
//// Temprature_CONFIG
//HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,TEMP_OUT_L,I2C_MEMADD_SIZE_8BIT,(uint
8_t*)&rxBuf[6],1,200);
//HAL_I2C_Mem_Read(&hi2c1,0xD0|0x01,TEMP_OUT_H,I2C_MEMADD_SIZE_8BIT,(uint
8_t*)&rxBuf[7],1,200);
//temp = (float)((float)((rxBuf[6]<<8 | rxBuf[7]) / (float)340.0F)+ (float)36.53);
// Send the data values to serial buffer
//HAL_UART_Transmit(&huart1,(uint8_t*)0xD0,sprintf(rxBuf,
// "Accelerometer\n- X:%d\n- Y:%d\n- Z:%d\nGyroscope\n- X:%d\n- Y:%d\n-
Z:%d\nTemperature\n- %3.4f\n\n\n", ay, az, gx, gy, gz, temprature
),1000);
}
}

AMLAKU FEB 2/27/2019 77


Void SystemClock_Config (void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
// configure the main internal regulator output voltage
__HAL_RCC_PWR_CLK_ENABLE ();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

/**Initializes the CPU, AHB and APB busses clocks


*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
If (HAL_RCC_OscConfig (&RCC_OscInitStruct) != HAL_OK)
{
_Error Handler (__FILE__, __LINE__);
}
// Initializes the CPU, AHB and APB busses clocks
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
_Error_Handler (__FILE__, __LINE__);
}

AMLAKU FEB 2/27/2019 78


//configure the Systick interrupt time
HAL_SYSTICK_Config (HAL_RCC_GetHCLKFreq ()/1000);
// Configure the Systick
HAL_SYSTICK_CLKSourceConfig (SYSTICK_CLKSOURCE_HCLK);
// SysTick_IRQn interrupt configuration
HAL_NVIC_SetPriority (SysTick_IRQn, 0, 0);
}
//I2C1 init function
Static void MX_I2C1_Init (void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
If (HAL_I2C_Init (&hi2c1)! = HAL_OK)
{
_Error Handler (__FILE__, __LINE__);
}
}
// USART1 init function
Static void MX_USART1_UART_Init (void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;

AMLAKU FEB 2/27/2019 79


huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
If (HAL_UART_Init (&huart1) != HAL_OK)
{
_Error_Handler (__FILE__, __LINE__);
}
}
// configure pins as
Static void MX_GPIO_Init (void)
{

/* GPIO Ports Clock Enable */


__HAL_RCC_GPIOH_CLK_ENABLE ();
__HAL_RCC_GPIOA_CLK_ENABLE ();
__HAL_RCC_GPIOB_CLK_ENABLE ();

}
Void _Error_Handler (char *file, int line)
{
// USER CODE BEGIN Error_Handler_Debug
//User can add his own implementation to report the HAL error return state
While (1)
{
}
}
#ifdef USE_FULL_ASSERT
Void assert_failed (uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
tex: printf ("Wrong parameters value: file %s on line %d\r\n", file, line) */
}

AMLAKU FEB 2/27/2019 80


#endif // USE_FULL_ASSERT
2.3 OUT PUT RESULTS FOR MPU6050

AMLAKU FEB 2/27/2019 81


AMLAKU FEB 2/27/2019 82
CHAPTER THREE
Digital Compass Module (HMC5883L) Using STM32F407vgtx
Microcontroller

HMC5883L (Magnetic compass)


STM32f4 Microcontroller

USART

Contents:
1. Principles of magnetometer (HMC5883L)

2. Introduce the HMC5883L library

3. Explain how to extract data from HMC5883L using STM Microcontroller kit.

4. Explain how to calculate a bearing angle from this data.

6. Full Algorithm development for HMC5883L using STM microcontroller

7. Analog Pressure Sensor with Kiel.

3.1 Principles of magnetometer (HMC5883L)


Magnetometer measures the magnetic field it is applied to. The magnetometer outputs
Three magnitudes: X, Y and Z. From these three values you can construct the magnetic field
vector (magnitude and direction) B= [X, Y, Z]
Magnetometers are devices that measures magnetic fields and it can sense where the strongest
Magnetic force is coming from. This sensor is a surface-mounted, multi-chip module designed for
low-field magnetic sensing with a digital interfaces for application such low-cost compassing and
magnetometer. The sensor include our state-of-the-art, high-resolution series magneto-resistive

AMLAKU FEB 2/27/2019 83


sensors plus an ASIC containing amplification, automatic degaussing strap drivers, offset
cancellation, and a 12-bit ADC that enables 1° to 2° compass heading accuracy. The I2C serial bus
allows for easy interface. This is a 3.0x3.0x0.9mm surface mount 16-pin leadless chip carrier
(LCC). Includes on-board voltage regulator, allowing you to power the module with voltages
between 3.3V and 6V. The module includes on-board pull-up resistors on the I2C lines
Applications for this sensor include Mobile Phones, Notebooks, Consumer Electronics, Auto
Navigation Systems, and Personal Navigation Devices. These anisotropic, directional sensors
feature precision in-axis sensitivity and linearity. Magnetometer full scale range is ±8 gauss and
has a resolution of up to 5 mG. A Magnetic compass works by aligning itself to the earth magnetic
field, because the compass needle is a ferrous material, it aligns swings on its bearing in the center
of the magnetic field of the earth pulls it into alignment. These magnetic fields expand throughout
the surface of the earth (and beyond) so we can use them to help us which direction we facing. The
Compass Module 3-Axis HMC5883L is a low-field magnetic sensing device with a digital
interface. The compass module converts any magnetic field to a differential voltage output on 3
axes (x, y and z). This voltage shift is the raw digital output value, which can then be used to
calculate headings or sense magnetic fields coming from different directions. The module is
designed for use with a large variety of microcontrollers with different voltage requirements.
Internal Schematic Diagram Hmc5883l

AMLAKU FEB 2/27/2019 84


3.1.1 Basic Device Operation
1. Power Management
This device has two different domains of power supply. The 1st is VDD that is the power supply
for internal operations and the 2nd is VDDIO that is dedicated to IO interface. It is possible to
work with VDDIO equal to VDD; Single Supply mode, or with VDDIO lower than VDD allowing
HMC5883L to be compatible with other devices on board.
2. I2C Interface
Control of this device is carried out via the I2C bus. This device will be connected to this bus as a
slave device under the control of a master device, such as the processor. This device is compliant
with I2C-Bus Specification. As an I2C compatible device, this device has a 7-bit serial address
and supports I2C protocols. Activities required by the master (register read and write) have priority
over internal activities, such as the measurement.
3. Internal Clock
The device has an internal clock for internal digital logic functions and timing management. This
clock is not available to external usage.

3.1.2 Modes of Operation


Continuous-Measurement Mode
During continuous-measurement mode, the device continuously makes measurements, at user
selectable rate, and places measured data in data output registers. Data can be re-read from the data
output registers if necessary; however, if the master does not ensure that the data register is
accessed before the completion of the next measurement, the data output registers are updated with
the new measurement. To conserve current between measurements, the device is placed in a state
similar to idle mode, but the Mode Register is not changed to Idle Mode. That is, MD[n] bits are
unchanged. Settings in the Configuration Register A affect the data output rate (bits DO[n]), the
measurement configuration (bits MS[n]), when in continuous-measurement mode. All registers
maintain values while in continuous-measurement mode. The I2C bus is enabled for use by other
devices on the network in while continuous-measurement mode.
Single-Measurement Mode

AMLAKU FEB 2/27/2019 85


This is the default power-up mode. During single-measurement mode, the device makes a single
measurement and places the measured data in data output registers. After the measurement is
complete and output data registers are updated, the device is placed in idle mode, and the Mode
Register is changed to idle mode by setting MD[n] bits. Settings in the configuration register affect
the measurement configuration (bits MS[n]) when in single-measurement mode. All registers
maintain values while in single-measurement mode. The I2C bus is enabled for use by other
devices on the network while in single-measurement mode.
Idle Mode
During this mode the device is accessible through the I2C bus, but major sources of power
consumption are disabled, such as, but not limited to, the ADC, the amplifier, and the sensor bias
current. All registers maintain values while in idle mode. The I2C bus is enabled for use by other
devices on the network while in idle mode.
Hmc5883l Registers
This device is controlled and configured via a number of on-chip registers, which are described
in this section. In the following descriptions, set implies a logic 1, and reset or clear implies a
logic 0, unless stated otherwise. All address locations are 8 bits.

Configuration Register A
The configuration register is used to configure the device for setting the data output rate and
measurement configuration. CRA0_CRA7 indicate bit locations, with CRA denoting the bits that
are in the configuration register A. CRA7 denotes the first bit of the data stream. The number in

AMLAKU FEB 2/27/2019 86


parenthesis indicates the default value of that bit. DO0_DO7indicate Data Output Rate Bits.
MS0_ MS1 indicate Measurement Configuration Bits.

Configuration Register B
The configuration register B for setting the device gain. CRB0_CRB7 indicate bit locations, with
CRB denoting the bits that are in the configuration register. CRB7 denotes the first bit of the data
stream. The number in parenthesis indicates the default value of that bit.CRB0_CRB4 indicate
zero value.
Mode Register
The mode register is an 8-bit register from which data can be read or to which data can be written.
This register is used to select the operating mode of the device. MR0 through MR7 indicate bit
locations, with MR denoting the bits that are in the mode register. MR7 denotes the first bit of the
data stream. The number in parenthesis indicates the default value of that bit. MD1 to MD0 Mode
Select Bits. These bits select the operation mode of this device.
Status Register
The status register is an 8-bit read-only register. This register is used to indicate device status. SR0
through SR7 indicate bit locations, with SR denoting the bits that are in the status register. SR7
denotes the first bit of the data stream.
Identification Register A
The identification register A is used to identify the device. IRA0 through IRA7 indicate bit
locations, with IRA denoting the bits that are in the identification register A. IRA7 denotes the
first bit of the data stream. The number in parenthesis indicates the default value of that bit.
The identification value for this device is stored in this register. This is a read-only register.
Register values. ASCII value H.
Identification Register B
The identification register B is used to identify the device. IRB0 through IRB7 indicate bit
locations, with IRB denoting the bits that are in the identification register A. IRB7 denotes the first
bit of the data stream. Register values. ASCII value 4
Identification Register C

AMLAKU FEB 2/27/2019 87


The identification register C is used to identify the device. IRC0 through IRC7 indicate bit
locations, with IRC denoting the bits that are in the identification register A. IRC7 denotes the first
bit of the data stream. Register values. ASCII value 3.

I2C communication Protocol


The HMC5883L communicates via a two-wire I2C bus system as a slave device. It uses a simple
protocol with the interface protocol defined by the I2C bus specification, and by this document.
The data rate is at the standard-mode 100kbps or 400kbps rates as defined in the I2C Bus
Specifications. The bus bit format is an 8-bit Data/Address send and a 1-bit acknowledge bit. The
format of the data bytes (payload) shall be case sensitive ASCII characters or binary data to the
HMC5883L slave, and binary data returned. Negative binary values will be in two’s complement
form. The default (factory) HMC5883L 8-bit slave address is 0x3C for write operations, or 0x3D
for read operations. The HMC5883L SCL and SDA lines require resistive pull-ups (Rp) between
the master device (usually a host microprocessor) and the HMC5883L. Pull-up resistance values
of about 2.2K to 10K ohms are recommended with a nominal VDDIO voltage. Other resistor
values may be used as defined in the I2C Bus Specifications that can be tied to VDDIO. The SCL
and SDA lines in this bus specification may be connected to multiple devices. The bus can be a
single master to multiple slaves, or it can be a multiple master configuration. All data transfers are
initiated by the master device, which is responsible for generating the clock signal, and the data
transfers are 8th bit long. All devices are addressed by I2C’s unique 7-bit address. After each 8-
bit transfer, the master device generates a 9th clock pulse, and releases the SDA line. The receiving
device (addressed slave) will pull the SDA line low to acknowledge (ACK) the successful transfer
or leave the SDA high to negative acknowledge (NACK).
Data are transmitted in byte format data/buffer. Each data/buffer transfer contains 8 bits. Data is
transferred with the most significant bit MSB/H first. If a receiver can’t receive another complete
byte of data until it has performed some other function, it can hold the clock line SCL LOW to
force the transmitter into a wait state. Data transfer only continues when the receiver is ready for
another byte and releases the data line. If a slave receiver doesn’t acknowledge the slave address
(i.e. it is not able to receive because it is performing some real-time function) the data line must
be left HIGH by the slave. The master can then abort the transfer. A LOW to HIGH transition on

AMLAKU FEB 2/27/2019 88


the SDA line while the SCL line is HIGH is defined as a STOP condition. Each data transfer must
be terminated by the generation of a STOP (SP) condition. The microcontroller sends a start
sequence to start Slave being ready. After sending Slave address being ready, the slave internal
memory For Analog data and if the device enough to transmit the data stop write shift to read cycle
and then send the data again to start the command to begin read cycle if necessary.

AMLAKU FEB 2/27/2019 89


The control unit (CU) is a component of a computer's central processing unit (CPU) that directs the
operation of the processor. It tells the computer's memory, arithmetic and logic unit and input and
output devices how to respond to the instructions that have been sent to the processor.[1]
It directs the operation of the other units by providing timing and control signals. Most computer
resources are managed by the CU. It directs the flow of data between the CPU and the other
devices.
The Control unit (CU) is digital circuitry contained within the processor that coordinates the sequence
of data movements into, out of, and between a processor's many sub-units. The result of these routed
data movements through various digital circuits (sub-units) within the processor produces the
manipulated data expected by a software instruction (loaded earlier, likely from memory). It controls
(conducts) data flow inside the processor and additionally provides several external control signals to
the rest of the computer to further direct data and instructions to/from processor external destinations
(i.e. memory).
More precisely, the Control Unit (CU) is generally a sizable collection of complex digital circuitry
interconnecting and directing the many execution units (i.e. ALU, data buffers, registers) contained
within a CPU. The CU is normally the first CPU unit to accept from an externally stored computer
program, a single instruction (based on the CPU's instruction set). The CU then decodes this
individual instruction into several sequential steps (fetching addresses/data from registers/ memory,
managing execution [i.e. data sent to the ALU or I/O], and storing the resulting data back into
registers/memory) that controls and coordinates the CPU's inner works to properly manipulate the
data. The design of these sequential steps are based on the needs of each instruction and can
range in number of steps, the order of execution, and which units are enabled.
Thus by only using a program of set instructions in memory, the CU will configure all the CPU's data
flows as needed to manipulate the data correctly between instructions. This results in a computer
that could run a complete program and require no human intervention to make hardware changes
between instructions (as had to be done when using only punch cards for computations before
stored programmed computers with CUs were invented). These detailed steps from the CU dictate
which of the CPU's interconnecting hardware control signals to enable/disable or which CPU units
are selected/de-selected and the unit's proper order of execution as required by the instruction's
operation to produce the desired manipulated data. Additionally, the CU's orderly hardware
coordination properly sequences these control signals then configures the many hardware units
comprising the CPU, directing how data should also be moved, changed, and stored outside the
CPU (i.e. memory) according to the instruction's objective.
EEPROM
The EEPROM uses the principle same as that of the UV-EPROM. The electrons which are trapped
in a floating gate will modify the characteristics of the cell, so instead of that logic “0” or logic “1”
will be stored.
EEPROM is the memory device which implements the fewest standards in cell design. Most of
the common cells are composed of two transistors. In this the storage transistor has the floating
gate that will trap the electrons. Apart from that there is an access transistor which is used in the

AMLAKU FEB 2/27/2019 90


operation. In EPROM, cell is erased when electrons are removed from the floating gate, whereas
in EEPROM, cell is erased when electrons are trapped in the floating cell.

Q.What is an accelerometer ?
Ans: An accelerometer is an electro-mechanical device that will measure acceleration forces.
These forces may be static, like the constant force of gravity pulling at your feet, or they could be
dynamic – caused by moving or vibrating the accelerometer.
Q.What is range of an accelerometer?
Ans: Range is the level of acceleration supported by the sensor’s output signal specifications,
typically specified in ±g. This is the greatest amount of acceleration the part can measure and
accurately represent as an output. For example, the output of a ±3g accelerometer is linear with
acceleration up to ±3g. If it is accelerated at 4g, the output may rail.
Q. why you are getting data even while the accelerometer is at rest?
Ans: The reading of the accelerometer when at rest is due to the zero g output (typically 2.5V,
varies depending upon the accelerometer model you have). Consider a sensor in a steady state on
a horizontal surface, will measure 0g in X axis and 0g in Y axis whereas the Z axis will measure
1g, this Z axis value is getting at output of the accelerometer.
Q.What is zero-g offset?
Ans: Zero-g level Offset (Off) describes the deviation of an actual output signal from the ideal
output signal if there is no acceleration present. A sensor in a steady state on a horizontal surface
will measure 0g in X axis and 0g in Y axis whereas the Z axis will measure 1g
Q.Where would you use an accelerometer?
Ans:There are a number of practical applications for accelerometers; accelerometers are used to
measure static acceleration (gravity), tilt of an object, dynamic acceleration, shock to an object,
velocity, orientation and the vibration of an object. Cell phones, computers and washing
machines now contain accelerometers. Other practical applications include: Measuring the
performance of an automobile, measuring the vibration of a machine, measuring the motions of a
bridge, measuring how a package has been handled.

An inertial measurement unit (IMU) is an electronic device that measures and reports a body's specific force,
angular rate, and sometimes the magnetic field surroundings the body, using a combination
of accelerometers and gyroscopes, sometimes also magnetometers. IMUs are typically used to
maneuver aircraft, including unmanned aerial vehicles (UAVs), among many others, and spacecraft,
including satellites and landers. Recent developments allow for the production of IMU-enabled GPS devices.
An IMU allows a GPS receiver to work when GPS-signals are unavailable, such as in tunnels, inside buildings,
or when electronic interference is present.[1] A wireless IMU is known as a WIMU.

AMLAKU FEB 2/27/2019 91

Vous aimerez peut-être aussi