完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
3个回答
|
|
一 任务及设计要求
1.1任务 模拟飞行器(如无人机、导弹等)在空中飞行过程中使用九轴加速度/陀螺仪/磁力计模块采集姿态信息;并且能使用摄像头模块采集图像信息实现目标检测功能,从而实现飞行器朝目标飞行或者对目标实施精确打击。 二 实现功能 2.1 stm32f427开发板板载陀螺仪最终温漂造成的yaw轴误差保持在1°/1min以内; 2.2 k210开发板能够较准确地识别目标,并将图像显示在LCD屏上; 2.3 k210开发板将目标在LCD屏的位置信息通过串口发送给stm32f427开发板; 2.4 若目标在LCD中心附近(即不需要飞行器调整姿态),则stm32f427开发板蜂鸣器响; 三 系统原理框图及模块作用 3.1 系统原理框图 3.2 各模块作用 3.2.1 蜂鸣器模块 stm32f427开发板板载一个贴片蜂鸣器,该蜂鸣器需要使用PWM驱动,额定频率2700Hz,用以提示飞行器是否对准目标。 3.2.2 mpu6500+ist8310九轴陀螺仪传感器模块 stm32f427开发板集成一个IMU模块,由mpu6500陀螺仪和ist8310地磁传感器组成,用以采集姿态信息。 3.2.3 LCD模块 用以显示摄像头采集的图像,并将目标物体用矩形框标记,显示矩形框中心点坐标位置以及识别到的物体名称。 3.2.4 OV2640模块 用以采集图像,为k210目标检测提供信息。 四 硬件说明 4.1 硬件设计 4.2 硬件电路图及模块说明 4.2.1 蜂鸣器(STM32F4) 开发板板载一个贴片蜂鸣器,需要使用PWM驱动,额定频率2700Hz。 4.2.2 IMU(STM32F4) 开发板集成-一个IMU模块,其IMU由MPU6500陀螺仪和IST8310地磁传感器组成。为了解决陀螺仪温飘的问题,在MPU6500四周增加10颗加热电阻,可以通过PB5加热电阻控制管脚和MPU6500内部的温度传感器做恒温处理,加热温度一般控制在比电路板正常工作温度高15~20C为宜。10个加热电阻工作电压为24V,该电阻可以在1S内将IMU模块的温度从25C加热到50°C。板载IST8310的地址为: 0x0E。 五 程序流程图 5.1 主程序流程图 5.2 模块流程图及其说明 5.2.1 串口中断及串口虚拟示波器(STM32F427) 串口中断主要用于接收PC端发送的数据,并打印到串口助手上;并且同时要接收K210发送的8位大小的数据串(发送数据形式为:LCD屏上目标的三位数横坐标+‘/’+LCD屏上目标的三位数纵坐标+‘n’),若当STM32F4串口接收完毕后,发生以下情况,则判断接收成功: (1)接收到了8位数据 (2)接收到的第四位数据为‘/’ (3)接收到的第八位数据为‘n’ 以上条件缺一不可,若串口接收完毕后未能满足以上条件,则将数组清零重新接收。 串口虚拟示波器是一个PC端软件,有两种通讯协议 一种是CRC16另一种是ChkSum,我使用CRC16通信协议,简单的来说就是把我单片机的数据转换为示波器软件可以识别的形式读取并且显示。 以上为串口示波器的界面展示,有四个通道对应四条波形,界面可以实现放大、缩小以及跟随波形等功能。 5.2.2 九轴陀螺仪传感器初始化 MPU6500使用SPI通信,IST8310使用IIC通信。 设置的测量精度为gyro LPF 41Hz、 LPF 92Hz、±2000dps、±8G。 5.2.3 PWM+PID补偿温度误差调节姿态输出(定时器中断) PWM+PID补偿温度误差调节姿态输出主体程序放在定时器中断内,5ms进入一次中断。 其中,温度PID+PWM调节函数mpu_temp_control用于控制陀螺仪环境温度处于理想状态,缓解温漂对YAW轴造成的误差。在开发板第一次上电后,PWM输出以一个较大的值2000加热陀螺仪传感器模块周围电阻,当温度超过设定温度累计次数20次以上时,启动PID调节PWM输出,PID算法函数pid_calc输入量为实际温度和设定温度。 其中,一阶低通滤波函数first_order_filter_calc起到的作用是放缓PID输出数据的变化,避免因为个别数据误差较大导致PID输出量突然变化较大导致的温度不稳定情况,sampling_period采样周期为1,RC_time时间常数为100。根据一阶数字低通滤波算法Y(n)=T/(T+RCX(n))+RC/(T+RCY(n−1))改造first_order_filter_calc函数,RC即为RC_time,T即为sampling_period。 5.2.4 深度学习模型(yolov3) 下次再出一个博客谈谈俺踩过的坑 |
|
|
|
六 代码分析
6.1 STM32F4 定时器部分 因为我大部分处理数据的代码都是放在定时器中断里 #include “timer_pid.h” #include “pid.h” #include “delay.h” #include “usart.h” #include “init.h” #include “filter.h” #include “ahrs.h” #include “mpu6500.h” #include “imu.h” #include “adc.h” #include “global_def.h” //5ms struct attitude mahony_atti; struct ahrs_sensor mpu_sensor; float mputemp2; extern float mcu_temp; extern pid_t pid_temp; uint8_t mpu_count=0,mpu_flag=0; static uint8_t first_temperate = 0;//µÚÒ»´ÎζÈÎȶ¨Ç° Îȶ¨ºóΪ1 static uint8_t second_temperate = 0; const float *get_mcu_temp(void) { return &mcu_temp; } const struct attitude* get_imu_data(void) { return &mahony_atti; } /** * @brief ¶¨Ê±Æ÷1³õʼ»¯|Ħ²ÁÂÖpwmÊä³ö * @param void * @retval void * @attention */ void timer1_init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; GPIO_InitTypeDef GPIO_InitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_TIM1); GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_TIM1); GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_TIM1); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_High_Speed; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; GPIO_Init(GPIOE, &GPIO_InitStruct); TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 2500 - 1; TIM_TimeBaseInitStruct.TIM_Prescaler = 180 - 1; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStruct); TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable; TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset; TIM_OCInitStruct.TIM_OCNIdleState = TIM_OCNIdleState_Reset; TIM_OCInitStruct.TIM_Pulse = 900; TIM_OC1Init(TIM1, &TIM_OCInitStruct); TIM_OC2Init(TIM1, &TIM_OCInitStruct); TIM_OC3Init(TIM1, &TIM_OCInitStruct); TIM_OC4Init(TIM1, &TIM_OCInitStruct); TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM1, ENABLE); TIM_CtrlPWMOutputs(TIM1, ENABLE); TIM_Cmd(TIM1, ENABLE); } /** * @brief 定时器3初始化,PWM加热陀螺仪周围电阻 * @param void * @retval void * @attention */ void timer3_init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_TIM3); RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //TIM3_Int_Init(5000,1) rm???? TIM_TimeBaseInitStructure.TIM_Period = 500 - 1;//50us TIM_TimeBaseInitStructure.TIM_Prescaler = 3 - 1;//90*1000000/9 = 10Mhz 0.1us TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; // TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); /* TIM3 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_Init(GPIOB, &GPIO_InitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM3, ENABLE); TIM_Cmd(TIM3, ENABLE); } void timer4_init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; GPIO_InitTypeDef GPIO_InitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_High_Speed; GPIO_Init(GPIOD, &GPIO_InitStruct); TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 20000; TIM_TimeBaseInitStruct.TIM_Prescaler = 90 - 1; //90 - 1 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct); TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM4, &TIM_OCInitStruct); TIM_OC2Init(TIM4, &TIM_OCInitStruct); TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM4, ENABLE); TIM_Cmd(TIM4, ENABLE); } //定时器5 开启定时器中断 void timer5_init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; NVIC_InitTypeDef NVIC_InitStruct; TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period=2000-1; TIM_TimeBaseInitStruct.TIM_Prescaler=90-1; TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStruct); TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE); TIM_Cmd(TIM5,ENABLE); NVIC_InitStruct.NVIC_IRQChannel=TIM5_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1; NVIC_InitStruct.NVIC_IRQChannelSubPriority=2; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStruct); } //蜂鸣器初始化 void Buzzer_Init(void) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM12,ENABLE); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed=GPIO_High_Speed; GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; GPIO_Init(GPIOH,&GPIO_InitStruct); } //蜂鸣器PWM void Buzzer_PWMSet(int16_t f) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; GPIO_PinAFConfig(GPIOH, GPIO_PinSource6, GPIO_AF_TIM12); TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 1000000/f - 1; TIM_TimeBaseInitStruct.TIM_Prescaler = 90 - 1; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM12, &TIM_TimeBaseInitStruct); TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC1Init(TIM12, &TIM_OCInitStruct); TIM_OC1PreloadConfig(TIM12, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM12, ENABLE); TIM_Cmd(TIM12, ENABLE); TIM_SetCompare1(TIM12, (1000000/f - 1)/2); } // void Buzzer_Disable(void) { TIM_Cmd(TIM12, DISABLE); } |
|
|
|
// 蜂鸣器播放音乐
void Music_Play(uint8_t flag) { int i; if(flag == 0) { Buzzer_PWMSet(D1); delay_ms(100); Buzzer_PWMSet(D5); delay_ms(100); } Buzzer_Disable(); } float input=1000; float d_yaw,lsat_d_yaw=0,final_yaw=0; //定时器中断服务函数 void TIM5_IRQHandler(void) { if(TIM_GetITStatus(TIM5,TIM_IT_Update)!=RESET) { mpu_get_data(&mpu_sensor); //获取陀螺仪信息 mahony_ahrs_updateIMU(&mpu_sensor,&mahony_atti); //用mahony_ahrs算法解算 mpu_get_temp(&mahony_atti.temp); //imu temp get by mpu/return *tmp mcu_temp=get_temprate(); //获取A板CPU温度,用ADC测量 mpu_temp_control(&mahony_atti.temp); // VisualScope_Output(mahony_atti.pitch,mahony_atti.roll ,mahony_atti.yaw, mahony_atti.temp); // d_yaw=(float)mahony_atti.yaw; //ÕâÀï²ÉÓù̶¨Ê±¼ä¼õÈ¥Õâ¶Îʱ¼äÄÚµÄÎÂƯ²úÉúµÄyawÖáÆ«²îµÄÀÛ¼ÆÖµ£¬»ººÍËäÈ»²ÉÓÃÁ˼ÓÈÈÍÓÂÝÒÇÀ´Î¬³Öζȣ¬µ«ÊÇÈÔÈ»»áÓдó¸Å1¡ã/1minµÄÇé¿ö // mahony_atti.yaw=constrain_judge_motion(d_yaw,lsat_d_yaw,0.05); //±È½ÏÁ½´ÎÍÓÂÝÒÇyawÖáÊý¾ÝµÄ²îÖµ£¬ÈôСÓÚ0.05£¬Ôò¼ÆÈëÍÓÂÝÒÇÎó²î·¶³ë£¬ÀÛ¼ÆÆðÀ´£¬¹ýÒ»¶Îʱ¼ä¾Í¼õµôÕâЩÀۼƲîÖµ£¬0.05Õâ¸öÊýÖµÊÇÒª±£Ö¤A°åÕý³£Ô˶¯Ï£¬yawÖáÊýÖµ±ä»¯²»±»¼ÆÈëÎó²î // lsat_d_yaw=(float)mahony_atti.yaw; // printf(“yaw angle is %f, pitch angle is %f, rol angle is %frnmcu temp is %f, mpu temp is %frn”, // mahony_atti.yaw, mahony_atti.pitch, mahony_atti.roll, mcu_temp, mahony_atti.temp); TIM_ClearFlag(TIM5,TIM_IT_Update); } } /** * @brief 陀螺仪温度控制函数,先以pwm比较值为2000加热陀螺仪,第一次达到设定温度后,启动pid * @param void * @retval void * @attention */ void mpu_temp_control(float *temp) { uint16_t temp_pwm; static uint8_t temp_conunt_time = 0 ,temp_conunt_time2=0; if (first_temperate==1) { pid_temp.ilimit = 100; pid_temp.iout=60; pid_temp.p=80; pid_temp.i=0.3; pid_temp.d=100; pid_calc(&pid_temp,*temp,mahony_atti.set_temp); temp_pwm = constrain_float(pid_temp.out, 0, +1000); first_order_filter_calc(&all_control_s.first_order_lowpass_filter_imu,temp_pwm); temp_pwm=all_control_s.first_order_lowpass_filter_imu.out; imu_temp_pwm_set(temp_pwm); } else { if (*temp 》 (mahony_atti.set_temp-1)) { temp_conunt_time ++; if(temp_conunt_time 》 20) { first_temperate = 1; } } imu_temp_pwm_set(2000); } } 6.2 串口中断部分 STM32用以接收K210发送的坐标数据,数据形式为图像在LCD屏上的x坐标+‘/’+y坐标+‘0x0d’,坐标都是3位数,百位小于一则补0如089,加起来总共8位数据,接收到的数据若第四位不是‘/’或者最后一位不是‘0x0d’则判断接收失败,失败的原因可能有串口与串口的连接线不等长或者信号干扰导致串口漏发、错位发送数据。 //USART2½ÓÊÜÖÐ¶Ï void USART2_IRQHandler(void) { u8 Res,len; if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) // 接收中断,接收到的数据必须以0x0d,0x0a结尾 { Res =USART_ReceiveData(USART2);//(USART2-》DR); //读取接收到的数据 if((USART_RX_STA&0x8000)==0)//接收未完成 { if(USART_RX_STA&0x4000)//接收到了0x0d { if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始 else USART_RX_STA|=0x8000; //接收完成了 len=USART_RX_STA&0x3fff; for(int t=0;t《len;t++) { USART2-》DR=USART_RX_BUF[t]; while((USART2-》SR&0X40)==0); } // printf(“%d%d%d %d%d%d rn”,USART_RX_BUF[0],USART_RX_BUF[1],USART_RX_BUF[2],USART_RX_BUF[4],USART_RX_BUF[5],USART_RX_BUF[6]); USART_RX_STA=0; } else //还没收到0x0d { if(Res==0x0d) { USART_RX_STA|=0x4000; } else { USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ; USART_RX_STA++; if(USART_RX_STA》(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收 } } } } // the width limit of k210-lcd:320---------the high limit of k210-lcd:240 if( (Res==0x0a)&&(USART_RX_BUF[3]!=‘/’)&&(USART_RX_BUF[7]!=‘n’ ) )//判断接收到的数据是否符合协议,若否,则赋予所有数据为‘w’ { for(int count_r=0;count_r《8;count_r++) { USART_RX_BUF[count_r]=‘w’; } USART_RX_STA=0; } // Music_Play(0); if((USART_RX_BUF[0]==‘1’)&&(USART_RX_BUF[4]==‘1’)&&(USART_RX_BUF[1]==‘4’)&&(USART_RX_BUF[5]==‘4’))//判断是否在设定坐标左右,若是,则蜂鸣器响 { Music_Play(0); } } 我使用了TF卡储存训练后转化为Kmodel文件的模型,然后K210串口与STM32F4串口相连,如何训练模型并且转化模型?请移步 或者我只后有时间再详细写。。。写博客太累了吧。 from fpioa_manager import * from fpioa_manager import fm from machine import UART from Maix import GPIO import sensor import image import lcd import time import math import KPU as kpu #LCD初始化 lcd.init() #摄像头初始化 sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) sensor.set_windowing((224, 224)) sensor.set_hmirror(0) sensor.run(1) clock = time.clock() #串口初始化 fm.register(board_info.PIN15,fm.fpioa.UART1_TX) fm.register(board_info.PIN17,fm.fpioa.UART1_RX) uart_A = UART(UART.UART1, 115200, 8, None, 1, timeout=1000, read_buf_len=4096) classes = [‘class_1’] #载入模型 task = kpu.load(“/sd/test.kmodel”) anchor = (1, 1.2, 2, 3, 4, 3, 6, 4, 5, 6.5) a = kpu.init_yolo2(task, 0.17, 0.3, 5, anchor) info=kpu.netinfo(task) while(True): clock.tick() img = sensor.snapshot() code = kpu.run_yolo2(task, img) print(clock.fps()) if code: for i in code: #计算目标框的几何中心坐标 center_x=( i.x()+ (i.w()//2) ) center_y=( i.y()+ (i.h()//2) ) #画框和十字 a=img.draw_rectangle(i.rect()) a=img.draw_cross(center_x,center_y) a = lcd.display(img) print(i.classid(),i.value()) for i in code: #显示目标类别 lcd.draw_string(i.x(), i.y(), classes[i.classid()], lcd.RED, lcd.WHITE) center_x_1=center_x//100 center_y_1=center_y//100 #判断坐标是否为3位十进制,若不是,则在数字前填充0直至3位十进制 if center_x_1《1: uart_A.write(‘0{}/’.format(center_x)) else: uart_A.write(‘{}/’.format(center_x)) if center_y_1《1: uart_A.write(‘0{}n’.format(center_y)) else: uart_A.write(‘{}n’.format(center_y)) else: a = lcd.display(img) uart_A.deinit() del uart_A a = kpu.deinit(task) 七 结果展示 7.1 陀螺仪效果展示 上图为串口示波器界面,其中CH1通道1为陀螺仪PITCH轴数据、CH2通道2为陀螺仪ROLL轴数据、CH3通道为陀螺仪YAW轴数据、CH4通道为陀螺仪实时温度。 其中,横坐标为时间坐标轴(1min/30000),纵坐标为数值大小,串口示波器的数值表现形式均为整数形式,解释了曲线部分地方为锯齿状的原因。 放大纵坐标轴对陀螺仪PITCH/ROLL/YAW轴数据进行观察,结合图 7.1可以发现在0-20000(时间坐标轴)时间段内,即大约40s内,陀螺仪传感器模块温度达到设定值,在此期间陀螺仪PITCH/ROLL/YAW轴数据抖动变化较明显。 而在大约50000-350000(1min40s-12min)温度稳定期间可以得出以下结果: (1)陀螺仪PITCH数据(红色)稳定在2°-3°内 (2)陀螺仪ROLL数据(黄色)稳定在(-2)°-(-3)°内 (3)陀螺仪YAW数据(蓝色)稳定在1°-3°内,平均3min变化1° 7.2 STM32F4串口接收K210数据效果展示 若检测到目标(浣熊)则发送坐标信息给STM32F4,反之则正常显示摄像头图像 上图为正确接收到正确数字的情况,通过debug观察USART_RX_BUF[]数组的内容[0]-[2]为x坐标,[4]-[6]为y坐标轴。[3]和[7]起到校验作用。 上图为接收到错误数字的情况,将给SART_RX_BUF[]数组赋值为‘w’。 若检测到目标(浣熊)则在LCD上以框的形式标记,反之则正常显示摄像头图像。效果展示以视频的形式展示,请参考附件视频。 检测15张照片,其中11张浣熊照片,2张猫照片,2张狗照片,能够稳定有效检测到9张浣熊照片,不稳定检测到2张浣熊照片,对其他照片没有反应。效果良好,影响效果的因素主要是摄像头像素太低,或者我没有调焦好。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1548 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1493 浏览 1 评论
915 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
656 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1544 浏览 2 评论
1845浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
598浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
499浏览 3评论
501浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
483浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-6 06:25 , Processed in 0.838751 second(s), Total 82, Slave 66 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号