Skip to content

Instantly share code, notes, and snippets.

@glebov21
Last active March 20, 2023 19:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save glebov21/b8500094cba9dd225bd5ab3d10bb67bb to your computer and use it in GitHub Desktop.
Save glebov21/b8500094cba9dd225bd5ab3d10bb67bb to your computer and use it in GitHub Desktop.
stm32 VL53L0X CONTINUOUS RANGING mode
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2023 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"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "vl53l0x_api.h"
/* 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;
TIM_HandleTypeDef htim3;
/* USER CODE BEGIN PV */
float leftMotorMultiplier = 1.07f;
int32_t counterVib;
int32_t vibrationsToWakeUp = 1;
uint16_t Distance = 34000; // cm
uint16_t PrevDiatance = 34000; // cm
int32_t startTimeoutSec = 5;
int32_t workingTimeSec = 60;
int32_t delayAfterWorkingTimeoutSec = 2;
//####################################
float maxSpeedPercent01 = 0.13f;
float maxSpeedPercentFastReverse01 = 0.30f;
float turnDistanceSm = 15.0f;
float fastReverseDistanceSm = 10.0f;
int32_t waitForEqualsDiatanceMs = 400;
int32_t waitForShortDiatanceMs = 100; //иногда неверные координаты приходят
int minEqualsDiatanceErrorSm = 5;
int errorDistance = 800;
//####################################
int isRotateToLeftNow = 1;
int32_t lastNotEqualsDistance = 0;
int32_t lastLongDistance = 0;
int32_t lastOk = 0;
int32_t lastWakeup = 0;
int isReverse = 0;
int isIdle = 0;
//#####################
uint8_t Message[64];
uint8_t MessageLen;
VL53L0X_RangingMeasurementData_t RangingData;
VL53L0X_Dev_t vl53l0x_c; // center module
VL53L0X_DEV Dev = &vl53l0x_c;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM3_Init(void);
static void MX_I2C1_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
//Prescaler 7 = 4Khz
//Prescalser 15 = 2Khz
//Prescalser 31 = 1Khz
//Prescaler 63 = 500Hz
/*void delay_us(uint16_t us) {
__HAL_TIM_SET_COUNTER(&htim1, 0); // set the counter value a 0
while (__HAL_TIM_GET_COUNTER(&htim1) < us)
; // wait for the counter to reach the us input in the parameter
}
void SendTrig() {
HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_SET); // pull the TRIG pin HIGH
delay_us(10);
HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET); // pull the TRIG pin low
}
void WaitForDistanceSm() {
uint32_t Value1 = 0;
uint32_t Value2 = 0;
uint32_t pMillis = HAL_GetTick(); // used this to avoid infinite while loop (for timeout)
// wait for the echo pin to go high
while (!(HAL_GPIO_ReadPin(ECHO_GPIO_Port, ECHO_Pin))
&& pMillis + 10 > HAL_GetTick())
;
Value1 = __HAL_TIM_GET_COUNTER(&htim1);
pMillis = HAL_GetTick(); // used this to avoid infinite while loop (for timeout)
// wait for the echo pin to go low
while ((HAL_GPIO_ReadPin(ECHO_GPIO_Port, ECHO_Pin))
&& pMillis + 50 > HAL_GetTick())
;
Value2 = __HAL_TIM_GET_COUNTER(&htim1);
Distance = (Value2 - Value1) * 0.034 / 2;
}
//измерение не раньше чем через 50мс
void GetDistance() {
SendTrig();
WaitForDistanceSm();
}*/
void BreakMLeft(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, htim3.Init.Period + 1);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, htim3.Init.Period + 1);
}
void IdleMLeft(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0);
}
void BreakMRight(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, htim3.Init.Period + 1);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, htim3.Init.Period + 1);
}
void IdleMRight(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
}
void IdleM(void) {
IdleMLeft();
IdleMRight();
}
void BreakM(void) {
BreakMLeft();
BreakMRight();
}
//-1 0 1
void SetSpeedMLeft(float speed101) {
if (speed101 >= 0.0) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4,
(htim3.Init.Period + 1) * (speed101 * leftMotorMultiplier));
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0);
} else {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3,
(htim3.Init.Period + 1) * -(speed101 * leftMotorMultiplier));
}
}
//-1 0 1
void SetSpeedMRight(float speed101) {
if (speed101 >= 0.0) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1,
(htim3.Init.Period + 1) * (speed101));
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
} else {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2,
(htim3.Init.Period + 1) * -(speed101));
}
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint32_t refSpadCount;
uint8_t isApertureSpads;
uint8_t VhvSettings;
uint8_t PhaseCal;
/* 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_TIM3_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
HAL_Delay(startTimeoutSec * 1000);
//HAL_TIM_Base_Start(&htim1);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);
//HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET); // pull the TRIG pin low
IdleM();
//MessageLen = sprintf((char*)Message, "msalamon.pl VL53L0X test\n\r");
//HAL_UART_Transmit(&huart2, Message, MessageLen, 100);
Dev->I2cHandle = &hi2c1;
Dev->I2cDevAddr = 0x52;
// HAL_GPIO_WritePin(TOF_XSHUT_GPIO_Port, TOF_XSHUT_Pin, GPIO_PIN_RESET); // Disable XSHUT
// HAL_Delay(20);
// HAL_GPIO_WritePin(TOF_XSHUT_GPIO_Port, TOF_XSHUT_Pin, GPIO_PIN_SET); // Enable XSHUT
// HAL_Delay(20);
//
// VL53L0X init for Single Measurement
//
VL53L0X_WaitDeviceBooted( Dev );
VL53L0X_DataInit( Dev );
VL53L0X_StaticInit( Dev );
VL53L0X_PerformRefCalibration(Dev, &VhvSettings, &PhaseCal);
VL53L0X_PerformRefSpadManagement(Dev, &refSpadCount, &isApertureSpads);
VL53L0X_SetDeviceMode(Dev, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING);
//High speed ranging:
VL53L0X_SetLimitCheckValue(Dev, VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, (FixPoint1616_t)(0.25*65536));
VL53L0X_SetLimitCheckValue(Dev, VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, (FixPoint1616_t)(32*65536));
VL53L0X_SetMeasurementTimingBudgetMicroSeconds(Dev, 20000);
//Long range
//VL53L0X_SetLimitCheckValue(Dev, VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, (FixPoint1616_t)(0.1*65536));
//VL53L0X_SetLimitCheckValue(Dev, VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, (FixPoint1616_t)(60*65536));
//VL53L0X_SetMeasurementTimingBudgetMicroSeconds(Dev, 33000);
//VL53L0X_SetVcselPulsePeriod(Dev, VL53L0X_VCSEL_PERIOD_PRE_RANGE, 18);
//VL53L0X_SetVcselPulsePeriod(Dev, VL53L0X_VCSEL_PERIOD_FINAL_RANGE, 14);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
lastWakeup = HAL_GetTick();
VL53L0X_StartMeasurement(Dev);
//Start
//SetSpeedMRight(1.0);
//SetSpeedMLeft(1.0);
while (1)
{
uint8_t pRangingMeasurementData = 0;
VL53L0X_GetMeasurementDataReady(Dev, &pRangingMeasurementData);
if(pRangingMeasurementData == 1)
{
VL53L0X_GetRangingMeasurementData(Dev, &RangingData);
if(RangingData.RangeStatus == 0 || RangingData.RangeStatus == 4)//valid / too high
{
uint32_t maxDist = 300;
if(RangingData.RangeStatus == 4)
lastLongDistance = maxDist;
else{
lastLongDistance = RangingData.RangeMilliMeter - 45; //45 это что-то лишнее
if(lastLongDistance > maxDist)
lastLongDistance = maxDist;
}
if(lastNotEqualsDistance != lastLongDistance)
{
float calcSpeed = ((float)lastLongDistance / (float)maxDist);
SetSpeedMRight(calcSpeed);
SetSpeedMLeft(calcSpeed);
lastNotEqualsDistance = lastLongDistance;
}
}
VL53L0X_ClearInterruptMask(Dev, VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY);
VL53L0X_PollingDelay(Dev);
}
/* USER CODE END WHILE */
/* 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};
/** 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_NONE;
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_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != 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)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
/**
* @brief TIM3 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM3_Init(void)
{
/* USER CODE BEGIN TIM3_Init 0 */
/* USER CODE END TIM3_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM3_Init 1 */
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 1;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 255;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM3_Init 2 */
/* USER CODE END TIM3_Init 2 */
HAL_TIM_MspPostInit(&htim3);
}
/**
* @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_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : LED_Pin */
GPIO_InitStruct.Pin = LED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
/* 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 */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment