我需要在不知道编译时库使用的gpio引脚的情况下使用OneWire库(与DallasTemperature库一起使用)。在该库的所有示例中,引脚都是硬编码的。我试图使用指针来解决此问题,但是我的测试代码(如下)不起作用。

OneWire * oneWire;
DallasTemperature * sensors;

void setup(void) {
    oneWire = &OneWire( 2 );
    sensors = &DallasTemperature( oneWire );


    sensors->begin();
}


省略了循环主体,但使用了与setup()中类似的对传感器对象的取消引用调用。我的示例代码在此测试中使用了硬编码2,但是生产代码将在setup()中动态提取该值。

我在这里做错了什么?还是这根本不可能?

最佳答案

您可以使用“虚拟”引脚值(例如:Pin = 13)设置一个oneWire实例。

在运行时,在setup()中将其更改为其他值。

OneWire oneWire(13); // Pin=13 (we'll not actually use pin13)
DallasTemperature sensors(&oneWire);

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

  // Runtime:
  //  Change PIN value associated with OneWire
  //  bus - From now on Pin 4 will be used
  oneWire.begin(4);

  sensors.begin();
}


编辑以澄清梵天恐惧症的评论:


  我们确定该库不会修改GPIO“虚拟”引脚的状态吗?即,引用的图钉是否可以被其他东西使用? –梵天恐惧


OneWire类的构造方法是
    OneWire(uint8_t引脚){begin(pin); }
因此调用了“ OneWire :: begin(pin)”,并在begin(pin)中调用了
    pinMode(pin, INPUT);

注意:
   Arduino引脚默认配置为输入(高阻抗状态)

因此,您可以将您的应用程序无法使用的图钉设置为“虚拟”
使用。例如,如果您没有连接到D13引脚(许多Arduino板上的BUILTIN LED):

OneWire oneWire(D13);


或设置您实际使用的PIN,但在setup()中将其设置为所需的任何值:

OneWire oneWire(D5);
...
setup(){
    pinMode(D5, OUTPUT);
}


请注意:
根据所使用的板/架构(Arduino-AVR,ESP32等),某些引脚可能用于板专用硬件。例如,PIN 0,1在许多Arduino开发板上都用作Serial:(RX),(TX)
在我首先提供的示例代码中,我使用了PIN = 1
这与SET(TX)和INPUT相同。这不是一件聪明的事情。
但是在setup()中有一个对“ Serial.begin(115200);”的调用。因此PIN 1会重置为Serial.begin()所需的任何内容(可能是OUTPUT ...)。


  另一种选择是在OneWire库中添加一条线...


上面建议的代码是所需的解决方法,因为OneWire类构造函数将PIN作为参数。
这意味着下面的代码无法编译:

OneWire oneWire(); // NO PIN
void setup(void)
    {
    Serial.begin(115200);
    oneWire.begin(2);
    .....
    }


您可以在OneWire lib'e头文件中找到构造函数定义(... Arduino / libraries / OneWire / OneWire.h-我拥有的版本中的第72行)

如果在该行上添加重载构造函数以不接受任何参数的行:

OneWire(){; }

比上面的代码可以编译,并且一切正常,不需要虚拟引脚。
如果您采用这种方式,我强烈建议您不要更改开发计算机中安装的OneWire lib。
将其复制到项目的子目录中,然后在其中进行修改并包含修改后的内容
项目中的版本。
或派生gitHub存储库并编辑代码。

关于c++ - OneWire arduino库,带有引脚的最新定义,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49119236/

10-11 18:48