赞
踩
做这个项目之前先要明白本次的任务和要求是什么,下面是本次项目的任务和要求
- #include "encoder.h"
- #include "stm32f4xx.h"
- #include "pwm.h"
- #include "pid.h"
- #include"usart.h"
- int readshuduzuo,readshuduyou;
- extern int y,x,biaozhi,shu,r,v,mubiaoshudu,a1,zuikuai1,zuikuai2,c1,w,da;
- extern float Velocity_Kp,Velocity_Ki,Vertical_Kp,Vertical_Kd,Velocity_Kd;
- PA0,1串口无法拉高
- 编码器左 tim4 ab相:b67
- int tiaochu=0,c=0;
- void Encoder_TIM4_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB ,ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //TIM4_CH1 TIM4_CH2
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_TIM4);
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_TIM4);
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
-
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInitStructure.TIM_Period = 0xffff;
- TIM_TimeBaseInitStructure.TIM_Prescaler = 0x00;
- TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
-
- //编码器模式
- TIM_ICInitTypeDef TIM_ICInitStructure;
- TIM_EncoderInterfaceConfig(TIM4,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//TIM_ICPolarity_Rising捕获发生在ICx的上升沿
- TIM_ICStructInit(&TIM_ICInitStructure); //将结构体中的内容缺省输入
- TIM_ICInitStructure.TIM_ICFilter = 0;//滤波器值
- TIM_ICInit(TIM4, &TIM_ICInitStructure);
-
- TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
-
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
- NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
- NVIC_Init(&NVIC_InitStructure);
-
- TIM_SetCounter(TIM4, 8400);
- TIM_Cmd(TIM4, ENABLE);
- }
- void TIM4_IRQHandler(void)
- {
- if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET) //溢出中断
- {
-
- }
- TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清除中断标志位
- }
-
-
-
-
-
-
-
- //编码器右 tim3 ab相:a67
-
-
-
-
- void Encoder_TIM3_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA ,ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //TIM4_CH1 TIM4_CH2
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3);
- GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_TIM3);
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
-
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInitStructure.TIM_Period = 0xffff;
- TIM_TimeBaseInitStructure.TIM_Prescaler = 0x00;
- TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
-
- //编码器模式
- TIM_ICInitTypeDef TIM_ICInitStructure;
- TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//TIM_ICPolarity_Rising捕获发生在ICx的上升沿
- TIM_ICStructInit(&TIM_ICInitStructure); //将结构体中的内容缺省输入
- TIM_ICInitStructure.TIM_ICFilter = 0;//滤波器值
- TIM_ICInit(TIM3, &TIM_ICInitStructure);
-
- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
-
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
- NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
- NVIC_Init(&NVIC_InitStructure);
-
- TIM_SetCounter(TIM3, 0);
- TIM_Cmd(TIM3, ENABLE);
- }
- void TIM3_IRQHandler(void)
- {
- if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
- {
-
- }
- TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
- }
-
-
- void TIM2_Int_Init(u16 arr,u16 psc)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); ///使能TIM3时钟
-
- TIM_TimeBaseInitStructure.TIM_Period = arr; //自动重装载值
- TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定时器分频
- TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
- TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
-
- TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//初始化TIM3
-
- TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //允许定时器3更新中断
- TIM_Cmd(TIM2,ENABLE); //使能定时器3
-
- NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn; //定时器3中断
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x03; //抢占优先级1
- NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
- NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
- NVIC_Init(&NVIC_InitStructure);
-
- }
- void TIM2_IRQHandler(void)//定时(10ms)读取编码器值(即速度),超声波测距
- {
- if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET) //溢出中断
- { shu=shu+1;
- readshuduzuo=(int16_t)TIM_GetCounter(TIM4);
- readshuduyou=(int16_t)TIM_GetCounter(TIM3);
- TIM_SetCounter(TIM4,0);
- TIM_SetCounter(TIM3,0);
- if(biaozhi==1&&tiaochu==0){
- v=Velocity(mubiaoshudu,readshuduzuo,readshuduyou);
- r=Vertical(80,y);
- Set_Pwm(r+v,-r+v);
- }
-
-
- //1停止
- if (a1==1 && x==2 && biaozhi==1)
- { tiaochu=1;
- //Set_Pwm(0,0);
-
- Velocity_Ki=0;
- v=Velocity(0,readshuduzuo,readshuduyou);
- Set_Pwm(v,v);
- if(readshuduzuo==0 ||readshuduyou==0)
- {
- Set_Pwm(0,0);
- }
- }
-
-
- //2停止
- if (a1==2 && x==4 && biaozhi==1&&da==0)
- { tiaochu=1;
- Set_Pwm(0,0);
- }
- //3停
-
- if (a1==3 && w==5 && biaozhi==1&&da==1)
- {Serial_SendByte(1);
- c=1;
- tiaochu=1;
- Vertical_Kp=0;
- Vertical_Kd=0;
- Set_Pwm(0,0);
- }
-
- if (a1==0&&x==1&&biaozhi==1&&da==0)
- {Serial_SendByte(1);
- c1=1;
- tiaochu=1;
- Vertical_Kp=0;
- Vertical_Kd=0;
- Velocity_Kp=-20000;
-
- Velocity_Ki=0;
- v=Velocity(0,readshuduzuo,readshuduyou);
- Set_Pwm(v,v);
- }
-
-
-
- }
-
-
-
- TIM_ClearITPendingBit(TIM2,TIM_IT_Update); //清除中断标志位
- }
-
-
-
-
-
-
-
pid的调整:
- #include "pid.h"
- #include "pwm.h"
- #include "encoder.h"
- extern int readshuduzuo,readshuduyou,x,y,w,h,Cx,Cy,Ch,Cw;
-
- float
- Vertical_Kp=0, //shudu20 12(0.3m/s) shudu30 20(0.5m/s) shudu40 20 shudu45 30 shudu50 30 shudu55 45 75
- Vertical_Ki=0,
- Vertical_Kd=0 // 5 100 220 350 530 770 1600
- ;
- float
- Velocity_Kp=-3000, //3000
- Velocity_Ki=1, //1
- Velocity_Kd=150 //150
- ;
-
- //角度环
- int Vertical(float Med,float Angle)
- {static float error,error_last;
- int PWM_out;
- error=Angle-Med;
-
- PWM_out = Vertical_Kp*error+Vertical_Kd*(error-error_last);
- error_last=error;
- return PWM_out;
- }
-
- //位置环
- int Velocity(int Target,int speedleft,int speedright)
- {
-
- //定义静态变量,保存在静态存储器,使得变量不丢掉
- static int PWM_out,Encoder_Err,Encoder_S,EnC_Err_Lowout,EnC_Err_Lowout_last,err_last;
- float a=0.7;
-
- //1.计算速度偏差
- //舍去误差--能够让速度为0的角度,就是机械中值
- Encoder_Err = (speedright+speedleft)/2-Target;
-
- //2.对速度误差进行低通滤波
- //Low_out=(1-a)*Ek+a*Low_out_Last
- EnC_Err_Lowout = (1-a)*Encoder_Err+a*EnC_Err_Lowout_last; //使波形更加平滑,滤除高频干扰,防止速度突变
-
- //3.对速度偏差积分出位移
- Encoder_S += EnC_Err_Lowout;
-
- //4.积分限幅
- Encoder_S=Encoder_S>1000?1000 : (Encoder_S<(-1000)?(-1000) : Encoder_S); //10000
-
- //5.速度环控制输出
- PWM_out=Velocity_Kp*EnC_Err_Lowout+Velocity_Ki*Encoder_S+Velocity_Kd*(Encoder_Err-err_last);
- err_last=Encoder_Err;
- return PWM_out;
-
- }
-
主函数部分:
- #include "stm32f4xx.h"
- #include "usart.h"
- #include "delay.h"
- #include "oled.h"
- #include "pwm.h"
- #include "led.h"
- #include "encoder.h"
- #include "pid.h"
- #include "openmv.h"
- extern int readshuduzuo,readshuduyou,shu;
- extern int x,y,w,h,biaozhi,c;
- extern float Vertical_Kp,Vertical_Kd,Velocity_Ki,Velocity_Kd,Velocity_Kp;
- int shu=0;
- int v=0,r=0,c1=0;
- int mubiaoshudu=0;
- int a1=0,zuikuai1=0,zuikuai2=0;
- int b1=0,b2=0,b3=0,b4=0,da=0;
- int main(void)
- { u8 key;
- uart_init(115200);
- usart6_init(115200);
- USART_Cmd(USART6,ENABLE);
-
- delay_init(168);
-
- TIM14_PWM_Init(8400,42);
- TIM13_PWM_Init(8400,42);
-
- SERVE_Init();
- SERVE_Init1();
-
- Encoder_TIM4_Init();
- Encoder_TIM3_Init();
-
- TIM2_Int_Init(8400-1,50-1);
- OLED_Init();
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- TIM_Cmd(TIM13, ENABLE);
- TIM_Cmd(TIM14, ENABLE);
-
- KEY_Init();
-
- int bex=0;
-
- while(1){
- OLED_ShowSNum(16,0,readshuduyou,4,16,1);
- OLED_ShowSNum(32,0,readshuduzuo,4,16,1);
- OLED_ShowSNum(0,16,y,4,16,1);
- OLED_ShowSNum(0,48,key,4,16,1);
- OLED_ShowSNum(16,48,w,4,16,1);
- OLED_ShowSNum(0,32,x,4,16,1);
- OLED_ShowSNum(16,32,a1,4,16,1);
- OLED_Refresh();
-
-
- key=KEY_Scan(0); //得到键值
- if(key)
- {
- switch(key)
- {
- case WKUP_PRES:
- mubiaoshudu=30;
- Vertical_Kp=20;
- Vertical_Kd=100;
- a1=3;
- da=1;
- break;
- case KEY0_PRES: //控制LED0翻转
- mubiaoshudu=20;
- Velocity_Kd=0;
- Velocity_Kp=-2000;
- Vertical_Kp=15;
- Vertical_Kd=0;
-
- a1=1;
-
- break;
-
- case KEY1_PRES: //控制LED1翻转
- mubiaoshudu=30;
- Vertical_Kp=20;
- Vertical_Kd=100;
- a1=2;
- break;
- }
- }
- if(a1==1&&biaozhi==1&&b1==0)
- { Serial_SendByte(4);
- b1=1;}
-
- if(a1==2&&biaozhi==1&&b2==0)
- { Serial_SendByte(5);
- b2=1;}
-
- if(a1==3&&biaozhi==1&&c==0&&b3==0)
- { delay_ms(500);
- Serial_SendByte(6);
- b3=1;}
-
- if (a1==3&&h==1&&bex==0)
- { delay_ms(300);
- mubiaoshudu=51;
- Vertical_Kp=40;
- Vertical_Kd=530;
- bex=1;
- }
- if(a1==3&&h==2)
- {
- delay_ms(350);
- mubiaoshudu=30;
- Vertical_Kp=20;
- Vertical_Kd=100;
-
- }
-
- if(a1==0&&biaozhi==1&&c1==0&&b4==0)
- { mubiaoshudu=51;
- Vertical_Kp=40;
- Vertical_Kd=530;
- delay_ms(50);
- Serial_SendByte(7);
- b4==1;
- }
-
- }
- }
-
-
openmv部分:
- import sensor, image, time,math,pyb
- from pyb import UART,LED
- import json
- import ustruct
- import pyb
- #THRESHOLD = (91, 3) #二分化系数
- ROI=(2,84,157,26)
- BINARY_VISIBLE = True
- sensor.reset()
- sensor.set_vflip(True) #垂直翻转
- sensor.set_hmirror(True) #水平翻转
- sensor.set_pixformat(sensor.RGB565) #彩色
- #sensor.set_pixformat(sensor.GRAYSCALE) #黑白
- sensor.set_framesize(sensor.QQVGA)
- sensor.skip_frames(time = 2000)
- sensor.set_auto_gain(False) # must be turned off for color tracking
- sensor.set_auto_whitebal(False) # must be turned off for color tracking
- RED_threshold=(6, 19, -39, 22, -38, 90)
- clock = time.clock()
- ROIXIN=(2,84,157,26)
- ROITING=(1,1,156,11)#停车
- ROI2=(2,51,158,18)
- ROI3=(2,29,156,15)
- uart = UART(3,115200)
- uart.init(115200,bits=8,parity=None,stop=1)
- ting=0
- twice1=0
- twice2=0
- huan=1
- san1=0
- san2=0
- san3=0
- san4=0
- quanshu=0
- x=0
- bx=0
- ting1=0
- xx=0
- xx1=0
- jia=0
- er1=0
- er2=0
- jia1=0
- while(True):
- clock.tick()
- img = sensor.snapshot()
- #寻找色块
- img.draw_rectangle(ROIXIN)
- img.draw_rectangle(ROITING)
- img.draw_rectangle(ROI2)
- img.draw_rectangle(ROI3)
- blobn1=img.find_blobs([RED_threshold],roi=ROITING)
- if blobn1:
- largest_blobn1 = max(blobn1,key=lambda c:c.pixels())
- img.draw_rectangle(largest_blobn1.rect())
- print(largest_blobn1.pixels(),largest_blobn1.h(),largest_blobn1.w(),ting)
- if largest_blobn1.pixels()>200 and largest_blobn1.h()>7 and largest_blobn1.w()>38:
- ting=1
- blobn2=img.find_blobs([RED_threshold],roi=ROI2)
- if blobn2:
- largest_blobn2 = max(blobn2,key=lambda c:c.pixels())
- img.draw_rectangle(largest_blobn2.rect())
- # print(largest_blobn2.pixels(),largest_blobn2.h(),largest_blobn2.w(),ting)
- if largest_blobn2.pixels()>700:
- twice1=1
- if twice1==1:
- if largest_blobn2.pixels()<700:
- twice2=1
- if twice1==1 and twice2==1 and largest_blobn2.pixels()>700:
- ting=4
- if ting==4 and largest_blobn2.pixels()<700:
- er1=1
- if er1==1 and largest_blobn2.pixels()>700:
- ting1=5
- blobn3=img.find_blobs([RED_threshold],roi=ROI3)
- if blobn3:
- largest_blobn3 = max(blobn3,key=lambda c:c.pixels())
- img.draw_rectangle(largest_blobn3.rect())
- print(largest_blobn3.pixels(),largest_blobn3.h(),largest_blobn3.w(),ting)
- if largest_blobn3.pixels()>350:
- san1=1
- ting=1
- if san1==1:
- if largest_blobn3.pixels()<350:
- san2=1
- if san1==1 and san2==1 and largest_blobn3.pixels()>350:
- quanshu=2
- san3=1
- if san1==1 and san2==1 and largest_blobn3.pixels()<350 and san3==1:
- san4=1
- if largest_blobn3.pixels()>350 and quanshu==2 and san4==1 and largest_blobn3.w()>50:
- xx=1
- if xx==1 and largest_blobn3.pixels()<350 :
- xx1=1
- if jia==1 and largest_blobn3.pixels()>350 and jia1==1:
- jia=2
- blobn=img.find_blobs([RED_threshold],roi=ROIXIN,x_stride=10,y_stride=10)
- for a in blobn:
-
- if a.pixels()>1500:
- ting=2
- if len(blobn)==2:
- print(blobn[0].cx(),blobn[1].cx())
- if len(blobn)==2:
- if quanshu==2 and jia1==0:
- jia=1
- jia1=1
- if quanshu==2:
- output_str=bytearray([0x2c,0x12,ting,min(blobn[0].cx(),blobn[1].cx()),ting1,jia,0x5B])
- uart.write(output_str)
- else:
- output_str=bytearray([0x2c,0x12,ting,max(blobn[0].cx(),blobn[1].cx()),ting1,jia,0x5B])
- uart.write(output_str)
- else:
- output_str=bytearray([0x2c,0x12,ting,a.cx(),ting1,jia,0x5B])
- uart.write(output_str)
- print(a.pixels())
openmv部分有点杂乱,没来得及及时整理,只是简单的移过来了,其中有许多部分可以删减,或者更改。
以上为本次项目的部分代码,详细的工程文件在后面一条文章中。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。