综合项目——智能分类垃圾桶
智能垃圾桶,垃圾分类更智能 #生活乐趣# #日常生活趣事# #生活趣味分享# #科技小发明#
综合项目——智能分类垃圾桶
一、讲在前面
之前做过许多项目,也写了许多工程代码,但是一直没能好好整理,导致我每做一个新的项目就跟重头开始似的,为了更好进行代码资料的管理,我决定开辟这个博客,作为我资料整理的开始。 -------------------------------------------分割线--------------------------------------- 最近刚结束了一个特别折磨人的项目设计,这个项目设计的题目是智能分类垃圾桶,其中需要进行机械设计制图、安卓开发板代码编写、FPGA代码设计、MCU代码设计等等。我在其中负责FPGA开发板代码和STM32开发板代码的编写,秉承记录的目的和开源的初心,我将更新一个系列的博文进行MCU端代码和FPGA端代码的介绍,供大家一起学习进步,不足之处望补正。二、博文介绍
在该系列博文,我会按照MCU代码和FPGA代码的顺序进行介绍,此次介绍MCU端的代码。三、MCU代码框架
3.1代码框架分析 此次项目选择的控制平台是意法半导体出产的stm32L476RGT6系列的集成控制主板。板上集成了ST-LINK烧录器、Arduino接口等资源,引出了I2C、SPI、串口、ADC等管脚资源(正经人谁用硬件I2C和SPI不是),可谓是资源丰富,但是又有许多无用之处。 我们的MCU需要做的就是利用以上的板载资源,设计一个控制系统、对整个智能分类垃圾桶系统进行控制,这个控制系统应该包含以下几个功能: (1)与安卓开发板进行通信; (2)与FPGA开发板进行通信; (3)读取TCS34725颜色传感器数据和VL6180距离传感器数据; (4)向广和通L610物联网通信主板发送AT指令,进而向阿里云发送垃圾桶事件; (5)用户服务程序,用于对用户预留的接口,用户在该任务里对垃圾桶的逻辑进行设计; (6) 开发者调试,串口打印垃圾桶属性和数据任务,用于垃圾桶维修者对垃圾桶进行维护。 3.2代码框架设计 根据以上的分析,我们需要实现6个任务,其中5个为常用任务,一个为调试维护任务。为此,我在我的MCU代码框架中开辟6个任务,对整个控制系统进行管理。下面附上一张代码框架图,有需要可以拷贝,但是请标注来源或者自己根据我的框架搭建一个类似的: 在上面介绍中,我提到了任务管理的概念,那么我运用的任务管理方法是什么呢?没错,聪明的你一定猜到了,我运用的是时间片的管理方法。在代码中,我开启定时器3作为任务管理的时钟,对任务资源进行调度,对时间片管理不熟悉的伙伴可以自行百度哦。也许有人会问,为什么不运用操作系统进行任务的管理。emmm…其实刚开始的时候是有用FreeRtos编写的版本的啦,不过效果不好,被我摒弃了。如果有想要的伙伴,我根据反响,考虑专门出一篇博文介绍FreeRtsos系统下的任务管理介绍,欢迎大家在评论区积极发言哦!行了,扯了这么多蛋,接下来该进入正题了——各个任务代码的介绍。四、各部分代码详解
4.1代码主循环 以下的主循环中运行着整个系统的全部任务,函数中的参数代表任务循行的频率的倒数,单位时ms。while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */data_read_task(5);//传感器数据读取fpga_com_task(10);//与FPGA通信Android_com_task(60);//与上位机通信L610_task(200);//与L610通信user_service_task(10);//用户服务程序 #if DBUG dbug_task(100);//开发者调试 #endif }
12345678910111213141516171819 4.2传感器数据读取任务 我们需要读取的传感器数据有两种,TCS34725颜色传感器数据和VL6180距离传感器数据。这两个传感器数据的读取协议采用IIC(不了解IIC的同学这边建议百度),具体初始化和读取方法网上有许多例程,我在这里不再赘述,只挑选几个比较重要的函数进行讲解,下面贴上代码: 4.2.1传感器初始化//传感器初始化 void sensor_init() { //读取TOF模块ID tof_name = VL6180X_Read_ID();//读取TOF模块的ID while(tof_name != 0xBE)//根据模块不同型号和焊接工艺选择IDtof_name = VL6180X_Read_ID();//循环读取TOF模块的ID init_flag = VL6180X_Init();//tof模块的初始化 HAL_Delay(300);//延时一段时间等待初始化完成 TCS34725_Setup();//颜色识别模块设置 TCS34725_Enable();//颜色识别模块使能 TCS34725_Read(TCS34725_ID,&TSC_name,1);//读取颜色识别模块ID while(TSC_name != 0x44)TCS34725_Read(TCS34725_ID,&TSC_name,1);//循环读取颜色识别模块的ID }
12345678910111213141516171819 这里需要注意的是传感器的ID,我用的距离传感器的ID是0XBE,别的同系列的距离传感器数据有0XB4的,如果程序卡在这个初始化循环里有可能是传感器ID设置的问题,对其进行修改即可。颜色传感器ID没什么大问题。代码注释在上面都有。 4.2.2传感器数据读取主体函数 由于我的整个程序运用的是时间片的管理方法,因此在进行函数的封装时,特别要注意的一个参数时任务运行的事件,原则上给定的任务运行时间只要大于任务的实际运行时间即可,但出于对各个任务实时性需求的不同,我们一般会把实时性需求比较大的任务给的运行频率更大。传感器数据更新实时性要求比较高,我们给定的运行频率比较大,有200HZ。//传感器数据读取任务,频率200HZ void data_read_task(uint32_t period) {if(task_count[DATA_READ_TASK] >= period){range = VL6180X_Read_Range();//读取距离数据HAL_Delay(1);//延时等待light = VL6180X_Read_Lux(VL6180X_ALS_GAIN_1_25);//读取光强数据HAL_Delay(1);//延时等待TCS34725_GetRawData(&my_color.CLE,&my_color.RED,&my_color.GRE,&my_color.BLU);//读取颜色传感器的颜色数据HAL_Delay(1);//延时等待voice_range = soner_getdistance();//超声波距离数据获取task_count[DATA_READ_TASK] = 0;} }
12345678910111213141516 4.3广和通L610通信模块通信任务 广和通通信模块遵循的是TCP传输协议,我们通过串口1向物联网通信主板发送AT指令,可以控制MCU与阿里云云端的通信(阿里云与广和通L610通信模块的相关使用如果有不清楚的根据反响将出一篇博客介绍)。内容比较简单,就是串口发送相关AT指令,值得注意的几个点就是,在发送的数据结尾加上回车和换行,在代码中体现为\r\n,还有就是字符串中的双引号注意要用ASSIC的表达方式,正常双引号表达方式是“ ,ASSIC的表达方式是\ 加上"。 4.3.1广和通通信模块连接阿里云配置int K ; void L610_init() {//配置阿里云服务器char *strx;Config_para();//配置阿里云服务参数strx = strstr((const char*)RECEIVE,(const char*)"OK");while(strx == NULL){K++;if(K>=6) //防止程序卡死,配置命令发送超过6次之后跳出初始化循环{break;}Config_para();//配置阿里云服务参数strx = strstr((const char*)RECEIVE,(const char*)"OK");HAL_Delay(300);}//以下为oled数据显示配置,可以选择注释 //if(K>=6) //{ //OLED_Clear_part(); //OLED_ShowString(20,5,(uint8_t *)"L610 ERROR!",16 ); //HAL_Delay(3000); //} //else //{ //OLED_Clear_part(); //OLED_ShowString(16,5,(uint8_t *)"L610 SUCCESS!",16 ); //HAL_Delay(3000); // //} }
1234567891011121314151617181920212223242526272829303132333435 4.3.2广和通物联网通信模块运行主体函数 以下代码块不仅包含广和通的通信部分,还包含oled的刷新部分。int j; void L610_task(uint32_t peirod) {if(task_count[L610_TASK] >= peirod){Config_para();//配置阿里云服务参数 //垃圾桶各项属性和数据显示 if(frame == 1) {OLED_Clear_part();OLED_ShowString(5,5,(uint8_t *)"type :",8 );OLED_ShowString(5,7,(uint8_t *)"state:",8 ); if(sevo_step == 1)OLED_ShowString(60,7,(uint8_t *)"complete",8 ); elseOLED_ShowString(60,7,(uint8_t *)"onging",8 );if(RX_DATA_FROM_FPGA == '1'){OLED_ShowString(60,5,(uint8_t *)"RB1",8 );}else if(RX_DATA_FROM_FPGA == '2'){OLED_ShowString(60,5,(uint8_t *)"RB2",8 );}else if(RX_DATA_FROM_FPGA == '3'){OLED_ShowString(60,5,(uint8_t *)"RB3",8 );}else if(RX_DATA_FROM_FPGA == '4'){OLED_ShowString(60,5,(uint8_t *)"RB4",8 );}else{OLED_ShowString(60,5,(uint8_t *)"NULL",8 );}frame = -frame; } else {OLED_Clear_part();OLED_ShowString(5,5,(uint8_t *)"range:",8 );OLED_ShowNum(60,5,range,3,8);OLED_ShowString(5,7,(uint8_t *)"remain:",8 );OLED_ShowNum(60,7,voice_range,3,8);frame = -frame; } //超声波数据作为垃圾余量的参考数据 if(voice_range<=6) {OLED_Clear_part();OLED_ShowString(6,5,(uint8_t *)"full sent:",8 );Send_data((char *)"\"hello\""); } //上位机发送呼叫管理员指令if(AS_call_manager == 1){OLED_Clear_part();OLED_ShowString(6,5,(uint8_t *)"calling sent:",8 );for(j=0;j<=20;j++)Send_data_call((char *)"\"hello\"");AS_call_manager = 0;} //用户模式和DBUG模式切换显示if(dbug_flag == 0){OLED_ShowString(92,2,(uint8_t *)"USER",8 );}elseOLED_ShowString(92,2,(uint8_t *)"DBUG",8 );task_count[L610_TASK] = 0;} }
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 以上就是此次的更新内容,剩余的与FPGA通信部分和与上位机的通信部分过于庞大,咱们下次介绍,这次先把代码贴上,有不清楚的可以下面评论留言哦。 上位机通信部分:主要是数据收发和协议约定//与上位机通信,运行频率(1000/60)HZ void Android_com_task(uint32_t peroid) {if(task_count[COM_TO_Andr] >= peroid){//接收上位机数据HAL_UART_Receive_IT(&huart4,&RX_DATA[0],1);//根据上位机指令选择调试模式和用户模式if(RX_DATA[0] == 'G'){dbug_flag = Android_DBUG;RX_DATA[0] = 0;}else if(RX_DATA[0] == 'U'){dbug_flag = Android_USER;RX_DATA[0] = 0;}range_temp = (uint8_t) voice_range;if(dbug_flag == Android_USER){if(range <= 100){TX_DATA[0] = 'l'; //TX_DATA[1] = 1;HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);}//用户模式下从上位机收到b,表示当前可以进行投放if(( RX_DATA[0] == 'b' || time_cmd == 1)&&(garbage_complete == 1) ){RX_DATA[0] = 0;AS_cmd = 1;} if((RX_DATA[0] == 'a') && (AS_call_manager == 0)) {AS_call_manager = 1;RX_DATA [0] = 0; }//当识别到垃圾,并且上位机发送投放指令之后,返回当前垃圾中类给上位机if((garbage_complete == 0)&&(sevo_cmd_type == GARBAGE_1))//垃圾1{TX_DATA[0] = 'k';HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);TX_DATA[0] = 61;//距离标号HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);}else if((garbage_complete == 0)&&(sevo_cmd_type == GARBAGE_2))//垃圾2{TX_DATA[0] = 'i';HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);TX_DATA[0] = 62;//距离标号HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);}else if((garbage_complete == 0)&&(sevo_cmd_type == GARBAGE_3))//垃圾3{TX_DATA[0] = 'o';HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);TX_DATA[0] = 63;//距离标号HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);}else if((garbage_complete == 0)&&(sevo_cmd_type == GARBAGE_4))//垃圾4{TX_DATA[0] = 'v';HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);TX_DATA[0] = 64;//距离标号HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);}else{TX_DATA[0] = 't';HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);}}else if(dbug_flag == Android_DBUG){if(RX_DATA[0] == 'M')//测试电机{RX_DATA[0] = 0;for(i=0;i<6000;i++){TX_DATA_TO_FPGA = 126;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}for(i=0;i<6000;i++){TX_DATA_TO_FPGA = 144;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}for(i=0;i<6000;i++){TX_DATA_TO_FPGA = 21;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}for(i=0;i<6000;i++){TX_DATA_TO_FPGA = 15;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}for(i=0;i<6000;i++){TX_DATA_TO_FPGA = 9;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}for(i=0;i<6000;i++){TX_DATA_TO_FPGA = 15;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}}else if(RX_DATA[0] == 'f')//测试距离,回传距离数据{if(range == 0)TX_DATA[0] = 'h';//如果距离数据收不到,给上位机发送NelseTX_DATA[0] = 'l';HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);RX_DATA[0] = 0;}else if(RX_DATA[0] == 'g')//测试颜色,回传当前识别到的垃圾种类{if(sevo_cmd_type == GARBAGE_1){ //TX_DATA[0] = 'h';TX_DATA[0] = 'k';HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);}else if(sevo_cmd_type == GARBAGE_2){ //TX_DATA[0] = 'h';TX_DATA[0] = 'i';HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);}else if(sevo_cmd_type == GARBAGE_3){ //TX_DATA[0] = 'h';TX_DATA[0] = 'o';HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);}else if(sevo_cmd_type == GARBAGE_4){ //TX_DATA[0] = 'h';TX_DATA[0] = 'v';HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);}else//表示当前没有识别到垃圾{ //TX_DATA[0] = 'h';TX_DATA[0] = 't';HAL_UART_Transmit_IT(&huart4,&TX_DATA[0],1);}RX_DATA[0] = 0;}}task_count[COM_TO_Andr] = 0;} }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 FPGA通信部分:用到了三级状态机int i; uint8_t ongoing1,ongoing2,ongoing3,ongoing4; //与FPGA通信任务,频率5HZ void fpga_com_task(uint32_t period) {if(task_count[COM_TO_FPGA] >= period){ //舵机运动状态机if(sevo_cmd_type == GARBAGE_1 || ongoing1 ==1)//类型1的垃圾{if(sevo_step == 1)//状态1,垃圾投放进入预备状态{if(sevo_cmd == 1){//收到指令之后,开始投放垃圾sevo_cmd = 0;//指令归0,防止重复进入该状态ongoing1 = 1;for(i=0;i<5000;i++)//控制水平舵机旋转到固定位置{TX_DATA_TO_FPGA = 21;//舵机1旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}TX_DATA_TO_FPGA = 15;//舵机1旋转控制量,水平舵机停止旋转HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);for(i=0;i<30000;i++);sevo_step = 2;//舵机1动作完毕,进入舵机2动作状态}}else if(sevo_step == 2)//控制竖直舵机旋转,开始投放{for(i=0;i<6000;i++){TX_DATA_TO_FPGA = 134;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}for(i=0;i<6000;i++){TX_DATA_TO_FPGA = 144;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}sevo_step = 3;//舵机1停止水平旋转,开始俯仰}else if(sevo_step == 3)//舵机进入归位状态动作{for(i=0;i<5000;i++)//舵机1归位{TX_DATA_TO_FPGA = 9;HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}for(i=0;i<3000;i++){TX_DATA_TO_FPGA = 15;//舵机2归位HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);garbage_complete = 1;}ongoing1 = 0;//指示投放完毕sevo_step =1;//完成倾倒动作之后,状态回归垃圾投放预备状态}}else if(sevo_cmd_type == GARBAGE_2|| ongoing2 ==1)//类型2的垃圾{if(sevo_step == 1){if(sevo_cmd == 1){sevo_cmd = 0;ongoing2 = 1;for(i=0;i<9300;i++){TX_DATA_TO_FPGA = 23;//舵机1旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}TX_DATA_TO_FPGA = 15;//舵机1旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);sevo_step = 2;//舵机1开始水平旋转}}else if(sevo_step == 2){for(i=0;i<8000;i++){TX_DATA_TO_FPGA = 122;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}for(i=0;i<8000;i++){TX_DATA_TO_FPGA = 144;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}sevo_step = 3;//舵机1停止水平旋转,开始俯仰}else if(sevo_step == 3){for(i=0;i<9300;i++){TX_DATA_TO_FPGA = 7;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}sevo_step =1;//完成倾倒动作之后,舵机2归位TX_DATA_TO_FPGA = 15;//电机回转HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);garbage_complete = 1;ongoing2 = 0;}}else if(sevo_cmd_type == GARBAGE_3|| ongoing3 ==1)//类型3的垃圾{if(sevo_step == 1){if(sevo_cmd == 1){sevo_cmd = 0;ongoing3 = 1;for(i=0;i<5000;i++){TX_DATA_TO_FPGA = 9;//舵机1旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}TX_DATA_TO_FPGA = 15;//舵机1旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);sevo_step = 2;//舵机1开始水平旋转}}else if(sevo_step == 2){for(i=0;i<6000;i++){TX_DATA_TO_FPGA = 126;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0X5); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}for(i=0;i<6000;i++){TX_DATA_TO_FPGA = 144;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0X5); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}sevo_step = 3;//舵机1停止水平旋转,开始俯仰}else if(sevo_step == 3){for(i=0;i<5000;i++){TX_DATA_TO_FPGA = 21;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}TX_DATA_TO_FPGA = 15;//电机回转HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);garbage_complete = 1;sevo_step =1;//完成倾倒动作之后,舵机2归位ongoing3 = 0;}}else if(sevo_cmd_type == GARBAGE_4|| ongoing4 ==1)//类型4的垃圾{if(sevo_step == 1){if(sevo_cmd == 1){sevo_cmd = 0;ongoing4 = 1;for(i=0;i<9000;i++){TX_DATA_TO_FPGA = 9;//舵机1旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}for(i=0;i<2000;i++){TX_DATA_TO_FPGA = 15;//舵机1旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}sevo_step = 2;//舵机1开始水平旋转}}else if(sevo_step == 2){for(i=0;i<6000;i++){TX_DATA_TO_FPGA = 126;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}for(i=0;i<6000;i++){TX_DATA_TO_FPGA = 144;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}sevo_step = 3;//舵机1停止水平旋转,开始俯仰}else if(sevo_step == 3){for(i=0;i<8700;i++){TX_DATA_TO_FPGA = 21;//舵机2旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);}for(i=0;i<2000;i++){TX_DATA_TO_FPGA = 15;//舵机1旋转控制量HAL_UART_Transmit(&huart3,&TX_DATA_TO_FPGA,1,0XF); //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);} //HAL_UART_Receive(&huart3,&RX_DATA_FROM_FPGA,1,0XF);garbage_complete = 1;sevo_step =1;//完成倾倒动作之后,舵机2归位ongoing4 = 0;}}task_count[COM_TO_FPGA] = 0;} }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262网址:综合项目——智能分类垃圾桶 https://www.yuejiaxmz.com/news/view/459211
相关内容
小区垃圾分类用上智能垃圾桶建筑垃圾综合利用项目
垃圾分类智能设备地埋垃圾桶/升降平稳/维护方便
垃圾桶有哪四种分类 垃圾桶分类颜色和标志
【32项目】基于stm32f103c8t6的智能垃圾桶设计(含完整代码)
垃圾桶不锈钢垃圾桶塑料垃圾桶垃圾分类房智慧驿站
芯片垃圾桶助力垃圾智慧分类 下月起随意投放生活垃圾或被罚
“刷脸”投放垃圾!垃圾分类智能环保屋亮相福山
环保分类垃圾桶
厨余垃圾桶什么颜色的桶,家居分类新蓝图