STM32传感器模块编程实践(四)舵机+MPU6050陀螺仪模块融合云台模型

news2024/11/25 7:16:29

文章目录

    • 一.概要
    • 二.实验模型原理
      • 1.硬件连接原理框图
      • 2.控制原理
    • 三.实验模型控制流程
    • 四.云台模型程序
    • 五.实验效果视频
    • 六.小结

一.概要

云台主要用来固定摄像头。准确地说,云台是一种可以多角度调节的支撑设备,类似于人的脖子可以支撑着脑袋,并通过转动来调节视野。
云台电机可以被用于相机、无人机和摄像机等设备上,以实现平滑稳定的拍摄效果,无人机在飞行过程中,尤其是遇到风力干扰或进行复杂飞行动作时,机身容易产生震动和晃动。而云台的存在可以有效地隔离这些抖动,保证挂载在上面的相机或摄像头能够拍摄出稳定、清晰的画面。这对于航拍、侦察、监测等需要高质量影像的任务至关重要。

本文就做了一个简单的云台模型,采用STM32F103C8T6单片机+舵机+陀螺仪模块,实现一个简易云台,随着陀螺仪模块倾斜多少度,舵机就转动到多少度。

在这里插入图片描述

二.实验模型原理

1.硬件连接原理框图

在这里插入图片描述

模型主要分为三部分:主芯片单元,倾斜测量单元,执行动作单元。

在这里插入图片描述

图中主控芯片为STM32F103C8T6单片机,倾斜测量为MPU6050陀螺仪模块,执行传感器为SG90舵机。

信号线连接:MPU6050陀螺仪模块信号脚SCL脚接到单片机的PB10脚,SDA脚接到单片机的PB11脚。SG90(180度)舵机的信号脚橙色线接到单片机的PA6脚。

2.控制原理

陀螺仪模块测量模块跟水平方向的夹角,如果大于0度,单片机驱动舵机也转到响应的角度,如果陀螺仪模块的倾斜角度没有变化,舵机角度保持不变,如果陀螺仪模块回到0度,舵机也相应转到0度。

陀螺仪模块测倾角原理:

MPU6050含3轴的加速度与3轴的陀螺仪,我们只要取单轴的加速度值,就能计算在某一方向上的倾斜角度。
在这里插入图片描述

舵机控制原理:
SG90舵机,首先,控制引脚是三根线,分别是GND(棕色)、VCC(红色)、PWM(黄色),控制方式也是一样的PWM时序,具体的方法如下:

(1)采用PWM控制的方式来进行舵机的旋转
(2)舵机的控制需要MCU产生一个20ms周期的脉冲信号,以0.5ms到2.5ms的高电平来控制舵机的角度。
(3)高电平时间跟舵机旋转的角度对应关系:
0.5ms-------------0度;对应函数中占空比为2.5%
1.0ms------------45度;对应函数中占空比为5.0%
1.5ms------------90度;对应函数中占空比为7.5%
2.0ms-----------135度;对应函数中占空比为10.0%
2.5ms-----------180度;对应函数中占空比为12.5%

三.实验模型控制流程

1.单片机先通过IIC口读取陀螺仪的角度。

2.计算陀螺仪的倾斜角度,如果有倾斜,驱动PA6引脚输出20ms周期控制舵机旋转到响应的角度。

3.如果倾斜角度回到0,控制舵机旋转到0度。

四.云台模型程序

板子与MPU6050陀螺仪模块用杜邦线连接:
板子G-----模块GND
板子3.3---模块VCC
板子B10---模块SCL
板子B11---模块SDA

板子与SG90舵机(180度舵机)用杜邦线连接:
板子5V----红色线
板子A6----橙色线
板子G-----棕色线

USB线需要接小系统板,给板子供5V。
在这里插入图片描述

打开STM32CubeMX软件,新建工程
在这里插入图片描述
Part Number处输入STM32F103C8,再双击就创建新的工程
在这里插入图片描述
配置下载口引脚
在这里插入图片描述
配置外部晶振引脚
在这里插入图片描述
配置系统主频
在这里插入图片描述

