cancel
Showing results for 
Search instead for 
Did you mean: 

Can't Read Data from VL53L8CX using STM32

gil_B
Associate

Hallo Everyone,

I am currently trying to retrieve data from a VL53L8CX time-of-flight distance sensor using a NUCLEO-F401RE and an X-NUCLEO-53L8A1 on STM32CubeIDE with the VL53L8CX API. However, I am struggling to get it working and have no idea what I am doing wrong, as I am not getting any error messages from the IDE. I  have never worked on a stm device and this like my first steps, i would be very grateful if someone could help me to solve this issue.

Here is my code:

 

#include "main.h"
#include "vl53l8cx_api.h"
#include "stdio.h"



/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;

UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */
VL53L8CX_Configuration dev;  // Sensor-Konfigurationsstruktur
uint8_t status;
uint8_t isAlive = 0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void VL53L8CX_Initialisation();
void VL53L8CX_ReadData();
void I2C_Scan();

#define I2C_TIMEOUT 1000

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
 // I2C_Scan();
  //VL53L8CX_ReadData();
  /* USER CODE END 2 */
  dev.platform.address = VL53L8CX_DEFAULT_I2C_ADDRESS ;
  status = vl53l8cx_init(&dev);
  status = vl53l8cx_set_ranging_frequency_hz(&dev, 30);
  status = vl53l8cx_set_resolution(&dev , VL53L8CX_RESOLUTION_8X8);
  status = vl53l8cx_set_integration_time_ms(&dev, 20);
  status = vl53l8cx_set_ranging_mode(&dev, VL53L8CX_RANGING_MODE_CONTINUOUS);
  /*if (status != VL53L8CX_STATUS_OK) {
      char buffer[100];
      int len = snprintf(buffer, sizeof(buffer), "Fehler bei der Initialisierung, Fehlercode: %d\n", status);
      HAL_UART_Transmit(&huart2, (uint8_t *)buffer, len, 1000);
      while (1);  // Stoppe das Programm bei einem Fehler
  }*/
  status = vl53l8cx_start_ranging(&dev);
 /* status = vl53l8cx_is_alive(&dev, &isAlive);
  if (status || !isAlive) {
          HAL_UART_Transmit(&huart2, (uint8_t *)"VL53L8CX nicht gefunden!\n", 26, 1000);
          while (1);  // Wenn der Sensor nicht gefunden wird, stoppe hier
      }
  HAL_UART_Transmit(&huart2, (uint8_t *)"VL53L8CX gefunden!\n", 20, 1000);
*/

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
	  VL53L8CX_ResultsData  data;
	          status = vl53l8cx_get_ranging_data(&dev, &data);

	          if (status == VL53L8CX_STATUS_OK) {
	              // Gib die Messwerte (z. B. Entfernung) über UART aus
	              char buffer[100];
	              int len = snprintf(buffer, sizeof(buffer), "Entfernung: %d mm\n", data.distance_mm);
	              HAL_UART_Transmit(&huart2, (uint8_t *)buffer, len, 1000);
	          } else {
	              HAL_UART_Transmit(&huart2, (uint8_t *)"Fehler beim Abrufen der Daten!\n", 30, 1000);
	          }

	          HAL_Delay(500);  // Alle 500 ms Daten ausgeben
	      }
    /* USER CODE BEGIN 3 */

  /* USER CODE END 3 */
}


/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 16;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief I2C1 Initialization Function
  *  None
  * @retval None
  */
