TOF050C VL6180X基于arduino修改测距范围

下载VL6180X和Adafruit_VL6180X这两个库

 

 在arduino的library路径下,分别打开这两个库对应的cpp和h文件

把VL6180X.cpp里面的setScaling函数和其内部包含的writeReg16Bit、writeReg、readReg一同打包到Adafruit_VL6180X.cpp下

在.h里面定义好所有参数地址,库文件就基本搞定了。

//----------------------------------------------------------------------------------------------------------
//                                       设置范围
//----------------------------------------------------------------------------------------------------------

void Adafruit_VL6180X::writeReg16Bit(uint16_t reg, uint16_t value)
{
  _i2c->beginTransmission(_i2caddr);
  _i2c->write((uint8_t)(reg >> 8)); // reg high byte
  _i2c->write((uint8_t)(reg >> 0)); // reg low byte
  _i2c->write((uint8_t)(value >> 8)); // value high byte
  _i2c->write((uint8_t)(value >> 0)); // value low byte
  last_status = _i2c->endTransmission();
}

void Adafruit_VL6180X::writeReg(uint16_t reg, uint8_t value)
{
  _i2c->beginTransmission(_i2caddr);
  _i2c->write((uint8_t)(reg >> 8)); // reg high byte
  _i2c->write((uint8_t)(reg >> 0)); // reg low byte
  _i2c->write(value);
  last_status = _i2c->endTransmission();
}

uint8_t Adafruit_VL6180X::readReg(uint16_t reg)
{
  uint8_t value;

  _i2c->beginTransmission(_i2caddr);
  _i2c->write((uint8_t)(reg >> 8)); // reg high byte
  _i2c->write((uint8_t)(reg >> 0)); // reg low byte
  last_status = _i2c->endTransmission();

  _i2c->requestFrom(_i2caddr, (uint8_t)1);
  value = _i2c->read();

  return value;
}

void Adafruit_VL6180X::setScaling(uint8_t new_scaling)
{
  uint16_t const ScalerValues[] = {0, 253, 127, 84};
  uint8_t const DefaultCrosstalkValidHeight = 20; // default value of SYSRANGE__CROSSTALK_VALID_HEIGHT

  // do nothing if scaling value is invalid
  if (new_scaling < 1 || new_scaling > 3) { return; }

  scaling = new_scaling;
  writeReg16Bit(RANGE_SCALER, ScalerValues[scaling]);

  uint8_t ptp_offset = read8(VL6180X_REG_SYSRANGE_PART_TO_PART_RANGE_OFFSET);

  // apply scaling on part-to-part offset
  writeReg(VL6180X_REG_SYSRANGE_PART_TO_PART_RANGE_OFFSET, ptp_offset / scaling);

  // apply scaling on CrossTalkValidHeight
  writeReg(SYSRANGE_CROSSTALK_VALID_HEIGHT, DefaultCrosstalkValidHeight / scaling);

  // This function does not apply scaling to RANGE_IGNORE_VALID_HEIGHT.

  // enable early convergence estimate only at 1x scaling
  uint8_t rce = readReg(SYSRANGE_RANGE_CHECK_ENABLES);
  writeReg(SYSRANGE_RANGE_CHECK_ENABLES, (rce & 0xFE) | (scaling == 1));
}

arduino正常引用Adafruit_VL6180X.h,setup里面加上setscaling和readrange的结果记得 * 3

#include "esp_system.h"
#include "esp_task_wdt.h"
#include <SPI.h>

#include <Adafruit_VL6180X.h>

#define SCALINE 3

#define LOX1_ADDRESS 0x30

#define SHT_LOX1 25

// objects for the VL6180X
Adafruit_VL6180X lox1 = Adafruit_VL6180X();

Adafruit_VL6180X *sensors[] = {&lox1};

unsigned long lastPrintTime = 0;
const unsigned long printInterval = 500; // 100ms

void setID() {
  digitalWrite(SHT_LOX1, HIGH);

  // initing LOX1
  if (!lox1.begin()) {
    Serial.println(F("Failed to boot first VL6180X"));
    while (1);
  }
  lox1.setAddress(LOX1_ADDRESS);
  delay(10);
}

