OneWire arduino库具有引脚的后期定义

时间:2018-03-05 20:49:54

标签: c++ pointers arduino

我需要在上下文中使用OneWire库(使用DallasTemperature库),在编译时我不会知道库使用的gpio引脚。在该库的所有示例中,引脚都是硬编码的。我试图使用指针解决这个问题,但我的测试代码(下面)不起作用。

OneWire * oneWire; 
DallasTemperature * sensors;

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


    sensors->begin(); 
}

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

我在这里做错了什么?或者这根本不可能?

2 个答案:

答案 0 :(得分:1)

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

在运行时,在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();
}

编辑以澄清Brahma Fear的评论:

  

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

OneWire类的构造函数是     OneWire(uint8_t pin){begin(pin); } 因此,调用“OneWire :: begin(pin)”并进入开始(引脚),调用
    pinMode(pin, INPUT);

注意:    默认情况下,Arduino引脚配置为输入(高阻态)

所以,你可以设置一个你的应用程序不会使用的主板的“虚拟” 使用。例如,如果您没有连接到引脚D13(许多Arduino板上的BUILTIN LED):

OneWire oneWire(D13);

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

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

请注意:
根据您使用的BOARD / Architecture(Arduino-AVR,ESP32,...),某些引脚可用于特定于板的硬件。例如,PIN 0,1在许多Arduino板中用作Serial:(RX),(TX)
在我首先提供的示例代码中,我使用了PIN = 1
这与作为INPUT的SET(TX)相同。不是一件聪明的事情。 但是在setup()中有一个对“Serial.begin(115200);”的调用。所以PIN 1被重置为Serial.begin()需要的东西(可能是OUTPUT ...)。

  

另一种选择是在OneWire lib中添加一行......

上面提出的代码是一个需要的解决方法,因为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 repo并编辑代码。

答案 1 :(得分:0)

我想简单的选择是: 您声明一个全局指针并使用new运算符在堆上创建您的实例。除非绝对必要,否则许多人不鼓励这样做。 如果你关心原因,你会发现很多关于在Arduino中使用new的讨论。

SomeClass * pMyInstance; 

void setup(void) {
    pMyInstance = new SomeClass(1);
}

另一种选择是将特定的初始化从设置转换为循环或多或少的处理循环作为您的全局环境。

void setup(void) {
}
void loop(void){
   SomeClass myInstance(1);
   while(1){
   // do the loopy stuff in here
   }

}

我确定有更多更好的解决方案。我的C / C ++ / Arduino非常生疏;)