วันอังคารที่ 27 กรกฎาคม พ.ศ. 2564

Algorithms of Sleeping Positions with Heart Rhythms Measurement :

 // Algorithms of Sleeping Positions with Heart Rhythms Measurement :

// Neramitr Chirakanphaisarn, Mit9bkk@gmail.com

// initial the up counter

#include <Wire.h>

#include <SD.h> 

#include <LiquidCrystal.h>      // used library of SLCD module with 20 digits x 4 lines

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  //assigned the SLCD functions of 16 digits x 2 lines

#define IN_PIN0  0         // set Digital Pin0 for control file.close of SD card

#define IN_PIN9  9         // set Digital Pin9 for show SEX type of MALE / FEMALE into EXCEL OR CSV file

#define IN_PIN10  10       // set Digital Pin10 for closed file for head label in EXCEL or CSV file

const int chipSelect = 53;

//-------------open declare speed of motion------------------

#define IN_PIN    19      //set Switch input to Digital pin19  ADKR3 mega2560

#define DEBOUNCE  10      // Delay 10 mSec , That no port number !!

#define BUZZER  7      // Digital Pin7 is Buzzer beep using Alert! when 60 seconds

#define ANALOG_PIN  5      // Sweep the PATIENT AGE to Analog input A5 of ADK R3 mega2560

int analogValue = 5;     // Sweep the PATIENT AGE to Analog input A5 of ADK R3 mega2560


#define ANALOG_PIN4  4      // Sweep the PATIENT ID or No. to Analog input A4 of ADK R3 mega2560

int analogValue4 = 4 ;     // Sweep the PATIENT ID or No. to Analog input A4 of ADK R3 mega2560


int state_sw = HIGH;

int reading;

int previous = HIGH;


unsigned long atime= 0;

unsigned long rtc= 0;

unsigned char counter=0;

unsigned long temp[200];    // temp is very importance for count 0 to 200 , not 60 Seconds

unsigned long sub=0;

bool data_effect=true;

const int max_heartpluse_duty=20000;    //you can change 20000 meams 20 seconds. 

//---------closed declare of debounce switch-------------------

// Closed the initial the up counter

//  VARIABLES of Pulse sensor

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

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

int fadePin = 6;         // default is pin5 ,pin to do fancy classy fading blink at each beat

int fadeRate = 0;                 // used to fade LED on with PWM on fadePin


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

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

volatile int Signal;                // holds the incoming raw data

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

volatile boolean Pulse = false;     // true when pulse wave is high, false when it's low

volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

// Closed the  VARIABLES of Pulse sensor

void setup(){

  pinMode(blinkPin,OUTPUT);         // pin that will blink to your heartbeat!

  pinMode(fadePin,OUTPUT);          // pin that will fade to your heartbeat!

  Serial.begin(115200);             // we agree to talk fast!

  Serial.println("neramitr chirakarnphaisarn");

  //--------- setup of debounce switch-------------------  

  pinMode(IN_PIN, INPUT);     // set pinMode digitalPin 19  name's IN_PIN is INPUT of ADK R3

//---------closed setup of debounce switch------------------- 

    lcd.begin(16, 4);

       lcd.setCursor(0, 0); 

     lcd.print("Id:");

       lcd.setCursor(9, 0); 

       lcd.print("Neramitr.TU");

     lcd.setCursor(0, 1); 

     lcd.print("Age:");

       lcd.setCursor(7, 1); 

       lcd.print("Sx:");

         lcd.setCursor(14, 1); 

         lcd.print("Amp:");

           lcd.setCursor(4, 2); 

           lcd.print("Measure=   /   sec.");

       

             lcd.setCursor(4, 3); 

             lcd.print("Pulse rate=    bpm. ");    

      

// Show Id after calibration  

  analogValue4 = analogRead(ANALOG_PIN4);

  int id = analogValue4/20;        // adjust Patients Id , values 0 to 50 persons (1000/20= 50 persons)

   if(id <= 50)                // Fix LCD shows 0 to 50 persons only

    {

        lcd.setCursor(3, 0);

        lcd.print(id); 

    }


// Show Sex after calibration

pinMode (IN_PIN9, INPUT);         //set pinMode digitalPin 9     

 int sex = digitalRead(IN_PIN9);    // default (IN_PIN9) 

   if(sex == LOW )                  // Assigned move right stoke is HIGH 

   {

     lcd.setCursor(10, 1);        // show position (column,row)

     lcd.print("MA");    

   }

   else

    {

     lcd.setCursor(10, 1);        // show position (column,row)

     lcd.print("FE");           

    }   

// End of show sex after calibration


// Show Age after calibration   

analogValue = analogRead(ANALOG_PIN);

  int age = analogValue/10;

  if(age <= 99) 

   {

    lcd.setCursor(4, 1);                  // show position (column,row)

    lcd.print(age);

   }

    

// Setup BUZZER loud for Alert when 60 Seconds OK!

pinMode(BUZZER, OUTPUT);      // sets the digital pin as output

// Closed Set up Buzzer OK!

 interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS

}


