1五湖四海1 发表于 2015-4-18 10:40:05

运动部件卡住报警器(应用实例矿车刹车加力器活塞卡住报警器)

本帖最后由 1五湖四海1 于 2015-4-18 10:49 编辑

      我这小项目是为了解决运动的活塞是否被卡住而设计的。在实际中汽车刹车系统出现故障容易造成重大事故发生。我们的矿车有两个加力器,如果一个加力器出现问题能及时发现是可以避免事故的发生。所以制作这个运动部件卡住报警器对安全是很有必要的。      实现原理上用一个能够检测距离的模拟量传感器。控制器先判断运动部件是否受人为控制开始运动,如果部件开始运动,控制器的模数转换器每隔一段时间采集一次距离,控制器计算前后两次采集距离值是否一样,就可以判断运动部件是否被卡住不动了。下面介绍下用到的器件和具体设计细节。      距离传感器用的是光电模拟量输出传感器,检测范围在10mm——100mm。如下图中两个圆柱形的便是距离传感器。       控制器用的是ARM cortek M3 STM32f103,有人会问为什么要用这个高性能的处理器呢?我认为现在已经不是51单片机是世界了,51单片机没有AD转换器,需要外接AD转换器,代码需要从零开始写。而ARM cortek M3 里面有10bit AD转换器,有大量的写好的库函数可以调用,可以缩短开发时间。他们的价格差不多为什么不选STM32f10。这次用的是现成的STM32f103最小系统板。如上图      代码设计上用到了两个定时器中断,一个定时器每隔200ms采集一次距离值,另一个发生故障时每隔500ms报警一次,用到的算法有AD软件滤波,采集500次距离值后,用冒泡排序法去掉最大值和最小值后,再求平均数算出距离值,这时采集的距离值很准。剩下的就是用if else编写的逻辑判断了。调试时用到了printf()库函数,结合电脑串口调试助手调试代码。调试代码如下图,部分程序代码在最下面       完成的控制器如上图,正常工作时指示灯和蜂鸣器不亮也不响,如果活塞被卡住时声光报警。       上图是加力器,它是用气顶动油完成输出二倍力的器件。如果活塞卡死这个报警就会报警提示故障。      下面是代码是主函数代码 最下面有全部代码如果有问题可以和我交流,QQ:835358518 微信:hm15041303104
#include <stm32f10x_lib.h>#include "sys.h"#include "usart.h"                #include "delay.h"      #include "led.h" #include "key.h"#include "exti.h"#include "wdg.h"#include "timer.h"         #include "adc.h"#include "alarm.h"
#define LIM 5                                                                              //卡住判断参数#define TREAD 2                                                                        //踩刹车#define LOOSEN 1                                                                     //松刹车#define CLEAR 3                                                                        //清除#define DIFFERENCE 50                                                            //回差

