Heart rate sensor MAX30102


Closed Thread
Results 1 to 40 of 85

Hybrid View

  1. #1
    Join Date
    May 2013
    Location
    australia
    Posts
    2,393


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    tidied up a bit and swaped to using ir data [still in mode 3 for now]

    Code:
    '****************************************************************'*  Name    : MAX30102  FOR PIC 18 DEMO                         *
    '*  Author  :  Richard                                          *
    '*  Notice  :                                                   *
    '*          :                                                   *
    '*  Date    : 9/1/2022                                          *
    '*  Version : 1.0                                               *
    '*  Notes   : MAX30102                                          *        
    '*          :18f26k22 @64Mhz                                    *
    '****************************************************************
     
      #CONFIG   ;  The PBP configuration for the PIC18F26K22 is:
        CONFIG FOSC     = INTIO67	       
        CONFIG PLLCFG   = OFF	        ;Oscillator multiplied by 4                       
        CONFIG PRICLKEN  = ON	        ;Primary clock enabled
        CONFIG FCMEN     = OFF	        ;Fail-Safe Clock Monitor disabled
        CONFIG IESO      = OFF	        ;Oscillator Switchover mode disabled
        CONFIG  BOREN    = SBORDIS      ; Brown-out Reset enabled in hardware only (SBOREN is disabled)
        CONFIG  WDTEN    = ON           ; WDT is always enabled. SWDTEN bit has no effect                     ;|
        CONFIG  WDTPS    = 32768        ; 1:32768 ---> HERE enable the watchdog timer with a 1:32768 postscale;|
        CONFIG  PWRTEN   = ON
        CONFIG  HFOFST   = ON           ; HFINTOSC output and ready status are not delayed by the oscillator stable status
        CONFIG  MCLRE    = EXTMCLR      ; MCLR pin enabled, RE3 input pin disabled
        CONFIG  LVP      = OFF          ; Single-Supply ICSP disabled
        CONFIG  XINST    = OFF          ; Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
        CONFIG  DEBUG    = OFF          ; Disabled
        CONFIG  CP0 = OFF             ; Block 0 (000800-003FFFh) not code-protected
        CONFIG  CP1 = OFF             ; Block 1 (004000-007FFFh) not code-protected
        CONFIG  CP2 = OFF             ; Block 2 (008000-00BFFFh) not code-protected
        CONFIG  CP3 = OFF             ; Block 3 (00C000-00FFFFh) not code-protected
        CONFIG  CPB = OFF             ; Boot block (000000-0007FFh) not code-protected
        CONFIG  CPD = OFF             ; Data EEPROM not code-protected
        CONFIG  WRT0 = OFF            ; Block 0 (000800-003FFFh) not write-protected
        CONFIG  WRT1 = OFF            ; Block 1 (004000-007FFFh) not write-protected
        CONFIG  WRT2 = OFF            ; Block 2 (008000-00BFFFh) not write-protected
        CONFIG  WRT3 = OFF            ; Block 3 (00C000-00FFFFh) not write-protected
        CONFIG  WRTC = OFF            ; Configuration registers (300000-3000FFh) not write-protected
        CONFIG  WRTB = OFF            ; Boot Block (000000-0007FFh) not write-protected
        CONFIG  WRTD = OFF            ; Data EEPROM not write-protected
        CONFIG  EBTR0 = OFF           ; Block 0 (000800-003FFFh) not protected from table reads executed in other blocks
        CONFIG  EBTR1 = OFF           ; Block 1 (004000-007FFFh) not protected from table reads executed in other blocks
        CONFIG  EBTR2 = OFF           ; Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks
        CONFIG  EBTR3 = OFF           ; Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks
        CONFIG  EBTRB = OFF           ; Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
     #ENDCONFIG  
     goto overasm  
     asm
    PutMulResult?D macro Din
        MOVE?BB   Din, R2
        MOVE?BB   Din + 1, R2 + 1
        MOVE?BB   Din + 2, R0
        MOVE?BB   Din + 3, R0 + 1
        RST?RP
      endm
     endasm
     overasm:
    
    
    define  OSC 64
    OSCCON    = %01110000   ; 16Mhz
    OSCTUNE.6 = 1           ; Enable 4x PLL
    while ! osccon2.7 :WEND ; to make sure the pll has stabilised before you run any other code
    
    
       
    TRISC = %11011000                  
    ANSELC=0
    ANSELB=0
    #DEFINE    DEBUGING 1
    DEFINE DEBUG_REG PORTB
    DEFINE DEBUG_BIT 7
    DEFINE DEBUG_BAUD 9600
    DEFINE DEBUG_MODE 0
    
    
    
    
    
    
    SDA     var portc.4  
    SCL     VAR portc.3  
     
    reg        var BYTE
    fifo       var byte[6] bank0
    addr       var byte 
    REVISION   var byte
    PARTID     var byte
    buffer     var word[384] 
    ptr        var byte
    btr        var byte
    index      var word
    average    var byte[4] bank0
    ave        var word
    peaks      var byte[8]
    lastpeak   var word 
    lastlow    var word 
    lpfdata    var word[192]
    result     var word ext
    result1    var word ext
    pulse      var word
    @result  =  _fifo 
    @result1 =  _fifo + 3
    ;-----------------------  REGISTER -------------------------
    REG_TEMP_INT         con $1F
    REG_TEMP_FRAC        con $20
    REG_TEMP_CONFIG      con $21
    REG_PART_REVISION    con $FE
    REG_MODE             con $09
    REG_SPO2_CONFIG      con $0A        ;SPO2_ADC_RGE[6:5]SPO2_SR[4:2]LED_PW[1:0]
    REG_LED1_PA          con $0C
    REG_LED2_PA          con $0D
    FIFO_WR_PTR          con $04        ;FIFO_WR_PTR[4:0]
    FIFO_RD_PTR          con $06
    FIFO_DATA            con $07
    FIFO_CONFIG          con $08        ;FIFO_A_FULL[3:0]   SMP_AVE[7:5]
    OVF_COUNTER          con $05
    STATUS1              con 0          ;A_FULL[7]
    INTERRUPT_EN         con 2
    ' -----------------------------------------------------------------------------|  
    
    
    #IFDEF  DEBUGING
        LATB.7=1
        PAUSE 2000
        DEBUG 13,10,  "READY"
    #ENDIF
        ADDR = $ae     ; addr is  0x57 << 1
        reg = REG_PART_REVISION
        i2cread  SDA,scl,ADDR,reg,[REVISION,PARTID]
        reg = REG_MODE 
        i2cwrite  SDA,scl,ADDR,reg,[3] 
        reg = REG_SPO2_CONFIG
        i2cwrite  SDA,scl,ADDR,reg,[$20]
        reg = REG_LED2_PA 
        i2cwrite  SDA,scl,ADDR,reg,[10]
        reg = REG_LED1_PA 
        i2cwrite  SDA,scl,ADDR,reg,[10]
        reg = FIFO_CONFIG  
        i2cwrite  SDA,scl,ADDR,reg,[16]        
        reg = INTERRUPT_EN  
        i2cwrite  SDA,scl,ADDR,reg,[$E0]
        DEBUG 13,10,  "PART ID: 0X",hex PARTID,"/0X",hex REVISION
    
    
    
    
    start:
        reg= REG_TEMP_CONFIG
        i2cwrite  SDA,scl,ADDR,reg,[1] 
        reg= REG_TEMP_INT        
        i2cread  sda,scl,ADDR,reg,[fifo[0],fifo[1]]
        DEBUG 13,10, "TEMP: ",DEC fifo[0],".",DEC2( fifo[1]<<6)
        GOSUB AQUIRE
        pause 2000
    goto start
    
    
    
    
    aquire:
        index=0
        reg= FIFO_WR_PTR
        i2cwrite  SDA,scl,ADDR,reg,[0]
        reg= FIFO_RD_PTR
        i2cwrite  SDA,scl,ADDR,reg,[0]
        reg = OVF_COUNTER
        i2cwrite sda,scl,ADDR,reg,[0]
        asm
        banksel 0 
        clrf _average
        clrf _average+1
        clrf _average+2
        clrf _average+3
        endasm
    while index <256
        btr = 0
        reg = STATUS1
        WHILE (btr & 192) = 0
            i2cread  sda,scl,ADDR,reg,[btr]
            
        WEND
        reg = FIFO_WR_PTR
        i2cread  SDA,scl,ADDR,reg,[Ptr]
        reg = FIFO_RD_PTR
        i2cread  SDA,scl,ADDR,reg,[btr]
        btr = (ptr - btr) &  31
        WHILE (btr &&  (index < 256))
            reg = FIFO_DATA           ;---------ir----------;===========red===========
            i2cread  sda,scl,ADDR,reg,[FIFO[2],FIFO[1],FIFO[0],FIFO[5],FIFO[4],FIFO[3]]
            asm         ;ROTATE READING TO GET SUFFICIENT RESOLOUTION INTO lower WORD
        banksel 0
        bcf STATUS,C
        RRCF  _fifo + 2 ,f
        RRCF  _fifo + 1 ,f
        RRCF  _fifo     ,f
        bcf STATUS,C
        RRCF  _fifo + 2 ,f
        RRCF  _fifo + 1 ,f
        RRCF  _fifo     ,f
        bcf STATUS,C
        RRCF  _fifo + 5 ,f
        RRCF  _fifo + 4 ,f
        RRCF  _fifo + 3 ,f
        bcf STATUS,C
        RRCF  _fifo + 5 ,f
        RRCF  _fifo + 4 ,f
        RRCF  _fifo + 3 ,f
       
        movf  _fifo  ,w         ;RED AVERAGE
        addwf  _average,f
        movf  _fifo + 1 ,w
        btfsc   STATUS,C
        incfsz _fifo + 1 ,w
        addwf  _average + 1,f
        btfsc   STATUS,C
        incf   _average + 2,f
    endasm 
            buffer[index] = result  ;ir
            index = index + 1
            buffer[index] = result1 ;red
            index = index + 1
            btr = btr - 1
        WEND
    wend  
    
    
      
       DEBUG 13,10,hex2 average[3],hex2 average[2],hex2 average[1],hex2 average 
      
       @ PutMulResult?D _average   ;RED AVERAGE
        ave  = DIV32 128            ;RED AVERAGE
        reg = OVF_COUNTER
        i2cread sda,scl,ADDR,reg,[reg ] 
        DEBUG 13,10,"OverFlows ",DEC reg,9,dec ave,9,hex ave
        FOR index = 0 TO 255 step 2
            ave = (ave ** 57000) + (buffer[index] ** 8535 )
            lpfdata[index>>1]=ave 
                  ;.....lpf..;;;;----red-----;;;;======-ir-========
          DEBUG 13,10,dec ave,9,dec buffer[index],9,dec buffer[index+1]
            
        NEXT 
    ' RETURN 
        
        lastpeak =  lpfdata[0]
        lastlow  =  lpfdata[0]
        asm
        banksel _peaks  
        clrf _peaks
        clrf _peaks+1
        clrf _peaks+2
        clrf _peaks+3
        clrf _peaks+4
        clrf _peaks+5
        clrf _peaks+6
        clrf _peaks+7
        banksel 0 
        endasm
        DEBUG 13,10,"lpf"
        lastpeak =  lpfdata[0]
        lastlow  =  lpfdata[0]
        for index = 0 TO 31    ;p1
       if    (lpfdata[index] > lastpeak) then
             lastpeak = lpfdata[index]
             peaks[4] = index :peaks[5]=index :peaks[6]=index :peaks[7]=index
        endif
       if    (lpfdata[index] < lastlow) then
             lastlow = lpfdata[index]
             peaks[0] = index :peaks[1]=index :peaks[2]=index :peaks[3]=index
        endif 
        NEXT
        lastpeak =  lpfdata[32]
        lastlow  =  lpfdata[32]    
         for index = 32 TO 63     ;p2
       if    (lpfdata[index] >lastpeak) then
             lastpeak = lpfdata[index]
             peaks[5] = index :peaks[6]=index :peaks[7]=index
        endif
       if    (lpfdata[index] <lastlow) then
             lastlow = lpfdata[index]
             peaks[1] = index :peaks[2]=index :peaks[3]=index
        endif 
        NEXT 
        
        lastpeak =  lpfdata[64]
        lastlow  =  lpfdata[64]      
          for index = 64 TO 95        ;p3
       if    (lpfdata[index] >lastpeak) then
             lastpeak = lpfdata[index]
             peaks[6]= index  :peaks[7]=index
        endif
       if    (lpfdata[index] < lastlow) then
             lastlow= lpfdata[index]
             peaks[2]= index :peaks[3]=index
        endif 
        NEXT 
         
        lastpeak =  lpfdata[96]
        lastlow  =  lpfdata[96]      
          for index = 96 TO 127        ;p4
       if    (lpfdata[index] >lastpeak) then
             lastpeak = lpfdata[index]
             peaks[7] = index
        endif
       if    (lpfdata[index] <lastlow) then
             lastlow = lpfdata[index]
             peaks[3] = index
        endif 
        NEXT 
        
        DEBUG 13,10,dec peaks[4],9,dec peaks[0];,9, dec lpfdata[peaks[0]]-lpfdata[peaks[1]] 
        DEBUG 13,10,dec peaks[5],9,dec peaks[1]
        DEBUG 13,10,dec peaks[6],9,dec peaks[2]
        DEBUG 13,10,dec peaks[7],9,dec peaks[3]
    
    
         
         
          
    '   pulse = 3000/abs( btr-ptr)
         
    '    DEBUG 13,10,dec ptr , 9,dec btr  , 9,dec pulse 
        
        
    RETURN
    Last edited by richard; - 16th January 2022 at 01:43.
    Warning I'm not a teacher

  2. #2
    Join Date
    Oct 2010
    Posts
    411


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    Richard thanks for your effort.

    These are the new results base on the last change on IR values.

    Code:
    8744	8760	9019
    8745	8759	8995
    8743	8740	9001
    8744	8754	9012
    8746	8764	8991
    8745	8751	9002
    8745	8755	8986
    8743	8744	9003
    8742	8739	9008
    8743	8756	9000
    8743	8752	9008
    8745	8763	9023
    8746	8762	8973
    8743	8738	9011
    8742	8745	8982
    8739	8728	8985
    8736	8726	9005
    8735	8738	8990
    8733	8727	8996
    8733	8741	9001
    8732	8736	8986
    8730	8726	8996
    8731	8750	8999
    8730	8731	8983
    8728	8725	9024
    8730	8751	9002
    8727	8720	9014
    8729	8748	9014
    8731	8751	8986
    8731	8742	8998
    8732	8749	8989
    8732	8741	9001
    8734	8761	9010
    8736	8757	9001
    8733	8722	9026
    8732	8736	9022
    8734	8756	8978
    8734	8741	8988
    8735	8752	8991
    8735	8743	9010
    8738	8762	9018
    8737	8745	8992
    8738	8746	8991
    8741	8771	8995
    8739	8734	8996
    8740	8756	9010
    8740	8753	9009
    8741	8754	9002
    8742	8759	8991
    8740	8733	9001
    8741	8755	9001
    8739	8735	8978
    8737	8733	8997
    8738	8746	8981
    8734	8720	8992
    8733	8732	9004
    8732	8735	8981
    8730	8725	9004
    8731	8750	8979
    8730	8735	8983
    8730	8743	8986
    8730	8742	8982
    8729	8732	8989
    8731	8748	9004
    8732	8752	8981
    8728	8715	8981
    8730	8748	9002
    8729	8732	8999
    8732	8758	9003
    8732	8742	8990
    8733	8747	9005
    8734	8752	8991
    8734	8742	8993
    8736	8756	9007
    8737	8753	8988
    8737	8739	9004
    8738	8750	8992
    8737	8745	8993
    8739	8759	9003
    8740	8754	8975
    8739	8743	8987
    8740	8754	8996
    8739	8743	8998
    8741	8763	8999
    8741	8749	8978
    8740	8743	8996
    8741	8756	8987
    8740	8740	8993
    8740	8747	9005
    8739	8742	8977
    8735	8720	8977
    8734	8737	8984
    8733	8732	8985
    8733	8739	8986
    8733	8743	8982
    8730	8722	8990
    8728	8729	8986
    8726	8717	8999
    8726	8731	8988
    8726	8735	8983
    8725	8729	8987
    8727	8751	8989
    8727	8732	8976
    8727	8733	8997
    8729	8751	8988
    8730	8740	9005
    8731	8749	8983
    8732	8750	8984
    8734	8755	8997
    8737	8766	8971
    8736	8733	8986
    8738	8760	8969
    8737	8740	8990
    8740	8762	9001
    8741	8755	8973
    8739	8735	8997
    8740	8761	8971
    8740	8747	8985
    8741	8758	8974
    8740	8744	8990
    8742	8763	9014
    8744	8763	8977
    8741	8727	8978
    8739	8732	8981
    8737	8734	8980
    8736	8736	8988
    8736	8742	8964
    8733	8717	8974
    Name:  Based on IRLED.png