void readSensor(Adafruit_VL6180X &vl) {
  uint8_t addr = vl.getAddress();
  Serial.print(" ");
  Serial.print(addr);

  Serial.print("-");
  uint8_t range = vl.readRange();
  uint8_t status = vl.readRangeStatus();
  if (status == VL6180X_ERROR_NONE) {
    Serial.print(range * 3);
  }

  if  ((status >= VL6180X_ERROR_SYSERR_1) && (status <= VL6180X_ERROR_SYSERR_5)) {
    Serial.print("(System error)");
  }
  else if (status == VL6180X_ERROR_ECEFAIL) {
    Serial.print("(ECE failure)");
  }
  else if (status == VL6180X_ERROR_NOCONVERGE) {
    Serial.print("(No convergence)");
  }
  else if (status == VL6180X_ERROR_RANGEIGNORE) {
    Serial.print("(Ignoring range)");
  }
  else if (status == VL6180X_ERROR_SNR) {
    Serial.print("Signal/Noise error");
  }
  else if (status == VL6180X_ERROR_RAWUFLOW) {
    Serial.print("Raw reading underflow");
  }
  else if (status == VL6180X_ERROR_RAWOFLOW) {
    Serial.print("Raw reading overflow");
  }
  else if (status == VL6180X_ERROR_RANGEUFLOW) {
    Serial.print("Range reading underflow");
  }
  else if (status == VL6180X_ERROR_RANGEOFLOW) {
    Serial.print("Range reading overflow");
  }
}

void read_sensors() {
  Serial.print("Addr-Range");
  readSensor(lox1);
  Serial.println();
}

void setup() {
  Serial.begin(115200);
  
  pinMode(SHT_LOX1, OUTPUT);
  digitalWrite(SHT_LOX1, LOW);
  
  setID();
  Serial.println("System initialized.");
  lox1.setScaling(3);
}


void loop() {
  if (millis() - lastPrintTime > printInterval) {
    lastPrintTime = millis();
    read_sensors();
  }
}

实习加班有感!

### TOF050C传感器与STM32微控制器的实现 对于TOF050C传感器,在STM32微控制器上的应用主要依赖于I2C通信协议来完成数据交换。由于硬件I2C接口提供了更稳定和高效的性能,推荐使用HAL库中的硬件I2C功能来进行开发[^1]。 下面是一个简单的例子,展示了如何初始化硬件I2C并读取来自TOF050C的距离测量值: #### 初始化硬件I2C配置 ```c #include "stm32f7xx_hal.h" // 定义 I2C 设备地址 (假设为 0x52, 需要查阅具体器件手册确认) #define TOF050C_ADDRESS 0x52 I2C_HandleTypeDef hi2c1; void 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) { Error_Handler(); } } ``` 这段代码实现了对`I2C1`外设的基本设置,并启用了它作为主设备工作在7位寻址模式下。 #### 发送命令给TOF050C获取距离信息 为了从TOF050C获得测距结果,通常需要发送特定指令让其执行一次测量操作,之后再接收返回的数据包。这里给出一个简化版的例子用于说明目的;实际应用中可能还需要处理更多细节如错误检测等。 ```c uint8_t buffer[2]; float distance_cm; /** * @brief 向TOF050C发出启动单次测量请求. */ void Start_TOF050C_Measurement() { uint8_t cmd[] = {0x00}; // 假定这是触发测量的操作码 /* 使用 HAL 库函数向指定地址写入命令字节 */ HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, TOF050C_ADDRESS << 1, cmd, sizeof(cmd), HAL_MAX_DELAY); if(status != HAL_OK){ // 错误处理逻辑... } } /** * @brief 获取由TOF050C计算得到的目标物体到传感器之间的距离. */ void Get_TOF050C_Distance(float* pDistance) { /* 准备好缓冲区准备接受两个字节的结果 */ memset(buffer, 0, sizeof(buffer)); /* 执行读取动作 */ HAL_StatusTypeDef status = HAL_I2C_Master_Receive(&hi2c1, TOF050C_ADDRESS << 1, buffer, sizeof(buffer), HAL_MAX_DELAY); if(status == HAL_OK && buffer[0] >= 0 && buffer[1] >= 0){ *pDistance = ((buffer[0]<<8)|buffer[1]) / 256.0f; // 将接收到的数据转换成厘米单位表示的实际距离 }else{ // 处理异常情况... } } ``` 上述两段代码片段分别负责发起一次新的测量周期以及随后从中提取有效数值。需要注意的是这些API调用均假定了已经成功完成了前面提到过的I2C总线初始化过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值