This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Hello ,I am beginner in programming with nrf52 development board. I tried to interface MAX30102 heart-rate sensor but output is still zero. Does anyone has code for max30102?

#include "nrf.h"
#include "nrf_drv_clock.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "nrf_drv_power.h"
#include "nrf_serial.h"
#include "nrf_drv_twi.h"
#include "app_timer.h"

#include "app_error.h"
#include "app_util.h"
#include "app_util_platform.h"
#include "boards.h"

#define OP_QUEUES_SIZE 3
#define RX_PIN 23
#define TX_PIN 24

#define TWI_INSTANCE_ID    0


/* MAX30100 Register Map */
#define MAX30102_ADDRESS	0x57

#define 	REV_ID			 ((uint8_t)0xFE)
#define 	PART_ID 		 ((uint8_t)0xFF)


#define		INT_STATUS_1	 ((uint8_t)0x00)
#define 	INT_STATUS_2	 ((uint8_t)0x01)
#define 	INT_ENABLE_1	 ((uint8_t)0x02)
#define 	INT_ENABLE_2	 ((uint8_t)0x03)
#define		FIFO_WR_PTR		 ((uint8_t)0x04)
#define		OVERFLOW_CTR	 ((uint8_t)0x05)
#define		FIFO_RD_PTR		 ((uint8_t)0x06)
#define		FIFO_DATA			 ((uint8_t)0x07)
#define		FIFO_CONF		 ((uint8_t)0x08)
#define		MODE_CONF		 ((uint8_t)0x09)
#define 	SPO2_CONF		 ((uint8_t)0X0A)
#define 	LED1_PA			 ((uint8_t)0x0C)
#define 	LED2_PA			 ((uint8_t)0x0D)
#define 	PILOT_PA		 ((uint8_t)0x10)
#define		MULTILED_1	 ((uint8_t)0x11)
#define 	MULTILED_2	 ((uint8_t)0x12)

#define 	TEMP_INTR		 0x1F
#define		TEMP_FRAC		 0x20
#define		TEMP_CONF		 0x21
#define		PROX_INT_TH	 0x30


extern uint8_t temp_array[6];

static const nrf_drv_twi_t m_twi_max30100 = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);

void MAX30102_reset ();
void MAX30102_init ();
void MAX30102_setup ();
void read_fifo ();

static void sleep_handler(void)
{
    __WFE();
    __SEV();
    __WFE();
}
void uart_event_handler(struct nrf_serial_s const *p_serial,nrf_serial_event_t event);

NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uart0_drv_config,
                               RX_PIN,TX_PIN,
                               RTS_PIN_NUMBER,CTS_PIN_NUMBER,
                               NRF_UART_HWFC_DISABLED,NRF_UART_PARITY_EXCLUDED,
                               NRF_UARTE_BAUDRATE_115200,
                               UART_DEFAULT_CONFIG_IRQ_PRIORITY
                               );

#define  SERIAL_FIFO_TX_SIZE 32
#define  SERIAL_FIFO_RX_SIZE 32

NRF_SERIAL_QUEUES_DEF(serial_queues,SERIAL_FIFO_RX_SIZE,SERIAL_FIFO_TX_SIZE);

#define SERIAL_BUFF_RX_SIZE 1
#define SERIAL_BUFF_TX_SIZE 1

NRF_SERIAL_BUFFERS_DEF(serial_buffs,SERIAL_BUFF_RX_SIZE,SERIAL_BUFF_TX_SIZE);

NRF_SERIAL_CONFIG_DEF(serial_config,NRF_SERIAL_MODE_IRQ,&serial_queues,&serial_buffs,uart_event_handler,sleep_handler);

NRF_SERIAL_UART_DEF(serial_uart,0);

