2024-08-29 03:44 PM
I need to reduce the RAM requirement to use the VL53L8CX with a STM32WL55 application. I am working with STM32duino implementation and need an example of how to implement disabling some of the data output by the VL53L8CX (e.g. motion indication, multi-targets) as discussed in section 5.2 of UM3109 (A guide to using the VL53L8CX, low-power, high-performance Time-of-Flight multizone ranging sensor).
An example "platform_config_custom.h" file or modified "platform.h" file and code snippets to include in STM32duino VL53L8CX example "VL53L8CX_HelloWorld_I2C" would be much appreciated and can permit me to proceed with our evaluation of the VL53L8CX for our use case.
Thanks!
Jim
Solved! Go to Solution.
2024-08-30 07:23 AM
The VL53L8CX uses a surprising amount of ROM. There is an 80K buffer of firmware that gets downloaded at the start. Then a 3K configuration. We probably should have flashed that bit, but we've created a good number of variants doing it this way, and it's worked for our really big applications.
So we generally run into ROM constraints before the RAM ones.
You can save a bit by reducing the number of return values by uncommenting those odd defines in Platform.H.
You will get the return structure down from 5200 bytes to a more manageable 1K or so.
But that does not save RAM.
And I think you cut too deep. You really need the number of targets and the status.
#define VL53L8CX_DISABLE_NB_TARGET_DETECTED 1
#define VL53L8CX_DISABLE_SIGNAL_PER_SPAD 1
#define VL53L8CX_DISABLE_RANGE_SIGMA_MM 1
// #define VL53L8CX_DISABLE_DISTANCE_MM
#define VL53L8CX_DISABLE_REFLECTANCE_PERCENT 1
#define VL53L8CX_DISABLE_TARGET_STATUS 1
The proper way to know you have a target is:
If the NB_Target_detected is greater than 0 AND the Target_Status is 5, 6, 9 and sometimes 12, you have a valid target.
So you need those 2 parameters and the distance. Signal strength can be handy as well. Do consider that one. We put this in to reduce I2C traffic. The RAM reduction is secondary.
I'm thinking that RAM comes out of your stack. So, it might not be obvious when you do your download.
- john
2024-08-29 04:27 PM - edited 2024-08-30 07:19 AM
Kindly scan the two files below for additional guidance:
* Includes ------------------------------------------------------------------*/
#include <vl53l8cx.h>
#include "platform_config_custom.h"
#ifdef ARDUINO_SAM_DUE
#define DEV_I2C Wire1
#else
#define DEV_I2C Wire
#endif
#define SerialPort Serial
#define LPN_PIN A3
#define PWREN_PIN 11
void print_result(VL53L8CX_ResultsData *Result);
void clear_screen(void);
void handle_cmd(uint8_t cmd);
void display_commands_banner(void);
// Components.
VL53L8CX sensor_vl53l8cx_top(&DEV_I2C, LPN_PIN);
bool EnableAmbient = false;
bool EnableSignal = false;
uint8_t res = VL53L8CX_RESOLUTION_4X4;
char report[256];
uint8_t status;
/* Setup ---------------------------------------------------------------------*/
void setup()
{
// Enable PWREN pin if present
if (PWREN_PIN >= 0) {
pinMode(PWREN_PIN, OUTPUT);
digitalWrite(PWREN_PIN, HIGH);
delay(10);
}
// Initialize serial for output.
SerialPort.begin(460800);
// Initialize I2C bus.
DEV_I2C.begin();
// Configure VL53L8CX component.
sensor_vl53l8cx_top.begin();
//JRM disable some outputs
//sensor_vl53l8cx_top.set_motion_indicator_enable(false);
status = sensor_vl53l8cx_top.init();
// Start Measurements
status = sensor_vl53l8cx_top.start_ranging();
}
void loop()
{
VL53L8CX_ResultsData Results;
uint8_t NewDataReady = 0;
do {
status = sensor_vl53l8cx_top.check_data_ready(&NewDataReady);
} while (!NewDataReady);
if ((!status) && (NewDataReady != 0)) {
status = sensor_vl53l8cx_top.get_ranging_data(&Results);
print_result(&Results);
}
if (Serial.available() > 0) {
handle_cmd(Serial.read());
}
delay(100);
}
void print_result(VL53L8CX_ResultsData *Result)
{
int8_t i, j, k, l;
uint8_t zones_per_line;
uint8_t number_of_zones = res;
zones_per_line = (number_of_zones == 16) ? 4 : 8;
display_commands_banner();
SerialPort.print("Cell Format :\n\n");
for (l = 0; l < VL53L8CX_NB_TARGET_PER_ZONE; l++) {
snprintf(report, sizeof(report), " \033[38;5;10m%20s\033[0m : %20s\n", "Distance [mm]", "Status");
SerialPort.print(report);
if (EnableAmbient || EnableSignal) {
snprintf(report, sizeof(report), " %20s : %20s\n", "Signal [kcps/spad]", "Ambient [kcps/spad]");
SerialPort.print(report);
}
}
SerialPort.print("\n\n");
for (j = 0; j < number_of_zones; j += zones_per_line) {
for (i = 0; i < zones_per_line; i++) {
SerialPort.print(" -----------------");
}
SerialPort.print("\n");
for (i = 0; i < zones_per_line; i++) {
SerialPort.print("| ");
}
SerialPort.print("|\n");
for (l = 0; l < VL53L8CX_NB_TARGET_PER_ZONE; l++) {
// Print distance and status
for (k = (zones_per_line - 1); k >= 0; k--) {
if (Result->nb_target_detected[j + k] > 0) {
snprintf(report, sizeof(report), "| \033[38;5;10m%5ld\033[0m : %5ld ",
(long)Result->distance_mm[(VL53L8CX_NB_TARGET_PER_ZONE * (j + k)) + l],
(long)Result->target_status[(VL53L8CX_NB_TARGET_PER_ZONE * (j + k)) + l]);
SerialPort.print(report);
} else {
snprintf(report, sizeof(report), "| %5s : %5s ", "X", "X");
SerialPort.print(report);
}
}
SerialPort.print("|\n");
if (EnableAmbient || EnableSignal) {
// Print Signal and Ambient
for (k = (zones_per_line - 1); k >= 0; k--) {
if (Result->nb_target_detected[j + k] > 0) {
if (EnableSignal) {
snprintf(report, sizeof(report), "| %5ld : ", (long)Result->signal_per_spad[(VL53L8CX_NB_TARGET_PER_ZONE * (j + k)) + l]);
SerialPort.print(report);
} else {
snprintf(report, sizeof(report), "| %5s : ", "X");
SerialPort.print(report);
}
if (EnableAmbient) {
snprintf(report, sizeof(report), "%5ld ", (long)Result->ambient_per_spad[j + k]);
SerialPort.print(report);
} else {
snprintf(report, sizeof(report), "%5s ", "X");
SerialPort.print(report);
}
} else {
snprintf(report, sizeof(report), "| %5s : %5s ", "X", "X");
SerialPort.print(report);
}
}
SerialPort.print("|\n");
}
}
}
for (i = 0; i < zones_per_line; i++) {
SerialPort.print(" -----------------");
}
SerialPort.print("\n");
}
void toggle_resolution(void)
{
status = sensor_vl53l8cx_top.stop_ranging();
switch (res) {
case VL53L8CX_RESOLUTION_4X4:
res = VL53L8CX_RESOLUTION_8X8;
break;
case VL53L8CX_RESOLUTION_8X8:
res = VL53L8CX_RESOLUTION_4X4;
break;
default:
break;
}
status = sensor_vl53l8cx_top.set_resolution(res);
status = sensor_vl53l8cx_top.start_ranging();
}
void toggle_signal_and_ambient(void)
{
EnableAmbient = (EnableAmbient) ? false : true;
EnableSignal = (EnableSignal) ? false : true;
}
void clear_screen(void)
{
snprintf(report, sizeof(report), "%c[2J", 27); /* 27 is ESC command */
SerialPort.print(report);
}
void display_commands_banner(void)
{
snprintf(report, sizeof(report), "%c[2H", 27); /* 27 is ESC command */
SerialPort.print(report);
Serial.print("53L8A1 Simple Ranging demo application\n");
Serial.print("--------------------------------------\n\n");
Serial.print("Use the following keys to control application\n");
Serial.print(" 'r' : change resolution\n");
Serial.print(" 's' : enable signal and ambient\n");
Serial.print(" 'c' : clear screen\n");
Serial.print("\n");
}
void handle_cmd(uint8_t cmd)
{
switch (cmd) {
case 'r':
toggle_resolution();
clear_screen();
break;
case 's':
toggle_signal_and_ambient();
clear_screen();
break;
case 'c':
clear_screen();
break;
default:
break;
}
}
#ifndef _PLATFORM_CONFIG_DEFAULT_H_
#define _PLATFORM_CONFIG_DEFAULT_H_
/*
* @brief The macro below is used to define the number of target per zone sent
* through I2C. This value can be changed by user, in order to tune I2C
* transaction, and also the total memory size (a lower number of target per
* zone means a lower RAM). The value must be between 1 and 4.
*/
#ifndef VL53L8CX_NB_TARGET_PER_ZONE
#define VL53L8CX_NB_TARGET_PER_ZONE 1U
#endif
/*
* @brief The macro below can be used to avoid data conversion into the driver.
* By default there is a conversion between firmware and user data. Using this macro
* allows to use the firmware format instead of user format. The firmware format allows
* an increased precision.
*/
// #define VL53L8CX_USE_RAW_FORMAT
/*
* @brief All macro below are used to configure the sensor output. User can
* define some macros if he wants to disable selected output, in order to reduce
* I2C access.
*/
#define VL53L8CX_DISABLE_AMBIENT_PER_SPAD 1
#define VL53L8CX_DISABLE_NB_SPADS_ENABLED 1
#define VL53L8CX_DISABLE_NB_TARGET_DETECTED 1
#define VL53L8CX_DISABLE_SIGNAL_PER_SPAD 1
#define VL53L8CX_DISABLE_RANGE_SIGMA_MM 1
// #define VL53L8CX_DISABLE_DISTANCE_MM
#define VL53L8CX_DISABLE_REFLECTANCE_PERCENT 1
#define VL53L8CX_DISABLE_TARGET_STATUS 1
#define VL53L8CX_DISABLE_MOTION_INDICATOR 1
#endif // _PLATFORM_CONFIG_DEFAULT_H_
2024-08-29 06:12 PM - edited 2024-08-29 06:13 PM
@jmeck Unfortunately, the post you replied to was written by a bot and had a malicious/spam link, so I flagged it for removal. It did not contain any particularly useful information, as you saw by your results.
2024-08-30 07:19 AM
I need to reduce the RAM requirement to use the VL53L8CX with a STM32WL55 application. I am working with STM32duino implementation and need an example of how to implement disabling some of the data output by the VL53L8CX (e.g. motion indication, multi-targets) as discussed in section 5.2 of UM3109 (A guide to using the VL53L8CX, low-power, high-performance Time-of-Flight multizone ranging sensor).
An example "platform_config_custom.h" file or modified "platform.h" file and code snippets to include in STM32duino VL53L8CX example "VL53L8CX_HelloWorld_I2C" would be much appreciated and can permit me to proceed with our evaluation of the VL53L8CX for our use case.
Thanks!
2024-08-30 07:23 AM
The VL53L8CX uses a surprising amount of ROM. There is an 80K buffer of firmware that gets downloaded at the start. Then a 3K configuration. We probably should have flashed that bit, but we've created a good number of variants doing it this way, and it's worked for our really big applications.
So we generally run into ROM constraints before the RAM ones.
You can save a bit by reducing the number of return values by uncommenting those odd defines in Platform.H.
You will get the return structure down from 5200 bytes to a more manageable 1K or so.
But that does not save RAM.
And I think you cut too deep. You really need the number of targets and the status.
#define VL53L8CX_DISABLE_NB_TARGET_DETECTED 1
#define VL53L8CX_DISABLE_SIGNAL_PER_SPAD 1
#define VL53L8CX_DISABLE_RANGE_SIGMA_MM 1
// #define VL53L8CX_DISABLE_DISTANCE_MM
#define VL53L8CX_DISABLE_REFLECTANCE_PERCENT 1
#define VL53L8CX_DISABLE_TARGET_STATUS 1
The proper way to know you have a target is:
If the NB_Target_detected is greater than 0 AND the Target_Status is 5, 6, 9 and sometimes 12, you have a valid target.
So you need those 2 parameters and the distance. Signal strength can be handy as well. Do consider that one. We put this in to reduce I2C traffic. The RAM reduction is secondary.
I'm thinking that RAM comes out of your stack. So, it might not be obvious when you do your download.
- john