配置IIC引脚
在这里插入图片描述

配置PWM输出,定时器3通道1,周期20ms
在这里插入图片描述

配置工程文件名,保存路径,KEIL5工程输出方式
在这里插入图片描述
生成工程
在这里插入图片描述
用Keil5打开工程
在这里插入图片描述

添加代码

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

主要程序:

short Accel[3];
short Gyro [3];
short Temp;
float AccelData[3];//单位g
float GyroData[3];//单位mdps
/* USER CODE END PFP */


/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint16_t Pluse_Time=1000;//1毫秒脉冲,单位是us

typedef struct Angle
{
    double X_Angle;
    double Y_Angle;
    double Z_Angle;
    
} MPU6050_Angle;
MPU6050_Angle data;
double Angle_Old;
/****************************************************************************** 
* 函数介绍: 计算 x, y, z 三轴的倾角 
* 输入参数: 无 
* 输出参数: data:角度结构体 
* 返回值 : 无 
******************************************************************************/
void MPU6050_Get_Angle(MPU6050_Angle *data)
{   
    /* 计算x, y, z 轴倾角,返回弧度值*/
    data->X_Angle = acos(AccelData[0]/1000);
    data->Y_Angle = acos(AccelData[1]/1000);
    data->Z_Angle = acos(AccelData[2]/1000);

    /* 弧度值转换为角度值 */
    data->X_Angle = data->X_Angle * 57.29577;
    data->Y_Angle = data->Y_Angle * 57.29577;
    data->Z_Angle = data->Z_Angle * 57.29577;
} 

/**
  * 函数功能: 读取MPU6050的加速度数据
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */ 
void MPU6050ReadAcc(short *accData)
{
    uint8_t buf[6];
		MPU6050_ReadData(MPU6050_ACC_OUT, &buf[0], 6);

	
    accData[0] = (buf[0] << 8) | buf[1];
    accData[1] = (buf[2] << 8) | buf[3];
    accData[2] = (buf[4] << 8) | buf[5];
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C2_Init();//IIC初始化
  MX_TIM3_Init();//配置定时器,20ms周期PWM波,初始化高电平是1ms
	
	MPU6050_Init();//MPU6050初始化配置,中断使能配置
	if(MPU6050ReadID() == 0)//读取MPU6050 ID
	{	
	  while(1);
  }
  /* USER CODE BEGIN 2 */

   if (HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1) != HAL_OK)//PA6脚PWM输出
  {
    /* PWM generation Error */
    while(1);
  }
	
	Pluse_Time=500;//0.5ms高电平脉冲,用于控制舵机转到0度
	HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);//PWM停止输出
	MX_TIM3_Init();//重新初始化配置PWM波
	if (HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1) != HAL_OK)//PA6脚PWM输出
	{
	/* PWM generation Error */
	while(1);
	}
	HAL_Delay(300);//等待300ms
	HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);//PWM停止输出	

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		MPU6050ReadAcc(Accel);//读取加速度数据
		for( int i=0;i<3;i++)
		{
		if(Accel[i]>=0)
		{
			AccelData[i]=Accel[i]*2000/32768;//转换成单位mg
		}else
		{
			AccelData[i]=-(-Accel[i]+1)*2000/32768;
		}	
		}	
	
		MPU6050_Get_Angle(&data);//计算倾角,通过X_Angle来控制舵机转角
	if(abs((int)Angle_Old-(int)data.X_Angle)>3)//当前角度与存储的角度差值大于3度,进行动作,主要是防止手抖动
	{	

			//以180度角度伺服为例,那么对应的控制关系是这样的(t为高电平时间):
			//t=0.5ms(占空比2.5%)---------0°;
			//t=1.0ms(占空比5%)-----------45°;
			//t=1.5ms(占空比7.5%)---------90°;
			//t=2.0ms(占空比10%)---------135°;
			//t=2.5ms(占空比12.5%)-------180°;		
			Pluse_Time=500+((float)data.X_Angle/18)*200;//高电平时间=0.5ms+(角度/180°)×2ms
			HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);//PWM停止输出
			MX_TIM3_Init();//重新初始化配置PWM波
			if (HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1) != HAL_OK)//PA6脚PWM输出
			{
			/* PWM generation Error */
			while(1);
			}
			HAL_Delay(50);
			HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);//PWM停止输出	
  }
	Angle_Old=data.X_Angle;//把目前读到的角度值存下来,以便下次比较使用

  }
  /* USER CODE END 3 */
}