Views: 2245
Size:  113.5 KB

  3. #3
    Join Date
    Oct 2010
    Posts
    411


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    Richard,

    i think i post #41 and #44, the graph was a bit better in terms of highs and lows. Dont know if the last configuration and modification in LPF made it easier to identify those highs and lows.

  4. #4
    Join Date
    Apr 2014
    Location
    OK
    Posts
    557


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    Have you checked to see if you actually have a pulse for this thing to read? Maybe you're dead and don't even know it?? Try it on someone else as a verification? Just joking...

  5. #5
    Join Date
    Oct 2010
    Posts
    411


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    Quote Originally Posted by mpgmike View Post
    Have you checked to see if you actually have a pulse for this thing to read? Maybe you're dead and don't even know it?? Try it on someone else as a verification? Just joking...
    hehehehe, sure i will do that. Just to check what will be the values on a different person, as i know my average Heart pulses are always around 82-90 Bpm.

    I will find someone with much lower and more normal heart pulses like 62-75 bpm.

    The following is my measurement right now.

    Code:
    lpf
    31	11
    63	11
    68	83
    68	109
    TEMP: 22.68
    000F7E26
    OverFlows 0	7932	1EFC
    7928	7915	7838
    7927	7925	7843
    7926	7929	7818
    7924	7921	7833
    7924	7938	7815
    7924	7933	7810
    7919	7899	7812
    7917	7916	7824
    7919	7940	7811
    7917	7916	7819
    7918	7936	7825
    7918	7928	7810
    7918	7930	7820
    7918	7930	7813
    7918	7931	7813
    7918	7926	7823
    7919	7933	7812
    7920	7935	7824
    7921	7932	7821
    7922	7935	7820
    7921	7923	7823
    7920	7922	7828
    7921	7932	7825
    7923	7943	7815
    7922	7921	7819
    7923	7939	7810
    7924	7936	7823
    7923	7925	7828
    7926	7950	7827
    7924	7923	7825
    7924	7936	7821
    7925	7942	7836
    7923	7924	7812
    7922	7921	7824
    7924	7943	7818
    7923	7929	7813
    7924	7935	7825
    7924	7933	7830
    7922	7917	7824
    7924	7943	7831
    7925	7946	7811
    7924	7928	7822
    7924	7938	7839
    7926	7952	7803
    7925	7928	7827
    7926	7941	7839
    7927	7947	7819
    7924	7916	7816
    7927	7957	7842
    7930	7958	7826
    7930	7933	7820
    7930	7932	7822
    7931	7947	7821
    7929	7925	7825
    7930	7943	7827
    7930	7935	7814
    7928	7918	7840
    7928	7936	7818
    7927	7929	7827
    7925	7919	7829
    7925	7937	7819
    7926	7946	7822
    7926	7936	7812
    7925	7929	7828
    7925	7938	7827
    7925	7933	7816
    7925	7936	7834
    7925	7938	7822
    7928	7957	7821
    7927	7928	7820
    7928	7940	7809
    7929	7942	7814
    7927	7918	7830
    7927	7938	7802
    7926	7925	7814
    7926	7932	7825
    7926	7932	7813
    7924	7923	7809
    7924	7936	7830
    7925	7940	7831
    7926	7942	7824
    7925	7926	7826
    7923	7924	7811
    7923	7928	7826
    7926	7950	7834
    7925	7930	7808
    7924	7930	7826
    7924	7932	7842
    7926	7948	7807
    7926	7934	7817
    7927	7941	7831
    7927	7937	7815
    7925	7917	7833
    7926	7945	7813
    7926	7932	7796
    7924	7922	7818
    7924	7939	7806
    7922	7921	7812
    7924	7940	7811
    7924	7936	7808
    7922	7918	7821
    7921	7924	7823
    7923	7943	7804
    7923	7925	7809
    7924	7934	7817
    7924	7939	7815
    7923	7931	7806
    7921	7915	7816
    7921	7925	7809
    7920	7923	7822
    7920	7925	7822
    7922	7947	7808
    7922	7925	7817
    7922	7929	7817
    7922	7928	7820
    7922	7926	7823
    7923	7933	7832
    7927	7959	7804
    7925	7919	7812
    7926	7942	7822
    7924	7918	7809
    7924	7935	7818
    7924	7936	7813
    7922	7923	7813
    7923	7937	7818
    7925	7941	7801
    7922	7914	7818
    7922	7929	7836
    lpf
    0	7
    52	33
    71	82
    117	109
    TEMP: 24.96
    (measured as well with the Samsung Galaxy Sensor 80 Bpm)
    Last edited by astanapane; - 17th January 2022 at 22:40.

  6. #6
    Join Date
    May 2013
    Location
    australia
    Posts
    2,393


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    looks like simplistic lowpass filtering of the data to obtain pulse will never give a
    reliable and repeatable result, it can deliver a nice picture but that is as far as it goes.
    i will need to learn a bit more about dsp techniques. first step, remove dc component i think.
    don't hold your breath, got more paid work this week
    Warning I'm not a teacher

  7. #7
    Join Date
    Oct 2010
    Posts
    411


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    Richard this is already lots of work, and i dont know how to thank you for all this.

    I believe that this will be useful for many people in the forum in the end. (even if noone else is involved).

Similar Threads

  1. New PIC failure rate
    By timmers in forum General
    Replies: 5
    Last Post: - 26th March 2009, 12:11
  2. Rf module baud rate
    By tazntex in forum Serial
    Replies: 4
    Last Post: - 5th August 2008, 18:47
  3. Replies: 6
    Last Post: - 18th January 2008, 08:17
  4. SHIFTOUT Clock rate
    By Brock in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 8th July 2006, 23:42
  5. Detect baud rate
    By Dick M in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 2nd July 2005, 21:10

Members who have read this thread : 3

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts