垃圾桶项目"/>
感应开关盖垃圾桶项目
项目需求
- 检测靠近时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
- 发生震动时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
- 按下按键时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
项目硬件图
一、sg90舵机介绍及实战
sg90舵机介绍
PWM波的频率不能太高,大约50HZ,即周期=1/频率=1/50=0.02s,20ms左右。
确定周期/频率
如果周期为20ms,则 PSC=7199,ARR=199
角度控制
- 0.5ms-------------0度; 2.5% 对应函数中CCRx为5
- 1.0ms------------45度; 5.0% 对应函数中CCRx为10
- 1.5ms------------90度; 7.5% 对应函数中CCRx为15
- 2.0ms-----------135度; 10.0% 对应函数中CCRx为20
- 2.5ms-----------180度; 12.5% 对应函数中CCRx为25
(0.5/20 = CCRx/ARR) ⇒ (0.5/20 = CCRx/200) ⇒ CCRx = 5
代码如下:
// 在main函数中
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);
while (1)
{
HAL_Delay(1000);
__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 5);
HAL_Delay(1000);
__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 10);
HAL_Delay(1000);
__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 15);
HAL_Delay(1000);
__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 20);
HAL_Delay(1000);
__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 25);
}
二、超声波传感器介绍及实战
超声波传感器介绍
- 怎么让它发送波
Trig ,给Trig端口至少10us的高电平 - 怎么知道它开始发了
Echo信号,由低电平跳转到高电平,表示开始发送波 - 怎么知道接收了返回波
Echo,由高电平跳转回低电平,表示波回来了 - 怎么算时间
Echo引脚维持高电平的时间! - 波发出去的那一下,开始启动定时器
波回来的拿一下,我们开始停止定时器,计算出中间经过多少时间 - 怎么算距离
距离 = 速度 (340m/s)* 时间/2
时序图:
需求:
使用超声波测距,当手离传感器距离小于5cm时,LED1点亮,否则保持不亮状态。
接线:
Trig — PB6
Echo — PB7
LED1 — PB8
- 配置时钟
- 配置定时器
代码如下:
//使用TIM2来做us级延时函数
void TIM2_Delay_us(uint16_t n_us)
{/* 使能定时器2计数 */__HAL_TIM_ENABLE(&htim2);__HAL_TIM_SetCounter(&htim2, 0);while(__HAL_TIM_GetCounter(&htim2) < ((1 * n_us)-1) );/* 关闭定时器2计数 */__HAL_TIM_DISABLE(&htim2);
}// main
int cnt = 0;
float distance = 0;while (1){/* USER CODE END WHILE *///1. Trig ,给Trig端口至少10us的高电平HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);TIM2_Delay_us(20);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);//2. echo由低电平跳转到高电平,表示开始发送波//波发出去的那一下,开始启动定时器 while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_RESET);HAL_TIM_Base_Start(&htim2);HAL_TIM_Base_Stop(&htim2);//3. 由高电平跳转回低电平,表示波回来了//波回来的那一下,我们开始停止定时器while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET);HAL_TIM_Base_Stop(&htim2);//4. 计算出中间经过多少时间cnt = __HAL_TIM_GetCounter(&htim2);//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)// * 0.000001 => us -> ms -> s// *100 => m => cmdistance = cnt * 340/2 * 0.000001 * 100;if(distance < 5){HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);}else{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);}//每500毫秒测试一次距离HAL_Delay(500);/* USER CODE BEGIN 3 */}
三、汇总实现感应开关盖垃圾桶项目
项目设计
超声波模块:
Trig – PB6
Echo – PB7
sg90舵机:
PWM – PB9
按键:
KEY1 – PA0
LED灯:
LED1 – PB8.
中断法
震动传感器:
D0 – PB5
VCC – 5V
蜂鸣器:
IO – PB4
VCC – 3V3
代码如下:
//使用TIM2来做us级延时函数
void TIM2_Delay_us(uint16_t n_us)
{/* 使能定时器2计数 */__HAL_TIM_ENABLE(&htim2);__HAL_TIM_SetCounter(&htim2, 0);while(__HAL_TIM_GetCounter(&htim2) < ((1 * n_us)-1) );/* 关闭定时器2计数 */__HAL_TIM_DISABLE(&htim2);
}// 超声波测距
double get_distance()
{int cnt = 0;//1. Trig ,给Trig端口至少10us的高电平HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);TIM2_Delay_us(20);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);//2. echo由低电平跳转到高电平,表示开始发送波//波发出去的那一下,开始启动定时器 while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_RESET);HAL_TIM_Base_Start(&htim2);__HAL_TIM_SetCounter(&htim2,0);//3. 由高电平跳转回低电平,表示波回来了//波回来的那一下,我们开始停止定时器while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET);HAL_TIM_Base_Stop(&htim2);//4. 计算出中间经过多少时间cnt = __HAL_TIM_GetCounter(&htim2);//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)// * 0.000001 => us -> ms -> s// *100 => m => cmreturn cnt * 340/2 * 0.000001 * 100;
}// 开灯
void openStatusLight()
{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
}// 关灯
void closeStatusLight()
{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
}// 初始化舵机
void initSG90_0()
{// 启动定时器HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4);// 将舵机置为0度__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5);
}// 开盖
void openDusbin()
{// 将舵机置为90度__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 15);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);HAL_Delay(100);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);HAL_Delay(2000);
}// 关盖
void closeDusbin()
{// 将舵机置为0度__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5);flag = CLOSE;HAL_Delay(150);
}// 重写中断函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin == GPIO_PIN_0 || GPIO_Pin == GPIO_PIN_5){// 按键 || 震动传感器if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET || HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) == GPIO_PIN_RESET){openDusbin();openStatusLight();}}
}// main
float distance;
/* USER CODE BEGIN 2 */initSG90_0();HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
/* USER CODE END 2 *
while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */// 超声波测距distance = get_distance();if(distance < 10){// 点亮LED1openStatusLight();// 开盖openDusbin();}else{// 熄灭LED1closeStatusLight();// 关盖closeDusbin();}}
更多推荐
感应开关盖垃圾桶项目
发布评论