Arduino下ESP32同时使用硬件I2C和软件I2C总线(软件I2C驱动VL53L0X为例)

由于ESP32-C3只有一条硬件I2C总线,然而我的程序中需要同时要两条I2C总线,所以不得不考虑同时使用硬件I2C和软件I2C。硬件I2C作为Slave用于与上位机通信,效率比较高,代码也简单,本篇不做详细介绍。本篇重点介绍软件I2C方式驱动VL53L0X,其他I2C设备可参考。

前面有篇文章写到了I2C总线驱动VL53L0X,这篇我们再深入点。

本文的I2C均是Wire模式使用。软件I2C只能作为master使用。

本人水平有限,以下骚操作仅做参考。

一、软件I2C总线库

arduino下搜索SoftI2CMaster能搜索到一个库:

其在github的链接地址如下:

GitHub - felias-fogg/SoftI2CMaster: Software I2C Arduino librarySoftware I2C Arduino library. Contribute to felias-fogg/SoftI2CMaster development by creating an account on GitHub.icon-default.png?t=N7T8https://github.com/felias-fogg/SoftI2CMaster为啥贴出来呢?因为这个库是为AVR写的,不是为ESP32写的,要使用的话必须要去github找找详细点的信息以便改造。

二、Wire这个名称

我的程序需要同时使用硬件I2C和软件I2C,所以我的头文件里有:

#include "Wire.h"
#include <SoftWire.h>

这肯定是有问题的。

打开SoftWire.h文件,第83行:

extern SoftWire Wire;

第248行:

SoftWire Wire = SoftWire();

这两行把Wire这个名称直接与SoftWire进行了绑定,甚至帮你定义好了一个叫做Wire的SoftWire对象。

写这个代码的人的本意,是你用软件I2C了,那你肯定不会用硬件I2C,所以不会在头文件中include "Wire.h"。但是他怎么没想到我会硬件和软件总线一起用呢。。。

这个Wire名称在"Wire.h"中被写成了第一条(0号)硬件I2C的对象,所以在SoftI2C中,我们不能再使用这个名称了。

处理方法很简单,直接把第83行和第248行注释掉。后面我们可以在自己的代码中去定义SoftI2C的名称。

三、增加适配文件

做完上面的工作,就可以编译了。但是肯定不会成功的,不然就没有后文了。

Arduino编译提示:

 #error "Not an AVR MCU! Use 'SlowSoftI2CMaster' library instead of 'SoftI2CMaster'!"
意思然你不是AVR CPU,得用另外一个库SlowSoftI2CMaster!

好吧。打开前面安装的SoftI2CMaster库目录,找遍了也没有这个库的cpp和h文件。

既然作者这么提示了,还是看看这个库的README.md文件,在文件最后发现线索:

去这两个链接地址,把SlowSoftI2CMaster.cpp、SlowSoftI2CMaster.h、SlowSoftWire.cpp和SlowSoftWire.h下载下来,放入SoftI2CMaster库目录的src文件夹中。

打开这几个源文件仔细看,并没有发现引用Wire.h,也没有直接使用Wire这个对象,那么就可以尝试测试了。

四、编码测试总线部分

头文件部分,同时包含硬件I2C的头文件"Wire.h"和软件I2C的头文件"SlowSoftWire.h"。

#include "Wire.h"
#include <VL53L0X.h>

//#include <SoftWire.h>
#include <SlowSoftWire.h>


SlowSoftWire Wire2 = SlowSoftWire(6, 7);
Wire2.begin();

基本就可以了。

注意软件I2C的引脚只能在SlowSoftWire(6, 7)指定,不能在begin()函数中指定了。

这时才发现,修改SoftWire.h文件是做了个无用功,这个文件并没有被用到。不过通过这个过程我们也知道了该怎么做。

五、适配VL53L0X

1.头文件VL53L0X.h中

第5行:

#include <Wire.h>
修改为:
#include <SlowSoftWire.h>

第103和104行,把TwoWire类型修改为SlowSoftWire:

    void setBus(TwoWire * bus) { this->bus = bus; }
    TwoWire * getBus() { return bus; }
修改为:
    void setBus(SlowSoftWire * bus) { this->bus = bus; }
    SlowSoftWire * getBus() { return bus; }   

第159行,把TwoWire类型修改为SlowSoftWire:

    TwoWire * bus;
修改为:
    SlowSoftWire * bus;

2.源代码VL53L0X.cpp中

第7行:

#include <Wire.h>
修改为:
#include <SlowSoftWire.h>

第38行,构造函数中,把写死的Wire(硬件0号总线)干掉,赋值NULL:

VL53L0X::VL53L0X()
  : bus(&Wire)
  , address(ADDRESS_DEFAULT)
  , io_timeout(0) // no timeout
  , did_timeout(false)
{
}

修改为:
VL53L0X::VL53L0X()
  : bus(NULL)
  , address(ADDRESS_DEFAULT)
  , io_timeout(0) // no timeout
  , did_timeout(false)
{
}

六、编码测试VL53L0X部分

代码:

#include "Wire.h"
#include <VL53L0X.h>

//#include <SoftWire.h>
#include <SlowSoftWire.h>

VL53L0X sensor;


SlowSoftWire Wire2 = SlowSoftWire(6, 7);

void setup() {
  Serial.begin(115200);


  Wire2.begin();
  sensor.setBus(&Wire2);


  #if defined LONG_RANGE
    // lower the return signal rate limit (default is 0.25 MCPS)
    sensor.setSignalRateLimit(0.1);
    // increase laser pulse periods (defaults are 14 and 10 PCLKs)
    sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
    sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
  #endif

  #if defined HIGH_SPEED
    // reduce timing budget to 20 ms (default is about 33 ms)
    sensor.setMeasurementTimingBudget(20000);
  #elif defined HIGH_ACCURACY
    // increase timing budget to 200 ms
    sensor.setMeasurementTimingBudget(200000);
  #endif

  sensor.setTimeout(500);
  while (!sensor.init())
  {
    Serial.println("Failed to detect and initialize sensor!");
    delay(2000);
  }
}

void loop() {
  Serial.println("start measure...");
  Serial.print(sensor.readRangeSingleMillimeters());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  delay(1000);
  Serial.println();

}

注意我们前面把VL53L0X源码中的bus(&Wire)给改成了bus(NULL),sensor对象初始化时bus对象是空的,所以我们这里要用sensor.setBus(&Wire2);将传感器的总线绑定到Wire2,也就是软件I2C总线上。

硬件I2C的使用代码部分我就没贴了,正常使用Wire.h中定义Wire就行了。

软件I2C驱动其他I2C设备可参考移植。

OK,到此为止,看到串口在不断输出VL53L0X的测量结果时,这个移植工作就算完成了。

  • 17
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值