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

How to read multiple sensors over TWI? (nrf_drv_twi)

I had slightly modified a TWI example (using nrf_drv_twi) to work with one of my sensors; It's basically the same with a different function called to handle the received data.

However, I have multiple sensors and multiple sets of data I'd like to be able to query from each, but it seems that the TWI interrupt handler doesn't provide much scope to do this. Or at least, I can't figure out how it would.

I initiate the transfer by making a call to the TWI tx function in my main loop:

     do
{
	__WFE();
}while(m_twi_rx_done == false);
err_code = nrf_drv_twi_tx(&m_twi_sensors, LSM303_ADDRESS_ACCEL, &test, sizeof(test), true);
APP_ERROR_CHECK(err_code);
m_twi_rx_done = false;

I can see that without much difficulty I could address a different register or sensor in changing this. However, I don't see how I would RECEIVE different data within the TWI interrupt handler:

void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
	ret_code_t err_code;
	static acc_sample_t m_sample; // 
	
	switch(p_event->type)
	{
		case NRF_DRV_TWI_RX_DONE:
			LSM303_read_acc(&m_sample);
			m_twi_rx_done = true;
			break;
		
		case NRF_DRV_TWI_TX_DONE:
			if(m_twi_cmd_done != true)
			{
				m_twi_cmd_done = true; // IF just a tx command, it's done
				return;
			}
			m_twi_rx_done = false;
			/* read sizeof(m_sample) bytes from the specified address */
			err_code = nrf_drv_twi_rx(&m_twi_sensors, LSM303_ADDRESS_ACCEL, (uint8_t*)&m_sample, sizeof(m_sample), false);
			APP_ERROR_CHECK(err_code);
			break;
			
		default:
			break;
	}
	
}

It doesn't seem like I can manage what happens on an "NRF_DRV_TWI_RX_DONE" event if I were to be addressing a different sensor which returned data of a different length; It would always just be set by what happens in the "NRF_DRV_TWI_TX_DONE" event, which I also can't change on the fly.

How would I go about managing this situation with multiple sensors?

Parents
  • nrf_drv_twi_tx(...) will always be followed by an NRF_DRV_TWI_TX_DONE event and nrf_drv_twi_rx(...) will always be followed by an NRF_DRV_TWI_RX_DONE event. Between the function call and the event, no other transactions will be allowed, meaning nrf_drv_twi_tx(...) or nrf_drv_twi_rx(...) will return NRF_ERROR_BUSY.

    You will need to handle the multiple sensors in your code. You can set a flag when starting transfer to the sensor and then check it in the TX or RX done events to know what action to do, something like this:

    err_code = nrf_drv_twi_tx(...);
    APP_ERROR_CHECK(err_code);    //you may want to do something else if NRF_ERROR_BUSY
    m_sensor1_xfer_started = true;
    

    And in the NRF_DRV_TWI_TX_DONE event do something like this:

    if(m_sensor1_xfer_started)
    {
        m_sensor1_xfer_started = false;
        //code for sensor 1 tx done
    }
    
  • I don't have the full overview of the new app_twi module, but it looks like it does exactly what you need.

Reply Children
No Data
Related