본 문서는 TOFSense_F 레이저 거리 측정 모듈을 위한 STM32F103 드라이버 예제를 제공합니다. 이 모듈은 5V 전원 공급으로 동작하며, 데이터 송수신은 UART 인터페이스를 통해 이루어집니다.
접선 방법
모듈의 TX 핀은 STM32F103의 RX(PA10)에 연결하고, RX 핀은 TX(PA9)에 연결하세요. 전원은 5V로 직접 공급하면 됩니다. 원래의 단자선은 브레드보드에 꽂을 수 없으므로, 적절한 도판트 선을 사용하여 연결해야 합니다.
모드 확인
모듈의 모드를 확인하려면, UART 포트에 접속하여 기본적으로 설정된 921600bps의 보드율로 데이터를 수신합니다. 데이터가 수신되면 'Active' 모드이며, 그렇지 않으면 명령어를 수동으로 보내야 합니다.
데이터 해석
데이터 프레임은 16바이트로 구성되며, 각 바이트는 특정 정보를 포함합니다. 다음은 데이터 프레임 해석 함수입니다:
void tofSenseDataReceive(uint8_t *data, uint8_t len) {
uint8_t checksum = 0;
for (uint8_t i = 0; i < len - 1; ++i) {
checksum += data[i];
}
if (checksum != data[len - 1]) return;
if (data[0] != 0x57 || data[1] != 0x00) return;
uint8_t sensorId = data[3];
tofData[sensorId].prevDistance = tofData[sensorId].lastDistance;
tofData[sensorId].lastDistance = tofData[sensorId].distance;
tofData[sensorId].lastVelocity = tofData[sensorId].velocity;
tofData[sensorId].lastSysTime = tofData[sensorId].sysTime;
tofData[sensorId].id = sensorId;
tofData[sensorId].sysTime = data[4] | (data[5] << 8) | (data[6] << 16) | (data[7] << 24);
tofData[sensorId].distance = ((int32_t)(data[8] | (data[9] << 8) | (data[10] << 16)) / 256.0f) / 10.0f;
tofData[sensorId].signalStrength = data[12] | (data[13] << 8);
tofData[sensorId].velocity = (tofData[sensorId].distance - tofData[sensorId].lastDistance) / 0.1f;
tofData[sensorId].acceleration = (tofData[sensorId].velocity - tofData[sensorId].lastVelocity) / 0.1f;
}
다음은 데이터 파싱 함수입니다:
void tofSenseParse(uint8_t byte) {
static uint8_t bufferIndex = 0;
static uint8_t state = 0;
static uint8_t expectedLength = 0;
if (state == 0 && byte == 0x57) {
state = 1;
tofBuffer[bufferIndex++] = byte;
} else if (state == 1 && byte == 0x00) {
state = 2;
tofBuffer[bufferIndex++] = byte;
} else if (state == 2 && byte == 0xFF) {
state = 3;
tofBuffer[bufferIndex++] = byte;
} else if (state == 3 && byte <= 0xFF) {
state = 4;
tofBuffer[bufferIndex++] = byte;
expectedLength = 11;
} else if (state == 4 && expectedLength > 0) {
expectedLength--;
tofBuffer[bufferIndex++] = byte;
if (expectedLength == 0) state = 5;
} else if (state == 5) {
state = 0;
tofBuffer[bufferIndex++] = byte;
tofSenseDataReceive(tofBuffer, 16);
tofParseFlag = 1;
} else {
state = 0;
}
}
다음은 전체 프로그램 파일 TOFSense.c의 일부입니다:
#include "TOFSense.h"
uint8_t tofParseFlag = 0;
uint8_t tofBuffer[20];
TOFSenseFT tofData[TOFSENSE_MAX_NUMBER];
void uartSend(uint8_t *data, uint16_t length) {
API_get_uart_ops()->write(&uart1_, data, length);
}
void tofSenseReadDataFrame(uint8_t id) {
uint8_t buf[8] = {0x57, 0x10, 0xFF, 0xFF, id, 0xFF, 0xFF};
uint8_t checksum = 0;
for (int i = 0; i < 7; ++i) checksum += buf[i];
buf[7] = checksum;
uartSend(buf, 8);
}
float tofSenseGetDistance(uint8_t id) {
if (id >= TOFSENSE_MAX_NUMBER) return 0.0f;
return tofData[id].distance;
}
헤더 파일 TOFSense.h에서 필요한 데이터 구조와 상수를 정의합니다:
#ifndef __TOFSENSE_H__
#define __TOFSENSE_H__
#include "stm32f10x.h"
#include "base_c/API/API_registry.h"
#include "APP/init.h"
#define TOFSENSE_TYPE TOFSenseF
#define TOFSENSE_MAX_NUMBER 4
typedef struct {
uint8_t id;
uint32_t sysTime;
int32_t distance;
uint8_t status;
uint16_t signalStrength;
uint8_t rangePrecision;
uint32_t lastSysTime;
float prevDistance;
float lastDistance;
float velocity;
float acceleration;
float lastVelocity;
} TOFSenseFT;
extern uint8_t tofBuffer[20];
extern TOFSenseFT tofData[TOFSENSE_MAX_NUMBER];
extern uint8_t tofParseFlag;
void tofSenseReadDataFrame(uint8_t id);
void tofSenseDataReceive(uint8_t *data, uint8_t len);
void tofSenseParse(uint8_t byte);
#endif