void loop()

{


// Adjust the PATIENT ID , Identification by we setting ID value 0-50 Persons  

// Press "Big Circle YELLOW" Switch is LOW , But NO Press "BIG CIRCLE GREEN" Switch is HIGH


   pinMode (IN_PIN10, INPUT);             // Control the CLOSE or IGNORE file

   int closed1 = digitalRead(IN_PIN10);    

   if(closed1 == LOW )        // Press BIG YELLOW swith      

         {

            {

            analogValue4 = analogRead(ANALOG_PIN4);

            int id = analogValue4/20;                // adjust 0 to 50 persons (1000/20= 50 persons)

      

            if(id <= 50)                             // Fix LCD shows 0 to 50 persons only      

                {

                 lcd.setCursor(3, 0);                  // show position (column,row)

                 lcd.print("  ");                     

                     lcd.setCursor(3, 0);                  // show position (column,row)

                     lcd.print(id);   

                } 

            }            

         }

        

        else     // NO Press hold BIG GREEN swith 

         {

          // At here is closed = LOW then NOT save RIGHT to EXCEL                        

         }

// Closed the Adjust the PATIENT ID by we setting AGE value 0-10 persons  

// Set Set SEX type MALE / FEMALE for EXCEL or CSV file

   pinMode (IN_PIN10, INPUT);             // Control the CLOSE or IGNORE file

   //int closed1 = digitalRead(IN_PIN10);    

   if(closed1 == LOW )        // Press BIG YELLOW swith    

     {

       pinMode (IN_PIN9, INPUT);  // set pinMode digitalPin 9  name's IN_PIN6 is INPUT of ADK R3 for RIGHT_LEG or LEFT_LEG   

       int sex = digitalRead(IN_PIN9);    // default (IN_PIN9) get input HIGH or LOW for select RIGHT_LEG or LEFT_LEG to shows EXCEL, CSV file

         if(sex == LOW )                  // Assigned move right stoke is HIGH , Assigned move left stoke is LOW 

           {    

             {

              lcd.setCursor(10, 1);        // show position (column,row)

              lcd.print("MA");    

             }

           }

         else 

            {

             lcd.setCursor(10, 1);        // show position (column,row)

             lcd.print("FE");

            }

     }

// End of Set SEX type MALE / FEMALE for EXCEL or CSV file


// Adjust the PATIENT AGE by we setting AGE value 0-80 years  

   pinMode (IN_PIN10, INPUT);             // Control the CLOSE or IGNORE file

   int closed = digitalRead(IN_PIN10);    

   if(closed == LOW )        // NO press BIG GREEN swith      

         {

            {

            analogValue = analogRead(ANALOG_PIN);

            int age = analogValue/10;                // adjust age 0 to 100 years (1000/10= 100 persons) 

      

            if(age <= 99)                           // Fix LCD shows 0 to 99 persons only

                {

                 lcd.setCursor(4, 1);                  // show position (column,row)

                 lcd.print("  ");   

                   lcd.setCursor(4, 1);                  // show position (column,row)

                   lcd.print(age);    

                } 

            }            

         }

        

        else  // Press hold BIG GREEN swith 

         {

           // At here is closed = LOW then NOT save RIGHT to EXCEL                        

         }

// Closed the Adjust the PATIENT AGE by we setting AGE value 30-80 years


//----------- Start of Section of speed of motion Up counter -------------------------

    reading=digitalRead(IN_PIN);    //read from Digital pin0 or PD2, INT2 , PACE NUMBER  

  if (reading == LOW && previous == HIGH)   //check the button switch 

  {

    delay(DEBOUNCE);                    // delay 10 mSec

    if(digitalRead(IN_PIN) == HIGH)

      state_sw = !state_sw;

   

    interruptCounter();

  }

  previous = reading;

// ---------------End of Section of speed of motion ---------------------------


// Start of the SLCD shows the value of PACE in SECOND , Angle = ?


  lcd.setCursor(12, 2);        // shown Hearth Beat per cycle

  lcd.print(counter);


  lcd.setCursor(16, 2);        // shown realtime clock 0-60 Sec.

  lcd.print(rtc);            


// Adjust the Pulse Swing (minimum to maximum situation) by we set the maximum is 90 peak

     int pulseSwingValue = analogRead(pulsePin);

     int signal = pulseSwingValue/13;           // adjust beat from Pulse sensor directly, for proper 

     if(signal <= 90)                       // Fix LCD shows 0 to 90 persons only

       {

                

         lcd.setCursor(18, 1);         // Pulse signal has minimum to maximum peak

         lcd.print(signal); 

         delay(50); 

       //Serial.print (pulseSwing);  

       }         

// Closed Adjust the Pulse swing (minimum to maximum situation)

   sendDataToProcessing('S', Signal);     // send Processing the raw Pulse Sensor data

  if (QS == true){                       // Quantified Self flag is true when arduino finds a heartbeat

        fadeRate = 255;                  // Set 'fadeRate' Variable to 255 to fade LED with pulse

        sendDataToProcessing('B',BPM);   // send heart rate with a 'B' prefix

        sendDataToProcessing('Q',IBI);   // send time between beats with a 'Q' prefix

        QS = false;                      // reset the Quantified Self flag for next time    

     }

  

  ledFadeToBeat();

  

  //delay(1);                             //  take a break , default is 20

  

}


