机械必威体育网址

 找回密码
 注册会员

QQ登录

只需一步,快速开始

搜索
查看: 2237|回复: 6
打印 上一主题 下一主题

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

[复制链接]
跳转到指定楼层
1#
发表于 2015-4-18 10:40:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 1五湖四海1 于 2015-4-18 10:49 编辑 * L! \6 z' y9 k7 P, z4 q2 H2 L

* K  o' m4 N- i. P$ v! l) \" I' ]3 L
      我这小项目是为了解决运动的活塞是否被卡住而设计的。在实际中汽车刹车系统出现故障容易造成重大事故发生。我们的矿车有两个加力器,如果一个加力器出现问题能及时发现是可以避免事故的发生。所以制作这个运动部件卡住报警器对安全是很有必要的。
      实现原理上用一个能够检测距离的模拟量传感器。控制器先判断运动部件是否受人为控制开始运动,如果部件开始运动,控制器的模数转换器每隔一段时间采集一次距离,控制器计算前后两次采集距离值是否一样,就可以判断运动部件是否被卡住不动了。下面介绍下用到的器件和具体设计细节。
      距离传感器用的是光电模拟量输出传感器,检测范围在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

5 s# ~: `) k2 M' s8 i$ V
#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"
$ X- Q  _! d* L: W* i0 Y( v
#define LIM 5                                                                              //卡住判断参数
#define TREAD 2                                                                        //踩刹车
#define LOOSEN 1                                                                     //松刹车
#define CLEAR 3                                                                        //清除
#define DIFFERENCE 50                                                            //回差
3 A8 Z& I1 U  h

( b$ Y, D( R: `0 P2 _
u16 lim_value = 1800;                                                              //极限报警值
u16 max_value_l = 1000, max_value_r = 1000;                      //踩刹车标志值
u16 min_value_l = 3000, min_value_r = 3000;                        //松刹车标志值
7 f( E2 V; b5 L; c
u8 count = 0;                                                                          //设置刹车标志防干扰计数                                                        
u8 lock_count;                                                                        //卡住时计数防干扰处理

- `0 V* ^2 K+ `
u16 distance_l[2] = {0,0};                                                      //卡住比较数组
u16 distance_r[2] = {0,0};
u8 i = 0;                                                                                 //采集数据计数变量
: @+ O4 H7 J; }' }9 z
bool brake_state_l, brake_state_r;                                         //刹车状态标志位
bool lock_alarm_l, lock_alarm_r, lock_alarm;                          //卡住报警标志位
" l6 w& U, I4 Q/ w* S0 W
u16 value_buf[N];                                                                 //滤波求平均缓存
u32 sum;                                                                              //滤波求平均总和缓存
u16 temp;                                                                             //滤波求排序缓存

. N' E5 Y6 ^; d5 k2 o
                                                                                             //判断是否活塞卡住
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;                                      //超限警报标志位                  
  d) d- b  I( {9 w! s
          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);                                            //定时打印
) [9 A, r8 ?) P/ U
        while(1)
        {                        
                lim_alarm_l = isOverrun(distance_l[0]);                        //返回超限标志
                lim_alarm_r = isOverrun(distance_r[0]);
                                                                                                   //返回刹车中标志
                brake_state_l = isBrake_state(distance_l[0], max_value_l, min_value_l);        
                brake_state_r = isBrake_state(distance_r[0], max_value_r, min_value_r);
                                                                                                   //报警处理函数
                Alarm_dispose(lim_alarm_l, lim_alarm_r, lock_alarm);
        }
}
/**
        定时器2中断服务程序
        功能:发生定时中断控制蜂鸣器报警         
*/
void TIM2_IRQHandler(void)
{

) ?* [8 V" O6 i+ X1 H2 g
        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;        

' k7 e* ~( t, G6 \
                data_collection();                                                          //数据采集后判断是否活塞卡住                                                
8 L" W/ N; \+ e' S- }6 I
        }                                          
        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;                  

. L3 Y, o/ o( c8 ^# l6 h4 W; n
        if( (distance_one-distance_zero) > 5)                        //松刹车标志
                motion = LOOSEN;
% ~" e( {, u1 w
        if( (distance_one-distance_zero) < -5)                        //踩刹车标志
                motion = TREAD;
3 ^/ u2 W5 h9 l1 \$ Z# q
        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;

, {. ^* i+ x- A" n' P4 l; _
/*
                                                松刹车时动态设置最大值刹车标志*/                        
                if(motion == LOOSEN)
/*                                                如果这次值比上次设置的标志值大说明上次是卡住值,更新新的标志*/
                        if(distance_zero-DIFFERENCE > *max_value )
                                count++;         //防干扰计数
                        if(count > 1)
                        {
                                *max_value = distance_zero-DIFFERENCE;
                                   count = 0;
                        }        
! W( z. N9 W. D( Y2 ~) y# o1 C
                motion = CLEAR;                                                //清除刹车标志

. p/ y( D# M4 ]% h, p* f  r+ m
                if( brake_state )                                                  //刹车时如果卡住开始计数
                        lock_count++;
, X9 ?9 P5 Z1 P, Q0 f. g6 s6 H4 `
                if( lock_count >= 5 )                                          //计数五次后报警位置位
                {
                        lock_count = 5;
                        return TRUE;
                }
        }
        else
        {
//                lock_alarm = 0;
                lock_count = 0;
                return FALSE;
        }
}
/**
        功能:判断活塞是否卡住数据采集函数
*/
void data_collection(void)
{

; e) }3 k4 \+ Y6 m
        u16 distance_zero, distance_one;        