static void MX_I2C1_Init(void)
{

  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 400000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
	  uint32_t errorCode = HAL_I2C_GetError(&hi2c1);
	      char buffer[100];
	      int len = snprintf(buffer, sizeof(buffer), "I2C Fehler: %lu\n", errorCode);
	      HAL_UART_Transmit(&huart2, (uint8_t *)buffer, len, 1000);
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */

  /* USER CODE END I2C1_Init 2 */

}
void I2C_Scan() {
	 uint8_t i;
	    uint8_t buffer[1];
	    for(i = 0; i < 128; i++)
	    {
	        // Versuche, auf jede I2C-Adresse zuzugreifen
	        if (HAL_I2C_Mem_Read(&hi2c1, (i << 1), 0, I2C_MEMADD_SIZE_8BIT, buffer, 1, 10) == HAL_OK)
	        {
	            // Gebe die Adresse aus, wenn das Gerät reagiert
	            char buffer[30];
	            int len = snprintf(buffer, sizeof(buffer), "I2C Gerät gefunden auf Adresse 0x%02X\n", i);
	            HAL_UART_Transmit(&huart2, (uint8_t *)buffer, len, 1000);
	        }
}
}


/**
  * @brief USART2 Initialization Function
  *  None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 460800;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  *  None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  /* USER CODE BEGIN MX_GPIO_Init_1 */

  /* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : B1_Pin */
  GPIO_InitStruct.Pin = B1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : LD2_Pin */
  GPIO_InitStruct.Pin = LD2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);

  /* USER CODE BEGIN MX_GPIO_Init_2 */

  /* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */
void c()
{
    // Sensor-Kommunikation über I2C initialisieren
    dev.platform.address = VL53L8CX_DEFAULT_I2C_ADDRESS;

    // Überprüfen, ob der Sensor erreichbar ist
    status = vl53l8cx_is_alive(&dev, &isAlive);
    if (status || !isAlive) {
        printf("VL53L8CX nicht gefunden!\n");
        while (1); // Stoppe das Programm, falls der Sensor nicht erkannt wird
    }

    // Sensor initialisieren
    status = vl53l8cx_init(&dev);
    if (status) {
        printf("Fehler bei der Initialisierung des VL53L8CX!\n");
        while (1);
    }

    printf("VL53L8CX erfolgreich initialisiert!\n");
}


void VL53L8CX_ReadData()
{
    VL53L8CX_ResultsData results; // Datenstruktur für die Messwerte
    status = vl53l8cx_start_ranging(&dev); // Messung starten

    if (status)
    {
        printf("Fehler beim Starten der Messung!\n");
        return;
    }

    while (1)  // Endlosschleife für kontinuierliche Messungen
    {
        uint8_t ready = 0;
        status = vl53l8cx_check_data_ready(&dev, &ready);

        if (!status && ready)
        {
            vl53l8cx_get_ranging_data(&dev, &results); // Messwerte abrufen

            // Ergebnisse ausgeben (VL53L8CX hat 64 Zonen, wir nehmen Zone[0] als Beispiel)
            printf("Distanz: %d mm\n", results.distance_mm[0]);

            HAL_Delay(100); // 100 ms Pause zwischen den Messungen
        }
    }

    vl53l8cx_stop_ranging(&dev); // Messung beenden
}


/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  *   file: pointer to the source file name
  *   line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
3 REPLIES 3
John E KVAM
ST Employee

The MCU is a lot faster than the sensor. And you are doing the initialization too soon.

Try putting the

status = vl53l8cx_is_alive(&dev, &isAlive);

 function call back in PRIOR to your call to 

vl53l8cx_init(&dev);

 Or just wait a ms or two before you begin. 

One note though. 

Try changing all those

status = 

to 

status |=
Then actually check the status. I'm betting that your init failed because the sensor was not ready when you initialized it. 
 

 

 


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.

Hallo @John E KVAM ,

Thank you for yours suggestions. I made some changes following yours Instructions, but there is still something  that does'nt work. I started a debugging process  and i found out that this line of code :

status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x00);

keeps returning me a "255U" (a status error if i am wright). But i don't know what i am suppose to do in this case! This error actually comes  from vl53l8cx_is_alive(). The same line is present in the init   function and whenever i call the init before the is_alive(), that line always give me the same status_error.

Here are my Changes :

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "vl53l8cx_api.h"
#include "stdio.h"



