我需要在不知道编译时库使用的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/