void uart_event_handler(struct nrf_serial_s const *p_serial,nrf_serial_event_t event)
{
    ret_code_t err_code;
    uint8_t c;
    switch(event)
    {
      case NRF_SERIAL_EVENT_TX_DONE:
          break;
      case NRF_SERIAL_EVENT_RX_DATA:
          err_code=nrf_serial_write(&serial_uart,"Int",3,NULL,5);
           APP_ERROR_CHECK(err_code);
          break;
      default:
          break;
    }
}
void twi_init()
{
  ret_code_t err_code;
  const nrf_drv_twi_config_t twi_config={
      .scl=16,
      .sda=17,
      .frequency=NRF_DRV_TWI_FREQ_400K,
      .interrupt_priority=APP_IRQ_PRIORITY_HIGH,
      .clear_bus_init=false,
   };
   err_code=nrf_drv_twi_init(&m_twi_max30100,&twi_config,NULL,NULL);
   APP_ERROR_CHECK(err_code);

   nrf_drv_twi_enable(&m_twi_max30100);
}

/*ret_code_t max30100_I2C_register_write(uint8_t reg_addr, uint8_t * p_tx_data, uint8_t bytes)
{
    ret_code_t ret_code;
    uint8_t tx_data[bytes+1];
    tx_data[0] = reg_addr;
    
    for(uint8_t i = 0 ; i<bytes ; i++) 
    {
        tx_data[i+1] = p_tx_data[i];
    }   
    ret_code = nrf_drv_twi_tx(&m_twi_max30100, MAX30100_ADDRESS, tx_data, sizeof(tx_data), false);
    return ret_code;
}*/

/**
 * @brief Function for reading from registers on the MAX30100.
 */

 /*ret_code_t max30100_I2C_register_read( uint8_t reg_addr,  uint8_t * p_rx_data, uint32_t bytes)
{   
    ret_code_t ret_code;
    ret_code = nrf_drv_twi_tx(&m_twi_max30100,MAX30100_ADDRESS, &reg_addr, 1, true);
    if(ret_code != NRF_SUCCESS)
    {
        return ret_code;
    }
    ret_code = nrf_drv_twi_rx(&m_twi_max30100, MAX30100_ADDRESS, p_rx_data, bytes);
    return ret_code;
}

void max30100_read_hr_spo2(int16_t * p_hr_val, int16_t * p_spo2_val)
{
        ret_code_t err_code;
    
    // Raw HR& SPo2 data from FIFO
          uint8_t hr_H[1];
	  uint8_t hr_L[1];
	  uint8_t spo2_H[1];
	  uint8_t spo2_L[1];
    
    // Read the four data registers from MAX30100_FIFO_DATA
          err_code = max30100_I2C_register_read(MAX30100_FIFO_DATA,hr_H,sizeof(hr_H));
	  err_code = max30100_I2C_register_read(MAX30100_FIFO_DATA,hr_L,sizeof(hr_L));
	  err_code = max30100_I2C_register_read(MAX30100_FIFO_DATA,spo2_H,sizeof(spo2_H));
	  err_code = max30100_I2C_register_read(MAX30100_FIFO_DATA,spo2_L,sizeof(spo2_L));
    
        APP_ERROR_CHECK(err_code);
    
    
    *p_hr_val = (hr_H[0]<<8)|hr_L[0];
    *p_spo2_val = (spo2_H[0]<<8)|spo2_L[0];
    nrf_serial_write(&serial_uart,spo2_H,1,NULL,10);
    nrf_serial_write(&serial_uart,spo2_L,1,NULL,10);
}*/
/**
 * @brief Function for application main entry.
 */

int main(void)
{
    ret_code_t err_code;
    uint8_t address=0x57;
    uint8_t sample_data=0x00;
    
    err_code=nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);
    
    err_code=nrf_drv_power_init(NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_clock_lfclk_request(NULL);

    err_code=app_timer_init();
    APP_ERROR_CHECK(err_code);

    uint8_t tx_buf[10]="Hello";
    err_code=nrf_serial_init(&serial_uart,&m_uart0_drv_config,&serial_config);
    APP_ERROR_CHECK(err_code);
    nrf_serial_write(&serial_uart,"Started",8,NULL,10);
    //printf("Begin");
    //======================MAX30100============================//
    twi_init();
    //=========================================================//
    err_code = nrf_drv_twi_rx(&m_twi_max30100,address,&sample_data,sizeof(sample_data));
    if(err_code==NRF_SUCCESS)
    {
        NRF_LOG_INFO("Device detected at address = 0x%x",address);
        nrf_serial_write(&serial_uart,"Ok ",3,NULL,10);
    }
    nrf_serial_write(&serial_uart,"Started1",9,NULL,10);
    NRF_LOG_FLUSH();

    MAX30102_init();
    MAX30102_reset();
 	
    MAX30102_setup ();

    while(true)
    {
          read_fifo();
	 nrf_delay_ms(1000);
    }
}


