機(jī)械社區(qū)

標(biāo)題: 運(yùn)動(dòng)部件卡住報(bào)警器(應(yīng)用實(shí)例礦車剎車加力器活塞卡住報(bào)警器) [打印本頁(yè)]

作者: 1五湖四海1    時(shí)間: 2015-4-18 10:40
標(biāo)題: 運(yùn)動(dòng)部件卡住報(bào)警器(應(yīng)用實(shí)例礦車剎車加力器活塞卡住報(bào)警器)
本帖最后由 1五湖四海1 于 2015-4-18 10:49 編輯 * B6 f: k+ e5 e

' x" |/ \, N( I' t% {
      我這小項(xiàng)目是為了解決運(yùn)動(dòng)的活塞是否被卡住而設(shè)計(jì)的。在實(shí)際中汽車剎車系統(tǒng)出現(xiàn)故障容易造成重大事故發(fā)生。我們的礦車有兩個(gè)加力器,如果一個(gè)加力器出現(xiàn)問(wèn)題能及時(shí)發(fā)現(xiàn)是可以避免事故的發(fā)生。所以制作這個(gè)運(yùn)動(dòng)部件卡住報(bào)警器對(duì)安全是很有必要的。
      實(shí)現(xiàn)原理上用一個(gè)能夠檢測(cè)距離的模擬量傳感器?刂破飨扰袛噙\(yùn)動(dòng)部件是否受人為控制開(kāi)始運(yùn)動(dòng),如果部件開(kāi)始運(yùn)動(dòng),控制器的模數(shù)轉(zhuǎn)換器每隔一段時(shí)間采集一次距離,控制器計(jì)算前后兩次采集距離值是否一樣,就可以判斷運(yùn)動(dòng)部件是否被卡住不動(dòng)了。下面介紹下用到的器件和具體設(shè)計(jì)細(xì)節(jié)。
      距離傳感器用的是光電模擬量輸出傳感器,檢測(cè)范圍在10mm——100mm。如下圖中兩個(gè)圓柱形的便是距離傳感器。
[attach]350378[/attach][attach]350381[/attach]
      控制器用的是ARM cortek M3 STM32f103,有人會(huì)問(wèn)為什么要用這個(gè)高性能的處理器呢?我認(rèn)為現(xiàn)在已經(jīng)不是51單片機(jī)是世界了,51單片機(jī)沒(méi)有AD轉(zhuǎn)換器,需要外接AD轉(zhuǎn)換器,代碼需要從零開(kāi)始寫(xiě)。而ARM cortek M3 里面有10bit AD轉(zhuǎn)換器,有大量的寫(xiě)好的庫(kù)函數(shù)可以調(diào)用,可以縮短開(kāi)發(fā)時(shí)間。他們的價(jià)格差不多為什么不選STM32f10。這次用的是現(xiàn)成的STM32f103最小系統(tǒng)板。如上圖
      代碼設(shè)計(jì)上用到了兩個(gè)定時(shí)器中斷,一個(gè)定時(shí)器每隔200ms采集一次距離值,另一個(gè)發(fā)生故障時(shí)每隔500ms報(bào)警一次,用到的算法有AD軟件濾波,采集500次距離值后,用冒泡排序法去掉最大值和最小值后,再求平均數(shù)算出距離值,這時(shí)采集的距離值很準(zhǔn)。剩下的就是用if else編寫(xiě)的邏輯判斷了。調(diào)試時(shí)用到了printf()庫(kù)函數(shù),結(jié)合電腦串口調(diào)試助手調(diào)試代碼。調(diào)試代碼如下圖,部分程序代碼在最下面
[attach]350377[/attach][attach]350379[/attach]
      完成的控制器如上圖,正常工作時(shí)指示燈和蜂鳴器不亮也不響,如果活塞被卡住時(shí)聲光報(bào)警。
[attach]350380[/attach]
      上圖是加力器,它是用氣頂動(dòng)油完成輸出二倍力的器件。如果活塞卡死這個(gè)報(bào)警就會(huì)報(bào)警提示故障。
      下面是代碼是主函數(shù)代碼 最下面有全部代碼如果有問(wèn)題可以和我交流,QQ:835358518 微信:hm15041303104
1 i0 t2 g0 Q9 W/ q7 l+ g
#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"
, t6 F! ?2 ^- T9 h+ K2 a$ H
#define LIM 5                                                                              //卡住判斷參數(shù)
#define TREAD 2                                                                        //踩剎車
#define LOOSEN 1                                                                     //松剎車
#define CLEAR 3                                                                        //清除
#define DIFFERENCE 50                                                            //回差
( l1 E- W( d+ s0 c3 n9 ~

7 J1 K6 H3 n! h5 m( z6 J
u16 lim_value = 1800;                                                              //極限報(bào)警值
u16 max_value_l = 1000, max_value_r = 1000;                      //踩剎車標(biāo)志值
u16 min_value_l = 3000, min_value_r = 3000;                        //松剎車標(biāo)志值
. O: c4 n5 r3 A" f, i- z4 K3 P
u8 count = 0;                                                                          //設(shè)置剎車標(biāo)志防干擾計(jì)數(shù)                                                        
u8 lock_count;                                                                        //卡住時(shí)計(jì)數(shù)防干擾處理
7 U5 s1 H1 \7 S
u16 distance_l[2] = {0,0};                                                      //卡住比較數(shù)組
u16 distance_r[2] = {0,0};
u8 i = 0;                                                                                 //采集數(shù)據(jù)計(jì)數(shù)變量
& s8 x$ c" e& m! G5 \' ?5 G" c
bool brake_state_l, brake_state_r;                                         //剎車狀態(tài)標(biāo)志位
bool lock_alarm_l, lock_alarm_r, lock_alarm;                          //卡住報(bào)警標(biāo)志位

- ^8 m# m# G" q! B' B& ~. `: |
u16 value_buf[N];                                                                 //濾波求平均緩存
u32 sum;                                                                              //濾波求平均總和緩存
u16 temp;                                                                             //濾波求排序緩存

! k# ~1 I; z0 r- v4 D, B0 S( }
                                                                                             //判斷是否活塞卡住
bool is_stuck(u16 distance_zero, u16 distance_one, bool brake_state, u16 *max_value, u16 *min_value);                                                                                
void data_collection(void);                                                    //數(shù)據(jù)采集
/**
        主函數(shù)        
*/
int main(void)
{
        bool lim_alarm_l, lim_alarm_r;                                      //超限警報(bào)標(biāo)志位                  

! l/ s/ w. m9 r' T( O6 R
          Stm32_Clock_Init(9);                                                //系統(tǒng)時(shí)鐘設(shè)置
        delay_init(72);                                                             //延時(shí)初始化
        uart_init(72,9600);                                                     //串口1初始化   
        LED_Init();                 
        Adc_Init();        
        Timer2_Init(5000,7199);                                              //定時(shí)報(bào)警
        Timer3_Init(2000,7199);                                              //定時(shí)采集ADC  
//        Timer4_Init(5000,7199);                                            //定時(shí)打印

/ B% i% q& t: F# T* t" ^4 F& m
        while(1)
        {                        
                lim_alarm_l = isOverrun(distance_l[0]);                        //返回超限標(biāo)志
                lim_alarm_r = isOverrun(distance_r[0]);
                                                                                                   //返回剎車中標(biāo)志
                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);
                                                                                                   //報(bào)警處理函數(shù)
                Alarm_dispose(lim_alarm_l, lim_alarm_r, lock_alarm);
        }
}
/**
        定時(shí)器2中斷服務(wù)程序
        功能:發(fā)生定時(shí)中斷控制蜂鳴器報(bào)警         
*/
void TIM2_IRQHandler(void)
{
2 r2 {2 s' R9 Y0 U; `' S
        if(TIM2->SR&0X0001)                                //溢出中斷
        {        
                BUZZER = 0;
                delay_ms(100);
                BUZZER = 1;                        
        }                                   
        TIM2->SR&=~(1<<0);                                //清除中斷標(biāo)志位             
}        
/**
        定時(shí)器3中斷服務(wù)程序         
        功能:發(fā)生定時(shí)中斷時(shí)采集ADC數(shù)據(jù),并根據(jù)判斷活塞是否卡住
*/         
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;        

# b* X/ O" P1 y& Q# ?8 t4 N
                data_collection();                                                          //數(shù)據(jù)采集后判斷是否活塞卡住                                                

6 \- U7 f3 D7 E6 x! I6 Y  F
        }                                          
        TIM3->SR&=~(1<<0);                                                        //清除中斷標(biāo)志位             
}
/**
        功能:1.判斷左活塞是否卡住
                  2.設(shè)置剎車標(biāo)志        
*/
bool is_stuck(u16 distance_zero, u16 distance_one, bool brake_state, u16 *max_value, u16 *min_value)
{
        u8 motion;                  
4 F3 G! N2 w- P+ r0 d1 U
        if( (distance_one-distance_zero) > 5)                        //松剎車標(biāo)志
                motion = LOOSEN;

5 |9 f  K9 R( [  d
        if( (distance_one-distance_zero) < -5)                        //踩剎車標(biāo)志
                motion = TREAD;
. ?( n- S& L3 R
        if( ( (distance_one-distance_zero) < LIM) && ( (distance_zero-distance_one) < LIM) )
        {
/*                                                
                                                踩剎車時(shí)動(dòng)態(tài)設(shè)置最小值剎車標(biāo)志*/
                if(motion == TREAD)
/*                                                如果這次值比上次設(shè)置的標(biāo)志值小說(shuō)明上次是卡住值,更新最小值標(biāo)志*/
                        if(distance_zero+DIFFERENCE < *min_value )
                                *min_value = distance_zero+DIFFERENCE;

1 q- M0 s+ Z1 U2 r+ Y6 ^* \
/*
                                                松剎車時(shí)動(dòng)態(tài)設(shè)置最大值剎車標(biāo)志*/                        
                if(motion == LOOSEN)
/*                                                如果這次值比上次設(shè)置的標(biāo)志值大說(shuō)明上次是卡住值,更新新的標(biāo)志*/
                        if(distance_zero-DIFFERENCE > *max_value )
                                count++;         //防干擾計(jì)數(shù)
                        if(count > 1)
                        {
                                *max_value = distance_zero-DIFFERENCE;
                                   count = 0;
                        }        

( ?+ c1 f8 n2 R; d+ k0 C
                motion = CLEAR;                                                //清除剎車標(biāo)志
0 G) P; u# h1 b, D- C
                if( brake_state )                                                  //剎車時(shí)如果卡住開(kāi)始計(jì)數(shù)
                        lock_count++;

8 D/ L$ D) d: V) O4 V! o
                if( lock_count >= 5 )                                          //計(jì)數(shù)五次后報(bào)警位置位
                {
                        lock_count = 5;
                        return TRUE;
                }
        }
        else
        {
//                lock_alarm = 0;
                lock_count = 0;
                return FALSE;
        }
}
/**
        功能:判斷活塞是否卡住數(shù)據(jù)采集函數(shù)
*/
void data_collection(void)
{
# c  M' v& g6 u
        u16 distance_zero, distance_one;        

8 u* m$ C' ]& Q  b5 ^
        filter(ADC_CH0);
        distance_l = sum;
6 J4 b1 {0 f  B- S1 m" B
        delay_ms(20);

5 M! E8 w& g2 p. [6 G4 F' _
        filter(ADC_CH1);
        distance_r = sum;
        i++;
         if(i > 1)                //采集了兩組數(shù)據(jù)后判斷一次是否卡住
        {
                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]);
        }        
}
& |" j: r7 l9 U4 M
[attach]350382[/attach]
: C$ x% C% k2 R2 g
2 A' n3 h4 k& J8 s- `

4 ^& }+ k3 {2 L# e' G' P0 Y9 _6 J) n& A8 W" c% n  z
' ~: V9 U1 U4 A0 ~5 s: J$ [" n. c
7 `4 S6 g9 p; x* Z3 F
; E( s% r0 G! ?( P0 v$ T4 }/ e8 ]

! E5 ~, t$ B/ s' P% _& l* A9 M2 ^
  Q. X7 h7 o: c( }/ D
3 L/ f$ D5 q; Q9 l; |, i; w$ C2 ]1 y/ T% m

3 h% t; w- j8 A
( L3 _' p, Z+ G, m% o2 P, N6 n/ x  Z4 J
$ K2 ^- p# d+ b( \% X" M

- N( Z: D' B. [- w1 A+ f) w; X8 P5 `0 U" Q! M& }( ^7 @
) i0 Y$ z7 v0 [) b# j9 N4 d: M! e
, Y9 K$ x0 y+ w& h

/ d2 M- C' u9 N9 L

作者: 竹桿捅飛機(jī)    時(shí)間: 2015-4-18 11:10

作者: huhaofei    時(shí)間: 2015-4-18 11:19
大俠用的啥編程軟件?c++嗎?
作者: 龍游大海    時(shí)間: 2015-4-18 15:37
好像很復(fù)雜的
作者: 925269815    時(shí)間: 2015-4-18 15:43
贊贊贊
作者: 那年丶哥很帥    時(shí)間: 2015-4-18 16:57
   代碼什么的就看不懂了
作者: 1五湖四海1    時(shí)間: 2015-4-18 17:22
開(kāi)發(fā)軟件是用keil 4,編寫(xiě)語(yǔ)言是用c




歡迎光臨 機(jī)械社區(qū) (http://mg7058.com/) Powered by Discuz! X3.4