在 Arduino 中读取传感器时按下按钮

Push a button while reading sensor in Arduino

我一直在做一个小温度计项目来学习 Arduino,有一件烦人的事情我不知道如何解决。

我有两个按钮来设置最低和最高温度,当我按下按钮时,它应该设置显示的最低和最高温度。 问题是有时(50% 的时间)当我在读取温度传感器的过程中按下按钮时,按钮不起作用。我按下它,但未设置 Min/Max 温度,因为 Arduino 卡在读取温度传感器中。

有什么技巧可以解决这种问题吗?例如,如果我有一个用于输入数字的键盘,我想我也会遇到同样的问题,但它不是 "user-friendly"。

这是我使用的部分代码的示例:

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>

//variables declaration...

void setup() {
  sensors.begin();
  sensors.getAddress(sensor1, 0);
  pinMode(buzzer, OUTPUT);
  pinMode(btBuzzer, INPUT);
  pinMode(btMin, INPUT);
  pinMode(btMax, INPUT);
}

void loop() {
  readButtons();

  playBuzzer();

  readTemperature();

  printDisplay();

  delay(150);
}

void readButtons(){
  if(digitalRead(btBuzzer)){
    buzzerOn = !buzzerOn;
  }

  if(digitalRead(btMin)){
    if(tempMin == 69)
      tempMin = 59;
    else
      tempMin++;
  }

  if(digitalRead(btMax)){
    if(tempMax == 75)
      tempMax = 63;
    else
      tempMax++;
  }
}

void readTemperature(){
  sensors.requestTemperatures();
  temperature = sensors.getTempC(sensor1);
}

//lots of other methods

学习编码的一些最佳方法存在于如何回答这个问题中。 我想建议做的是尝试为您的代码计时。请记住 loop() 正在创建一个重复结构。因此,我们可以说计算机每次循环 运行 需要多长时间。当我们有一个像按下按钮这样的中断时,它如何影响循环中的迭代,它是否取决于如何让处理器休息(延迟)。

延迟是必需的,以便不执行所谓的 "spin" 处理器(让处理器尽可能快地完成大量工作以完成任何事情)。但是,请注意代码如何不考虑更改我们延迟多长时间完成的工作? 现在让我们想象一下处理器实际上可以非常快地多次执行该循环。请记住,仅 150 毫秒的延迟时间并不长。因此,也许按下一个按钮就足以将 tempMin 快速连续地从 59 设置为 69 并循环多次,而不是一次只增加一个数字。 您在这里拥有的是学习调试的机会。第一个技巧是确定循环 运行ning 是太快还是太慢;您是否获得了所需的功能,最后是否可以在知道问题发生得太快或太慢后重新提出问题。 现在,我建议看看全局变量和有限状态机(即,如果你处于按下按钮的状态,在你完成你的状态之前不要接受任何进一步的按钮按下,并且只在已知方法)。

正如其他人在这里指出的那样,按下按钮可能不会在您使用 digitalRead(btBuzzer) 查询 pin 的同时发生。这种类型的问题就是所谓的 "interrupts" 的发明目的,它允许您响应在您不监视感兴趣的引脚时可能发生的事件。

例如,Arduino UNO R3 允许在引脚 2 和 3 上进行中断。您应该查找 attachInterrupt() 的参考资料。处理器将在您注册的事件("interrupt")中执行回调函数(例如,引脚 2 上的电压从低变为高)。这意味着您将不再需要从主循环中调用 readButtons() 函数。