uint32_t read_register(uint8_t reg, uint8_t * p_data, uint32_t length)
{
    uint32_t err_code;
    err_code = nrf_drv_twi_tx(&m_twi_max30100, MAX30102_ADDRESS, &reg, 1, false);
    if(err_code != NRF_SUCCESS) return err_code;

    
    err_code = nrf_drv_twi_rx(&m_twi_max30100, MAX30102_ADDRESS, p_data, length);
    if(err_code != NRF_SUCCESS) return err_code;
    return err_code;
}

uint32_t write_register(uint8_t reg_address, uint8_t data)
{
    ret_code_t err_code; 
    uint8_t buffer_send[2] = {reg_address, data};
		
    err_code = nrf_drv_twi_tx(&m_twi_max30100, MAX30102_ADDRESS, buffer_send, sizeof(buffer_send), true);
    APP_ERROR_CHECK(err_code);
	
}

void MAX30102_reset (void)
{	
	
    write_register(MODE_CONF, 0x40);	
	
}


void MAX30102_setup (void)
{
	write_register(INT_ENABLE_1, 0xC0);
	write_register(INT_ENABLE_2, 0x00);
	
	
	write_register(FIFO_WR_PTR, 0x00);	// Reset FIFO Write pointer
	write_register(OVERFLOW_CTR, 0x00); // Reset OVERFLOW_CTR pointer
	write_register(FIFO_RD_PTR, 0x00); 	// Reset FIFO READ pointer
	
	write_register(FIFO_CONF, 0x4F); //average sampling  = 4
	write_register(MODE_CONF, 0x03); // ADC range = 4096nA | Sampling Rate = 100 Hz | LED pulseWidth = 411uS
	
	write_register(SPO2_CONF, 0x27); // 400 samples per second
	write_register(LED1_PA, 0x5F); // LED1 current = 19 mA 
	write_register(LED2_PA, 0x5F); // LED2 current = 19 mA 
	write_register(PILOT_PA, 0x7F); // Pilot LED ~ 25mA
	
	
}


void MAX30102_init (void)
{

    uint8_t revID; 
    uint8_t partID;
		ret_code_t err_code;
    err_code  = read_register (PART_ID, &partID,sizeof(partID));
		APP_ERROR_CHECK(err_code);
	
    NRF_LOG_INFO("MAX30102 PART ID: 0x%02x \r\n", partID);
    
	
    err_code = read_register (REV_ID, &revID,sizeof(revID));
		APP_ERROR_CHECK(err_code);
	
    NRF_LOG_INFO("MAX30102 REV ID: 0x%02x \r\n", revID);
}


void read_fifo()
{

    uint8_t clearINT1;
		uint8_t clearINT2;
    uint32_t LEDdata=0;
    uint8_t dataArray[6];
    ret_code_t err_code;
    uint8_t FIFO_data;
    
		//Clear Interrupts
    err_code = read_register(INT_STATUS_1, &clearINT1,sizeof(clearINT1));
		err_code = read_register(INT_STATUS_1, &clearINT2,sizeof(clearINT2));
  
		
		err_code =read_register(FIFO_DATA,dataArray,sizeof(dataArray));
    APP_ERROR_CHECK(err_code);	
		
		//Extract 3 bytes for IR LED
    LEDdata=dataArray[0]<<16|dataArray[1]<<8 |dataArray[2];
  
		NRF_LOG_RAW_INFO("%d,",LEDdata) ;	   // RED LED data		

    LEDdata=0;

		//Extract 3 bytes for RED LED
    LEDdata=dataArray[3]<<16|dataArray[4]<<8 |dataArray[5];
  	NRF_LOG_RAW_INFO("%d\r\n", LEDdata);	// IR LED data
		
}

Parents Reply Children
Related