I can receive data from 1 sensor. But when I try to read 2 VL53L1XV2 sensors I run into a problem.
- February 4, 2021
- 1 reply
- 905 views
Hey! Sorry for my english.
I am facing a problem. when trying to read 2 VL53L1XV2 sensors, the program execution stops in a loop. in this loop I am using:
VL53L1X_BootState(dev, &Bootstate);... and exit it when Bootstate is 0x03 ...
I use the HAL_Delay (100) delay to blink LD2 on the NUCLEO-F401RE. Without delay, the program behaves the same.
When I debug the program, I see that when I try to get Model_ID, Module_Type, I get 0.
Most likely the problem is in initiating the sensors. I tried many similar codes and also took the Pololu library
in which similar actions occur. but I keep getting it.
I am using a NUCLEO-F401RE board, a VL53L1X_ULD driver from ST, and two VL53L1XV2 sensors.
I would be grateful for any help in solving my question.
the code I wrote:
#include "stm32xxx_hal.h"
#include "main.h"
#include "VL53L1X_API.h"
#include "VL53l1X_calibration.h"
#include "X-NUCLEO-53L1A1.h"
I2C_HandleTypeDef hi2c1;
UART_HandleTypeDef huart2;
uint16_t dev = 0x52;
int status = 0;
volatile int IntCount;
#define isInterrupt 1
int SystemClock_Config(void);
static void MX_GPIO_Init(void);
static int MX_USART2_UART_Init(void);
static int MX_I2C1_Init(void);
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#define VL53L1_DISTANCEMODE_SHORT 1
#define VL53L1_DISTANCEMODE_LONG 2
#define SET_ZERO_POSITION "\033[0;0H"
#define CLEAR_WINDOW "\033[2J"
#define CLEAR_LINE "\r\033[K"
uint8_t clear_window[] = CLEAR_WINDOW;
uint8_t str[] = "\r\n\0";
uint8_t set_zero_position[] = SET_ZERO_POSITION;
uint8_t clear_line[] = CLEAR_LINE;
uint8_t str1[] = "test\r\n\0";
#define NumOfTOFSensors 2
#define ROWS_OF_SPADS 4
#define DISTANCES_ARRAY_SIZE ROWS_OF_SPADS
#define ROWS 8
#define COLS 8
#define TIMING_BUDGET 33
#define DISTANCE_MODE VL53L1_DISTANCEMODE_LONG // VL53L1_DISTANCEMODE_SHORT // VL53L1_DISTANCEMODE_LONG
uint16_t dictanse_array[DISTANCES_ARRAY_SIZE];
#define ZONE_CENTER_1 227
#define ZONE_CENTER_2 92
#define ZONE_CENTER_3 28
#define ZONE_CENTER_4 163
uint16_t Devs[NumOfTOFSensors] = {0x62, 0x64/*, 0x66, 0x68, 0x6A, 0x6C, 0x6E, 0x70, 0x72*/};
PUTCHAR_PROTOTYPE {
HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, 0xFFFF);
return ch;
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if (GPIO_Pin == VL53L1X_INT_Pin) {
IntCount++;
}
}
void dump_depths_2x2() {
HAL_UART_Transmit(&huart2, set_zero_position, sizeof(set_zero_position), 30);
HAL_UART_Transmit(&huart2, clear_line, sizeof(clear_line), 30);
printf("%d", dictanse_array[0]);
for(uint8_t idx = 1; idx < DISTANCES_ARRAY_SIZE; idx++) {
if (idx == 2 || idx == 4) {
printf("\n");
HAL_UART_Transmit(&huart2, clear_line, sizeof(clear_line), 30);
} else printf("\t");
printf("%d", dictanse_array[idx]);
}
}
void TurnOnSensor(uint8_t SensorNum) {
printf("GPIO Sensor_%d:", SensorNum + 1);
switch (SensorNum) {
case 0:
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET); // GPIO PC2
printf("Active\r\n");
break;
case 1:
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_SET); // GPIO PC3
printf("Active\r\n");
break;
default:
printf("Error: Number sensor is invalid!");
break;
}
}
void ResetAllSensors(void) {
printf("ResetAllSensors...");
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET); // Sensor_1
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_RESET); // Sensor_2
printf("Done\r\n");
}
void ResetAndInitializeAllSensors(void) {
uint8_t i, Sensor, error = 0;
uint8_t Bootstate = 0;
uint8_t byteData = 0;
uint16_t wordData;
printf("ResetAndInitializeAllSensors...\r\n");
ResetAllSensors();
HAL_Delay(10);
for (i = 0; i < NumOfTOFSensors; i++) {
TurnOnSensor(i);
HAL_Delay(20);
printf("Sensor_%d loading...\r\n", i + 1);
status = VL53L1_RdByte(dev, 0x010F, &byteData);
printf("VL53L1X Model_ID: %X\r\n", byteData);
status = VL53L1_RdByte(dev, 0x0110, &byteData);
printf("VL53L1X Module_Type: %X\r\n", byteData);
status = VL53L1_RdWord(dev, 0x010F, &wordData);
printf("VL53L1X: %X\r\n", wordData);
error += VL53L1X_BootState(dev, &Bootstate);
while (Bootstate != 0x03) {
HAL_Delay(100);
error += VL53L1X_BootState(dev, &Bootstate);
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
}
printf("Chip booted\r\n");
printf("reading!\r\n");
printf("[%d]\tSensor_%d SetI2CAddress: 0x%X\r\n", VL53L1X_SetI2CAddress(dev, Devs[i]), i + 1, Devs[i]);
printf("[%d]\tSensor_%d init: \r\n", VL53L1X_SensorInit(dev), i + 1);
}
for (Sensor = 0; Sensor < NumOfTOFSensors; Sensor++) {
VL53L1X_SetDistanceMode(Devs[Sensor], DISTANCE_MODE);
VL53L1X_SetTimingBudgetInMs(Devs[Sensor], TIMING_BUDGET);
VL53L1X_SetInterMeasurementInMs(Devs[Sensor], TIMING_BUDGET);
VL53L1X_SetROI(Devs[Sensor], ROWS, COLS);
VL53L1X_SetROICenter(Devs[Sensor], ZONE_CENTER_1);
}
for (Sensor = 0; Sensor < NumOfTOFSensors; Sensor++) {
VL53L1X_StartRanging(Devs[Sensor]);
HAL_Delay(1);
}
}
int main(void) {
VL53L1X_ERROR error = 0;
uint16_t Distance;
uint8_t RangeStatus;
uint8_t dataReady;
int center_2x2[4] = {ZONE_CENTER_1, ZONE_CENTER_2, ZONE_CENTER_3, ZONE_CENTER_4};
HAL_Init();
error = SystemClock_Config();
MX_GPIO_Init();
error += MX_USART2_UART_Init();
error += MX_I2C1_Init();
HAL_UART_Transmit(&huart2, clear_window, sizeof(clear_window), 30);
HAL_UART_Transmit(&huart2, set_zero_position, sizeof(set_zero_position), 30);
if (error != 0) {
printf("Could not initialize the nucleo board\n");
return -1;
}
ResetAndInitializeAllSensors();
/* Initialize and configure the device according to people counting need */
status = VL53L1X_SensorInit(dev);
status += VL53L1X_SetDistanceMode(dev, DISTANCE_MODE); /* 1=short, 2=long */
status += VL53L1X_SetTimingBudgetInMs(dev, TIMING_BUDGET); /* in ms possible values [15, 20, 50, 100, 200, 500] */
status += VL53L1X_SetInterMeasurementInMs(dev, TIMING_BUDGET);
status += VL53L1X_SetROI(dev, ROWS, COLS);
if (status != 0) {
printf("Initialization or configuration of the device\n");
return (-1);
}
status = VL53L1X_StartRanging(dev); /* This function has to be called to enable the ranging */
while (1) {
error = 0;
for(uint8_t Zone = 0; Zone < ROWS_OF_SPADS; Zone++) {
for (uint8_t Sensor=0; Sensor < NumOfTOFSensors ; Sensor++)
VL53L1X_SetROICenter(Devs[Sensor], center_2x2[Zone]);
for (uint8_t Sensor = 0; Sensor < NumOfTOFSensors ; Sensor++) {
while (dataReady == 0) {
status = VL53L1X_CheckForDataReady(Devs[Sensor], &dataReady);
HAL_Delay(1);
}
dataReady = 0;
status += VL53L1X_GetRangeStatus(Devs[Sensor], &RangeStatus);
status += VL53L1X_GetDistance(Devs[Sensor], &Distance);
status += VL53L1X_ClearInterrupt(Devs[Sensor]);
if (status != 0) {
printf("Error in operating the device\n");
return (-1);
}
dictanse_array[Zone] = (RangeStatus != 0 && RangeStatus != 4 && RangeStatus != 7) ? 0 : Distance;
}
}
}
}
int SystemClock_Config(void) {
...
}
/* I2C1 init function */
static int MX_I2C1_Init(void) {
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
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)
return -1;
return 0;
}
/* USART2 init function */
int MX_USART2_UART_Init(void) {
...
}
static void MX_GPIO_Init(void) {
...
// Sensor_1
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
// Sensor_2
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}full code i attached below.
Thank you!
Volodymyr.
where the ellipsis is the code that does not matter. for correct display I use ESC-sequences.