, b1 q0 u( t6 d, f% S6 T& u0 B% q
        filter(ADC_CH0);
        distance_l = sum;
7 `# w; D( K* F. x4 L
        delay_ms(20);

2 h% `6 ^" ~. z* @; x
        filter(ADC_CH1);
        distance_r = sum;
        i++;
         if(i > 1)                //采集了两组数据后判断一次是否卡住
        {
                i = 0;
                distance_zero = distance_l[0];
                distance_one  = distance_l[1];
                lock_alarm_l  = is_stuck(distance_zero, distance_one, brake_state_l, &max_value_l, &min_value_l);                          
                distance_zero = distance_r[0];
                distance_one  = distance_r[1];
                lock_alarm_r  = is_stuck(distance_zero, distance_one, brake_state_r, &max_value_r, &min_value_r);                          
//                 d_value = distance_l[1]-distance_l[0];                        
//                 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[0],distance_l[1],distance_r[0],distance_r[1]);
//                printf("%d,%d\n",distance_l[1]-distance_l[0],distance_r[1]-distance_r[0]);
//                printf("%d\n",distance_r[1]-distance_r[0]);
        }        
}

. s3 z/ v! p  Q- T6 Q( L' `1 j

) t  ^- x* v# }# v7 I; T( ]" v! k5 m$ J

: n4 ]3 [! f) R$ M  \8 O; \2 R; S' I; K; w5 T

2 s6 C; e  }! _6 c& r5 d: L3 U0 r5 |, ~5 S' c
2 ^2 c% V' W& c) ?, t
4 [% \: p6 @5 g& ^. p

5 _4 g  R9 X* z( s$ g+ j
/ b% E. w9 |2 T: y) [: K4 o3 ~- V0 M: L( R
7 H) b5 v7 J5 i1 ^3 w7 c
* n- B( Y6 y% D
6 T+ w5 _* H0 _; D  M6 P
/ `: c* |) d, @, h; |, {6 G
% Y/ K9 p/ J+ t7 V$ [
! m  B2 I- v1 S, {

$ K* k( o& b2 k1 c4 c5 V! w8 {* S, L; K& [6 x

! M5 I* d9 {9 o/ b. x

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册会员

x

评分

参与人数 1威望 +100 收起 理由
老鹰 + 100

查看全部评分

回复

使用道具 举报

2#
发表于 2015-4-18 11:10:39 | 只看该作者
回复 支持 反对

使用道具 举报

3#
发表于 2015-4-18 11:19:35 | 只看该作者
大侠用的啥编程软件?c++吗?
回复 支持 反对

使用道具 举报

4#
发表于 2015-4-18 15:37:17 | 只看该作者
好像很复杂的
回复 支持 反对

使用道具 举报

5#
发表于 2015-4-18 15:43:23 | 只看该作者
赞赞赞
回复 支持 反对

使用道具 举报

6#
发表于 2015-4-18 16:57:23 | 只看该作者
   代码什么的就看不懂了
回复 支持 反对

使用道具 举报

7#
 楼主| 发表于 2015-4-18 17:22:48 | 只看该作者
开发软件是用keil 4,编写语言是用c
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

小黑屋|手机版|Archiver|机械必威体育网址 ( 京ICP备10217105号-1,京ICP证050210号,浙公网安备33038202004372号 )

GMT+8, 2024-11-23 02:01 , Processed in 0.060165 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表