機械社區
標題: 運動部件卡住報警器(應用實例礦車剎車加力器活塞卡住報警器) [打印本頁]
作者: 1五湖四海1 時間: 2015-4-18 10:40
標題: 運動部件卡住報警器(應用實例礦車剎車加力器活塞卡住報警器)
本帖最后由 1五湖四海1 于 2015-4-18 10:49 編輯
! s' V. Q8 T! D5 ?8 I
* f1 {% D4 V! C+ T 我這小項目是為了解決運動的活塞是否被卡住而設計的。在實際中汽車剎車系統出現故障容易造成重大事故發生。我們的礦車有兩個加力器,如果一個加力器出現問題能及時發現是可以避免事故的發生。所以制作這個運動部件卡住報警器對安全是很有必要的。
實現原理上用一個能夠檢測距離的模擬量傳感器??刂破飨扰袛噙\動部件是否受人為控制開始運動,如果部件開始運動,控制器的模數轉換器每隔一段時間采集一次距離,控制器計算前后兩次采集距離值是否一樣,就可以判斷運動部件是否被卡住不動了。下面介紹下用到的器件和具體設計細節。
距離傳感器用的是光電模擬量輸出傳感器,檢測范圍在10mm——100mm。如下圖中兩個圓柱形的便是距離傳感器。
[attach]350378[/attach][attach]350381[/attach]
控制器用的是ARM cortek M3 STM32f103,有人會問為什么要用這個高性能的處理器呢?我認為現在已經不是51單片機是世界了,51單片機沒有AD轉換器,需要外接AD轉換器,代碼需要從零開始寫。而ARM cortek M3 里面有10bit AD轉換器,有大量的寫好的庫函數可以調用,可以縮短開發時間。他們的價格差不多為什么不選STM32f10。這次用的是現成的STM32f103最小系統板。如上圖
代碼設計上用到了兩個定時器中斷,一個定時器每隔200ms采集一次距離值,另一個發生故障時每隔500ms報警一次,用到的算法有AD軟件濾波,采集500次距離值后,用冒泡排序法去掉最大值和最小值后,再求平均數算出距離值,這時采集的距離值很準。剩下的就是用if else編寫的邏輯判斷了。調試時用到了printf()庫函數,結合電腦串口調試助手調試代碼。調試代碼如下圖,部分程序代碼在最下面
[attach]350377[/attach][attach]350379[/attach]
完成的控制器如上圖,正常工作時指示燈和蜂鳴器不亮也不響,如果活塞被卡住時聲光報警。
[attach]350380[/attach]
上圖是加力器,它是用氣頂動油完成輸出二倍力的器件。如果活塞卡死這個報警就會報警提示故障。
下面是代碼是主函數代碼 最下面有全部代碼如果有問題可以和我交流,QQ:835358518 微信:hm15041303104
+ E- R# e2 C% u/ @. v# 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"
$ V- i7 Y6 y/ Y3 ?( E! i1 i#define LIM 5 //卡住判斷參數
#define TREAD 2 //踩剎車
#define LOOSEN 1 //松剎車
#define CLEAR 3 //清除
#define DIFFERENCE 50 //回差
7 y# t& v* A2 l; z& b+ C7 W" y2 ~8 e; M( X8 _1 `! d
u16 lim_value = 1800; //極限報警值
u16 max_value_l = 1000, max_value_r = 1000; //踩剎車標志值
u16 min_value_l = 3000, min_value_r = 3000; //松剎車標志值
U ~* u1 a2 Q9 _* f
u8 count = 0; //設置剎車標志防干擾計數
u8 lock_count; //卡住時計數防干擾處理
8 w9 Z0 U+ G, F ], J6 P
u16 distance_l[2] = {0,0}; //卡住比較數組
u16 distance_r[2] = {0,0};
u8 i = 0; //采集數據計數變量
w8 n) P T' A3 ]' J) Ubool brake_state_l, brake_state_r; //剎車狀態標志位
bool lock_alarm_l, lock_alarm_r, lock_alarm; //卡住報警標志位
+ X* B# i5 l0 c
u16 value_buf[N]; //濾波求平均緩存
u32 sum; //濾波求平均總和緩存
u16 temp; //濾波求排序緩存
+ `8 P' f5 A! V5 P
//判斷是否活塞卡住
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; //超限警報標志位
! {$ m3 w/ X( k- E; ^7 I1 m6 N
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); //定時打印
2 w# g: X) \7 |# W 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)
{
3 _; d. H+ \! N; [& A5 w 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;
4 P. O# ]$ I: ]; t; m# J" T* t, m
data_collection(); //數據采集后判斷是否活塞卡住
Q' @$ V; L& u6 F- r( D7 N }
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;
8 }3 F/ x. v* h2 R if( (distance_one-distance_zero) > 5) //松剎車標志
motion = LOOSEN;
/ p7 x" C8 U ? if( (distance_one-distance_zero) < -5) //踩剎車標志
motion = TREAD;
' s+ j& Y: h9 H) K% X
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;
; t! J- S# y( p% `3 \. i
/*
松剎車時動態設置最大值剎車標志*/
if(motion == LOOSEN)
/* 如果這次值比上次設置的標志值大說明上次是卡住值,更新新的標志*/
if(distance_zero-DIFFERENCE > *max_value )
count++; //防干擾計數
if(count > 1)
{
*max_value = distance_zero-DIFFERENCE;
count = 0;
}
/ C0 F( w; Q% V9 ^/ h- a) i6 H) D- e motion = CLEAR; //清除剎車標志
/ R! l7 c6 v1 l+ O$ S
if( brake_state ) //剎車時如果卡住開始計數
lock_count++;
& H" B4 A: C- o5 s0 E# \$ V* L
if( lock_count >= 5 ) //計數五次后報警位置位
{
lock_count = 5;
return TRUE;
}
}
else
{
// lock_alarm = 0;
lock_count = 0;
return FALSE;
}
}
/**
功能:判斷活塞是否卡住數據采集函數
*/
void data_collection(void)
{
' f5 _' y3 J4 G0 \ u16 distance_zero, distance_one;
8 K# c8 ~$ k6 }2 v
filter(ADC_CH0);
distance_l = sum;
5 i5 o6 ^' x8 p: k% c* U delay_ms(20);
0 e+ W F' b" @+ b' |4 Y. v 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]);
}
}
7 ?: y( V5 o& J5 a) d! n
[attach]350382[/attach]
" R8 ?9 ^" y- \% @( N; b' p, s( f( J! Z8 `
: g+ n: L; `9 o% _# t0 k0 V& R' j1 `
& b3 O U) G+ p* |( s0 X( q% T8 g% k( p
6 k) k: }: i1 z; `! P# y" |$ X5 a
6 Y B) @. V' L, x: c& d, O p
6 W4 X3 h' x$ s1 L- Y, I& Y7 U+ e% o8 D$ N& @$ ^
, Z$ x7 A" P$ Q
& L" w, [( K+ W3 F8 [( Q8 R
1 k5 |% ^! m9 R3 z+ Z( A) ^9 X6 j2 J0 @) Q) \
7 V9 {' o6 e3 u4 n1 v" B5 [3 I
" | X+ t* n( I% F% Q. b
4 n/ S" T, ~9 W( k I
6 f1 f* H3 g- |$ P6 X
, N/ \6 _3 N* O$ A3 f
, Z! q6 n$ }) |! P1 I
& a. N: [7 U- Y6 x8 t
作者: 竹桿捅飛機 時間: 2015-4-18 11:10
贊
作者: huhaofei 時間: 2015-4-18 11:19
大俠用的啥編程軟件?c++嗎?
作者: 龍游大海 時間: 2015-4-18 15:37
好像很復雜的
作者: 925269815 時間: 2015-4-18 15:43
贊贊贊
作者: 那年丶哥很帥 時間: 2015-4-18 16:57
代碼什么的就看不懂了
作者: 1五湖四海1 時間: 2015-4-18 17:22
開發軟件是用keil 4,編寫語言是用c
歡迎光臨 機械社區 (http://www.ytsybjq.com/) |
Powered by Discuz! X3.5 |