/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define VL53L8A1_PWR_EN_C_PORT GPIOB
#define VL53L8A1_PWR_EN_C_PIN  GPIO_PIN_0

#define VL53L8A1_LPn_C_PORT    GPIOB
#define VL53L8A1_LPn_C_PIN     GPIO_PIN_1

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;

UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */
VL53L8CX_Configuration dev;  // Sensor-Konfigurationsstruktur
uint8_t status;
uint8_t isAlive = 0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void VL53L8CX_Initialisation();
void VL53L8CX_ReadData();
void I2C_Scan();

#define I2C_TIMEOUT 1000

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
 // I2C_Scan();
  //VL53L8CX_ReadData();
  /* USER CODE END 2 */
  dev.platform.address = VL53L8CX_DEFAULT_I2C_ADDRESS;
  
  status |= vl53l8cx_is_alive(&dev, &isAlive);
  	if(!isAlive)
  	{
  		printf("VL53L8CX with SPI communication not detected, error : %d\n", status);

  		//return 255;
  	}
  	printf("Sensor initializing, please wait few seconds\n");

  	status |= vl53l8cx_init(&dev);
  	if(status){
  		printf("Init failed with status %d\n", status);
  	}

  	status|= vl53l8cx_set_ranging_frequency_hz(&dev, 5);				// Set 5Hz ranging frequency
  	status |=vl53l8cx_set_ranging_mode(&dev, VL53L8CX_RANGING_MODE_AUTONOMOUS);  // Set mode autonomous
  	status |=vl53l8cx_set_resolution(&dev , VL53L8CX_RESOLUTION_8X8);

  	printf("Ranging starts\n");
  	status |=vl53l8cx_start_ranging(&dev);





  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
	  VL53L8CX_ResultsData  data;
	          status |=vl53l8cx_get_ranging_data(&dev, &data);

	          if (status == VL53L8CX_STATUS_OK) {
	              // Gib die Messwerte (z. B. Entfernung) über UART aus
	              char buffer[100];
	              int len = snprintf(buffer, sizeof(buffer), "Entfernung: %d mm\n", data.distance_mm);
	              printf("%s", buffer);
	          } else {
	             printf("Fehler beim Abrufen der Daten!\n");
	          }

	          HAL_Delay(500);  // Alle 500 ms Daten ausgeben
	      }
    /* USER CODE BEGIN 3 */

  /* USER CODE END 3 */
}


/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 16;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief I2C1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2C1_Init(void)
{

  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 400000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
	  uint32_t errorCode = HAL_I2C_GetError(&hi2c1);
	      char buffer[100];
	      int len = snprintf(buffer, sizeof(buffer), "I2C Fehler: %lu\n", errorCode);
	      HAL_UART_Transmit(&huart2, (uint8_t *)buffer, len, 1000);
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */

  /* USER CODE END I2C1_Init 2 */

}
void I2C_Scan() {
	 uint8_t i;
	    uint8_t buffer[1];
	    for(i = 0; i < 128; i++)
	    {
	        // Versuche, auf jede I2C-Adresse zuzugreifen
	        if (HAL_I2C_Mem_Read(&hi2c1, (i << 1), 0, I2C_MEMADD_SIZE_8BIT, buffer, 1, 10) == HAL_OK)
	        {
	            // Gebe die Adresse aus, wenn das Gerät reagiert
	            char buffer[30];
	            int len = snprintf(buffer, sizeof(buffer), "I2C Gerät gefunden auf Adresse 0x%02X\n", i);
	            HAL_UART_Transmit(&huart2, (uint8_t *)buffer, len, 1000);
	        }
}
}


/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 460800;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  /* USER CODE BEGIN MX_GPIO_Init_1 */

  /* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : B1_Pin */
  GPIO_InitStruct.Pin = B1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : LD2_Pin */
  GPIO_InitStruct.Pin = LD2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);

  /* USER CODE BEGIN MX_GPIO_Init_2 */

  /* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */
