-
Heart rate sensor MAX30102
Dear all,
the covid-19 period, i have spent lots of time designing a 3D printed Adaptable medical Mask for covid-19. It was succesful using bio-compatible materials
(here's the liink: https://www.linkedin.com/feed/update...6630277947393/)
I have printed free of charge, for the kids in school about 50 of face shields in order to be safe inside the lectures.
The same i did for the professional 3D printed Adaptable Medical Mask, for Hospitals. Just printed couple of those for testing.
Now i would like to prepare a free of charge again low cost electronic heart rate circuit, for my sons classroom. Kids are in total 15 in class.
As it is my first time using I2C protocol, i would like your help in order to establish a connection with the heart sensor MAX30102.
If anyone have tried this sensor i would be much appreciated if you could share a part of your code.
I have in front of me the manual of the MAX30102 and all the control and register modes. Actually i'm reading this 2 days now, and really as a newbie, cant understand where to start from.
I will use the PIC18F26K22 at 16Mhz as from the PICBASIC manual I2C protocol needs to run up to 20MHZ using the I2CWRITE or I2CREAD software commands. (i hope i'm right)
Next the following ports will be used.
Code:
LATC.1 for Data
LATC.2 for Clock
also reserved two more ports for external serial display
LATC.6 for TX
LATC.7 for RX
Some MAX30102 registers
Code:
;-------------------------------------------------------------|
;------------------------ max30102 registers------------------|
;-------------------------------------------------------------|
define I2C_WRITE_ADDR $AE ; b10101110
define I2C_READ_ADDR $AF ; b10101111
define I2C_ID_ADDR $57 ; 7-bit version of the above
;define I2C_ID_ADDR 57h ; 7-bit version of the above
;//register addresses
;---------------------- STATUS REGISTER -----------------------
define REG_INTR_STATUS_1 $00
define REG_INTR_STATUS_2 $01
define REG_INTR_ENABLE_1 $02
define REG_INTR_ENABLE_2 $03
;----------------------- FIFO REGISTERS -----------------------
define REG_FIFO_WR_PTR $04 ; FIFO WRITE POINTER REG ADDR IS 0X04
define REG_OVF_COUNTER $05
define REG_FIFO_RD_PTR $06
define REG_FIFO_DATA $07
;---------------------- CONFIG REGISTER -----------------------
define REG_FIFO_CONFIG $08
define REG_MODE_CONFIG $09
define REG_SPO2_CONFIG $0A
define REG_LED1_PA $0C
define REG_LED2_PA $0D
define REG_PILOT_PA $10
define REG_MULTI_LED_CTRL1 $11
define REG_MULTI_LED_CTRL2 $12
;----------------------- TEMP REGISTER -------------------------
define REG_TEMP_INTR $1F
define REG_TEMP_FRAC $20
define REG_TEMP_CONFIG $21
define REG_PROX_INT_THRESH $30
;----------------------- PART ID REGISTER ----------------------
define REG_REV_ID $FE
define REG_PART_ID $FF
Now i'm trying to understand based on the manual how could i communicate with sensor and at least see it alive (any led light on the sensor)
Really looking for your help.
-
Re: Heart rate sensor MAX30102
on the first post i think i made a mistake with Defines.
Is this the correct way to assign a constant value to the name?
Code:
;-------------------------------------------------------------|
;------------------------ max30102 registers------------------|
;-------------------------------------------------------------|
I2C_WRITE_ADDR con $AE ; b10101110
I2C_READ_ADDR con $AF ; b10101111
I2C_ID_ADDR con $57 ; 7-bit version of the above
;I2C_ID_ADDR con 57h ; 7-bit version of the above
;//register addresses
;---------------------- STATUS REGISTER -----------------------
REG_INTR_STATUS_1 con $00
REG_INTR_STATUS_2 con $01
REG_INTR_ENABLE_1 con $02
REG_INTR_ENABLE_2 con $03
;----------------------- FIFO REGISTERS -----------------------
REG_FIFO_WR_PTR con $04 ; FIFO WRITE POINTER REG ADDR IS 0X04
REG_OVF_COUNTER con $05
REG_FIFO_RD_PTR con $06
REG_FIFO_DATA con $07
;---------------------- CONFIG REGISTER -----------------------
REG_FIFO_CONFIG con $08
REG_MODE_CONFIG con $09
REG_SPO2_CONFIG con $0A
REG_LED1_PA con $0C
REG_LED2_PA con $0D
REG_PILOT_PA con $10
REG_MULTI_LED_CTRL1 con $11
REG_MULTI_LED_CTRL2 con $12
;----------------------- TEMP REGISTER -------------------------
REG_TEMP_INTR con $1F
REG_TEMP_FRAC con $20
REG_TEMP_CONFIG con $21
REG_PROX_INT_THRESH con $30
;----------------------- PART ID REGISTER ----------------------
REG_REV_ID con $FE
REG_PART_ID con $FF
-
Re: Heart rate sensor MAX30102
Quote:
LATC.1 for Data
LATC.2 for Clock
a recipe for failure in the making ?
use of LATx ports in "highlevel" commands is incorrect and will not work as expected
Quote:
Is this the correct way to assign a constant value to the name?
a quick little exercise trying to compile this will reveal the differences between defines and constants
Code:
reg var byte'#define bite_me 5 ;try one or the other of these two or niether
'bite_me con 5 ; "
REG_INTR_STATUS_1 con $00
REG_INTR_STATUS_2 con $01
REG_INTR_STATUS_2 con $07
REG_INTR_STATUS_3 con bite_me
define REG_INTR_ENABLE_1 $02
define REG_INTR_ENABLE_2 bite_me
define REG_INTR_ENABLE_2 1
#define REG_INTR_ENABLE_3 $02
#define REG_INTR_ENABLE_4 bite_me
#define REG_INTR_ENABLE_4 1
loopy:
reg = bite_me
reg = REG_INTR_ENABLE_3
reg = REG_INTR_ENABLE_1
reg = REG_INTR_STATUS_1
goto loopy
-
Re: Heart rate sensor MAX30102
Thanks for the reply.
do you mean that i cannot use the following format?
Code:
DataPin var LATC.1
ClockPin var LATC.2
-
Re: Heart rate sensor MAX30102
if that will become
I2CREAD DataPin, ClockPin, Control,{Address,}[Var{,Var...}]{,Label}
then yes that is not allowable and will cause difficult to determine bugs.
you have to remember pbp is ancient technology, latx registers did not exist when it was created
it never gets any significant updates
-
Re: Heart rate sensor MAX30102
It is a bit consfusing for me.
But i will try to figure it out.
My goal is to communicate with this heart sensor. First step is to send this command to light up the LED and then try to read the information needed.
I have tried this I2C ping program http://www.picbasic.co.uk/forum/showthread.php?t=20185, in order to see if the sensor responds with the ACK. (i though that the sensor was dead)
-
Re: Heart rate sensor MAX30102
this i2c sniffer will usually do the job
Code:
DEFINE I2C_SLOW 1
anselA=0 'dig i/o
ANSELC=0
TRISC= %11111111
TRISA= %11111110
SCL var Portc.1 ' I2C Clock PortA.3
SDA var Portc.0 ' I2C Data PortA.2
I VAR BYTE
addr var byte
rd var byte
porta.0=1
DEFINE DEBUG_REG PORTA
DEFINE DEBUG_BIT 0 ; if not used for pwr
DEFINE DEBUG_BAUD 38400
DEFINE DEBUG_MODE 0
pause 2000
Debug "Start",13 ,10
addr=0
for I = $02 to $fe step 2
I2Cread SDA,SCL,i,addr,[rd] ; or I2Cread SDA,SCL,i,[rd] ;
Debug "found addr ",#i , 13,10
nak:
Next I
end
-
4 Attachment(s)
Re: Heart rate sensor MAX30102
thanks for the book.
on the other hand, i would like to continue with this project as it is important for me and the kids in school.
I have done the first attempt to communicate with the sensor but no luck.
Based on the Datasheet MAX30102, device address, or slave id: %1010111, consists of 7 bit, B7-B1,and the MSB-7 is transmitted first followed by the remaining bits. B0 is LSB which can be 0 if we write or 1 if we read.
Then again from the manual explains that for the first write operation, we send the slave id as the first byte!....followed by the register address byte and then one or more data.
From the PBP manual, and from this link http://www.picbasic.co.uk/forum/cont...-EEPROM-Part-1
It is clear that I2CWRITE and I2CREAD command takes care of the write or read bit, also for the ACK.
Attachment 8924
Now i have tried to send the following:
if PBP and command I2CWRITE takes care of the 8th bit then how could i manage to correspond it in the code.
Code:
i2cwrite sda,scl,%1010111,$04,error ' this is slave id cosnist of 7 bits.
If i send the above command nothing will happen, and the data line will be offset from the clock.
Attachment 8925
Now using the following code:
Code:
i2cwrite sda,scl,%10101110,$04,error
i get this on the scope:
Attachment 8926
then i tried the following:
Code:
i2cwrite sda,scl,%10101110,$04,error
pause 100
i2cwrite sda,scl,%10101110,$04,error
and the result on the scope: it looks strange again.
Attachment 8927
-
Re: Heart rate sensor MAX30102
did you try my i2c sniffer ?
Quote:
i2cwrite sda,scl,%10101110,$04,error
how can that work ? you are attempting to write to the FIFO_WR_PTR yet providing no data to be written .
i2cwrite sda,scl,$ae,$04,[1],error
in general code snippets are a waste of time
what pins , how are they set
a schematic
-
4 Attachment(s)
Re: Heart rate sensor MAX30102
Richard i havent used your sniffer code. Will do today it today.
The breadboarding....i think is clear as schematic, if you like schematic i could also make one.
Attachment 8928
SCL is set as input in TRISC
Code:
TRISC = %10000100 ' portc.7 and portc.2 set as input.
all other unused ports are configured as output and set to low.
SDA var portc.1
SCL var portc.2
Now regarding the FIFO_WR_PTR it is not clear to me in the manual what data to write to it.
Attachment 8929
for example for the REG_MODE_CONFIG which is $09
Attachment 8930
there is a detailed info of the bits need to be set.
Attachment 8931
For someone that is the first time working with a peripheral or a new method, it should be so many years a detailed info for configuration. At least a step by step guide.
I'm not talking about you, but for all the others were in this forum for so many years. There were few guys were really helping. We lost a chief who was really made detailed explanations like talking to a baby.
If we need to keep PBP alive, we need to start from 0. Here is not a plave to learn from skratch, and i agree. But if anyone loves PBP, we need to do that. Attract newbies like me, that would like to learn.
Anyway, i will get in focus on this project, because it matters to me. If anyone would like to get involved and have in house a MAX30102, i would be really happy if could help me out as well.
Richard i understand that you have no time and you have really other things to focus. Really appreciate your help, and i think you are one of the persons help in here.
Many thanks.
-
Re: Heart rate sensor MAX30102
Quote:
The breadboarding....i think is clear as schematic, if you like schematic i could also make one
not really , i looked at 3 modules the mikroe one is 3.3v only .the one mouser/e14 sell is 3.3 or 5v and has a logic level converter on board
another provides no schematic and only vague spec no schema, i cannot identify your module
by the look of your cro traces you are belting 5v in on the scl,sda pins , better hope its 5v tolerant
Quote:
TRISC = %10000100 ' portc.7 and portc.2 set as input.
is wrong both must be input , the routine will switch tris as req
if the module have 3.3 v pull ups might be better to use the open collector/drain method for i2c command
[edit] forget that ,its open collecter by default.
Quote:
all other unused ports are configured as output and set to low.
unnecessary
Quote:
SDA var portc.1
SCL var portc.2
conflicts with your tris statement anyway
Quote:
Now regarding the FIFO_WR_PTR it is not clear to me in the manual what data to write to it.
me either but it will do something if everything else is correct
-
Re: Heart rate sensor MAX30102
Quote:
For someone that is the first time working with a peripheral or a new method, it should be so many years a detailed info for configuration. At least a step by step guide.
I'm not talking about you, but for all the others were in this forum for so many years. There were few guys were really helping. We lost a chief who was really made detailed explanations like talking to a baby.
If we need to keep PBP alive, we need to start from 0. Here is not a plave to learn from skratch, and i agree. But if anyone loves PBP, we need to do that. Attract newbies like me, that would like to learn
if you are familiar with i2c protocol and the vagaries of the device you have studied and intend to use then the pbp manual
tells you everything you need to know to communicate with your device with pbp's i2c commands.
the pbp manual is not there to teach i2c protocol to a novice , its raison d'etre is to explain usage of pbp implementation.
having said that you can always ask questions on forums but really the onus is on you to do the ground work. its your project.
its a pretty tall order to expect a complete novice tutorial for every device you can pluck out of the air from unpaid volunteers
there are still few here willing to have a go at helping but don't forget dt was paid support , that resource has never been replaced.
leo will usually help but he has not ventured onto this forum for years and years afaik.
-
1 Attachment(s)
Re: Heart rate sensor MAX30102
Changed to input both portc.1 and portc.2
This is the module.
https://reedpaper.wordpress.com/2018...x-wrong-board/
I have also following the "fix". Well module is 3.3V but i have never seen in all of the Arduino connections any note.
I have changed the connections and used the 3.3V output from the Display to power the rest of the circuit.
I dont beleive that i have burned the module as this is the result before i change the voltage supply from 5V to 3.3V.
Code:
i2cwrite sda,scl,$AE,$04
pause 100
This is the proof of ACK in 9th bit. As from the data sheet if the Id is the right one, the module pulls down the SDA during 9th bit to acknowledge receipt of data.
Attachment 8932
-
Re: Heart rate sensor MAX30102
Quote:
i2cwrite sda,scl,$AE,$04
i see you're still torturing the device sending incomplete write resister i2c control messages at it
-
Re: Heart rate sensor MAX30102
yes i havent send any data yet as i'm searching in the i2c how to do that corresponds to the max30102 manual.
At least i know sensor is responded by pulling SDA down on 9th bit. This is something for me.
-
Re: Heart rate sensor MAX30102
i've done many tries. I just want to see if the red LED inside the sensor is alive. At least by sending a command to activate it.
Code:
This is as from the pseudo code the first step. I really do not know if that is the right way to send Device ID + write mode
Then send the FIFO_WR_PTR (i still dont know what are the bits needs to be configured)
REPEAT START
addr = $04 ; FIFO WRITE POINTER REG ADDR IS 0X04
i2cwrite SDA,scl,contwr
i2cwrite SDA,scl,contwr,addr
i2cwrite SDA,scl,contwr
i2cwrite SDA,scl,contwr,addr
Apart from pseudo code in the datasheet, Next i tried to send mode for the heart rate mode only
addr = $09 ' mode configuration
i2cwrite SDA,scl,contwr,addr,[modled],error ' ModLED = $02 as per data sheet heart rate mode only
In the end i tried to send the led pulse amplitute.
addr = $0C ' led pulse amplitute
i2cwrite SDA,scl,contwr,addr,[led1_pa],error' LED1_PA = $3F , 12.6 mA
no luck......keep walking.
-
Re: Heart rate sensor MAX30102
given that you can buy these for < $20us delivered to your door i doubt its worth while making them other than as an intellectual exercise
https://au.banggood.com/BOXYM-oFit-2...r_warehouse=CN
i have tried the sparkfun arduino demos and was not particularly impressed with accuracy or stability of readings obtained
{maybe my heart is inaccurate and unstable}
the raspberrypi code goes about it quite differently with some dsp done on data collected in a fixed sampling period [not tried it].
i have no experience with these things , i don't know if reverse engineering the arduino code is even worthwhile
but no matter how you go about it the sort of digital signal processing needed will be lots and lots of hard work with pbp
do you have a plan ? have you established optimal device settings to get the best readings ? how much data is needed and from where ?
reading and writing to the device is child's play, setting it up to get meaningful data and being able to extract information from that data is another story
-
Re: Heart rate sensor MAX30102
I double what Richard pointed.
Ioannis
-
Re: Heart rate sensor MAX30102
Thanks both for your kind reply.
I will find the way. I know it is quite difficult and options are limited to use Arduino.
-
Re: Heart rate sensor MAX30102
i tried the arduino code again with the sensor attached to my finger with a rubber band , it works a bit better that way
do you have a stl model for an enclosure ? . its difficult to make any sense of wildly unstable readings
i'm thinking a ESP8285 M3 board would make a better platform and allow use of arduino libs if they can be proven to be adequate
ESP8285's these cut down esp8266's are very cheap and still have more processing power than a bucket full of pic chips they are quite happy to run on two aaa batteries and consume little energy if wifi not engaged
-
Re: Heart rate sensor MAX30102
Hi Richard,
once i have all the components (including the arduino board or ESP8285) then i will be ready to design the 3D cad model and printed.
I will order some arduino and ESP and check them out.
-
Re: Heart rate sensor MAX30102
Use of such finger sensors need to have your finger cleaned from oil with alcohol (isoprop. alcohol or similar).
It is necessary for the sensors to keep working with consistency.
Ioannis
-
Re: Heart rate sensor MAX30102
thanks ioannis, with out the repeatable test conditions its all guess work
i might see if i can print this
https://www.thingiverse.com/thing:4395147
-
Re: Heart rate sensor MAX30102
Interesting 3D print!
Ioannis
-
1 Attachment(s)
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.
Attachment 9132
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
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 ?
-
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.
-
1 Attachment(s)
Re: Heart rate sensor MAX30102
There is your first major hurdle
Attachment 9133
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
https://youtu.be/wYIggIHlJTI
-
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
-
4 Attachment(s)
Re: Heart rate sensor MAX30102
well noted,
1. Changed the crystal and used only the interal
Quote:
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.
Attachment 9135
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.
Attachment 9136
Attachment 9137
Attachment 9134
-
2 Attachment(s)
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
Attachment 9140
Attachment 9139
-
Re: Heart rate sensor MAX30102
Ok the FIFODT, FIFO DATA is not the one we are looking for.
Just tried to see what could i get by requesting it using the following code. Also the code is not right but that is why i would like your help in here.
Code:
REG_FIFO_DATA = $07
i2cread sda,scl,contrd,REG_FIFO_DATA,[fifod1,fifod2,fifod3],error
HSEROUT [$73,$04,$0C,$11,$F8,$1F,dec fifod1,dec fifod2,dec fifod3,$00] ' fuchsia color $F8, $1F
Hserin timeout,error,[wait(6)]
First i would like to retrieve the raw data of the IR LED.
-
Re: Heart rate sensor MAX30102
my code , you should know i have no idea :-
1, what led pwr to use
2, what led pwidth to use
3, what sample rate to use
4, what sample resolution to use
5, if there are any fifo overflows and if it matters much
6, what led the readings represents
7, how to interpret the data
8, how much data to collect [i assume at least 2 seconds worth]
when graphed i see no regular pattern that could be a heart beat
there is a difference between finger and no finger pattern
Code:
'****************************************************************'* Name : MAX30102 FOR PIC 18 test *
'* 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
'define I2C_SLOW 1
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
#DEFINE DEBUGING 1
#IFNDEF DEBUGING
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
#ELSE
DEFINE DEBUG_REG PORTB
DEFINE DEBUG_BIT 7
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0
ANSELB=0
LATB.7=1
#ENDIF
SDA var portc.4 ' DATA PIN
SCL VAR portc.3 ' CLOCK PIN
Timeout cON 2000
reg var BYTE
fifo var byte[6]
addr var byte
REVISION var byte
PARTID var byte
buffer var byte[1152]
ptr var byte
btr var byte
index var word
;----------------------- 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]
STATUS1 con 0 ;A_FULL[7]
' -----------------------------------------------------------------------------|
#IFDEF DEBUGING
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,[$30]
reg = REG_LED2_PA
i2cwrite SDA,scl,ADDR,reg,[2]
reg = REG_LED1_PA
i2cwrite SDA,scl,ADDR,reg,[2]
reg = FIFO_CONFIG
i2cwrite SDA,scl,ADDR,reg,[16]
#IFNDEF DEBUGING
HSEROUT [$73,$03,$04,$11,$ff,$ff,"PART ID: 0X",hex PARTID,"/0X", hex REVISION,$00]
Hserin timeout,error,[wait(6)]
#ELSE
DEBUG 13,10, "PART ID: 0X",hex PARTID,"/0X",hex REVISION
#ENDIF
'********************************************************************************
start:
reg= REG_TEMP_CONFIG
i2cwrite SDA,scl,ADDR,reg,[1]
reg= REG_TEMP_INT
i2cread sda,scl,ADDR,reg,[fifo[0],fifo[1]]
#IFNDEF DEBUGING
HSEROUT [$73,$05,$0A,$11,$07,$E0,"TEMP: ",DEC fifo[0],".",DEC2( fifo[1]<<6),$00]
Hserin timeout,error,[wait(6)]
#ELSE
DEBUG 13,10, "TEMP: ",DEC fifo[0],".",DEC2( fifo[1]<<6)
#ENDIF
GOSUB AQUIRE
pause 5000
goto start
aquire:
reg= FIFO_WR_PTR
i2cwrite SDA,scl,ADDR,reg,[0]
reg= FIFO_RD_PTR
i2cwrite SDA,scl,ADDR,reg,[0]
FOR index = 0 TO 1151 STEP 0
btr =0
reg= STATUS1
WHILE btr&$80=0
i2cread sda,scl,ADDR,reg,[btr]
WEND
reg= FIFO_RD_PTR
i2cread SDA,scl,ADDR,reg,[btr]
btr = (btr- ptr) & 31
WHILE btr
reg = FIFO_DATA
i2cread sda,scl,ADDR,reg,[buffer[index],buffer[index+1],buffer[index+0],buffer[index+5],buffer[index+4],buffer[index+3]]
index=index+6
btr=btr-1
ptr = (Ptr+1) & 31
WEND
pause 200 ; no sure about this either
NEXT
FOR index = 0 TO 1151 STEP 0
DEBUG 13,10,HEX2 buffer[index+0],HEX2 buffer[index+1],9,HEX2 buffer[index+3],HEX2 buffer[index+4]
index=index+6
NEXT
RETURN
-
Re: Heart rate sensor MAX30102
thanks Richard,
i will read carefully your code and will come back because i have couple of questions.
In the begging i got confused the way you use addr and reg names inside the I2Cread or write command.
Code:
ADDR = $ae ; addr is 0x57 << 1
reg= REG_PART_REVISION
i2cread SDA,scl,ADDR,reg,[REVISION,PARTID]
I followed the manual example: so i wont get consfused.
Code:
I2CWRITE PORTA.0,PORTA.1,cont,addr,[B2]
-
Re: Heart rate sensor MAX30102
Quote:
I followed the manual example: so i wont get consfused.
not really
addr is the i2c device address , reg is the register you are accessing. that example you refer is for an eeprom
where those words make a little sense, in this context they are totally misleading
-
Re: Heart rate sensor MAX30102
Quote:
Originally Posted by
richard
not really
addr is the i2c device address , reg is the register you are accessing. that example you refer is for an eeprom
where those words make a little sense, in this context they are totally misleading
once again you are right. I will change the names in the code as well.
One more question. What is the difference on the following?
With the [] and without them. I noticed that i get completely different results. The ones with the [] looks like is the right one as once i place them, i can control the values of the LED's pulse amplidute. Now it is visible the difference.
Code:
addr = $09 ' MODE CONFIGURATION
i2cwrite SDA,scl,contwr,addr,[%00000011],error ' ModLED = $02 as per data sheet heart rate mode, $03 SpO2 mode
pause 10
addr = $0A ' SpO2 mode configuration
i2cwrite SDA,scl,contwr,addr,[%01111101],error ' check the manual for this configuration
pause 100
addr = $0C 'LED PULSE AMLIDUDE FOR for LED1_PA[7:0] 0x0C
i2cwrite SDA,scl,Contwr,addr,[$03],error' if LED1_PA = $3F , 12.6 mA , ($7F is 25.4 mA)
pause 10
addr = $0D 'LED PULSE AMLIDUDE FOR LED2_PA[7:0] 0x0D
i2cwrite SDA,scl,contwr,addr,[$03],error ' if LED2_PA = $1F , 6.2 mA , ($7F is 25.4 mA)
pause 10
and the following:
Code:
addr = $09 ' MODE CONFIGURATION
i2cwrite SDA,scl,contwr,addr,%00000011,error ' ModLED = $02 as per data sheet heart rate mode, $03 SpO2 mode
pause 10
addr = $0A ' SpO2 mode configuration
i2cwrite SDA,scl,contwr,addr,%01111101,error ' check the manual for this configuration
pause 100
addr = $0C 'LED PULSE AMLIDUDE FOR for LED1_PA[7:0] 0x0C
i2cwrite SDA,scl,Contwr,addr,$03,error' if LED1_PA = $3F , 12.6 mA , ($7F is 25.4 mA)
pause 10
addr = $0D 'LED PULSE AMLIDUDE FOR LED2_PA[7:0] 0x0D
i2cwrite SDA,scl,contwr,addr,$03,error ' if LED2_PA = $1F , 6.2 mA , ($7F is 25.4 mA)
pause 10
-
Re: Heart rate sensor MAX30102
no brackets means no data will be written
-
Re: Heart rate sensor MAX30102
fifo read was stuffed up
Quote:
reg = FIFO_DATA
i2cread sda,scl,ADDR,reg,[buffer[index+2],buffer[index+1],buffer[index+0],buffer[index+5],buffer[index+4],buffer[index+3]]
the fifo print out is incorrect also , not yet solved
-
Re: Heart rate sensor MAX30102
Quote:
my code , you should know i have no idea :-
1, what led pwr to use
2, what led pwidth to use
3, what sample rate to use
4, what sample resolution to use
5, if there are any fifo overflows and if it matters much
6, what led the readings represents
7, how to interpret the data
8, how much data to collect [i assume at least 2 seconds worth]
most of the drivers i've seen over the net are using the following...
1, what led pwr to use : 0x1F about 6.2 mA
2, what led pwidth to use : 411 which is 18 ADC BIT RESOLUTION based on the manual.
3, what sample rate to use : sample rate per second 100
a configuration should also include: sampleAverage = 8
4, what sample resolution to use :
5, if there are any fifo overflows and if it matters much.
6, what led the readings represents. I will search and find out.
7, how to interpret the data....
8, how much data to collect [i assume at least 2 seconds worth]
-
Re: Heart rate sensor MAX30102
this looks like something, probably needs a lpf and sum of the squares function to remove dc drift
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
'define I2C_SLOW 1
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
#DEFINE DEBUGING 1
#IFNDEF DEBUGING
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
#ELSE
DEFINE DEBUG_REG PORTB
DEFINE DEBUG_BIT 7
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0
ANSELB=0
LATB.7=1
#ENDIF
SDA var portc.4 ' DATA PIN
SCL VAR portc.3 ' CLOCK PIN
Timeout cON 2000
reg var BYTE
fifo var byte[6]
addr var byte
REVISION var byte
PARTID var byte
buffer var byte[1152]
ptr var byte
btr var byte
index var word
result var word ext
@result = _fifo
;----------------------- 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]
STATUS1 con 0 ;A_FULL[7]
' -----------------------------------------------------------------------------|
#IFDEF DEBUGING
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,[9]
reg = REG_LED1_PA
i2cwrite SDA,scl,ADDR,reg,[9]
reg = FIFO_CONFIG
i2cwrite SDA,scl,ADDR,reg,[16]
#IFNDEF DEBUGING
HSEROUT [$73,$03,$04,$11,$ff,$ff,"PART ID: 0X",hex PARTID,"/0X", hex REVISION,$00]
Hserin timeout,error,[wait(6)]
#ELSE
DEBUG 13,10, "PART ID: 0X",hex PARTID,"/0X",hex REVISION
#ENDIF
'********************************************************************************
start:
reg= REG_TEMP_CONFIG
i2cwrite SDA,scl,ADDR,reg,[1]
reg= REG_TEMP_INT
i2cread sda,scl,ADDR,reg,[fifo[0],fifo[1]]
#IFNDEF DEBUGING
HSEROUT [$73,$05,$0A,$11,$07,$E0,"TEMP: ",DEC fifo[0],".",DEC2( fifo[1]<<6),$00]
Hserin timeout,error,[wait(6)]
#ELSE
DEBUG 13,10, "TEMP: ",DEC fifo[0],".",DEC2( fifo[1]<<6)
#ENDIF
GOSUB AQUIRE
pause 5000
goto start
aquire:
reg= FIFO_WR_PTR
i2cwrite SDA,scl,ADDR,reg,[0]
reg= FIFO_RD_PTR
i2cwrite SDA,scl,ADDR,reg,[0]
pause 200
FOR index = 0 TO 1151 STEP 0
btr = 0
reg = STATUS1
WHILE btr&$80 = 0
i2cread sda,scl,ADDR,reg,[btr]
WEND
reg = FIFO_RD_PTR
i2cread SDA,scl,ADDR,reg,[btr]
btr = (btr - ptr) & 31
WHILE btr
reg = FIFO_DATA
i2cread sda,scl,ADDR,reg,[buffer[index + 2],buffer[index + 1],buffer[index + 0],buffer[index + 5],buffer[index + 4],buffer[index + 3]]
index = index + 6
btr = btr - 1
ptr = (Ptr + 1) & 31
WEND
pause 200
DEBUG "."
NEXT
FOR index = 0 TO 1151 STEP 0
for ptr = 0 to 2
fifo[ptr] = buffer[index + ptr]
next
DEBUG 13,10;, hex2 fifo[2] , hex2 fifo[1], hex2 fifo[0]
' asm ;ROTATE READING TO GET SUFFICIENT RESOLOUTION INTO UPPER WORD
' banksel _fifo
' 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
' banksel 0
' endasm
DEBUG 9,HEX4 result
index = index + 3
' DEBUG 13,10, hex2 buffer[index+2],hex2 buffer[index+1],hex2 buffer[index],9 ,HEX4 result
' DEBUG 9, hex2 fifo[2] , hex2 fifo[1], hex2 fifo[0]
for ptr = 0 to 2
fifo[ptr] = buffer[index + ptr]
next
' DEBUG 9, hex2 fifo[2] , hex2 fifo[1], hex2 fifo[0]
' asm ;ROTATE READING TO GET SUFFICIENT RESOLOUTION INTO UPPER WORD
' banksel _fifo
' 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
' banksel 0
' endasm
DEBUG 9,HEX4 result
index = index + 3
NEXT
RETURN