本项目基于STM32F103C8T6单片机设计一款电子水平仪。STM32F103C8T6作为一种性能强大的微控制器,具有较高的计算能力和丰富的外设接口,能够满足项目对实时数据处理和显示控制的需求。该单片机将与MPU6050传感器相结合,利用其内置的加速度计和陀螺仪,实现设备的倾斜角度测量。MPU6050传感器能够高精度地检测设备在三个轴向上的加速度信息,从而计算出设备在左右方向(X轴)和前后方向(Y轴)的倾斜角度。
为了更直观地展示测量结果,本项目选用了一款高分辨率的OLED显示屏。该显示屏可以清晰地呈现实时的角度数据,并且提供了足够的分辨率来实现可视化的图形展示。通过中心点圆圈和滚动小球的设计,用户可以轻松识别设备当前的水平状态。这种可视化的反馈方式不仅更加直观,而且提升了用户体验,特别适用于需要频繁调整水平状态的场景。
随着智能化技术的普及,越来越多的传统工具开始向数字化、智能化方向发展。电子水平仪作为数字工具的一种,其精度、稳定性和用户友好性成为了设计的核心目标。项目通过结合MPU6050传感器的高精度检测与STM32F103C8T6单片机的强大处理能力,提供了一种新型的、可视化的电子水平仪设计方案。这种方案不仅满足了基础的角度测量功能,还通过创新的显示方式,使得用户能够更加高效和精准地进行水平调整和测量。
随着智能化技术的普及,越来越多的传统工具开始向数字化、智能化方向发展。电子水平仪作为数字工具的一种,其精度、稳定性和用户友好性成为了设计的核心目标。项目通过结合MPU6050传感器的高精度检测与STM32F103C8T6单片机的强大处理能力,提供了一种新型的、可视化的电子水平仪设计方案。这种方案不仅满足了基础的角度测量功能,还通过创新的显示方式,使得用户能够更加高效和精准地进行水平调整和测量。
核心的部件:
功能要求:
1. 本地一个SPI协议接口的OLED显示屏,展示当前 设备左右方向的倾斜角度,设备前后方向的倾斜角度。
2. 能够通过一个中心点圆圈+一个滚动的小球展示可视化展示当前的水平状态。
3. 支持按键校准,校准水平仪的参数
硬件要求:
1. 单片机采用STM32F103C8T6
2. 水平状态监测采用MPU6050
3. 显示屏采用高分辨率的OLED显示屏
4. 供电采用可充电锂电池供电,方便便携式携带
5. 一个按钮,进行复位参数校准。
倾斜角度测量
通过 MPU6050 传感器,实时测量设备在 X 轴(左右方向)和 Y 轴(前后方向)的倾斜角度。系统能够精准地计算设备相对于水平的角度,并将其显示在 OLED 屏幕上,提供清晰的数值反馈,帮助用户了解设备当前的水平状态。
实时水平状态可视化显示
在 OLED 显示屏上,采用图形化方式展示设备的水平状态。通过中心圆圈和滚动的小球,用户可以直观地看到设备的水平偏差。小球会根据设备的倾斜方向和角度实时滚动,偏离水平时会向对应方向移动,水平时则停留在圆圈中心,增强用户体验。
数据滤波与角度计算
在数据处理方面,设计了合适的滤波算法,如卡尔曼滤波或简单平均滤波,用于去除传感器数据中的噪声和提高计算的准确性。通过这些算法,系统能够更加稳定和精准地输出设备的倾斜角度。
校准功能
系统提供校准功能,用户可以通过按下按钮来重置设备的零点,校准设备的水平状态。当按下按钮时,设备的当前角度被重置为零,确保在每次使用时都能从准确的水平状态开始。此功能特别适用于设备多次使用后的精度校正,保证每次测量的精度和可靠性。
OLED 显示角度数值
在 OLED 屏幕上,实时显示设备的具体倾斜角度,分别显示 X 轴(左右方向)和 Y 轴(前后方向)的倾斜角度数值。通过直观的数字显示,用户可以准确了解当前设备的水平状态,并在需要时进行调整。
便携性与充电功能
该电子水平仪设计为便携式设备,配备了可充电锂电池,用户可以在不依赖外部电源的情况下,长时间使用设备。通过电池管理模块,支持 USB 充电接口,方便充电并延长使用时间。电池的可充电特性使得设备在户外、工地等环境下更加便捷。
低功耗设计
为了提高设备的使用时长,设计中采用了低功耗模式。STM32F103C8T6 单片机与 MPU6050 传感器均支持低功耗操作,系统在不进行操作时可以进入低功耗待机状态,减少能耗,延长电池使用时间。
用户友好界面
通过简洁直观的 OLED 显示屏界面,用户可以轻松获取设备的实时倾斜角度和水平状态。显示内容清晰、易于阅读,设计了视觉化的反馈方式,使得设备使用者能够快速理解设备的水平偏差并进行相应调整。
整体代码框架
初始化硬件、读取传感器数据、计算倾斜角度并通过 OLED 显示屏显示结果。
#include "stm32f10x.h"
#include "mpu6050.h"
#include "oled.h"
#include "math.h"
// 常量定义
#define ALPHA 0.98 // 互补滤波的权重系数
#define DEG_TO_RAD(x) ((x) * 3.14159265358979 / 180.0)
// 全局变量定义
float pitch = 0.0f; // 俯仰角
float roll = 0.0f; // 滚转角
float pitch_prev = 0.0f; // 上一周期俯仰角
float roll_prev = 0.0f; // 上一周期滚转角
float gyroX = 0.0f, gyroY = 0.0f, gyroZ = 0.0f; // 陀螺仪数据
float accelX = 0.0f, accelY = 0.0f, accelZ = 0.0f; // 加速度计数据
float gyroXrate = 0.0f, gyroYrate = 0.0f, gyroZrate = 0.0f; // 角速度
void delay_ms(uint32_t ms);
void MPU6050_Init(void);
void ReadMPU6050(void);
void UpdateAngles(void);
void Display(void);
int main(void)
{
// 初始化硬件
SystemInit(); // 初始化系统时钟
MPU6050_Init(); // 初始化MPU6050
OLED_Init(); // 初始化OLED显示屏
while (1)
{
// 读取MPU6050传感器数据
ReadMPU6050();
// 更新角度数据
UpdateAngles();
// 显示结果到OLED屏幕
Display();
}
}
// 延时函数
void delay_ms(uint32_t ms)
{
uint32_t i;
for(i = 0; i < ms * 1000; i++)
{
__NOP();
}
}
// 初始化MPU6050传感器
void MPU6050_Init(void)
{
// 假设已经实现了 I2C 初始化和MPU6050的配置
MPU6050_InitI2C(); // I2C初始化
MPU6050_Config(); // 配置MPU6050
}
// 读取MPU6050传感器数据
void ReadMPU6050(void)
{
// 从MPU6050读取加速度和陀螺仪数据
accelX = (float)MPU6050_ReadAccelX(); // 读取X轴加速度数据
accelY = (float)MPU6050_ReadAccelY(); // 读取Y轴加速度数据
accelZ = (float)MPU6050_ReadAccelZ(); // 读取Z轴加速度数据
gyroX = (float)MPU6050_ReadGyroX(); // 读取X轴陀螺仪数据
gyroY = (float)MPU6050_ReadGyroY(); // 读取Y轴陀螺仪数据
gyroZ = (float)MPU6050_ReadGyroZ(); // 读取Z轴陀螺仪数据
// 将陀螺仪的角速度转换为角度变化
gyroXrate = gyroX * DEG_TO_RAD(1.0f); // 角速度转化为角度
gyroYrate = gyroY * DEG_TO_RAD(1.0f);
gyroZrate = gyroZ * DEG_TO_RAD(1.0f);
}
// 更新俯仰角和滚转角
void UpdateAngles(void)
{
// 加速度计计算角度(静态)
float accel_pitch = atan2f(accelX, sqrtf(accelY * accelY + accelZ * accelZ)) * 180.0f / M_PI;
float accel_roll = atan2f(accelY, sqrtf(accelX * accelX + accelZ * accelZ)) * 180.0f / M_PI;
// 陀螺仪计算角度(动态)
pitch += gyroXrate * 0.01f; // 0.01f为采样时间间隔
roll += gyroYrate * 0.01f;
// 互补滤波(数据融合)
pitch = ALPHA * (pitch_prev + gyroXrate * 0.01f) + (1 - ALPHA) * accel_pitch;
roll = ALPHA * (roll_prev + gyroYrate * 0.01f) + (1 - ALPHA) * accel_roll;
// 更新上一周期角度
pitch_prev = pitch;
roll_prev = roll;
}
// 显示数据到OLED屏幕
void Display(void)
{
// 清屏
OLED_Clear();
// 显示俯仰角(pitch)和滚转角(roll)
OLED_ShowString(0, 0, "Pitch: ");
OLED_ShowFloat(60, 0, pitch, 2); // 显示俯仰角,保留2位小数
OLED_ShowString(0, 2, "Roll: ");
OLED_ShowFloat(60, 2, roll, 2); // 显示滚转角,保留2位小数
// 显示中心圆圈与小球可视化(此部分需根据具体显示库实现)
OLED_DrawCircle(64, 32, 30); // 圆心 (64, 32),半径 30
int ball_x = (int)(64 + 30 * sin(DEG_TO_RAD(roll)));
int ball_y = (int)(32 + 30 * sin(DEG_TO_RAD(pitch)));
OLED_DrawCircle(ball_x, ball_y, 3); // 小球,半径3
}
本项目设计并实现了一款基于 STM32F103C8T6 单片机的电子水平仪,采用 MPU6050 传感器进行姿态检测,并通过 OLED 显示屏实时展示设备的俯仰角和滚转角。通过应用互补滤波算法,项目有效地融合了加速度计和陀螺仪的数据,提供了高效、实时且精确的角度估算,满足了设备在动态和静态环境下的姿态检测需求。
本系统设计具有高度的可扩展性,可以根据不同的应用场景进一步优化滤波算法、增加功能如按键校准、低功耗优化等。该电子水平仪不仅在电子设备的水平测量中具有广泛应用,还可以作为嵌入式系统设计中的经典实践,展示了如何结合传感器数据融合、实时显示和用户交互。