Interesting 3D print!
Ioannis
 Re: Heart rate sensor MAX30102
 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.
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
 Re: Heart rate sensor MAX30102
 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
 Re: Heart rate sensor MAX30102
 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.
 Re: Heart rate sensor MAX30102
 Re: Heart rate sensor MAX30102
		There is your first major hurdle
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
 Re: Heart rate sensor MAX30102
 Re: Heart rate sensor MAX30102
		well noted,
1. Changed the crystal and used only the interal
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)CONFIG FOSC = INTIO67 ; Internal oscillator block
MAX30102 can be supplied with 5V as from the following link.
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.

Last edited by astanapane; - 11th January 2022 at 17:35.
 Re: Heart rate sensor MAX30102
 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

Last edited by astanapane; - 11th January 2022 at 20:22.
 Re: Heart rate sensor MAX30102
 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
 Re: Heart rate sensor MAX30102
 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
Bookmarks