所以我下午忙着处理我的编程作业,我似乎无法在下面的代码中解决这个问题。
练习是我需要通过按下按钮来切换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代码块没有意义,因为在这种情况下previousState
和currentState
将始终分别为1和0.
你们有什么提示吗?
顺便说一下,这个Arduino是一个Arduino Uno。
答案 0 :(得分:0)
我可以在你的代码中看到,按下按钮后你没有再关灯。如果你将if语句放入"而#34;那么它就会消失。声明。
答案 1 :(得分:0)
编辑:扩展了大部分内容,以解决评论中的其他问题。
您有两个名为currentState
的变量,一个全局变量和一个loop()
本地变量。全局一个定义在程序顶部附近,而不是在另一个函数内部。在loop()
中,您从这一行开始:
int currentState = digitalRead(pinButton);
因为你在那里包含了int
,所以这实际上创建了第二个变量,它恰好与全局变量同名。 currentState
的两个版本的值可以独立更改。在loop()
内,每次引用currentState
时,您都会引用本地副本。其他地方(如toggleLed
)将引用全局副本。如果您只想设置全局(这是我假设您打算这样做),那么您需要删除int
:
currentState = digitalRead(pinButton);
这将更改currentState
的全局版本,而不会创建新版本。
你没有进行任何去抖动,所以根据按钮的类型你可以看到零星的结果。有许多按钮和开关,打开和关闭之间的过渡可能会很嘈杂。去抖过滤掉那些噪音。 修改:toggleLed()
的延迟可能足以去抖,但通常在响应状态更改之前完成去抖动。
您应该初始化previousState
。由于它是全局的,并且全局变量具有静态存储持续时间,并且未进行其他初始化,系统将确保将其初始化为0.对于必须读取代码的任何人来说,显式初始化将更加明显,特别是如果他们不知道C的所有规则也是如此。此外,您可能希望将其初始化为LOW
而不是0
。这导致了我的最后一点。
digitalRead()
的返回值为HIGH
或LOW
。在Uno上,使用1
或0
代替HIGH
或LOW
可能并不重要,但我相信如果您移植代码可能会很重要对某些其他董事会。存在HIGH
和LOW
常量来隐藏详细信息,但只有在您始终如一地使用它们时才有帮助。有时候使用HIGH
和LOW
以及1
和0
其他时间只会让人们更难理解您的代码,如果您曾经这样做,可能会导致可移植性问题想在不同的电路板上试用你的代码。
答案 2 :(得分:0)
您可以通过读取定义为“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);
}
}