자율 모드란?
"자율 모드"(Autonomous mode)는 외부 입력 없이 장치나 시스템이 독립적으로 작업을 수행할 수 있는 상태를 의미합니다. 센서의 경우 자율 모드에서는 매번 호스트의 명령 없이도 주기적으로 스스로 측정을 수행할 수 있습니다.
VL53L8 센서의 자율 모드 사용 이유는 다음과 같습니다:
- 제어 간소화: 구성 후 센서가 독립적으로 작동하여 호스트와의 통신 빈도를 줄일 수 있습니다.
- 일관된 측정 주기: 고정된 주기로 측정이 이루어져 데이터의 안정성과 연속성을 보장합니다.
- 응답 지연 감소: 센서가 지속적으로 또는 주기적으로 측정하기 때문에 요청과 결과 사이의 대기 시간이 줄어듭니다.
- 호스트 부하 경감: 호스트가 다른 작업에 집중할 수 있도록 하여 센서 제어 부담을 줄입니다.
- 저전력 운용 가능: 측정 간격 동안 센서가 절전 상태로 진입하여 전력 소비를 최적화할 수 있습니다.
- 예약된 작업 실행: 특정 조건에서 알림이나 트리거 기능을 구현할 수 있습니다.
하지만 모든 애플리케이션에서 자율 모드가 적합한 것은 아닙니다. 실시간 데이터가 필요한 경우 연속 모드가 더 적절할 수 있습니다.
비디오 튜토리얼
https://www.bilibili.com/video/BV1UtzZY7EGA/
샘플 신청
https://www.wjx.top/vm/OhcKxJk.aspx#
소스 코드 다운로드
https://download.csdn.net/download/qq_24312945/90425840
하드웨어 준비
본 개발에는 STM32H503CBT6 마이크로컨트롤러와 VL53L8CX ToF 센서가 탑재된 커스텀 PCB를 사용합니다. 필요 시 샘플 신청이 가능합니다.
자율 모드의 장점
● 전력 절약: VCSEL 발진기가 필요할 때만 작동하여 배터리 구동 장치에 이상적입니다. ● 독립 운영: 호스트의 지속적인 제어 없이 센서 자체적으로 작동합니다. ● 유연한 설정: 응용 목적에 따라 측정 주기와 적분 시간을 조절할 수 있습니다. ● 활용 분야: 스마트 홈의 사용자 감지, 물체 인식, 제스처 인식 등에서 유용하게 사용됩니다.
자율 모드 vs 연속 모드 비교
VL53L8CX 센서의 자율(AUTONOMOUS) 모드와 연속(CONTINUOUS) 모드는 모두 연속적인 측정을 지원하지만 작동 방식과 적용 사례가 다릅니다:
연속 모드(CONTINUOUS): ● 센서가 지속적으로 측정을 수행하며 각 측정 직후 새로운 결과를 생성합니다. ● 설정된 시간 예산 내에서 가능한 한 빠르게 측정합니다. ● 호스트는 주기적으로 센서로부터 데이터를 읽어야 합니다. ● 실시간 업데이트가 필요한 애플리케이션에 적합합니다.
자율 모드(AUTONOMOUS): ● 호스트의 정기적인 개입 없이 센서가 자체적으로 측정을 수행합니다. ● 호스트는 센서가 데이터 준비를 완료하면 인터럽트를 통해 깨워지는 절전 상태로 유지될 수 있습니다. ● 대부분의 시간 동안 호스트가 절전 상태에 있어 저전력 애플리케이션에 적합합니다. ● 측정 주기를 설정하여 센서가 얼마나 자주 측정할지를 결정할 수 있습니다.
애플리케이션 요구사항에 따라 선택해야 합니다. 실시간 고속 데이터가 필요하다면 연속 모드를, 전력 절약이 우선이라면 자율 모드를 선택하는 것이 좋습니다.
참조 프로젝트
https://github.com/CoreMaker-lab/VL53L8CX
https://gitee.com/CoreMaker/VL53L8CX
STM32CUBEMX 프로젝트 생성
MCU로 STM32H503CB를 선택하여 STM32CUBEMX를 이용해 기본 프로젝트를 생성합니다. 클록 트리를 구성하고 클록 주파수를 250MHz로 설정합니다.
UART 설정
회로도에 따라 PA9와 PA10 핀을 UART 통신으로 설정합니다.
UART 통신 속도를 921600bps로 설정합니다.
I2C 설정
VL53L8CX 모듈은 I2C 인터페이스를 통해 MCU와 통신합니다. PB6(SCL) 및 PB7(SDA) 핀을 사용합니다.
I2C를 Fast Mode(400kHz)로 설정합니다.
LPn 핀 설정
I2C 통신을 위해 LPn 핀(PB0)을 HIGH로 설정합니다.
INT 핀 설정
자율 모드에서는 INT 핀(PB1)을 입력 모드로 설정하여 데이터 준비 여부를 확인합니다.
X-CUBE-TOF1 패키지 추가
STM32CubeMX에서 X-CUBE-TOF1 패키지를 프로젝트에 추가합니다. 이 설정은 드라이버 계층만 구성됩니다.
스택 메모리 설정
정상 작동하지 않는 경우 컴파일러 최적화 레벨을 조정해야 할 수 있습니다.
UART 리디렉션
Keil µVision에서 마법사(Magic Wand) 설정에서 MicroLIB를 활성화합니다.
코드 수정
custom_ranging_sensor.c 파일에서 IO 포트를 통한 리셋 코드가 있으나 해당 핀이 구성되지 않았으므로 주석 처리합니다.
ToF 코드 구성
main.c 파일에 측정 주기를 500ms로 설정하여 2Hz 주파수를 얻습니다.
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "custom_ranging_sensor.h"
#define MEASUREMENT_TIME_BUDGET (500U)
#define MEASUREMENT_RATE_HZ (2U)
#define POLLING_INTERVAL_MS (1000U / MEASUREMENT_RATE_HZ)
/* USER CODE END Includes */
함수 및 변수 선언:
/* USER CODE BEGIN PFP */
static uint8_t interpret_target_status(uint8_t raw_status);
static int32_t transform_output_data(VL53L8CX_Object_t *sensor_obj, VL53L8CX_ResultsData *raw_data, RANGING_SENSOR_Result_t *processed_result);
static void display_measurement_results(RANGING_SENSOR_Result_t *results);
static RANGING_SENSOR_ProfileConfig_t sensor_profile_config;
static int32_t operation_result = 0;
static RANGING_SENSOR_Result_t measurement_output;
/* USER CODE END PFP */
ToF 초기화 코드:
/* USER CODE BEGIN 2 */
VL53L8CX_Object_t *sensor_instance = CUSTOM_RANGING_CompObj[CUSTOM_VL53L8CX];
static VL53L8CX_ResultsData raw_results;
uint8_t data_available_flag = 0;
sensor_profile_config.RangingProfile = RS_PROFILE_4x4_AUTONOMOUS;
sensor_profile_config.TimingBudget = MEASUREMENT_TIME_BUDGET;
sensor_profile_config.Frequency = MEASUREMENT_RATE_HZ;
sensor_profile_config.EnableAmbient = 0;
sensor_profile_config.EnableSignal = 0;
sensor_instance->IsAmbientEnabled = sensor_profile_config.EnableAmbient;
sensor_instance->IsSignalEnabled = sensor_profile_config.EnableSignal;
operation_result = vl53l8cx_set_resolution(&(sensor_instance->Dev), VL53L8CX_RESOLUTION_4X4);
operation_result |= vl53l8cx_set_ranging_mode(&(sensor_instance->Dev), VL53L8CX_RANGING_MODE_AUTONOMOUS);
operation_result |= vl53l8cx_set_integration_time_ms(&(sensor_instance->Dev), MEASUREMENT_TIME_BUDGET);
operation_result |= vl53l8cx_set_ranging_frequency_hz(&(sensor_instance->Dev), MEASUREMENT_RATE_HZ);
if (operation_result != VL53L8CX_STATUS_OK) {
printf("Error: Sensor configuration failed!\n");
while (1);
}
operation_result = vl53l8cx_start_ranging(&(sensor_instance->Dev));
if (operation_result != VL53L8CX_STATUS_OK) {
printf("Failed to start ranging\n");
while (1);
}
/* USER CODE END 2 */
적분 시간(Integration Time) 설정
적분 시간은 자율 모드에서만 조절 가능한 파라미터로 VCSEL의 작동 시간을 변경합니다. 연속 모드에서는 무시됩니다. 기본값은 5ms입니다.
- 4x4 해상도: 하나의 적분 시간 사용
- 8x8 해상도: 네 개의 적분 시간 사용
총 적분 시간 + 1ms 오버헤드는 측정 주기보다 짧아야 하며, 그렇지 않으면 측정 주기가 자동으로 증가합니다.
메인 루프
INT 핀(PB1)의 상태를 확인하여 데이터 준비 여부를 판단합니다.
/* Infinite loop */
while (1) {
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0) {
do {
(void)vl53l8cx_check_data_ready(&(sensor_instance->Dev), &data_available_flag);
} while (!data_available_flag);
if (data_available_flag != 0) {
operation_result = vl53l8cx_get_ranging_data(&(sensor_instance->Dev), &raw_results);
if (operation_result == VL53L8CX_STATUS_OK) {
if (transform_output_data(sensor_instance, &raw_results, &measurement_output) < 0) {
printf("Data conversion error\n");
while (1);
}
display_measurement_results(&measurement_output);
}
}
}
}
실행 결과
- 4x4 해상도: 1회 적분, 500ms 적분 시간 → 2Hz 측정 주기
- 8x8 해상도: 4회 적분, 500ms 적분 시간 → 0.5Hz 측정 주기
설정 완료 후 Tera Term 등의 터미널 프로그램을 통해 아래와 같은 8x8 결과를 확인할 수 있습니다.