u16 lim_value = 1800;                                                            //极限报警值u16 max_value_l = 1000, max_value_r = 1000;                      //踩刹车标志值u16 min_value_l = 3000, min_value_r = 3000;                        //松刹车标志值
u8 count = 0;                                                                        //设置刹车标志防干扰计数                                                      u8 lock_count;                                                                        //卡住时计数防干扰处理
u16 distance_l = {0,0};                                                      //卡住比较数组u16 distance_r = {0,0};u8 i = 0;                                                                                 //采集数据计数变量
bool brake_state_l, brake_state_r;                                       //刹车状态标志位bool lock_alarm_l, lock_alarm_r, lock_alarm;                        //卡住报警标志位
u16 value_buf;                                                               //滤波求平均缓存 u32 sum;                                                                              //滤波求平均总和缓存u16 temp;                                                                           //滤波求排序缓存
                                                                                             //判断是否活塞卡住bool is_stuck(u16 distance_zero, u16 distance_one, bool brake_state, u16 *max_value, u16 *min_value);                                                                              void data_collection(void);                                                    //数据采集/**      主函数      */int main(void){      bool lim_alarm_l, lim_alarm_r;                                    //超限警报标志位                
          Stm32_Clock_Init(9);                                                //系统时钟设置      delay_init(72);                                                             //延时初始化      uart_init(72,9600);                                                   //串口1初始化         LED_Init();                     Adc_Init();            Timer2_Init(5000,7199);                                              //定时报警      Timer3_Init(2000,7199);                                              //定时采集ADC//      Timer4_Init(5000,7199);                                          //定时打印
      while(1)      {                                        lim_alarm_l = isOverrun(distance_l);                        //返回超限标志                lim_alarm_r = isOverrun(distance_r);                                                                                                   //返回刹车中标志                brake_state_l = isBrake_state(distance_l, max_value_l, min_value_l);                      brake_state_r = isBrake_state(distance_r, max_value_r, min_value_r);                                                                                                   //报警处理函数                Alarm_dispose(lim_alarm_l, lim_alarm_r, lock_alarm);      }}/**      定时器2中断服务程序      功能:发生定时中断控制蜂鸣器报警         */void TIM2_IRQHandler(void){
      if(TIM2->SR&0X0001)                              //溢出中断      {                      BUZZER = 0;                delay_ms(100);                BUZZER = 1;                              }                                       TIM2->SR&=~(1<<0);                              //清除中断标志位             }      /**      定时器3中断服务程序               功能:发生定时中断时采集ADC数据,并根据判断活塞是否卡住*/         void TIM3_IRQHandler(void){                                                                         if(TIM3->SR&0X0001)//溢出中断      {                                        if( ( lock_alarm_l && brake_state_l) || ( lock_alarm_r && brake_state_r) )                        lock_alarm = 1;                else                        lock_alarm = 0;      
                data_collection();                                                          //数据采集后判断是否活塞卡住                                                
      }                                                 TIM3->SR&=~(1<<0);                                                      //清除中断标志位             }/**      功能:1.判断左活塞是否卡住                  2.设置刹车标志      */bool is_stuck(u16 distance_zero, u16 distance_one, bool brake_state, u16 *max_value, u16 *min_value){      u8 motion;                  
      if( (distance_one-distance_zero) > 5)                        //松刹车标志                motion = LOOSEN;
      if( (distance_one-distance_zero) < -5)                        //踩刹车标志                motion = TREAD;
      if( ( (distance_one-distance_zero) < LIM) && ( (distance_zero-distance_one) < LIM) )      {/*                                                                                                踩刹车时动态设置最小值刹车标志*/                if(motion == TREAD)/*                                                如果这次值比上次设置的标志值小说明上次是卡住值,更新最小值标志*/                        if(distance_zero+DIFFERENCE < *min_value )                              *min_value = distance_zero+DIFFERENCE;
/*                                                松刹车时动态设置最大值刹车标志*/                                        if(motion == LOOSEN)/*                                                如果这次值比上次设置的标志值大说明上次是卡住值,更新新的标志*/                        if(distance_zero-DIFFERENCE > *max_value )                               count++;         //防干扰计数                        if(count > 1)                        {                              *max_value = distance_zero-DIFFERENCE;                                 count = 0;                        }      
                motion = CLEAR;                                                //清除刹车标志
                if( brake_state )                                                //刹车时如果卡住开始计数                        lock_count++;
                if( lock_count >= 5 )                                          //计数五次后报警位置位                {                        lock_count = 5;                        return TRUE;                }      }      else      {//                lock_alarm = 0;                lock_count = 0;                return FALSE;      }}/**      功能:判断活塞是否卡住数据采集函数*/void data_collection(void){
      u16 distance_zero, distance_one;      
      filter(ADC_CH0);       distance_l = sum;
      delay_ms(20);
      filter(ADC_CH1);      distance_r = sum;      i++;         if(i > 1)                //采集了两组数据后判断一次是否卡住      {                i = 0;                distance_zero = distance_l;                distance_one= distance_l;                lock_alarm_l= is_stuck(distance_zero, distance_one, brake_state_l, &max_value_l, &min_value_l);                                        distance_zero = distance_r;                distance_one= distance_r;                lock_alarm_r= is_stuck(distance_zero, distance_one, brake_state_r, &max_value_r, &min_value_r);                        //               d_value = distance_l-distance_l;                        //               printf("%d,%d\n", motion_l, motion_r);                   printf("%d,%d,%d,%d\n",max_value_l,min_value_l,max_value_r,min_value_r);                        //                printf("%d,%d,%d,%d\n",lock_alarm_l, lock_alarm_r ,lock_count_l, lock_count_r);//                printf("%d,%d,%d,%d\n",distance_l,distance_l,distance_r,distance_r);//                printf("%d,%d\n",distance_l-distance_l,distance_r-distance_r);//                printf("%d\n",distance_r-distance_r);      }      }




















竹杆捅飞机 发表于 2015-4-18 11:10:39

huhaofei 发表于 2015-4-18 11:19:35

大侠用的啥编程软件?c++吗?

龙游大海 发表于 2015-4-18 15:37:17

好像很复杂的

925269815 发表于 2015-4-18 15:43:23

赞赞赞

那年丶哥很帅 发表于 2015-4-18 16:57:23

   代码什么的就看不懂了

1五湖四海1 发表于 2015-4-18 17:22:48

开发软件是用keil 4,编写语言是用c
页: [1]
查看完整版本: 运动部件卡住报警器(应用实例矿车刹车加力器活塞卡住报警器)