cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with multiple sensors (3) on the I2C bus and C++ API

userLM
Associate

Hi ST team and community !

I'm here because i have some troubles on the processus of initialisation of multiple sensors VL53L1CB.

I use the following library available on gitHub : https://github.com/stm32duino/VL53L1

The processus is the following :

  • Shut down reset pin XSHUT of each sensor

Then, in a for loop (to setup my 3 sensors) :

  • Power ON the first sensor with XSHUT pin
  • I2C scanner to detect my only sensor ON (normally at address 0x29)
  • Create my C++ component with the I2C link and XSHUT digital/analog PIN
  • Init sensor with the new address with InitSensor function in the class VL53L1 of C++ API
  • I2C scanner again to check if the address has been changed

Then, switch to another sensor in the for loop until initialisation of my 3 sensors.

My problem is when the for loop arrives on the third sensor, it's impossible to execute InitSensor function and the program turn to infinity.

Question is, there is a RAM probleme when i create C++ component with "new/delete" ? (load the entire VL53L1 class ?) I have 32KB of RAM

Do you have some exemple of multiple VL53L1CB (not VL53L1X) initialisation with C++ API ?

Here is my code :

const int numberOfSensor = 3;                                 
uint8_t devAddr[3] = {0x62, 0x64, 0x66};                       
VL53L1 *nVL53L1[numberOfSensor];                    
int sensor = 0;              
static const uint8_t XSHUT[3] = {0,1,2};             
 
void setup()
{
   // Initialize serial for output.
   delay(5000);
   SerialPort.begin(115200);
   SerialPort.println("Starting...");
 
   // Initialize I2C bus.
   DEV_I2C.begin();
   DEV_I2C.setClock(400000); // 400KHz
   SerialPort.println("Start I2C : ok");
 
   // XSHUT declarer en sortie et mis au niveau bas
   pinMode(XSHUT[0], OUTPUT);
   pinMode(XSHUT[1], OUTPUT);
   pinMode(XSHUT[2], OUTPUT);
   digitalWrite(XSHUT[0], LOW);
   digitalWrite(XSHUT[1], LOW);
   digitalWrite(XSHUT[2], LOW);
   SerialPort.println("ALL XSHUT OUTPUT DOWN : ok");
   
   // Initialize VL53L1 satellite component.
   for (sensor=0; sensor<numberOfSensor; sensor++)
   {
      // SHUT ON reset pin of sensor
      digitalWrite(XSHUT[sensor], HIGH);
      SerialPort.println("XSHUT UP"+String(sensor)+" : ok");
 
      // Search all addr connected to my SAMD21
      debug_I2C_scanner();
      SerialPort.println("Scanner I2C : ok");
 
      // Create VL53L1 satellite component
      nVL53L1[sensor] = new VL53L1(&DEV_I2C, XSHUT[sensor]);
      SerialPort.println("Create component : ok");
      
      status += nVL53L1[sensor]->InitSensor(devAddr[sensor]); 
      SerialPort.println("Statut initialisation : "+String(status));
 
      //  Search all addr connected to my SAMD21 to check
      debug_I2C_scanner();
      SerialPort.println("Scanner I2C check : ok"); 
   }
}

(I call the delete just after)

There is the result in the shell of the execution :

//START
 
Starting...
Start I2C : ok
ALL XSHUT OUTPUT DOWN : ok
XSHUT UP0 : ok
Scanning...
I2C device found at address 0x19  !
I2C device found at address 0x1E  !
I2C device found at address 0x29  !
done
 
Scanner I2C : ok
Create component : ok
Statut Initialisation : 0
Scanning...
I2C device found at address 0x19  !
I2C device found at address 0x1E  !
I2C device found at address 0x31  !
done
 
Scanner I2C check : ok
 
XSHUT UP1 : ok
Scanning...
I2C device found at address 0x19  !
I2C device found at address 0x1E  !
I2C device found at address 0x29  ! // NEW SENSOR ON
I2C device found at address 0x31  !
done
 
Scanner I2C : ok
Create component : ok
Statut Initialisation : 0
Scanning...
I2C device found at address 0x19  !
I2C device found at address 0x1E  !
I2C device found at address 0x31  !
I2C device found at address 0x32  !
done
 
Scanner I2C check : ok
 
XSHUT UP2 : ok
Scanning...
I2C device found at address 0x19  !
I2C device found at address 0x1E  !
I2C device found at address 0x29  ! //NEW SENSOR ON
I2C device found at address 0x31  !
I2C device found at address 0x32  !
done
 
Scanner I2C : ok
 
//STOP

I need help ! I don't understand...

If there any C++ dev in the community, don't hesit to tell me what's my error.

Best regards,

LM

1 ACCEPTED SOLUTION

Accepted Solutions
userLM
Associate

Hi John,

Thanks for your fast answer !

I use uint8_t devAddr[3] = {0x62, 0x64, 0x66};

Those adresses are divided by 2 in the function VL53L1_SetDeviceAddress(address) (include in the function InitSensor(uint8_t address)) that's why i have 0x31, 0x32 ...

I will try to change these addresses by {0x62, 0x66, 0x70} to have finally 0x31, 0x33, 0x35 if i understood well

I have 32KB of RAM, it's not enought ?

If my dev is right, with a sizeof of the main class VL53L1, i obtain 10800 bytes. So, 10,8*3=32.4 KB, so i overload my memory i'am right ? If yes, do you try to use modern C++ function like unique_ptr, make_unique and shared_ptr to share the class to differents objets defines on the same I2C bus ?

With those methode, we can maybe just create 1 call of the main class and share this class to 3 differents sensors... i will think about it !

LM

View solution in original post

2 REPLIES 2
John E KVAM
ST Employee

I have a superstition. It bothers the heck out of me when the I2C addresses are next to each other.

In all my code I use address 29- the default, and then change them to 39, 49, 59 and so on.

I know it makes no sense. You should be able to use all the addresses.

But I've never had luck with it.

In your code you changed the 29 to 32.

I recommend trying it again and avoid the even addresses at the very least.

But perhaps someone else will have a better idea.

As for you suggestion that there might be a ram problem, are you using a particularly small MCU?

  • john


Our community relies on fruitful exchanges and good quality content. You can thank and reward helpful and positive contributions by marking them as 'Accept as Solution'. When marking a solution, make sure it answers your original question or issue that you raised.

ST Employees that act as moderators have the right to accept the solution, judging by their expertise. This helps other community members identify useful discussions and refrain from raising the same question. If you notice any false behavior or abuse of the action, do not hesitate to 'Report Inappropriate Content'
userLM
Associate

Hi John,

Thanks for your fast answer !

I use uint8_t devAddr[3] = {0x62, 0x64, 0x66};

Those adresses are divided by 2 in the function VL53L1_SetDeviceAddress(address) (include in the function InitSensor(uint8_t address)) that's why i have 0x31, 0x32 ...

I will try to change these addresses by {0x62, 0x66, 0x70} to have finally 0x31, 0x33, 0x35 if i understood well

I have 32KB of RAM, it's not enought ?

If my dev is right, with a sizeof of the main class VL53L1, i obtain 10800 bytes. So, 10,8*3=32.4 KB, so i overload my memory i'am right ? If yes, do you try to use modern C++ function like unique_ptr, make_unique and shared_ptr to share the class to differents objets defines on the same I2C bus ?

With those methode, we can maybe just create 1 call of the main class and share this class to 3 differents sensors... i will think about it !

LM