?? resp.c
字號:
#include "comuse.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
////////////////////////////////////////////////////////////////////////////////
int SAMPLE_RATE=125;
//#define SAMPLE_RATE 125 //8ms調(diào)用一次所以是125
#define CALPERIOD 2000 //最小是15/分的呼吸波,4秒一個(gè)波形,4秒500個(gè)點(diǎn),2000個(gè)點(diǎn)16秒,4個(gè)波形
int resp_rate=0;
int iCalCnt=0;
void calculate(int Restdata) //
{
// constant definitions
#define INIT_VALIDDIRLEN 8 // initial ValidDirCheckLen(Rising/Falling enough length)
#define INIT_MAXDISTURBLEN 2 // initial Maximum disturb length
#define RESET_PERIOD 30 // Timer in Second for no valid Reset found reset
#define VALIDDIRLEN_PROP 8 // Properation of ValidDirectCheckLen as RespPeriod
#define MIN_VALIDDIRLEN 2 // Minimum ValidDirCheckLen for disturb tolerence //
#define MAX_VALIDDIRLEN 40 // Minimum ValidDirCheckLen for MaxRespRate find //
#define MAXDISTLEN_PROP 4 // Properation of MaxDisturbLen as ValidDirectCheckLen
#define MIN_MAXDISTLEN 1 // Minimum MaxDisturbLen //
#define INIT_RESPPERIOD 300 // Init Resp Period(for RespRate=15 at 80hz sample rate) 有問題,采樣率是125應(yīng)該是500次一個(gè)呼吸周期(resprate=15)
#define INIT_DIR_LEN 2 // minimum length of first Rising/Falling
// disturb ___means Falling/Rising while count the length of Rising/Falling
// if define this constant,the discret disturb will all be counted
// else only continous disturb will be counted
//#define DISCRET_DISTURB 1
// define this constant for running in Windows enviroment
//#define RUN_IN_WINDOWS 1
// define this constant if want a mark to be drawn on key pos
//#define DRAW_MARK 1
static short ValidDirLenUp = INIT_VALIDDIRLEN; // up threthold of sucessive Rising/Falling length
static short MaxDisturbLen = INIT_MAXDISTURBLEN; // up threthold of sucessive disturb length
static short ProcStage = 0; // process stage counter
static unsigned short BegRisingPos = 0; // first(initial) Rising position
static unsigned short SecondRisingPos; // Second(after valid length of falling) Rising position
static unsigned short PeriodCnt = 0; // counter for remember the postion
static unsigned short PeriodAveragePos = 0; // begin pos of PeriodAverage
static short RisingCount = 0; // Sucessive Rising length counter
static short FallingCount = 0; // Sucessive Falling length counter
static short LearnOver = 0; // flag for any valid peak found
static unsigned long PeriodAverage = 0; // average of every period for checking of SecondRising validity
static unsigned long PeriodAverageRn = 0; // average of every rising renew the PeriodAvarege
static short LastData = 128;
short Data = Restdata; // the current sample data
//#if !defined RUN_IN_WINDOWS
//#define DRAW_SMP_RATE 4
// static short DrawCount = DRAW_SMP_RATE;
//#define SAMPLE_RATE 82
//#endif
static short ResetCnt = 0; // Process reset WatchDog timer counter
static short CntRespPeriod = INIT_RESPPERIOD; // current found RespPeriod
static short LastRespPeriod = INIT_RESPPERIOD; // Last found RespPeriod
static short PeriodAcc = 0; // Accumulate of RespPeriod when not accept
static short PeriodAccCnt = 0; // Count of RespPeriodACC when not accept
#define WEIGHT_ACC_LEN 12 // up limit of PeriodAcc length that will be accept
static short Weight[4]={WEIGHT_ACC_LEN,6,3,2};
static short WeightAcc = 0;
#define MIN_RESPRATE 3
#define MAX_RESPRATE 120
if(iCalCnt++>=CALPERIOD)
iCalCnt=0;
PeriodCnt++;
if( PeriodCnt == 0 )
{
PeriodCnt = (BegRisingPos < SecondRisingPos) ? BegRisingPos : SecondRisingPos; //取小的
PeriodCnt = (PeriodCnt < PeriodAveragePos) ? PeriodCnt : PeriodAveragePos;
BegRisingPos -= PeriodCnt; //從PeriodCnt開始記一個(gè)新的周期
SecondRisingPos -= PeriodCnt;
PeriodAveragePos -= (PeriodCnt-1);
PeriodCnt = 0-PeriodCnt;
}
// If the time period of no valid resp found more than given period,reset the
// process to learning again
ResetCnt++;
if( LearnOver && ResetCnt>RESET_PERIOD*SAMPLE_RATE )
{
ProcStage = 0;
ValidDirLenUp = INIT_VALIDDIRLEN; //8
MaxDisturbLen = INIT_MAXDISTURBLEN; //2
ResetCnt = 0;
PeriodCnt = 1;
LearnOver = 0;
RisingCount = 0;
FallingCount = 0;
CntRespPeriod = INIT_RESPPERIOD; // current found RespPeriod=300
LastRespPeriod = INIT_RESPPERIOD; // Last found RespPeriod=300
PeriodAveragePos = 0;
PeriodAverage = 0;
#if !defined RUN_IN_WINDOWS
resp_rate = -1; // for indicator of no RespRate detected
#endif
}
Data = (Data+LastData+1)/2; // average with roundup
PeriodAverage += Data;
if(ProcStage==0)
{
if( Data > LastData )
{
RisingCount++;
if( RisingCount == INIT_DIR_LEN ) //INIT_DIR_LEN =2
{
BegRisingPos = PeriodCnt; //上升沿起始位置1
ProcStage++;
RisingCount = 0; //上升沿計(jì)數(shù)清零
FallingCount = 0; //下降沿計(jì)數(shù)清零
}
}
else if( Data < LastData ) RisingCount = 0; //找上升沿起始位置
}
else if(ProcStage==1)
{
if( Data >= LastData )
{
RisingCount++;
if( RisingCount > ValidDirLenUp ) //ValidDirLenUp=8
{
ProcStage++;
RisingCount = 0; //如果找到8個(gè)連續(xù)的上升就認(rèn)為找到上升沿了
FallingCount = 0;
}
//#if defined DISCRET_DISTURB
// if( Data > LastData ) FallingCount = 0;
//#else
FallingCount = 0;
//#endif
}
else if( Data < LastData ) //如果有兩個(gè)連續(xù)的 下降沿就說明有干擾,重新開始算
{
FallingCount++;
if( FallingCount > MaxDisturbLen )
{
ProcStage = 0;
ValidDirLenUp = INIT_VALIDDIRLEN; //8
MaxDisturbLen = INIT_MAXDISTURBLEN; //2
ResetCnt = 0;
PeriodCnt = 0;
LearnOver = 0;
RisingCount = 0;
FallingCount = 0;
CntRespPeriod = INIT_RESPPERIOD; // current found RespPeriod
LastRespPeriod = INIT_RESPPERIOD; // Last found RespPeriod
PeriodAveragePos = 0;
PeriodAverage = 0;
#if !defined RUN_IN_WINDOWS
resp_rate = -1; // for indicator of no RespRate detected
#endif
}
}
}
if(ProcStage==2) //找下降沿
{
if( Data < LastData )
{
FallingCount++;
if( FallingCount == INIT_DIR_LEN ) //如果發(fā)現(xiàn)連續(xù)2個(gè)下降沿就進(jìn)入procstage3
{
ProcStage++;
FallingCount = 0;
RisingCount = 0;
}
}
else if( Data > LastData ) FallingCount = 0;
}
else if(ProcStage==3)
{
if( Data <= LastData )
{
FallingCount++;
if( FallingCount > ValidDirLenUp ) //如果有8個(gè)連續(xù)的下降沿 說明找到下降沿了
{
ProcStage++; //進(jìn)入procstage4
RisingCount = 0;
FallingCount = 0;
}
//#if defined DISCRET_DISTURB
// if( Data < LastData ) RisingCount = 0;
//#else
RisingCount = 0;
//#endif
}
else if( Data > LastData )
{
RisingCount++;
if( RisingCount > MaxDisturbLen ) ProcStage = 2; //如果有上升沿的干擾,那么重新開始找下降沿
}
}
else if(ProcStage==4) //找第二個(gè)上升沿
{
if( Data > LastData )
{
RisingCount++;
if( RisingCount == INIT_DIR_LEN ) // 如果連續(xù)2個(gè)上升沿且不大于平均值
{ // if the Second Rising pos is above average,invalid
if( Data <= (int)(PeriodAverage/(PeriodCnt-PeriodAveragePos)) )
{
SecondRisingPos = PeriodCnt;
PeriodAverageRn = PeriodAverage; // remeber the begin of Re-Average
ProcStage++;
RisingCount = 0;
FallingCount = 0;
}
else
RisingCount = 0;
}
}
else if( Data < LastData ) RisingCount = 0;
}
else if(ProcStage==5)
{
if( Data >= LastData )
{
RisingCount++;
if( RisingCount > ValidDirLenUp ) //連續(xù)發(fā)現(xiàn)8個(gè)上升沿
{
CntRespPeriod = SecondRisingPos-BegRisingPos; //計(jì)算CntRespPeriod
FallingCount = 0;
RisingCount = 0;
// a valid wave peak found and to calculate the RespRate
// to check its validity
if( LearnOver ) // valid check only when any valid found before
{ // for RespRate<MIN_RESPRATE,To find initial Rising
if( CntRespPeriod >= 60*SAMPLE_RATE/MIN_RESPRATE )
{
ProcStage = 0;
ValidDirLenUp = INIT_VALIDDIRLEN;
MaxDisturbLen = INIT_MAXDISTURBLEN;
ResetCnt = 0;
PeriodCnt = 0;
LearnOver = 0;
RisingCount = 0;
FallingCount = 0;
CntRespPeriod = INIT_RESPPERIOD; // current found RespPeriod
LastRespPeriod = INIT_RESPPERIOD; // Last found RespPeriod
PeriodAveragePos = 0;
PeriodAverage = 0;
#if !defined RUN_IN_WINDOWS
resp_rate = -1; // for indicator of no RespRate detected
#endif
return;
}
// for RespRate>MAX_RESPRATE,Continue to find new Rising after enough falling
else if( CntRespPeriod <= 60*SAMPLE_RATE/MAX_RESPRATE)
{
ProcStage = 4;
return;
}
else
{
int WeightIndex;
ResetCnt = 0;
PeriodAcc +=CntRespPeriod;
PeriodAccCnt++;
if( CntRespPeriod>LastRespPeriod )
{
WeightIndex = (2*CntRespPeriod-LastRespPeriod)/(2*LastRespPeriod);
}
else
{
WeightIndex = 4*(LastRespPeriod-CntRespPeriod)/LastRespPeriod;
}
BegRisingPos = SecondRisingPos;
PeriodAveragePos = SecondRisingPos;
PeriodAverage -= PeriodAverageRn;
WeightAcc += Weight[WeightIndex];
if( WeightAcc < WEIGHT_ACC_LEN )
{ // research from Stage2
ProcStage = 2; // (To find Falling)
return;
}
CntRespPeriod = PeriodAcc/PeriodAccCnt;
LastRespPeriod = (CntRespPeriod+LastRespPeriod+1)/2;
}
}
// for LeasrnOver = 0,accept the Period directly
else
{
LastRespPeriod = CntRespPeriod;
LearnOver = 1;
}
PeriodAcc = 0;
PeriodAccCnt = 0;
WeightAcc = 0;
// renew the deciding limit
ValidDirLenUp = LastRespPeriod/VALIDDIRLEN_PROP;
if( ValidDirLenUp < MIN_VALIDDIRLEN ) ValidDirLenUp = MIN_VALIDDIRLEN;
if( ValidDirLenUp > MAX_VALIDDIRLEN ) ValidDirLenUp = MAX_VALIDDIRLEN;
MaxDisturbLen = ValidDirLenUp/MAXDISTLEN_PROP;
if( MaxDisturbLen < MIN_MAXDISTLEN ) MaxDisturbLen = MIN_MAXDISTLEN;
ProcStage = 2; // (To find Falling)
resp_rate = (60*SAMPLE_RATE+LastRespPeriod/2)/LastRespPeriod;
//if(bSampleRT200==1)resp_rate=resp_rate-(resp_rate/5);//(resp_rate<<2)/5;
}
//#if defined DISCRET_DISTURB
// if( Data > LastData ) FallingCount = 0;
//#else
FallingCount = 0;
//#endif
}
else if( Data < LastData )
{
FallingCount++;
if( FallingCount > MaxDisturbLen ) ProcStage = 4;
}
}
LastData = Data;
}
////////////////////////////////////////////////////////////////////////////////
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -