cancel
Showing results for 
Search instead for 
Did you mean: 

How can I use two sensors over the same I2C1 line at the same time?

alitastan
Associate II

Hello everyone, I have recently started learning C language and I am kind of new into embedded systems. I am using NUCLEO WB15CC and trying to develop a system using VL53L1X with MPU6050 sensors. I am getting two sensor data successfully every time I write 0x101 to read/write characteristic. What I want to do now is, I want to start continuously measuring the acceleration data of X axis of the MPU6050 sensor until its value is between -990.0 and -1010.0 and if it is true I want to measure the distance over VL53L1X sensor. However, when I am debugging I receive -1 value over VL53L1X and I think its because MPU6050 is still using the I2C1 line. I have tried to put MPU6050 into sleep and wake it up back but it didn't work well. I am thinking that the way to solve this issue is by using scheduler or I2C event interrupt. I don't know which one is more practical. I am using P2PServer example provided by ST with STM32Cube_FW_WB_V1.13.0. 

Here is my code snippets:

#if(P2P_SERVER1 != 0)  
      if(pNotification->DataTransfered.pPayload[0] == 0x01){ /* end device 1 selected - may be necessary as LB Routeur informs all connection */
        if(pNotification->DataTransfered.pPayload[1] == 0x01){
			BSP_LED_On(LED_BLUE);
 
			//APP_DBG_MSG("-- P2P APPLICATION SERVER 1 : LED1 ON\n");
			//APP_DBG_MSG(" \n\r");
			while(1){
				P2P_Server_App_Context.SensorControl.MPU6050AccelValueX = mpu6050_get_measurement();
				if((P2P_Server_App_Context.SensorControl.MPU6050AccelValueX <= -990.0) && (P2P_Server_App_Context.SensorControl.MPU6050AccelValueX >= -1010.0)){
					APP_DBG_MSG("-- The device is parallel to the ground\n");
					APP_DBG_MSG(" \n\r");
					P2PS_STM_App_Update_Char(P2P_READ1_CHAR_UUID, (uint8_t *)&P2P_Server_App_Context.SensorControl.MPU6050AccelValueX);
 
					P2P_Server_App_Context.SensorControl.SensorHeightValue = vl53l1x_get_measurement();
					P2PS_STM_App_Update_Char(P2P_READ_CHAR_UUID, (uint8_t *)&P2P_Server_App_Context.SensorControl.SensorHeightValue);
				}
			}
 
			P2P_Server_App_Context.LedControl.Led1=0x01; /* LED1 ON */
        }
          //P2P_Server_App_Context.SensorControl.SensorHeightValue = vl53l1x_get_measurement();
          //P2PS_STM_App_Update_Char(P2P_READ_CHAR_UUID, (uint8_t *)&P2P_Server_App_Context.SensorControl.SensorHeightValue);
          //P2P_Server_App_Context.LedControl.Led1=0x01; /* LED1 ON */
 
        if(pNotification->DataTransfered.pPayload[1] == 0x00)
        {
          BSP_LED_Off(LED_BLUE);
          //APP_DBG_MSG("-- P2P APPLICATION SERVER 1 : LED1 OFF\n");
          //APP_DBG_MSG(" \n\r");
          P2P_Server_App_Context.LedControl.Led1=0x00; /* LED1 OFF */
        }
    }

Here are the two functions which I use to return values:

