0% found this document useful (0 votes)
22 views

Mini Projectcode

The document defines variables and functions for reading heart rate data from a sensor and displaying the results on an LCD. It initializes peripherals, sets up interrupts to read sensor data every 2ms, calculates heart rate in BPM, and displays the results on the LCD screen.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views

Mini Projectcode

The document defines variables and functions for reading heart rate data from a sensor and displaying the results on an LCD. It initializes peripherals, sets up interrupts to read sensor data every 2ms, calculates heart rate in BPM, and displays the results on the LCD screen.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Sbit LCD_RS at RD0_bit;

Sbit LCD_EN at RD6_bit;

Sbit LCD_D4 at RD5_bit;

Sbit LCD_D5 at RD4_bit;

Sbit LCD_D6 at RD3_bit;

Sbit LCD_D7 at RD2_bit;

Sbit LCD_RS_Direction at TRISD0_bit;

Sbit LCD_EN_Direction at TRISD6_bit;

Sbit LCD_D4_Direction at TRISD5_bit;

Sbit LCD_D5_Direction at TRISD4_bit;

Sbit LCD_D6_Direction at TRISD3_bit;

Sbit LCD_D7_Direction at TRISD2_bit;

Enum {FALSE = 0, TRUE = 1};

Char intro_msg[] = “ELECTRONIC HEART RATE MONITOR”;

Char temp_str[8], disp_result;

Int rate[10]; // array to hold last ten IBI values

Unsigned long sampleCounter = 0; // used to determine pulse timing

Unsigned long lastBeatTime = 0; // used to find IBI

Int Peak =512; // used to find peak in pulse wave, seeded

Int Trough = 512; // used to find trough in pulse wave, seeded

Int thresh = 512; // used to find instant moment of heart beat, seeded

Int amp = 100; // used to hold amplitude of pulse waveform, seeded

Bit firstBeat; // used to seed rate array so we startup with reasonable BPM
Bit secondBeat; // used to seed rate array so we startup with reasonable BPM

Int pulsePin = 0; // Pulse Sensor purple wire connected to analog pin 0

Int blinkPin = 13; // pin to blink led at each beat

Int runningTotal = 0; // clear the runningTotal variable

// these variables are volatile because they are used during the interrupt service routine!

Unsigned int BPM; // used to hold the pulse rate

Unsigned int Signal; // holds the incoming raw data

Unsigned int IBI = 600; // holds the time between beats, must be seeded!

Bit Pulse ; // true when pulse wave is high, false when it’s low

Bit QS;

Int N_cnt, P_cnt;

Int I = 0;

Void InitTimer0(){ //timer0 is set to Interrupt every 2ms. PIC18F452 is running at 32MHz

T0CON = 0xC5;

TMR0L = 0x06;

GIE_bit = 1;

TMR0IE_bit = 1;

Void Interrupt(){

GIE_bit = 0;

If (TMR0IF_bit){ //every 2ms

//READ HEART RATE FROM LCD

Signal = ADC_Get_Sample(0);
sampleCounter += 2;

N_cnt = sampleCounter – lastBeatTime;

If(Signal < thresh && N_cnt > (IBI/5)*3){

If (Signal < Trough){

Trough = Signal;

If(Signal > thresh && Signal > P_cnt){

P_cnt = Signal;

// NOW IT’S TIME TO LOOK FOR THE HEART BEAT

// signal surges up in value every time there is a pulse

If (N_cnt > 250){ // avoid high frequency noise

If ( (Signal > thresh) && (Pulse == FALSE) && (N_cnt > (IBI/5)*3) ){

Pulse = TRUE; // set the Pulse flag when we think there is a pulse

IBI = sampleCounter – lastBeatTime; // measure time between beats in mS

lastBeatTime = sampleCounter; // keep track of time for next pulse

if(secondBeat){ // if this is the second beat, if secondBeat == TRUE

secondBeat = FALSE; // clear secondBeat flag

for(i=0; i<=9; i++){ // seed the running total to get a realisitic BPM at startup

rate[i] = IBI;

}
If(firstBeat){ // if it’s the first time we found a beat, if firstBeat == TRUE

firstBeat = FALSE; // clear firstBeat flag

secondBeat = TRUE; // set the second beat flag

return; // IBI value is unreliable so discard it

// keep a running total of the last 10 IBI values

runningTotal = 0; // clear the runningTotal variable

for(i=0; i<=8; i++){ // shift data in the rate array

rate[i] = rate[i+1]; // and drop the oldest IBI value

runningTotal += rate[i]; // add up the 9 oldest IBI values

Rate[9] = IBI; // add the latest IBI to the rate array

runningTotal += rate[9]; // add the latest IBI to runningTotal

runningTotal /= 10; // average the last 10 IBI values

BPM = 60000/runningTotal; // how many beats can fit into a minute? That’s BPM!

QS = TRUE; // set Quantified Self flag

// QS FLAG IS NOT CLEARED INSIDE THIS ISR

If (Signal < thresh && Pulse == TRUE){ // when the values are going down, the beat is over
Pulse = FALSE; // reset the Pulse flag so we can do it again

Amp = P_cnt – Trough; // get amplitude of the pulse wave

Thresh = amp/2 + Trough; // set thresh at 50% of the amplitude

P_cnt = thresh; // reset these for next time

Trough = thresh;

If (N_cnt > 2500){ // if 2.5 seconds go by without a beat

Thresh = 512; // set thresh default

P_cnt = 512; // set P default

Trough = 512; // set T default

lastBeatTime = sampleCounter; // bring the lastBeatTime up to date

firstBeat = TRUE; // set these to avoid noise

secondBeat = FALSE; // when we get the heartbeat back

TMR0IF_bit = 0;

TMR0L = 0x06;

GIE_bit =1;

}// end isr

GIE_bit =1; // enable interrupts when youre done!

Void main() {

Int g;

OSCCON.IRCF0=0;

OSCCON.IRCF1=1;
OSCCON.IRCF2=1;

ANSELA=0x01;

ANSELB=0x00;

ANSELC=0x00;

ANSELD=0x00;

ANSELE=0x00;

Pulse = FALSE;

QS = FALSE;

firstBeat = TRUE;

secondBeat = FALSE;

Lcd_Init(); //initialize LCD

Lcd_Cmd(_LCD_CLEAR); // Clear display

Delay_ms(200);

Lcd_Cmd(_LCD_CURSOR_OFF);

Delay_ms(200);

Lcd_Out(1,1, intro_msg);

Delay_ms(1500); // First row

For(g=0; g<sizeof(intro_msg)-16; g++) { // Move text to the right 4 times

Lcd_Cmd(_LCD_SHIFT_LEFT);

Delay_ms(250);

Lcd_Cmd(_LCD_CLEAR); // Clear display

Delay_ms(200);

ADC_Init();
InitTimer0();

While(1){

If (QS == TRUE){ //New Pulse detected

Lcd_Out(1,1,”HEART RATE (BPM)”);

Lcd_Out(2,1,” “);

IntToStr(BPM, temp_str);

Lcd_Out(2,8,temp_str);

Delay_ms(2000);

You might also like