機(jī)械社區(qū)
標(biāo)題: 運(yùn)動(dòng)部件卡住報(bào)警器(應(yīng)用實(shí)例礦車(chē)剎車(chē)加力器活塞卡住報(bào)警器) [打印本頁(yè)]
作者: 1五湖四海1 時(shí)間: 2015-4-18 10:40
標(biāo)題: 運(yùn)動(dòng)部件卡住報(bào)警器(應(yīng)用實(shí)例礦車(chē)剎車(chē)加力器活塞卡住報(bào)警器)
本帖最后由 1五湖四海1 于 2015-4-18 10:49 編輯 4 x* R6 h8 |6 p$ r
/ y$ C, `6 R3 }! S0 x v# P
我這小項(xiàng)目是為了解決運(yùn)動(dòng)的活塞是否被卡住而設(shè)計(jì)的。在實(shí)際中汽車(chē)剎車(chē)系統(tǒng)出現(xiàn)故障容易造成重大事故發(fā)生。我們的礦車(chē)有兩個(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
3 ~8 H& b( ?' a- k
#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"
% q2 ^7 x8 H2 A& a- O1 f) K#define LIM 5 //卡住判斷參數(shù)
#define TREAD 2 //踩剎車(chē)
#define LOOSEN 1 //松剎車(chē)
#define CLEAR 3 //清除
#define DIFFERENCE 50 //回差
$ e; Z8 Z) n3 L% ^, r1 ~9 ^, S' G( E& i( W4 k, Q
u16 lim_value = 1800; //極限報(bào)警值
u16 max_value_l = 1000, max_value_r = 1000; //踩剎車(chē)標(biāo)志值
u16 min_value_l = 3000, min_value_r = 3000; //松剎車(chē)標(biāo)志值
. o5 H+ e( x0 L$ Q( `u8 count = 0; //設(shè)置剎車(chē)標(biāo)志防干擾計(jì)數(shù)
u8 lock_count; //卡住時(shí)計(jì)數(shù)防干擾處理
( c) `& \ M8 e, E3 Wu16 distance_l[2] = {0,0}; //卡住比較數(shù)組
u16 distance_r[2] = {0,0};
u8 i = 0; //采集數(shù)據(jù)計(jì)數(shù)變量
( Z6 J: l+ K0 \! ]; ]' b3 G
bool brake_state_l, brake_state_r; //剎車(chē)狀態(tài)標(biāo)志位
bool lock_alarm_l, lock_alarm_r, lock_alarm; //卡住報(bào)警標(biāo)志位
4 ^/ u5 y: }) A8 s
u16 value_buf[N]; //濾波求平均緩存
u32 sum; //濾波求平均總和緩存
u16 temp; //濾波求排序緩存
2 G: \1 O; k9 L7 t4 d+ c
//判斷是否活塞卡住
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)志位
0 D1 Y8 P2 Y |5 d4 Z3 S; x' n 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í)打印
8 e7 o0 F- a- O! e( }- t
while(1)
{
lim_alarm_l = isOverrun(distance_l[0]); //返回超限標(biāo)志
lim_alarm_r = isOverrun(distance_r[0]);
//返回剎車(chē)中標(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)
{
& y" ~, |' S) q7 W B6 L
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;
& R9 {. [' B) U1 s; w3 v
data_collection(); //數(shù)據(jù)采集后判斷是否活塞卡住
& v$ l z C( H3 _* O }
TIM3->SR&=~(1<<0); //清除中斷標(biāo)志位
}
/**
功能:1.判斷左活塞是否卡住
2.設(shè)置剎車(chē)標(biāo)志
*/
bool is_stuck(u16 distance_zero, u16 distance_one, bool brake_state, u16 *max_value, u16 *min_value)
{
u8 motion;
& b3 z( O4 X: x I2 P+ E7 Y$ I if( (distance_one-distance_zero) > 5) //松剎車(chē)標(biāo)志
motion = LOOSEN;
7 ^* n# g7 a* I) Q2 K if( (distance_one-distance_zero) < -5) //踩剎車(chē)標(biāo)志
motion = TREAD;
& {, }' ?1 V4 X' w5 q% V, @) f+ m
if( ( (distance_one-distance_zero) < LIM) && ( (distance_zero-distance_one) < LIM) )
{
/*
踩剎車(chē)時(shí)動(dòng)態(tài)設(shè)置最小值剎車(chē)標(biāo)志*/
if(motion == TREAD)
/* 如果這次值比上次設(shè)置的標(biāo)志值小說(shuō)明上次是卡住值,更新最小值標(biāo)志*/
if(distance_zero+DIFFERENCE < *min_value )
*min_value = distance_zero+DIFFERENCE;
- d2 Q; p8 u X$ g' P, f. O/*
松剎車(chē)時(shí)動(dòng)態(tài)設(shè)置最大值剎車(chē)標(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;
}
Z; O4 A5 ]2 Y
motion = CLEAR; //清除剎車(chē)標(biāo)志
1 Y% R7 p/ u9 K' k( M! R* u
if( brake_state ) //剎車(chē)時(shí)如果卡住開(kāi)始計(jì)數(shù)
lock_count++;
* m( f% t2 o; n s, x* [
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)
{
7 _6 y5 r1 ~ g' i: k5 _7 O
u16 distance_zero, distance_one;
5 h! ^' d$ N) j: ]$ H: l5 M8 q filter(ADC_CH0);
distance_l = sum;
( K2 u3 L$ p3 I6 {* j
delay_ms(20);
' B: @. a4 M* R, R 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]);
}
}
$ a' O$ b' O1 I( l4 p5 x$ d
[attach]350382[/attach]
2 W0 T" p4 f8 R+ r) n6 R+ Z# F
3 T. g B# w! H2 a0 v: W2 n5 U
- N. d3 y6 o4 m; W8 v: C8 s
1 T6 v; t0 W# [' d' f5 I1 j. q/ s4 C" j
0 M* H- o! [+ Y& F5 Y! z+ x, l* X5 y
$ s+ M8 _) g1 ^
2 L- Q4 m5 l' G# W5 ^1 ~& |3 s$ T/ B, O: m: T& N
: L& U7 E. `! M" e; j9 Y( W' ~/ N+ M2 j( u% {8 C( R! |. W/ \, c
' O4 Z) N o$ G2 x: ]
6 C0 S( v) b& o1 G, H6 s
- s6 _1 ` D) P" u& |
: v0 e9 o4 e/ y' p8 W: H$ A
5 j; L7 A4 f* c# j$ Y
( H, p# A2 |% \+ g. G- D6 t) Z0 q+ N: Z( X" b% s) i# Q, t
4 S: w. w" l4 K2 t9 q, N. M
5 {5 R: K5 T s5 r. L% V
作者: 竹桿捅飛機(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://e-learninguniversity.com/) |
Powered by Discuz! X3.4 |