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

Write command for HRMI board using TWI

Hello,

I am trying to implement a Heart Rate Monitor Interface (HRMI) board with my nRF52, using the TWI_sensor example from SDK 12.2. I am running into trouble Writing to commands to the peripheral I2C address. Here is the driver I have written to do so:

#define HRMI_I2C_ADDR1 127 #define HRMI_SET_MODE 0x53 #define HRMI_GET_HR_DATA 0x47

ret_code_t HRMI_set_mode() {
ret_code_t ret_code;
uint8_t command_address2 = HRMI_SET_MODE; // <0x53>
ret_code = nrf_drv_twi_tx(&m_twi, HRMI_I2C_ADDR, &command_address2, 1, false);
return ret_code;}

ret_code_t start_HR() {
ret_code_t ret_code;
uint8_t command_address = HRMI_GET_HR_DATA; // <0x47>
ret_code = nrf_drv_twi_tx(&m_twi, HRMI_I2C_ADDR, &command_address, 3, false);
return ret_code;}

ret_code_t fetch_HR(uint8_t * hr){
ret_code_t ret_code;
uint8_t returned_over_I2C[3]; //Array to hold returned data
	int data;
ret_code = nrf_drv_twi_rx(&m_twi, HRMI_I2C_ADDR, returned_over_I2C, sizeof(returned_over_I2C)); 
nrf_delay_ms(10);
	*hr = returned_over_I2C[2];
	return ret_code;}

int main(void){
	
ret_code_t err_code;  
uint8_t hr;	
/* Initializing TWI master  */
err_code = twi_master_init();
HRMI_set_mode(); //write command <0x53> to I2C address to set heart rate algorithm mode
APP_ERROR_CHECK(err_code);
	
while (true)
{           
    nrf_delay_ms(500);
    start_HR(); //write command <0x47> to I2C address to Get Heart Rate Data
    nrf_delay_ms(500);
    fetch_HR(&hr);  
    SEGGER_RTT_printf(0, "Heart Rate: ");
    SEGGER_RTT_printf(0, "%d\n", hr);}}

My code is not working and I believe I know why. The HRMI datasheet lists the I2C commands in a different way than I've seen using the nRF52. For example, the I2C command to set the mode is <0x53><N>, where is a 3-bit mask value where bit-place zero should be set to '1' to set average mode.

Additionally, the I2C command to Get Heart Rate Data is <0x47><N> where <N> is the number of HR values requested. I would like to access 1 value.

I believe I am not writing the correct values to the I2C register because of the format with these <N> values. Currently, the nRF52 shows a *hr = returned_over_I2C[2]; value of ASCII "244", and this appears even if my SDA and SCL lines are disconnected from the nRF52.

My question is: How can I make sure my Write commands are for the command and the following arguments using the nrf_drv_twi_tx() function?

Thank you for your time.

  • Hi,

    From the data sheet is see the following statement:

    Commands and arguments are encoded as 8-bit binary values. Command Sequences consist of 1- or 2-byte I2C write sequences (the command byte followed by any required argument byte) followed by the STOP condition.

    This is not different from the TWI examples in our SDK. However, your start_HR() function does not look entirely correct.

    You set the length parameter of the nrf_drv_twi_tx() function to 3, but you only pass a 1-byte variable to argument p_data. If I understand you correctly, you want to send <0x47><0x03> to get 3 HR values? This can be done like this:

    ret_code_t start_HR(uint8_t num_samples) 
    {
    	ret_code_t ret_code;
    	uint8_t reg[2] = {HRMI_GET_HR_DATA, num_samples}; // <0x47>
    	ret_code = nrf_drv_twi_tx(&m_twi, HRMI_I2C_ADDR, reg, sizeof(reg), false);
    	return ret_code;
    }
    

    And then call the function with the number of samples you want:

    start_HR(0x03);
    

    Best regards,

    Jørgen

  • Hi Jørgen,

    Thank you very much for the response. I have corrected my function as you suggested. However, I am still unable to read any heart rate values and it appears the the SDA and SCL lines are not communicating whatsoever. Can you help me with this?

    You have answered my original question so I will accept it, and I will go ahead and create a new question in the devzone for future use. New question here.

    Thank you very much!

    Levi

Related