int16_t vl53l1x_get_measurement(void){
	uint8_t buff[50];
	int16_t rangingResult = 0;
 
	// polls on the device interrupt status until ranging data are ready.
	VL53L1_WaitMeasurementDataReady( Dev );
 
	VL53L1_GetRangingMeasurementData( Dev, &RangingData );
	rangingResult = RangingData.RangeMilliMeter;
 
	sprintf( (char*)buff, "%d, %.2f, %.2f, %.2f\n\r", RangingData.RangeStatus, RangingData.RangeMilliMeter / 10.0,
			 ( RangingData.SignalRateRtnMegaCps / 65536.0 ), RangingData.AmbientRateRtnMegaCps / 65336.0 );
 
	HAL_UART_Transmit( &huart1, buff, strlen( (char*)buff ), 0xFFFF );
 
	VL53L1_ClearInterruptAndStartMeasurement( Dev );
 
	return rangingResult;
 
}
float mpu6050_get_measurement(void){
	//3. Get MPU6050 measurements.
	float xAcceleration = 0;
	MPU6050_Get_Accel_Cali(&myAccelCalib);
	//MPU6050_Get_Gyro_Scale(&myGyroScaled);
	xAcceleration = myAccelCalib.x;
	HAL_Delay(100);
 
	return xAcceleration;
 
}

I would be really grateful if you could guide me which way is more efficient and how to do that. Thank you.

Best Regards

4 REPLIES 4

If the two sensors have different I2C address, they don't influence each other on the bus.

JW

You will have to arbitrate/sequence usage of the peripheral as you can't have two threads using it concurrently, so watch that and interrupt/callback behaviour and interaction.

The I2C bus is designed to deal with multiple devices with different addresses, and a properly terminated/timed bus.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thanks for your replies, both sensors have different I2C address. I put a breakpoint on while loop at line 8 at the first code snippet and I receive acceleration of X axis data until it gets into if statement. Then I step over until I receive data from vl53l1x_get_measurement() function and it returns -1 on live expressions tab in stm32cube IDE and returns 0xFFFF on read characteristic value. Then program hanged and I couldn't step over any more. Maybe one of the cables went off while I was turning the breadboard. There were no faults detected. I will observe more and try to solve this problem and then get back to you!

alitastan
Associate II

Okay, I figured out that the problem was because of the loose jumper wires and my while loop. The program actually works as intended inside the while loop but when I leave the bluetooth connection I am not able to connect back to the device because it is not advertising. It keeps receiving the sensor data but I am not able to connect back to read or write into any characteristic. How can I keep MPU6050 sensor active and taking measurements without blocking the device advertising? I am basically stuck inside the while loop and I can't even turn the led off by writing 0x100 to the write characteristic again.

#if(P2P_SERVER1 != 0)
      while(1){
      if(pNotification->DataTransfered.pPayload[0] == 0x01){ /* end device 1 selected - may be necessary as LB Routeur informs all connection */
        if(pNotification->DataTransfered.pPayload[1] == 0x01){
			//APP_DBG_MSG("-- P2P APPLICATION SERVER 1 : LED1 ON\n");
			//APP_DBG_MSG(" \n\r");
			BSP_LED_On(LED_BLUE);
			P2P_Server_App_Context.LedControl.Led1=0x01; /* LED1 ON */
			P2P_Server_App_Context.SensorControl.MPU6050AccelValueX = mpu6050_get_measurement();
			P2PS_STM_App_Update_Char(P2P_READ1_CHAR_UUID, (uint8_t *)&P2P_Server_App_Context.SensorControl.MPU6050AccelValueX);
			if((P2P_Server_App_Context.SensorControl.MPU6050AccelValueX <= 1010.0) && (P2P_Server_App_Context.SensorControl.MPU6050AccelValueX >= 990.0)){
				APP_DBG_MSG("-- The device is parallel to the ground\n");
				APP_DBG_MSG(" \n\r");
				P2P_Server_App_Context.SensorControl.SensorHeightValue = vl53l1x_get_measurement();
				P2PS_STM_App_Update_Char(P2P_READ_CHAR_UUID, (uint8_t *)&P2P_Server_App_Context.SensorControl.SensorHeightValue);
			}
 
	        if(pNotification->DataTransfered.pPayload[1] == 0x00)
	        {
	          BSP_LED_Off(LED_BLUE);
	          //APP_DBG_MSG("-- P2P APPLICATION SERVER 1 : LED1 OFF\n");
	          //APP_DBG_MSG(" \n\r");
	          P2P_Server_App_Context.LedControl.Led1=0x00; /* LED1 OFF */
	        }
        }
      }
    }