In the applications of smart homes and the Internet of Things, gesture control is an interactive method that provides a great user experience—no need to press switches, just wave your hand to control the lights.The MPU6050 is a six-axis sensor that integrates a three-axis accelerometer and a three-axis gyroscope, which can obtain the motion posture of an object in real-time. By analyzing the changes in acceleration and angular velocity, actions such as waving can be recognized, achieving “contactless” control.
Application Scenarios
-
Smart lighting control
-
Contactless exhibit lighting in museums and exhibition halls
-
Touchless operation for the elderly or people with limited mobility
System Composition and Principles
Hardware Composition
-
Main Control: STM32F103C8T6 (or other STM32 series)
-
Sensor: MPU6050 six-axis sensor module
-
Lighting: LED (different colors indicate different states)
Hardware Connection (I²C Interface)
| STM32 Pin | MPU6050 Pin |
|---|---|
| PB6 (SCL) | SCL |
| PB7 (SDA) | SDA |
| 3.3V | VCC |
| GND | GND |
Working Principle
-
Data Acquisition: Obtain acceleration and gyroscope data from the MPU6050 via I²C.
-
Data Processing: Analyze acceleration changes to determine if a waving action has occurred.
-
Control Output: If a waving action is recognized, switch the LED state (on/off).
Code Implementation (STM32 Standard Library)
MPU6050 Driver File
#ifndef __MPU6050_H
#define __MPU6050_H
#include "stm32f10x.h"
#define MPU6050_ADDR 0x68 // 7-bit address
typedef struct {
int16_t ax, ay, az;
int16_t gx, gy, gz;
} MPU6050_Data;
void MPU6050_Init(void);
void MPU6050_ReadData(MPU6050_Data *data);
#endif
#ifndef __MPU6050_H
#define __MPU6050_H
#include "stm32f10x.h"
#define MPU6050_ADDR 0x68 // 7-bit address
typedef struct {
int16_t ax, ay, az;
int16_t gx, gy, gz;
} MPU6050_Data;
void MPU6050_Init(void);
void MPU6050_ReadData(MPU6050_Data *data);
#endifCode Explanation
#define MPU6050_ADDR 0x68
This is the I²C address of the MPU6050, equivalent to a “house number” that the STM32 uses to locate this sensor.
typedef struct {
int16_t ax, ay, az;
int16_t gx, gy, gz;
} MPU6050_Data;
This defines a data structure to store the values measured by the sensor:
ax, ay, az → acceleration in three directions
gx, gy, gz → angular velocity in three directions (rate of rotation)
void MPU6050_Init(void);
void MPU6050_ReadData(MPU6050_Data *data);
Declares two functions: one to initialize the sensor and one to read data.
mpu6050.c
#include "mpu6050.h"
#include "i2c.h"
void MPU6050_Init(void) {
I2C_WriteReg(MPU6050_ADDR, 0x6B, 0x00); // Wake up from sleep mode
}
void MPU6050_ReadData(MPU6050_Data *data) {
uint8_t buf[14];
I2C_ReadMulti(MPU6050_ADDR, 0x3B, buf, 14);
data->ax = (buf[0] << 8) | buf[1];
data->ay = (buf[2] << 8) | buf[3];
data->az = (buf[4] << 8) | buf[5];
data->gx = (buf[8] << 8) | buf[9];
data->gy = (buf[10] << 8) | buf[11];
data->gz = (buf[12] << 8) | buf[13];
}
Code Explanation
void MPU6050_Init(void) {
I2C_WriteReg(MPU6050_ADDR, 0x6B, 0x00); // Wake up from sleep mode
}
The MPU6050 is in sleep mode by default (power-saving mode). Writing register 0x6B to 0x00 wakes it up to work.
void MPU6050_ReadData(MPU6050_Data *data) {
uint8_t buf[14];
I2C_ReadMulti(MPU6050_ADDR, 0x3B, buf, 14);
Starting from register 0x3B, read 14 bytes at once. The data includes:
6 bytes: acceleration (X, Y, Z)
2 bytes: temperature (not used here)
6 bytes: gyroscope (X, Y, Z)
data->ax = (buf[0] << 8) | buf[1];
Combines the high 8 bits and low 8 bits into a 16-bit integer (the sensor outputs 16-bit raw values).
The same method is used to combine ay, az, gx, gy, and gz.
Main Program
#include "stm32f10x.h"
#include "mpu6050.h"
#include "delay.h"
MPU6050_Data mpu_data;
uint8_t led_state = 0;
void LED_Init(void) {
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
void LED_Toggle(void) {
if (led_state) {
GPIO_SetBits(GPIOC, GPIO_Pin_13);
led_state = 0;
} else {
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
led_state = 1;
}}
int main(void) {
delay_init();
I2C_Init_Config();
MPU6050_Init();
LED_Init();
while (1) {
MPU6050_ReadData(&mpu_data);
// Simple gesture recognition: detect changes in X-axis acceleration
if (mpu_data.ax > 15000 || mpu_data.ax < -15000) {
LED_Toggle();
delay_ms(500); // Debounce
}
}}