|
|
| Line 1: |
Line 1: |
| <nowiki>
| |
|
| |
|
| #define HB_INT_PIN 4
| |
|
| |
| static const unsigned char PROGMEM still_heart_logo_bmp[] =
| |
| {
| |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
| |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x0F, 0x00, 0x00, 0x67, 0x18, 0xC0, 0x00, 0xC1, 0xB0, 0x60,
| |
| 0x01, 0x80, 0xE0, 0x20, 0x01, 0x00, 0xC0, 0x30, 0x01, 0x00, 0x40, 0x10, 0x01, 0x00, 0x40, 0x10,
| |
| 0x01, 0x04, 0x00, 0x10, 0x01, 0x04, 0x00, 0x10, 0x01, 0x0C, 0x00, 0x30, 0x00, 0x88, 0x80, 0x20,
| |
| 0x00, 0x8B, 0x80, 0x40, 0x0F, 0xF3, 0x70, 0x80, 0x00, 0x13, 0x01, 0x80, 0x00, 0x19, 0x03, 0x00,
| |
| 0x00, 0x0C, 0x06, 0x00, 0x00, 0x06, 0x0C, 0x00, 0x00, 0x03, 0x18, 0x00, 0x00, 0x01, 0xB0, 0x00,
| |
| 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
| |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
| |
| };
| |
|
| |
| static const unsigned char PROGMEM beat_heart_logo_bmp[] =
| |
| {
| |
| 0x01, 0xF0, 0x0F, 0x80, 0x06, 0x1C, 0x38, 0x60, 0x18, 0x06, 0x60, 0x18, 0x10, 0x01, 0x80, 0x08,
| |
| 0x20, 0x01, 0x80, 0x04, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0xC0, 0x00, 0x08, 0x03,
| |
| 0x80, 0x00, 0x08, 0x01, 0x80, 0x00, 0x18, 0x01, 0x80, 0x00, 0x1C, 0x01, 0x80, 0x00, 0x14, 0x00,
| |
| 0x80, 0x00, 0x14, 0x00, 0x80, 0x00, 0x14, 0x00, 0x40, 0x10, 0x12, 0x00, 0x40, 0x10, 0x12, 0x00,
| |
| 0x7E, 0x1F, 0x23, 0xFE, 0x03, 0x31, 0xA0, 0x04, 0x01, 0xA0, 0xA0, 0x0C, 0x00, 0xA0, 0xA0, 0x08,
| |
| 0x00, 0x60, 0xE0, 0x10, 0x00, 0x20, 0x60, 0x20, 0x06, 0x00, 0x40, 0x60, 0x03, 0x00, 0x40, 0xC0,
| |
| 0x01, 0x80, 0x01, 0x80, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x30, 0x0C, 0x00,
| |
| 0x00, 0x08, 0x10, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x01, 0x80, 0x00
| |
| };
| |
|
| |
| MAX30105 particleSensor;
| |
|
| |
| int HB_x_offset = 0;
| |
| int HB_y_offset = 77;
| |
| int HB_x_width = 46;
| |
| int HB_y_height = 82;
| |
|
| |
| int HB_initialize_screen = -1;
| |
|
| |
| void HB_Reset()
| |
| {
| |
| HB_initialize_screen = -1;
| |
| }
| |
|
| |
| bool setup_HB()
| |
| {
| |
| // Initialize sensor
| |
| if (!particleSensor.begin()) //Use default I2C port, 400kHz speed
| |
| {
| |
| Serial.println("MAX30105 was not found. Please check wiring/power. ");
| |
| return(false);
| |
| }
| |
|
| |
| particleSensor.setup(); //Configure sensor with default settings
| |
| particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
| |
| particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED
| |
| return(true);
| |
| }
| |
|
| |
| void HB_Frame_Message(int message_left, int message_top)
| |
| {
| |
| DrawScreenText(message_left,message_top,"Place",COMMON_WHITE,COMMON_BLACK);
| |
| DrawScreenText(message_left,message_top+12,"your",COMMON_WHITE,COMMON_BLACK);
| |
| DrawScreenText(message_left,message_top+24,"finger",COMMON_WHITE,COMMON_BLACK);
| |
| DrawScreenText(message_left,message_top+36,"on",COMMON_WHITE,COMMON_BLACK);
| |
| DrawScreenText(message_left,message_top+48,"sensor",COMMON_WHITE,COMMON_BLACK);
| |
| }
| |
|
| |
| void HB_Frame()
| |
| {
| |
| int box_top = HB_y_offset;
| |
| int box_left = HB_x_offset;
| |
| int box_width = HB_x_width;
| |
| int box_height = HB_y_height;
| |
|
| |
| const byte RATE_SIZE = 6; //Increase this for more averaging. 4 is good.
| |
| byte rates[RATE_SIZE]; //Array of heart rates
| |
| long pulse_ir[RATE_SIZE];
| |
| long pulse_red[RATE_SIZE];
| |
|
| |
| long lastBeat = 0; //Time at which the last beat occurred
| |
| float beatsPerMinute;
| |
| int beatAvg = -1, lastAvg = 0;
| |
| long irAVG = 0;
| |
|
| |
| bool beatDetect = false;
| |
| int latentBeatMax = 2;
| |
| int latentBeat = 0;
| |
|
| |
| long irValue = 0;
| |
| long maxValue = 0;
| |
| long lastValue = 0;
| |
| long turnValue = 0;
| |
| long lastMax = 0;
| |
|
| |
| int now_HB_Screen = 0;
| |
| int last_HB_Screen = -1;
| |
|
| |
| unsigned long start_time;
| |
| unsigned long delta = 0;
| |
| int HB_detect_threshold = 7000;
| |
|
| |
| // Clear rate calculating array
| |
| for(byte x = 0; x < RATE_SIZE ; ++x)
| |
| rates[x] = 0;
| |
|
| |
| if (HB_initialize_screen == -1)
| |
| {
| |
| DrawScreenCompartment(box_left, box_top, box_width, box_height, COMMON_BLACK, COMMON_BLUE);
| |
| HB_Frame_Message(box_left + 2,box_top + 4);
| |
| HB_initialize_screen = 0;
| |
|
| |
| for (byte x = 0 ; x < RATE_SIZE ; x++)
| |
| rates[x] = 0;
| |
| }
| |
|
| |
| irValue = particleSensor.getIR();
| |
|
| |
| while(irValue > HB_detect_threshold)
| |
| {
| |
| irValue = particleSensor.getIR(); //Reading the IR value it will permit us to know if there's a finger on the sensor or not
| |
|
| |
| if (irValue > 7000)
| |
| {
| |
| //finger is detected
| |
| now_HB_Screen = 1;
| |
| if (irValue > maxValue)
| |
| maxValue = irValue;
| |
|
| |
| // if ((irValue < maxValue - 200) && (irValue > lastValue + 20)) // alternate detect beat method
| |
| if (irValue < maxValue - 200)
| |
| {
| |
| beatDetect = true;
| |
| lastMax = maxValue;
| |
| maxValue = irValue;
| |
| turnValue = lastValue;
| |
| latentBeat = latentBeatMax;
| |
| }
| |
|
| |
| lastValue = irValue;
| |
|
| |
| if (beatDetect == true)
| |
| {
| |
| beatDetect = false;
| |
|
| |
| //We sensed a beat!
| |
| delta = millis() - lastBeat; //Measure duration between two beats
| |
| lastBeat = millis();
| |
|
| |
| beatsPerMinute = 60 / (delta / 1000.0); //Calculating the BPM
| |
| lastAvg = beatAvg;
| |
|
| |
| if ((beatsPerMinute < 255.0) && (beatsPerMinute > 20.0)) //To calculate the average we strore some values (4) then do some math to calculate the average
| |
| {
| |
| //Take average of readings
| |
|
| |
| beatAvg = 0;
| |
| for (byte x = 0 ; x < RATE_SIZE ; x++)
| |
| beatAvg += rates[x];
| |
| beatAvg /= RATE_SIZE;
| |
| }
| |
| }
| |
| }
| |
|
| |
|
| |
| if (irValue < 7000)
| |
| { //If no finger is detected it inform the user and put the average BPM to 0 or it will be stored for the next measure
| |
| now_HB_Screen = 0;
| |
| beatAvg=0;
| |
| lastAvg = 0;
| |
| for(byte x = 0; x < RATE_SIZE ; ++x)
| |
| rates[x] = 0;
| |
| }
| |
|
| |
| switch(now_HB_Screen)
| |
| {
| |
| case 0:
| |
| if (last_HB_Screen != 0)
| |
| DrawScreenBlock(box_left+1,box_top+1,box_width-2,box_height-2,COMMON_BLACK);
| |
| HB_Frame_Message(box_left + 2,box_top + 4);
| |
| break;
| |
| case 1:
| |
| if (last_HB_Screen != 1)
| |
| DrawScreenBlock(box_left+1,box_top+1,32,32,COMMON_BLACK);
| |
| if (latentBeat == latentBeatMax)
| |
| {
| |
| DrawScreenBitmap(box_left + 6,box_top + 2,beat_heart_logo_bmp, 32, 32, COMMON_BLACK, COMMON_RED);
| |
| }
| |
| if (latentBeat == 0)
| |
| {
| |
| DrawScreenBitmap(box_left + 6,box_top + 2,still_heart_logo_bmp, 32, 32, COMMON_BLACK, COMMON_WHITE);
| |
| latentBeat = -1;
| |
| }
| |
| if (latentBeat > 0)
| |
| -- latentBeat;
| |
| if (lastAvg != beatAvg)
| |
| {
| |
| DrawScreenBlock(box_left+1,box_top+34,box_width-2,box_height-35,COMMON_BLACK);
| |
| DrawScreenText(box_left + 4, box_top + 34,"BPM",COMMON_WHITE,COMMON_BLACK);
| |
| DrawScreenText(box_left + 4, box_top + 44,String(beatAvg),COMMON_WHITE,COMMON_BLACK);
| |
| lastAvg = beatAvg;
| |
| }
| |
| break;
| |
| case 2:
| |
| DrawScreenBitmap(box_left + 6,box_top + 2,beat_heart_logo_bmp, 32, 32, COMMON_BLACK, COMMON_RED);
| |
| DrawScreenBlock(box_left+1,box_top+34,box_width-2,box_height-35,COMMON_BLACK);
| |
| DrawScreenText(box_left + 4, box_top + 34,"BPM",COMMON_WHITE,COMMON_BLACK);
| |
| DrawScreenText(box_left + 4, box_top + 44,String(beatAvg),COMMON_WHITE,COMMON_BLACK);
| |
| lastAvg = beatAvg;
| |
| break;
| |
| case 3:
| |
| break;
| |
| }
| |
| last_HB_Screen = now_HB_Screen;
| |
| delay(90);
| |
| }
| |
| }
| |
|
| |
| </nowiki>
| |
|
| |
| [[Pseudo-Medical_Monitor_Code#Custom_Includes]]
| |