·本人是个钓鱼佬,打窝经常不准,又麻烦,所以想到了用无人机打窝实现精准打窝
·适用于所有带有接收机的多旋翼/固定翼的简易投放装置
目录
无人机开发-投放装置-运输-钓鱼打窝
一、主要器件
二、原理
三、代码
四、投放装置接线
五、结果
飞控、PX4
任何带接收机飞控都可以使用不局限于PX4
接收机、futeba
接收机第八通道B/8是电源通道 分别从上到下对应是 信号 VCC GND ,接收机模式1/即默认模式 S.BUS和通道模式
遥控器、futeba
次处理器、stm32f1
uln2003芯片
此芯片可容纳更大的电压相比stm32直接驱动情况下,也可根据情况更换电机
升降电机
投放装置-
简单的利用升降电机来达到开关效果
还有无人机的相关配件这里就不一一写出了
·ULN2003原理介绍
·STM32捕获原理介绍
·原理简单来说就是捕获遥控器通道信号stm32处理后给uln2003芯片 带动电机
main.
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "timer.h"
#include "usart.h"
/*
经过打印测试得知 三个PWM信号时长分别是 2067~2068 1517~1518 967~968
捕获输入口------PA0
*/
extern u8 TIM2CH1_CAPTURE_STA; //输入捕获状态
extern u16 TIM2CH1_CAPTURE_VAL; //输入捕获值
int main(void)
{
u32 temp=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
delay_init(); //延时函数初始化
LED_Init();
uart_init(9600); //9600
TIM2_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数
while(1)
{
delay_ms(10);
TIM_SetCompare1(TIM1,TIM_GetCapture1(TIM1)+1);
if(temp>2060&&temp<2080) //判断输入通道
{
GPIO_SetBits(GPIOA,GPIO_Pin_8);//输出高
GPIO_SetBits(GPIOD,GPIO_Pin_2);
delay_ms(10);
}
else
{
GPIO_ResetBits(GPIOA,GPIO_Pin_8); //输出低电平
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
if(TIM_GetCapture1(TIM1)==300)TIM_SetCompare1(TIM1,0);
if(TIM2CH1_CAPTURE_STA&0X80)//成功捕获到了一次高电平
{
temp=TIM2CH1_CAPTURE_STA&0X3F;
temp*=65536; //溢出时间总和
temp+=TIM2CH1_CAPTURE_VAL; //得到总的高电平时间
printf("当前高电平时间:%d us\r\n",temp); //打印总的高点平时间
TIM2CH1_CAPTURE_STA=0; //开启下一次捕获
}
}
}
定时器中断配置
#include "timer.h"
#include "led.h"
#include "usart.h"
#include "sys.h"
//arr:自动重装值
//psc:时钟预分频数
//定时器2通道1输入捕获配置
TIM_ICInitTypeDef TIM2_ICInitStructure;
void TIM2_Cap_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能TIM2时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0 清除之前设置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_0); //PA0 下拉
//初始化定时器2 TIM2
TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM2输入捕获参数
TIM2_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上
TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM2_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
TIM_ICInit(TIM2, &TIM2_ICInitStructure);
//中断分组初始化
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断
TIM_Cmd(TIM2,ENABLE ); //使能定时器2
}
u8 TIM2CH1_CAPTURE_STA=0; //输入捕获状态
u16 TIM2CH1_CAPTURE_VAL; //输入捕获值
//定时器中断服务程序
void TIM2_IRQHandler(void)
{
if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
TIM2CH1_CAPTURE_VAL=0XFFFF;
}else TIM2CH1_CAPTURE_STA++;
}
}
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//捕获1发生捕获事件
{
if(TIM2CH1_CAPTURE_STA&0X40) //捕获到一个下降沿
{
TIM2CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次上升沿
TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);
TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
}else //还未开始,第一次捕获上升沿
{
TIM2CH1_CAPTURE_STA=0; //清空
TIM2CH1_CAPTURE_VAL=0;
TIM_SetCounter(TIM2,0);
TIM2CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿
TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获
}
}
}
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
}
LED灯初始化
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE); //使能PA,PD端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.8
GPIO_SetBits(GPIOA,GPIO_Pin_8); //PA.8 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PD.2 端口配置, 推挽输出
GPIO_Init(GPIOD, &GPIO_InitStructure); //推挽输出 ,IO口速度为50MHz
GPIO_SetBits(GPIOD,GPIO_Pin_2); //PD.2 输出高
}
stm32 PA0--接收机通道口(需要接电 5V)
接收机B/8 接电源 通道信号口接STM32 PA0
ULN2003 1B接PD2 1C接电机负极
结果完全满足 短距离投放等.
最后建议:无人机起飞全重不要超过7KG也不要在人多的地方飞行.注意重心调试
此文只供学习