Heart rate sensor MAX30102


Closed Thread
Results 1 to 40 of 85

Hybrid View

  1. #1
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,170


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    Interesting 3D print!

    Ioannis

  2. #2
    Join Date
    Oct 2010
    Posts
    413


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    I will try once again to find out how could i make this sensor work.

    Anyone is interested of helping in creating a simple driver for this sensor, please any help is much appreciated.

    At the moment i have changed the diagram. For being aligned with the following code please check the test board as well.

    Name:  circuit board.png
Views: 7636
Size:  716.0 KB

    Up to now the componets im using:

    1. PIC18F26K22
    2. A Crystal 16Mhz
    3. 2 capacitors 22p
    4. 2 capacitors 100n
    5. 3 LEDs, RED, ORANGE, BLUE
    6. couple of resistors, 4.7K, 100Ohm, 220Ohm
    7. An LCD screen from 4D Systems
    8. MAX30102 Heart Rate Sensor

    I have managed with the following code to understand and complete easy tasks like:

    1. to read the PART NUMBER ID of the sensor based on the manual.
    2. How to light up the LEDs (IR and RED LEDs) Cant really understand how to send the right command for controlling the current)


    Code:
    '*********************************************************************************
    @ ERRORLEVEL -306 ; this command prevents the compiler to give you a notice of   *
                      ; crossing page boundary - make sure bits are set              *
    '********************************************************************************* 
     
      #CONFIG   ;  The PBP configuration for the PIC18F26K22 is:
    
        CONFIG FOSC     = HSHP	        ; HS oscillator (high power > 16 MHz)
        CONFIG PLLCFG   = ON	        ;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
      
    ;*---------------------------------------------------------------------------------------------------------|
    ;*---------------------------------------------------------------------------------------------------------|
    'define I2C_SLOW 1
    define  OSC 64
    
            INCLUDE "modedefs.bas"
            INCLUDE "ALLDIGITAL.pbp"
    
    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
    
    TRISA = %00000000  
    TRISB = %00000000   
    TRISC = %10011000                  
    
    '----------------------- At start all PORTS LOW -------------------------|
    '------------------------------------------------------------------------|
    PORTA = 0            'make low all ports at A range                      |
    PORTB = 0            'make low all ports at B range                      |
    PORTC = 0            'make low all ports at C range                      |
    PORTE = 0            'make low all ports at E range                      |
    '------------------------------------------------------------------------|
    
    '-------------------------- COMPARATORS OFF -----------------------------|
    '------------------------------------------------------------------------|
    CM1CON0.7 = 0 'Disable comparator1                                       |
    CM2CON0.7 = 0 'Disable comparator2                                       |
    '------------------------------------------------------------------------|
    
    '*----------------------- | EUART 1 Configuration  | --------------------------|
    
            DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
            DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
            DEFINE HSER_CLROERR 1 ' Clear overflow automatically
            DEFINE HSER_SPBRG 160 ' 38400 Baud @ 64MHz, -0.08%
            SPBRGH = 1
            BAUDCON.3 = 1         ' Enable 16 bit baudrate generator
    '*-----------------------------------------------------------------------------|
    
    ORANGE  var LATA.2   ' ORANGE LED TO INDICATE POWER ON OF THE PIC
    BLUE    var LATC.0   ' BLUE LED TO INDICATE SENSOR WOKRING CONDITION
    RED     VAR LATC.5   ' RED LED TO INDICATE ERROR
    SDA     var portc.4  ' DATA PIN
    SCL     VAR portc.3  ' CLOCK PIN
    
    ;-------------------------------------------------------------|
    ;------------------------ max30102 registers------------------|
    ;-------------------------------------------------------------| 
    Timeout  cON 2000
    i        var byte
    mydata   var BYTE
    fifowr   var byte
    fiford   var byte
    fifoD1   var byte
    fifoD2   var byte
    fifoD3   var byte
    
    ContWR   var byte      ; $AE or b10101110
    ContRD   var byte      ; $AF or b10101111
    ContRD = $AF           ; b10101111
    ContWR = $AE           ; b10101110
    addr     var byte      ; this must be defined as variable word
    
    'I2C_ID_ADDR  con   $57     ; 7-bit version of the above
    'define I2C_ID_ADDR  57h ; 7-bit version of the above
    
    ;//register addresses
    ;---------------------- STATUS REGISTER -----------------------
    REG_INTR_STATUS_1 var byte ' con  $00
    REG_INTR_STATUS_2 var byte ' con $01
    
    REG_INTR_ENABLE_1 var byte ' con  $02
    REG_INTR_ENABLE_2 var byte 'con  $03
    
    ;----------------------- FIFO REGISTERS -----------------------
    REG_FIFO_WR_PTR  var byte 'con   $04   ; FIFO WRITE POINTER REG ADDR IS 0X04
    REG_OVF_COUNTER  var byte 'con   $05
    REG_FIFO_RD_PTR  var byte 'con   $06
    REG_FIFO_DATA    var byte 'con   $07
    
    ;---------------------- CONFIG REGISTER -----------------------
    REG_FIFO_CONFIG  var byte 'con   $08
    REG_MODE_CONFIG  var byte 'con   $09
    REG_SPO2_CONFIG  var byte 'con   $0A
    REG_LED1_PA      var byte 'con   $0C
    REG_LED2_PA      var byte 'con   $0D
    
    
    REG_PILOT_PA        var byte 'con $10
    REG_MULTI_LED_CTRL1 var byte 'con $11
    REG_MULTI_LED_CTRL2 var byte 'con $12
    
    ;----------------------- TEMP REGISTER -------------------------
    REG_TEMP_INTR        var byte 'con $1F
    REG_TEMP_FRAC        var byte 'con $20
    REG_TEMP_CONFIG      var byte 'con $21
    REG_PROX_INT_THRESH  var byte 'con $30
    
    ;----------------------- PART ID REGISTER ----------------------
    REG_PART_ID      var byte
    ' -----------------------------------------------------------------------------|  
    ' indication of the working code
    
    for i= 0 to 3
    orange = 1
    pause 100
    orange = 0
    pause 50
    next i
    orange = 1
    
    init: 
    low blue
    low red
    pause 100
    
    REG_PART_ID = $FF     ' this is the part id reg adress which gives hex 15
    i2cread  SDA,scl,contrd,REG_PART_ID,[mydata],error
    
    '*******************************************************************************
    ' if %00000010 is used then only IR LED for heart rate mode is set             *
    ' if %00000011 is used then only RED & IR LED for SPO2 mode is set             *
    ' if %00000111 is used then Multi Led Mode is set                              *
    '*******************************************************************************
    
    addr = $09   ' MODE CONFIGURATION 
    i2cwrite  SDA,scl,contwr,addr,%00000010,error  ' ModLED = $02 as per data sheet heart rate mode, $03 SpO2 mode
    'pause 100
    
    addr = $0C    'LED PULSE AMLIDUDE FOR for LED1_PA[7:0] 0x0C
    i2cwrite  SDA,scl,Contwr,addr,$3f,error' if LED1_PA = $3F  , 12.6 mA , ($7F is 25.4 mA)
    'pause 100
    
    '********************************************************************************
    
    REG_FIFO_DATA = $07
    i2cread  sda,scl,contrd,REG_FIFO_DATA,[fifod1,fifod2,fifod3],error
    '********************************************************************************
    
    start:
    HSEROUT [$73,$03,$04,$11,$ff,$ff,"PART ID: ",hex mydata,"h",$00]
    Hserin  timeout,error,[wait(6)]
    
    HSEROUT [$73,$05,$0A,$11,$07,$E0,"FIFO DT: ",$00]   ' lime color $07,$E0
    Hserin  timeout,error,[wait(6)]
    
    HSEROUT [$73,$03,$0C,$11,$07,$E0,dec fifod1,dec fifod2,dec fifod3,$00]   ' lime color $07,$E0
    Hserin  timeout,error,[wait(6)]
    'goto start
    
    blueled: 
    high blue
    PAUSE 300
    goto init
    
    error:
    high RED
    pause 100
    end

  3. #3
    Join Date
    May 2013
    Location
    australia
    Posts
    2,680


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    it looks like there is not much interest in this project

    there are a number of issues i can see, starting at the top with the physicals

    1, why a xtal osc, getting a stable xtal osc to work on a bread board is not guaranteed.
    xtal pins are often too thin for reliable connection and the capacitive coupling between strips is high.
    the internal osc is easily stable enough for this project and so much simpler.
    2, you provide nil detail on the display specs, the 3.3 v supply from lcd is it stable and capable of suppling the project ?
    Warning I'm not a teacher

  4. #4
    Join Date
    Oct 2010
    Posts
    413


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    Thanks for the reply.

    I will give it a try as i would like to make this sensor work. I just need some guidance if possible.

    1. I will remove the external crystal, less part the better, in case for this project the internal is stable enough.
    2. The 4D Systems display, is an easy display to use, as they have on board chip and loaded a ready made driver for ease of use. I have this display couple of years now and it works as expected.

    You can find the datashet of the display here and the SERIAL COMMAND REFERENCE

    Regarding the output 3.3V from the display, looks like it is quite stable as i measured it. The Sensor's Power Supply: 3.3V~5V, so i could also use 5V.

  5. #5
    Join Date
    May 2013
    Location
    australia
    Posts
    2,680


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    There is your first major hurdle

    Name:  LEO.jpg