void MX_TIM3_Init(void)
{
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 71;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 19999;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = Pluse_Time;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_TIM_MspPostInit(&htim3);

}

五.实验效果视频

演示效果

六.小结

融合了舵机,陀螺仪模块的控制,对STM32的单片机的定时器PWM功能,IIC通讯,陀螺仪的产品有更深的了解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2212206.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++STL--------vector

文章目录 一、vector常用接口介绍1、initializer_list2、接口有很多类似3、typeid(类型).name()4、find() 函数5、内置类型构造 二、vector()常用接口模拟实现 截图来源网站&#xff1a;https://legacy.cplusplus.com/reference/vector/vector/ 一、vector常用接口介绍 是一个…

架构设计笔记-8-系统质量属性与架构评估

目录 知识要点 案例分析 1.质量属性 2.非功能性需求 3.质量属性效用树&#xff0c;风险点/敏感点/权衡点&#xff0c;设计策略 4.管道过滤器/仓库风格&#xff0c;质量属性 5.质量属性效用树 6.质量属性 7.质量属性效用树 8.质量属性效用树&#xff0c;风险点/敏感点…

架构师备考-背诵精华(架构开发方法)

软件架构风格 类型 子类型 说明 数据流风格 批处理 每个处理步骤是一个单独的程序&#xff0c;每一步必须在前一步结束后才能开始&#xff0c;而且数据必须是完整的&#xff0c;以整体的方式传递。 管道过滤器 把系统分解为几个序贯的处理步骤&#xff0c;这些步骤之间…

目标检测系统【环境详细配置过程】(CPU版本)

&#xff08;如果你使用的是笔记本电脑&#xff0c;没有比较好的GPU&#xff0c;可以配置CPU运行环境&#xff09; 链接&#xff1a;上百种【基于YOLOv8/v10/v11的目标检测系统】目录&#xff08;pythonpyside6界面系统源码可训练的数据集也完成的训练模型&#xff09; 1.安装…

leetcode热题100.编辑距离

题目 72. 编辑距离 - 力扣&#xff08;LeetCode&#xff09; 给你两个单词 word1 和 word2&#xff0c; 请返回将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作&#xff1a; 插入一个字符删除一个字符替换一个字符 示例 1&#xff1a; 输…

Spring Web MVC快速入门:掌握Java Web开发基础

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f439;今日诗词:桃李春风一杯酒&#xff0c;江湖夜雨十年灯&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4…

基于Arduino的红外遥控智能小车实现方法

一、简介 使用红外遥控器实现智能小车前进、后退、左转、右转、停止运动五种动作。 二、控制方法 使用红外遥控器遥控智能小车运行之前&#xff0c;需要使用红外线接收电路来读取红外线遥控器的按键代码&#xff0c;将获取的按键代码定义为控制智能小车前进、后退、左转、右…

Web Socket 使用详解

在信息爆炸的时代&#xff0c;用户对网页的期待早已超越了静态内容的展示。实时聊天、股票报价、协同编辑等功能的实现&#xff0c;都离不开服务器与客户端之间持续、高效的数据交互。传统的HTTP请求-响应模型难以满足这种需求&#xff0c;而WebSocket的出现&#xff0c;为构建…

个人健康系统|个人健康数据管理系统|基于小程序+java的个人健康数据管理系统设计与实现(源码+数据库+文档)

个人健康数据管理系统 目录 基于小程序java的个人健康数据管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道师…

C语言刷题 LeetCode 删除单链表的重复节点 双指针法

