cancel
Showing results for 
Search instead for 
Did you mean: 

VL53L8CX - example "platform.h" RAM reduction implementation request

jmeck
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions
John E KVAM
ST Employee

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

 


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.

View solution in original post

4 REPLIES 4
jmeck
Associate II

 

Kindly scan the two files below for additional guidance:

  • VL53L8CX_HelloWorld_I2C_jm.ino (only modification is addition of line 4 (#include)

 

 

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

 

 

  • platform_config_custom.h   (partial showing modification)

 

 

#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_

 

 

 

 

@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.

If you feel a post has answered your question, please click "Accept as Solution".
jmeck
Associate II

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!

John E KVAM
ST Employee

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

 


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.