Views: 7267
Size:  171.9 KB

    each led in 30102 can draw 50ma the two leds on your board 20ma each , the pic chip maybe another 20ma.
    at least use a 470uF smoothing cap but another 3.3v power source would be better

    the led can be lit
    Warning I'm not a teacher

  6. #6
    Join Date
    Oct 2010
    Posts
    413


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    well noted,

    1. Changed the crystal and used only the interal

    CONFIG FOSC = INTIO67 ; Internal oscillator block
    2. i've changed the circuit from 3.3V which was the output of the Display, and supplied the circuit with the PICKIT2 5V. I checked that this specific circuit draws up to 80mA. (USB 2 can deliver 100mA and at its maximum 500mA)

    MAX30102 can be supplied with 5V as from the following link.

    Name:  MAX30102 drawing.png
Views: 7258
Size:  258.2 KB

    I have also applied the fix they have from the given link, and measured the output voltage at 1.8V which goes to the MAX30102 chip on the tiny board. So everything looks good now.

    Name:  MAX30102 board.png
Views: 7188
Size:  373.4 KB

    Name:  MAX30102 board fix.png
Views: 7922
Size:  264.8 KB

    Name:  1.8V output.png
Views: 7303
Size:  567.8 KB
    Last edited by astanapane; - 11th January 2022 at 17:35.

  7. #7
    Join Date
    Oct 2010
    Posts
    413


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    up to now this is the code and the output.....

    Code:
    '*********************************************************************************
    @ ERRORLEVEL -306 ; this command prevents the compiler to give you a notice of   *
                      ; crossing page boundary - make sure bits are set              *
    '********************************************************************************* 
     
      #CONFIG   ;  The PBP configuration for the PIC18F26K22 is:
    
        CONFIG FOSC     = INTIO67  ; Internal oscillator block
        CONFIG PLLCFG   = ON	   ; 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
      
    ;*---------------------------------------------------------------------------------------------------------|
    ;*---------------------------------------------------------------------------------------------------------|
    'define I2C_SLOW 1
    define  OSC 64
    
            INCLUDE "modedefs.bas"
            INCLUDE "ALLDIGITAL.pbp"
    
    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
    
    TRISA = %00000000  
    TRISB = %00000000   
    TRISC = %10011000                  
    
    '----------------------- At start all PORTS LOW -------------------------|
    '------------------------------------------------------------------------|
    PORTA = 0            'make low all ports at A range                      |
    PORTB = 0            'make low all ports at B range                      |
    PORTC = 0            'make low all ports at C range                      |
    PORTE = 0            'make low all ports at E range                      |
    '------------------------------------------------------------------------|
    
    '-------------------------- COMPARATORS OFF -----------------------------|
    '------------------------------------------------------------------------|
    CM1CON0.7 = 0 'Disable comparator1                                       |
    CM2CON0.7 = 0 'Disable comparator2                                       |
    '------------------------------------------------------------------------|
    
    '*----------------------- | EUART 1 Configuration  | --------------------------|
    
            DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
            DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
            DEFINE HSER_CLROERR 1 ' Clear overflow automatically
            DEFINE HSER_SPBRG 160 ' 38400 Baud @ 64MHz, -0.08%
            SPBRGH = 1
            BAUDCON.3 = 1         ' Enable 16 bit baudrate generator
    '*-----------------------------------------------------------------------------|
    
    ORANGE  var LATA.2   ' ORANGE LED TO INDICATE POWER ON OF THE PIC
    GREEN   var LATC.0   ' BLUE LED TO INDICATE SENSOR WOKRING CONDITION
    RED     VAR LATC.5   ' RED LED TO INDICATE ERROR
    SDA     var portc.4  ' DATA PIN
    SCL     VAR portc.3  ' CLOCK PIN
    
    ;-------------------------------------------------------------|
    ;----------------------      variables      ------------------|
    ;-------------------------------------------------------------| 
    Timeout  cON 2000
    i        var byte
    mydata   var BYTE
    fifowr   var byte
    fiford   var byte
    fifoD1   var byte
    fifoD2   var byte
    fifoD3   var byte
    
    ContWR   var byte      ; $AE or b10101110
    ContRD   var byte      ; $AF or b10101111
    ContRD = $AF           ; b10101111
    ContWR = $AE           ; b10101110
    addr     var byte      ; this must be defined as variable word
    
    'I2C_ID_ADDR  con   $57     ; 7-bit version of the above
    'define I2C_ID_ADDR  57h ; 7-bit version of the above
    
    ;//register addresses
    ;---------------------- STATUS REGISTER -----------------------
    REG_INTR_STATUS_1 var byte 'con  $00
    REG_INTR_STATUS_2 var byte 'con  $01
    
    REG_INTR_ENABLE_1 var byte 'con  $02
    REG_INTR_ENABLE_2 var byte 'con  $03
    
    ;----------------------- FIFO REGISTERS -----------------------
    REG_FIFO_WR_PTR  var byte 'con   $04   ; FIFO WRITE POINTER REG ADDR IS 0X04
    REG_OVF_COUNTER  var byte 'con   $05
    REG_FIFO_RD_PTR  var byte 'con   $06
    REG_FIFO_DATA    var byte 'con   $07
    
    ;---------------------- CONFIG REGISTER -----------------------
    REG_FIFO_CONFIG  var byte 'con   $08
    REG_MODE_CONFIG  var byte 'con   $09
    REG_SPO2_CONFIG  var byte 'con   $0A
    REG_LED1_PA      var byte 'con   $0C
    REG_LED2_PA      var byte 'con   $0D
    
    
    REG_PILOT_PA        var byte 'con $10
    REG_MULTI_LED_CTRL1 var byte 'con $11
    REG_MULTI_LED_CTRL2 var byte 'con $12
    
    ;----------------------- TEMP REGISTER -------------------------
    REG_TEMP_INTR        var byte 'con $1F
    REG_TEMP_FRAC        var byte 'con $20
    REG_TEMP_CONFIG      var byte 'con $21
    REG_PROX_INT_THRESH  var byte 'con $30
    
    ;----------------------- PART ID REGISTER ----------------------
    REG_PART_ID      var byte
    ' -----------------------------------------------------------------------------|  
    ' -----------------------------------------------------------------------------|  
    '                          [ LCD Initialization ]                              |
    '------------------------------------------------------------------------------|
              ' FIRST TIME BOOTUP: We give plenty of time for tbe LCD '
              
    pause 1000  
    HSEROUT[$55]      ' uOLED Initialize this is the 'U' character of autoband rate to LCD
    Hserin  timeout,error,[wait(6)]
    HSEROUT [$45]    ' clear the LCD
    Hserin  timeout,error,[wait(6)]
    hserout[$73,$00,$03,$11,$ff,$ff,"HEART RATE SENSOR",$00] 
    Hserin  timeout,error,[wait(6)]           
    Hserout[$4F,$01] ; Set Transparent-Opaque Text - 4Fhex
    Hserin  timeout,error,[wait(6)]
    pause 500
    HSEROUT [$45]    ' clear the LCD
    Hserin  timeout,error,[wait(6)]
    
    ' indication of the working code
    
    for i= 0 to 3
    orange = 1
    pause 100
    orange = 0
    pause 50
    next i
    orange = 1
    
    init: 
    low green
    low red
    pause 100
    
    REG_PART_ID = $FF     ' this is the part id reg adress which gives hex 15
    i2cread  SDA,scl,contrd,REG_PART_ID,[mydata],error
    
    '*******************************************************************************
    ' if %00000010 is used then only IR LED for heart rate mode is set             *
    ' if %00000011 is used then only RED & IR LED for SPO2 mode is set             *
    ' if %00000111 is used then Multi Led Mode is set                              *
    '*******************************************************************************
    
    addr = $09   ' MODE CONFIGURATION 
    i2cwrite  SDA,scl,contwr,addr,%00000010,error  ' ModLED = $02 as per data sheet heart rate mode, $03 SpO2 mode
    'pause 100
    
    addr = $0C    'LED PULSE AMLIDUDE FOR for LED1_PA[7:0] 0x0C
    i2cwrite  SDA,scl,Contwr,addr,$3f,error' if LED1_PA = $3F  , 12.6 mA , ($7F is 25.4 mA)
    'pause 100
    '********************************************************************************
    REG_FIFO_WR_PTR = $04   ; FIFO WRITE POINTER REG ADDR IS 0X04
    i2cwrite  SDA,scl,contrd,REG_FIFO_WR_PTR,[fifowr],error
    
    REG_FIFO_RD_PTR = $06   ; FIFO READ POINTER REG ADDR IS 0X06
    i2cread  SDA,scl,contrd,REG_FIFO_rd_PTR,[fiford],error
    
    REG_FIFO_DATA = $07
    i2cread  sda,scl,contrd,REG_FIFO_DATA,[fifod1,fifod2,fifod3],error
    '********************************************************************************
    
    start:
    HSEROUT [$73,$03,$04,$11,$ff,$ff,"PART ID: ",hex mydata,"h",$00]
    Hserin  timeout,error,[wait(6)]
    
    HSEROUT [$73,$05,$0A,$11,$07,$E0,"FIFO DT: ",$00]   ' lime color $07,$E0
    Hserin  timeout,error,[wait(6)]
    
    HSEROUT [$73,$04,$0C,$11,$F8,$1F,dec fifod1,dec fifod2,dec fifod3,$00]   ' fuchsia color $F8, $1F
    Hserin  timeout,error,[wait(6)]
    'goto start
    
    blueled: 
    high green
    PAUSE 300
    goto init
    
    error:
    high RED
    pause 100
    end
    Name:  IR LED HR MODE.png
Views: 7259
Size:  730.5 KB

    Name:  FIFODT.png
Views: 7362
Size:  726.6 KB
    Last edited by astanapane; - 11th January 2022 at 20:22.

  8. #8
    Join Date
    May 2013
    Location
    australia
    Posts
    2,680


    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 02:43.
    Warning I'm not a teacher

  9. #9
    Join Date
    May 2013
    Location
    australia
    Posts
    2,680


    Did you find this post helpful? Yes | No

    Default Re: Heart rate sensor MAX30102

    mine has 3.3v written on it but the data sheet says the led supply can be 6v and the other sda scl pins are 6v tolerant
    maybe mine has a cheap 1.8v regulator , it works fine at 3.3v
    Last edited by richard; - 11th January 2022 at 10:43.
    Warning I'm not a teacher

Similar Threads

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

Members who have read this thread : 1

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