题目要求 链表结构&#xff1a;题目中提到的是未排序的链表&#xff0c;链表是由一系列节点组成的&#xff0c;每个节点包含一个值&#xff08;数据&#xff09;和一个指向下一个节点的指针。去重&#xff1a;我们需要遍历链表&#xff0c;删除所有重复的节点&#xff0c;只保…

开源新生活,社区齐乐活:COSCon'24 社区合作和开源集市招募中,诚邀广大社区参与!...

一年一度的开源盛会&#xff0c;COSCon24第九届中国开源年会暨开源社10周年嘉年华&#xff0c;将于11月2-3日&#xff0c;在北京•中关村国家自主创新示范区展示中心召开&#xff01;本次大会的主题是&#xff1a;「Open Source&#xff0c;Open Life | 开源新生活」&#xff0…

react antd redux 全局状态管理 解决修改菜单状态 同步刷新左侧菜单

npm i react-redux1.src新建两个文件 globalState.js 全局状态定义 store.js 全局存储定义 2.globalState.js import { createSlice } from "reduxjs/toolkit";export const globalState createSlice({name: "globalState",initialState: { data: {} },r…

Qt 学习第 天:QPainter类

一、先创建一个widget窗口 二、包含头文件 #include <QPainter> #include <QFont> 三、在widget.h中声明paintEvent函数 使用画家类在窗口中画图, 操作必须在paintEvent函数中完成 #ifndef WIDGET_H #define WIDGET_H#include <QWidget>namespace Ui { cla…

Spring Boot框架下的知识管理自动化

3系统分析 3.1可行性分析 通过对本知识管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本知识管理系统采用JAVA作为开发语言&#xff0c;Spring Boot框…

C语言题目练习3

这一篇博客也来看看和链表有关的题目~ 反转链表 反转链表&#xff1a; https://leetcode.cn/problems/reverse-linked-list/description/ 这个题目已经十分清晰了&#xff0c;那我们可以怎么做呢&#xff1f; 结合前面单链表的知识点&#xff0c;我们很容易可以想到第一个思路…

RTC -

RTC 目录 RTC 回顾 RTC 如何实现RTC制作一个时钟日历 代码编写 rtc.c完整代码 模块开发的步骤&#xff1a; 1、找文档 2、 在文档里面找通信方式&#xff0c;通信过程&#xff08;协议&#xff09; 3、代码> -- 前面学的是模块的开发&#xff0c;串口类&#xff0c;I…

决策树和集成学习的概念以及部分推导

一、决策树 1、概述 决策树是一种树形结构&#xff0c;树中每个内部节点表示一个特征上的判断&#xff0c;每个分支代表一个判断结果的输出&#xff0c;每个叶子节点代表一种分类结果 决策树的建立过程&#xff1a; 特征选择&#xff1a;选择有较强分类能力的特征决策树生成…

【论文阅读】SRCNN

学习资料 论文题目&#xff1a;Learning a Deep Convolutional Network for Image Super-Resolution&#xff08;学习深度卷积网络用于图像超分辨率&#xff09;论文地址&#xff1a;link.springer.com/content/pdf/10.1007/978-3-319-10593-2_13.pdf代码&#xff1a;作者提出的…

Java 一维数组作为函数参数

//一维数组的引用 #define SIZE 5 void input(int a[], int len); void output(int a[], int len);//函数的声明 int main(void) { int i 0; int arr[SIZE] { 86,85,85,896,45 };//同理五个数据只是偶然&#xff0c;可能会更多 //输入 input(arr, SIZE); …

目标检测系统操作说明【用户使用指南】(python+pyside6界面+系统源码+可训练的数据集+也完成的训练模型)

1.链接&#xff1a;上百种【基于YOLOv8/v10/v11的目标检测系统】目录&#xff08;pythonpyside6界面系统源码可训练的数据集也完成的训练模型&#xff09; 2.目标检测系统【环境搭建过程】&#xff08;GPU版本&#xff09; 3.目标检测系统【环境详细配置过程】&#xff08;CP…