Skip to main content
alitastan
Associate II
June 7, 2022
Question

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

  • June 7, 2022
  • 4 replies
  • 1648 views

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

This topic has been closed for replies.

4 replies

waclawek.jan
Super User
June 7, 2022

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

JW

Tesla DeLorean
Guru
June 7, 2022

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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
alitastan
alitastanAuthor
Associate II
June 7, 2022

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
alitastanAuthor
Associate II
June 8, 2022

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 */
	 }
 }
 }
 }