背景:抒微 VB50A 激光雷达以 DTOF 技术实现 50 米量程、IIC输出版及抗 100KLux 强光,本文为arduino UNO R3通讯例程。
代码:surertech/code (github.com)
软件:arduino IDE
硬件:arduino UNO R3
通信:默认烧录串口与电脑通信,IIC1与模组通讯(SDA,SCL需接上拉电阻到VCC)
硬件连接:
IIC寄存器各地址的含义:
使用系统烧录串口打印解析到的IIC各寄存器的数据:
#include <Wire.h> // ================= Configuration Parameters / 配置参数 ================= #define DEVICE_ADDR 0x52 // IIC device 7-bit address / IIC设备7位地址 #define START_REG 0x00 // Start register address for reading / 数据起始寄存器地址 #define BYTE_COUNT 15 // Total bytes to read (Reg 0x00 to 0x0E) / 需要读取的总字节数 void setup() { // 1. Initialize Serial Port / 初始化串口 Serial.begin(9600); // Standard baud rate for Uno / Uno常用波特率 // 2. Initialize IIC Bus / 初始化 IIC 总线 Wire.begin(); // On Uno: SDA=A4, SCL=A5. No pins needed. / Uno默认引脚,无需传参 Wire.setClock(400000); // Set IIC clock to 400kHz (Fast Mode) / 设置IIC时钟为400kHz delay(100); // Wait for hardware stabilization / 等待硬件稳定 // 3. Initialize Sensor: Enable Laser / 初始化传感器:开启激光 // According to datasheet, write 1 to Reg 0x02 to enable laser / 根据手册,向寄存器0x02写入1以开启激光 Wire.beginTransmission(DEVICE_ADDR); // Start transmission / 开始传输 Wire.write((uint8_t)0x02); // Target register address / 目标寄存器地址 Wire.write((uint8_t)0x01); // Data value 1 (Enable Laser) / 数据值1 (开启) // endTransmission returns error code (0 = success) / endTransmission返回错误码 (0=成功) uint8_t init_err = Wire.endTransmission(); if (init_err == 0) { Serial.println("Sensor Init Success: Laser ON"); } else { Serial.print("Sensor Init Failed (Error: "); Serial.print(init_err); Serial.println(")"); } Serial.println("Arduino Uno Ready. Reading data..."); Serial.println("--------------------------------"); } void loop() { uint8_t reg_data[BYTE_COUNT]; // Buffer for raw byte data / 用于存储原始数据的字节数组 // ================= IIC Read Sequence / IIC 读取流程 ================= // Step 1: Send "Write" operation to specify start register / 第一步:发送“写”操作指定起始寄存器 Wire.beginTransmission(DEVICE_ADDR); Wire.write((uint8_t)START_REG); // Tell slave: start reading from Reg 0x00 / 告诉从机从0x00开始读 // false means send Repeated Start condition (keep bus connected) / false表示发送重复起始条件(保持总线连接) uint8_t err = Wire.endTransmission(false); if (err != 0) { Serial.print("IIC Write Error: "); Serial.println(err); delay(1000); return; // Skip this cycle if write fails / 如果写入失败则跳过本次循环 } // Step 2: Send "Read" operation to request bytes / 第二步:发送“读”操作请求数据 // Explicit cast to uint8_t to avoid compiler ambiguity warnings on AVR / 显式转换类型以避免AVR编译器警告 Wire.requestFrom((uint8_t)DEVICE_ADDR, (uint8_t)BYTE_COUNT); // Check if enough data is available / 检查是否有足够的数据 if (Wire.available() < BYTE_COUNT) { Serial.println("IIC Read Error: Data incomplete"); while(Wire.available()) Wire.read(); // Clear buffer / 清空缓冲区 delay(500); return; } // Step 3: Read all bytes into array / 第三步:将所有字节读入数组 for (int i = 0; i < BYTE_COUNT; i++) { reg_data[i] = Wire.read(); } // ================= Data Parsing (Big-Endian) / 数据解析 (大端模式) ================= // Note: Big-Endian means High Byte first (lower address), Low Byte last (higher address) // 注意:大端模式意味着高字节在前(低地址),低字节在后(高地址) // 1. Distance Data (Reg 0x00, 0x01) / 距离数据 // reg_data[0] is High Byte, reg_data[1] is Low Byte / [0]是高字节,[1]是低字节 uint16_t distance = ((uint16_t)reg_data[0] << 8) | reg_data[1]; // 2. Laser ID / Status (Reg 0x03) / 激光ID/状态 uint8_t laser_id = reg_data[3]; // 3. Software Version (Reg 0x06, 0x07) / 软件版本号 uint8_t ver_major = reg_data[6]; // Major version / 主版本 uint8_t ver_minor = reg_data[7]; // Minor version / 次版本 // 4. Serial Number (Reg 0x08 - 0x0B, 4 bytes) / 序列号 // Concatenate in Big-Endian order / 按大端顺序拼接 uint32_t serial_num = ((uint32_t)reg_data[8] << 24) | ((uint32_t)reg_data[9] << 16) | ((uint32_t)reg_data[10] << 8) | reg_data[11]; // 5. Slave Address (Reg 0x0C) / 从机地址 uint8_t slave_addr = reg_data[12]; // ================= Print Results / 打印结果 ================= Serial.println("--- Sensor Data Report ---"); Serial.print("Distance : "); Serial.print(distance); Serial.println(" mm"); Serial.print("Laser ID : 0x"); if (laser_id < 0x10) Serial.print("0"); // Format hex with leading zero / 格式化16进制前导零 Serial.println(laser_id, HEX); Serial.print("Soft Version : v"); Serial.print(ver_major); Serial.print("."); Serial.println(ver_minor); Serial.print("Serial Number : "); Serial.println(serial_num); Serial.print("Slave Address : 0x"); if (slave_addr < 0x10) Serial.print("0"); Serial.println(slave_addr, HEX); Serial.println("--------------------------\n"); delay(500); // Delay 500ms for ~2Hz refresh rate / 延时500ms,刷新率约2Hz }连接好,选择Arduino UNO
验证上传后打开串口监视器
可以看到打印出来的解析的数据