void VL53L8CX_Initialisation()
{   dev.platform.address = VL53L8CX_DEFAULT_I2C_ADDRESS;


	/*HAL_GPIO_WritePin(VL53L8A1_PWR_EN_C_PORT, VL53L8A1_PWR_EN_C_PIN, GPIO_PIN_RESET);
	HAL_Delay(2);
	HAL_GPIO_WritePin(VL53L8A1_PWR_EN_C_PORT, VL53L8A1_PWR_EN_C_PIN, GPIO_PIN_SET);
	HAL_Delay(2);
	HAL_GPIO_WritePin(VL53L8A1_LPn_C_PORT, VL53L8A1_LPn_C_PIN, GPIO_PIN_RESET);
	HAL_Delay(2);
	HAL_GPIO_WritePin(VL53L8A1_LPn_C_PORT, VL53L8A1_LPn_C_PIN, GPIO_PIN_SET);
	HAL_Delay(2); */

    // 2. I²C-Adresse setzen
    VL53L8CX_Reset_Sensor(&dev.platform);

    // Überprüfen, ob der Sensor erreichbar ist
   /* status = vl53l8cx_is_alive(&dev, &isAlive);
    if (status || !isAlive) {
        printf("VL53L8CX nicht gefunden!\n");
        while (1); // Stoppe das Programm, falls der Sensor nicht erkannt wird
    } */

    // Sensor initialisieren
    status = vl53l8cx_init(&dev.platform);
    if (status) {
        printf("Fehler bei der Initialisierung des VL53L8CX!\n");
        while (1);
    }

    printf("VL53L8CX erfolgreich initialisiert!\n");
}


void VL53L8CX_ReadData()
{
    VL53L8CX_ResultsData results; // Datenstruktur für die Messwerte
    status = vl53l8cx_start_ranging(&dev); // Messung starten

    if (status)
    {
        printf("Fehler beim Starten der Messung!\n");
        return;
    }

    while (1)  // Endlosschleife für kontinuierliche Messungen
    {
        uint8_t ready = 0;
        status = vl53l8cx_check_data_ready(&dev, &ready);

        if (!status && ready)
        {
            vl53l8cx_get_ranging_data(&dev, &results); // Messwerte abrufen

            // Ergebnisse ausgeben (VL53L8CX hat 64 Zonen, wir nehmen Zone[0] als Beispiel)
            printf("Distanz: %d mm\n", results.distance_mm[0]);

            HAL_Delay(100); // 100 ms Pause zwischen den Messungen
        }
    }

    vl53l8cx_stop_ranging(&dev); // Messung beenden
}


/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

 

John E KVAM
ST Employee

When you get a failure on an VL53L8CX_WrByte(), it's because your I2C failed. 

When the I2C fails it's because the function in Platform.c is incorrect or you have a hardware issue.

There are 3 jumpers on the board right next to each other. If they are in the SPI position, you are going to have an issue. Check that first.  

So I have 3 things I want you to do.

1) download the Eval Kit software from ST.

It has a bit of code that you download onto your STM32, and when it starts ranging you get a graphical view of what you are looking it.

If this works, we can be assured you have no hardware issues.

Next, have another look at your STSW-IMG040. It's where you got your driver. 

look in the:

JohnEKVAM_0-1743518557799.png

It has a complete functioning bit of code that you can open with your STM32CubeIDE. 

Try running that code. It will help you learn the ins and outs of your development system. 

And it should run with no changes.

Now try inserting one of the bits of code in the example directory of code into your mix. 

That will show you what can be done. 

Lastly, I want you to compare the function platform.c  in your failing code to the platform.c in the working code.

You might find yours is rather empty. And it doesn't do anything. 

The reason is that we don't know which MCU/CPU you are trying to run. So we have to let you complete the interface between our C code and your hardware.

But - as you are running an STM32 - you can take the platform.c file from the CubeIDE_F401RE_example_i2C project and put in in your project. 

and that should do it, 

 

 

 

 


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.