void ledFadeToBeat(){

    fadeRate -= 15;                         //  set LED fade value

    fadeRate = constrain(fadeRate,0,255);   //  keep LED fade value from going into negative numbers!

    analogWrite(fadePin,fadeRate);          //  fade LED

  }


void sendDataToProcessing(char symbol, int data ){

    Serial.print(symbol);                // symbol prefix tells Processing what type of data is coming

    Serial.println(data);                // the data to send culminating in a carriage return

  }


// the funtions are up counter only 

void interruptCounter()

{

  //check no move the goniometer then the monitor shows 0 second

  if(counter <= 0)

  {    

  }

  else

    atime = millis();

  rtc= atime/1000;

  temp[counter]=millis();


   

  switch (counter)

  {

    case(0):

    sub=temp[counter]-temp[60];

    break;

  default:

    sub=temp[counter]-temp[counter-1];

    break;

  }

  if(sub > max_heartpluse_duty)//set 20 seconds as max pluse duty

  {

    data_effect=0;//sign bit

    counter=0;

   // Serial.println("End of measuring,please reset for begin." );

    array_init();

  }


  if (rtc >= 60 and rtc <= 62)

  {            

    lcd.setCursor (16,3);   // show Pulse rate per minute

    lcd.print (counter); 

     //lcd.setCursor (12,1);

     //lcd.print (" bpm");

       digitalWrite(BUZZER,HIGH);

       delay(100);

       digitalWrite(BUZZER,LOW);

  }


  else if(rtc != 60 && data_effect)        // default is rtc!=60

    counter++   ;            //counter++;


  else 

  {

    counter = counter ;      //counter=0;

    data_effect=1;


  }

}

void array_init()

{

  for(unsigned char i=0; i!=60; ++i)

  {

    temp[i]=0;

  }

  

  temp[60]=millis();

  }






----------------------------------------------------------------------------------------------------

Interrupt:

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

volatile unsigned long sampleCounter = 0;          // used to determine pulse timing

volatile unsigned long lastBeatTime = 0;           // used to find IBI

volatile int P =512;                      // used to find peak in pulse wave, seeded

volatile int T = 512;                     // used to find trough in pulse wave, seeded

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

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

volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM

volatile boolean secondBeat = false;      // used to seed rate array so we startup with reasonable BPM



void interruptSetup(){     

  // Initializes Timer2 to throw an interrupt every 2mS.

  TCCR2A = 0x02;     // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE

  TCCR2B = 0x06;     // DON'T FORCE COMPARE, 256 PRESCALER 

  OCR2A = 0X7C;      // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE

  TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A

  sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED      



// THIS IS THE TIMER 2 INTERRUPT SERVICE ROUTINE. 

// Timer 2 makes sure that we take a reading every 2 miliseconds

ISR(TIMER2_COMPA_vect){                         // triggered when Timer2 counts to 124

  cli();                                      // disable interrupts while we do this

  Signal = analogRead(pulsePin);              // read the Pulse Sensor 

  sampleCounter += 2;                         // keep track of the time in mS with this variable

  int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise


    //  find the peak and trough of the pulse wave

  if(Signal < thresh && N > (IBI/5)*3){       // avoid dichrotic noise by waiting 3/5 of last IBI

    if (Signal < T){                        // T is the trough

      T = Signal;                         // keep track of lowest point in pulse wave 

    }

  }


  if(Signal > thresh && Signal > P){          // thresh condition helps avoid noise

    P = Signal;                             // P is the peak

  }                                        // keep track of highest point in pulse wave


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

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

  if (N > 250){                                   // avoid high frequency noise

    if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ){        

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

      digitalWrite(blinkPin,HIGH);                // turn on pin 13 LED

      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(int 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

        sei();                               // enable interrupts again

        return;                              // IBI value is unreliable so discard it

      }   



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

      word runningTotal = 0;                  // clear the runningTotal variable    


      for(int 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

    digitalWrite(blinkPin,LOW);            // turn off pin 13 LED

    Pulse = false;                         // reset the Pulse flag so we can do it again

    amp = P - T;                           // get amplitude of the pulse wave

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

    P = thresh;                            // reset these for next time

    T = thresh;

  }


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

    thresh = 512;                          // set thresh default

    P = 512;                               // set P default

    T = 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

  }


  sei();                                   // enable interrupts when youre done!

}// end isr




ไม่มีความคิดเห็น:

แสดงความคิดเห็น

Engineering of Robotics Industry & Computer (ERIC) , 2008-2022

นาย เนรมิธ   จิรกาญจน์ไพศาล,  Add Line : Click here คลิ๊กตรงนี้   NERAMITR CHIRAKANPHAISARN, Curriculum vitae Research evidence areas :  -G...