【问题标题】:LED from Arduino board doesn't switch off using the click of a buttonArduino 板的 LED 不会通过单击按钮关闭
【发布时间】:2017-10-28 16:59:09
【问题描述】:

所以我下午一直忙于处理我的编程作业,我似乎无法解决下面找到的代码中的问题。

练习是我需要通过按下按钮来切换 LED。在我的代码中,当我单击按钮时 LED 会亮起,但当我再次单击按钮时它不会关闭。

int pinButton = 5;
int LED = 10;
int currentState;
int previousState;

void setup() {
  Serial.begin(9600);
  pinMode(pinButton, INPUT);
  pinMode(LED, OUTPUT);
}

void toggleLed(){
  if (previousState == 1 && currentState == 0){

    digitalWrite(LED, HIGH);
    Serial.println(currentState);
    Serial.println(previousState);
    delay(100);

  } else {

    digitalWrite(LED, LOW);
    Serial.println(currentState);
    Serial.println(previousState);
    delay(100);

  }
}

void loop() {

int currentState = digitalRead(pinButton);

if (currentState == 0 && previousState == 1) {

  Serial.println("Knop is losgelaten");

  toggleLed();

} 

previousState = currentState;

}

我猜在第一个 if 语句中 else 代码块没有意义,因为在这种情况下 previousStatecurrentState 将始终分别为 1 和 0。

你们有什么建议吗?

顺便说一句,这个 Arduino 是一个 Arduino Uno。

【问题讨论】:

    标签: button arduino arduino-uno led


    【解决方案1】:

    我可以在您的代码中看到,您在按下按钮后没有再次关闭灯。如果您将 if 语句放入“while”语句中,它就会消失。

    【讨论】:

    • 不幸的是,将其放入“while”语句中是行不通的。
    【解决方案2】:

    编辑:扩展了大多数点以解决 cmets 中的其他问题。

    1. 您有两个名为 currentState 的不同变量,一个是全局变量,一个是 loop() 的局部变量。全局的定义在程序顶部附近,而不是在另一个函数内部。在loop() 中,您从这一行开始:

      int currentState = digitalRead(pinButton);

      因为您已经在其中包含了int,这实际上创建了第二个变量,它恰好与全局变量同名。 currentState 的两个版本的值可以独立改变。在loop() 中,每次引用currentState 时,都会引用本地副本。其他任何地方(如toggleLed)都将引用全局副本。如果您只想设置全局设置(我假设您打算这样做),那么您需要删除int

      currentState = digitalRead(pinButton);

      这将更改currentState 的全局版本,而不创建新版本。

    2. 您没有进行任何去抖动,因此您可能会看到零星的结果,具体取决于按钮的类型。由于有许多按钮和开关,打开和关闭之间的转换可能会很吵。去抖动过滤掉了噪音。 编辑toggleLed() 中的延迟可能足以消除抖动,但通常在响应状态更改之前完成去抖动。

    3. 您可能应该初始化previousState。由于它是一个全局变量,并且全局变量具有静态存储持续时间,并且不会以其他方式初始化,因此系统将确保将其初始化为 0。对于必须阅读代码的任何人来说,显式初始化会更加明显,尤其是如果他们不知道C的所有规则也是如此。此外,您可能希望将其初始化为 LOW 而不是 0。这引出了我的最后一点。

    4. digitalRead() 的返回值为HIGHLOW。在 Uno 上,使用 10 而不是 HIGHLOW 可能并不重要,但我相信如果您将代码移植到某些其他板上可能会很重要。 HIGHLOW 常量的存在是为了隐藏细节,但这只有在你始终如一地使用它们时才有帮助。有时使用HIGHLOW,有时使用10 只会让人们更难理解你的代码,如果你想在不同的平台上尝试你的代码,它可能会导致可移植性问题董事会。

    【讨论】:

    • 感谢 Adrion 的详尽回复。但是,在您建议的某些点上,我不同意您的意见。 previousState 在代码的最顶部初始化,对吗?在 Uno 上,HIGH 或 LOW 无关紧要,我们也可以使用 1 和 0。你能多解释一下你的第一个陈述是什么意思吗?我对这一切还是有点陌生​​。我听说过本地整数和全局整数,但我不明白它是如何工作的。非常感谢您。
    • 我已扩展答案以解决您的其他问题。
    【解决方案3】:

    您可以通过读取定义为“LED”的引脚状态来实现这一点。如果它处于 HIGH 状态,则将其转为 LOW,反之亦然。

    void toggleLed(){
    // check if pin state is low, turn it on
    if (digitalRead(LED) == 0)
    digitalWrite(LED, HIGH);
    } else {
    digitalWrite(LED, LOW);
     }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      • 2011-05-22
      • 2014-07-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多