#include #include #asm .equ __lcd_port = 0x15 #endasm #include #include #include #include //define states for Measure control #define Sys_Measure 6 #define Sys_Cal 7 #define Rate_Measure 8 #define dias_Measure 9 #define dias_Cal 10 #define LCDwidth 16 void initialize(void); //declare all functions for measuring control void pressuremeasure(void); void sysmeasure(void); void syscal(void); void ratemeasure(void); void diasmeasure(void); void diascal(void); //declare variable for measuring and calculating value float DC_gain; unsigned char meas_state; unsigned int timing, timerate, timerun_dias, timecount, timedeflate, timedisplay; float maxpressure, pressure,accum_data, press_data; unsigned char count, stop_count; //ADC data variabls float Vref; unsigned char data; float adc_data, former; //define counter unsigned char sys_count,count_average, countpulse; //declare rate measure variable float time_pulse,pulse_period, total_pulse_period, pulse_per_min; //declare systolic and diastolic variable float systolic, diastolic; //declare all the threshold values float TH_sys, TH_rate, TH_dias; //*********************************************** //timer 0 compare ISR interrupt [TIM0_COMP] void timer0_compare(void) { if(~PINB & 0x01) timepress0++; if(~PINB & 0x02) timepress1++; if(~PINB & 0x04) timepress2++; timecount++; timedeflate++; //Decrement each time tast if they are not already zero //timing for sampling data at every 40 msec if(timing>0) --timing; //----------------------------------------------------- //run time for different tasks //run timerate for measuring heart rate if(timerate<6000) ++timerate; //run timerun_dias if(timerun_dias<2000) ++timerun_dias; //if(countlcd) timelcd++; //run time for the display if(timedisplay<2000) ++timedisplay; } //*********************************************** // ADC Interrupt //********************************************************** interrupt [ADC_INT] void adc_complete(void) { data = ADCH; //then calculate adc_data into float; adc_data = (float)(((float)data)/256*Vref); //if signal is above threshold, go to calculate systolic pressure if(meas_state ==Sys_Measure) { if(former<=TH_sys && adc_data>TH_sys) sys_count++; former = adc_data; } //----------------------------------------------------------- else if(meas_state==Sys_Cal) { if(count<4) { accum_data=accum_data+adc_data; count++; } if(count==4) { press_data=accum_data/4; systolic = (press_data/DC_gain)*9375;//calculate from adc_data meas_state = Rate_Measure; countpulse=0; former = 2.4; //set the initial point for rate measuring count_average=0; } } //---------------------------------------------------------- else if(meas_state==Rate_Measure) { if(count_average<5) { if(formerTH_rate && countpulse==0) { timerate=0; countpulse=1; former=adc_data; } if(formerTH_rate && countpulse==1) { total_pulse_period=total_pulse_period+timerate; timerate=0; count_average++; //finish reading one period } }//count_average former=adc_data; }// else if(meas_state=Rate_Measure) //------------------------------------------------------------- else if(meas_state==dias_Measure) { if(timerun_dias<2000) { if(adc_data>TH_dias) { timerun_dias=0; //reset time if the signal //is still greater than threshold (so it will never reach 1999) //if it doesn't reset,the time will stuck at 1999 lcd_clear(); lcd_gotoxy(0,0); lcd_putsf("Dias measure"); } } if(timerun_dias>=2000) { meas_state = dias_Cal;//if done go back to Sys_Measure to be ready for next opt } } //------------------------------------------------------------- else if(meas_state==dias_Cal) { diastolic = (adc_data/DC_gain)*9375;//calculate from adc_data meas_state = Sys_Measure; currentState = displayState; //open valve PORTD=0; } timing = 40;//set time for another conversion }// end of ADC interrupt //*********************************************************** //********************************************** void start_state(void) { sys_count=0; pressure = 0; accum_data=0; press_data=0; count=0; stop_count=0; maxpressure = 200; meas_state = Sys_Measure; former=TH_sys-0.01; timerun_dias=0; time_pulse=0; timerate=0; timing=50; total_pulse_period=0; systolic=0; diastolic=0; pulse_per_min=0; sys_count=0; count_average=0; countpulse=0; if((~PINB & 0x01) && (timepress0 > 30)) Maybe0 = 1; if(Maybe0 && (PINB == 0xff)) { countlcd = 1; timelcd = 0; lcd_clear(); lcd_gotoxy(0,0); lcd_putsf("Inflating"); currentState = inflate1State; Maybe0 = 0; timepress0 = 0; timecount=0; //turn on motor and close the valve PORTD=0x03; //activate ADC } } //*********************************************** //*********************************************** // Function to measure everything //------------------------------------------------ void pressuremeasure(void) { switch (meas_state) { case Sys_Measure: if(timing==0) sysmeasure(); //sampling signal at 40msec break; case Sys_Cal: if(timing==0) syscal(); break; case Rate_Measure: if(timing==0) ratemeasure(); break; case dias_Measure: diasmeasure(); break; case dias_Cal: diascal(); break; } //switch }//pressuremeasure //********************************************************* void sysmeasure(void) { if(timing==0) {ADMUX = 0b00100000; //choose ADC0 for reading AC //enable ADC and set prescaler to 1/128*16MHz=125,000 //and set interupt enable //and start a conversion ADCSR = 0b11001111; } if(sys_count>=6) { meas_state = Sys_Cal; timecount=0; } if(timecount>=200) { lcd_clear(); lcd_gotoxy(0,0); lcd_putsf("Measuring"); timecount=0; } } //*********************************************************** //this function is to calculate systolic pressure void syscal(void) { ADMUX=0b00100001;//choose ADC1 for reading DC //enable ADC and set prescaler to 1/128*16MHz=125,000 //and set interupt enable //and start a conversion ADCSR = 0b11001111; if(timecount>=200) { lcd_clear(); lcd_gotoxy(0,0); lcd_putsf("Sys Cal"); timecount=0; } }//syscal //************************************************************ void ratemeasure(void) { ADMUX=0b00100000; //choose ADC0 for reading AC //enable ADC and set prescaler to 1/128*16MHz=125,000 //and set interupt enable //and start a conversion ADCSR = 0b11001111; //calculate the mean of pulse rate if(count_average==5) { pulse_period = total_pulse_period/5000; pulse_per_min= 60/pulse_period; lcd_clear(); lcd_gotoxy(0,0); lcd_putsf("Pulse Rate"); sprintf(lcd_output,"%-i",(int)pulse_per_min); lcd_gotoxy(0,1); lcd_puts(lcd_output); meas_state = dias_Measure; //then set timerun_dias=0 //also reset count_average for the next operation count_average=0; timerun_dias=0; } } //************************************************************ void diasmeasure(void) { ADMUX=0b00100000;//choose ADC1 for reading AC //enable ADC and set prescaler to 1/128*16MHz=125,000 //and set interupt enable //and start a conversion ADCSR = 0b11001111; }//dias measure //************************************************************* void diascal(void) { ADMUX=0b00100001;//choose ADC1 for reading DC //enable ADC and set prescaler to 1/128*16MHz=125,000 //and set interupt enable //and start a conversion ADCSR = 0b11001111; if(timecount>=200) { lcd_clear(); lcd_gotoxy(0,0); lcd_putsf("Dias_Cal"); timecount=0; } } void initialize(void) { //Initialize LCD timecount=0; lcd_init(LCDwidth); lcd_clear(); lcd_gotoxy(0,0); lcd_putsf("White: Start"); lcd_gotoxy(0,1); lcd_putsf("Grey: Stop"); //set up timer0 TIMSK =2; //turn on timer 0 comp match OCR0 = 250; //set the compare register to 250 //prescaler to 64 and turn on clear-on-match TCCR0 = 0b00001011; timepress0 = 0; timepress1 = 0; DDRB=0x00; //PORT B is an input(2 buttons) DDRD=0xff; //PORT D is an output(motor control); PORTD=0x00; PORTB=0xff; PORTA=0x00; maxpressure = 160; meas_state = Sys_Measure; former=TH_sys-0.01; TH_sys=4.0; TH_rate = 2.5; TH_dias = 4.8; timerun_dias=0; time_pulse=0; timerate=0; timing=40; timedisplay=0; total_pulse_period=0; systolic=0; diastolic=0; pulse_per_min=0; Vref=5.0; sys_count=0; count_average=0; countpulse=0; DC_gain=213; accum_data=0; press_data=0; count=0; #asm sei #endasm }