-2

我想只用一个按钮来更换 LED。第一次单击按钮 - 红色 LED 亮起,第二次 - 红色熄灭,绿色亮起,第三次 - 绿色熄灭,黄色亮起,第四次 - 再次以红色开始...

首先,我尝试一键打开红色,然后关闭...

int red = 8;
int button = 13;
int buttonstate = 0;
bool redOn = false;


void setup(){
  pinMode(red,OUTPUT);
  pinMode(button,INPUT);
}

void loop(){
  
 buttonstate = digitalRead(button);
    

if (buttonstate == 1){
  if (redOn == false){
    digitalWrite(red,HIGH); 
    redOn = true;
        }
  else{
    digitalWrite(red,LOW);
    redOn = false;
    }
}
}

这样可行。然后我尝试添加另外两个 LED ..

int red = 8;
int yellow = 3;
int green = 6;
int button = 13;
int buttonstate = 0;
bool redOn = false;
bool yellowOn = false;
bool greenOn = false;


void setup(){
  pinMode(red,OUTPUT);
  pinMode(yellow,OUTPUT);
  pinMode(green,OUTPUT);
  pinMode(button,INPUT);
}

void loop(){
  
 buttonstate = digitalRead(button);
    

if (buttonstate == 1){
  if (redOn == false){
    digitalWrite(red,HIGH); 
    redOn = true;
        }
  else if (redOn == true && greenOn == false && yellowOn == false) {
    digitalWrite(red,LOW);
    redOn = false;
    digitalWrite(green,HIGH);
    greenOn = true;
    }
  else if (redOn == false && greenOn == true && yellowOn == false) {
    digitalWrite(green,LOW);
    greenOn = false;
    digitalWrite(yellow,HIGH);
    yellowOn = true;
    }
   else if (redOn == false && greenOn == false && yellowOn == true) {
    digitalWrite(yellow,LOW);
    yellowOn = false;
    }
  
  else{
      redOn = false;
      greenOn = false;
      yellowOn = false;
}
}
}

那是行不通的。有人知道如何实现这一点吗?

4

2 回答 2

0

有两点需要考虑:

首先,Arduino 的处理器比人类快得多,这意味着即使您短时间按下按钮,您的代码也会快速获得它。您可以通过在 loop() 函数的末尾添加一个小的延迟来解决这个问题,例如:

delay(1000)

或者通过设置一个包含按钮先前状态的变量并根据状态的变化(从0到1)进行操作

第二件事是你开始先单独检查红灯:

if (redOn == false){
    digitalWrite(red,HIGH); 
    redOn = true;
        }

当您在此处将 redOn 设置为 false 时,此 if 语句将在绿灯亮起时有效

else if (redOn == true && greenOn == false && yellowOn == false) {
    digitalWrite(red,LOW);
    **redOn = false;**
    digitalWrite(green,HIGH);
    greenOn = true;
    }

因此,在您关闭红灯并打开绿灯并按下按钮后,红灯将亮起,绿灯将保持亮起,因为您将执行第一个 if 语句,您对绿灯和黄灯:

if (redOn == false){
    digitalWrite(red,HIGH); 
    redOn = true;
        }

此外,您永远不会达到黄灯亮起的状态。因此,您可以通过替换将第一个 if 语句修改为像其他 if 语句一样更具体

if (redOn == false){
    digitalWrite(red,HIGH); 
    redOn = true;
        }

if (!greenOn && !yellowOn){
    digitalWrite(red,HIGH); 
    redOn = true;
        }

删除最后一个 else,因为您不希望它们再次全部关闭

else{
      redOn = false;
      greenOn = false;
      yellowOn = false;
}

旁注:在 if 语句中使用布尔变量时,您不必使用“==”比较器,只需使用布尔变量

利用:

if(redOn)

代替:

if(redOn == true)

并使用:

if(!redOn)

代替:

if(redOn == false)

希望我的回答对你有帮助:)

此致。

于 2022-02-05T01:22:03.743 回答
-1

您应该首先检测按钮是否在遇到灯开关之前发生了变化:

int buttonState = 0;
void loop()
{
    int bs = digitalRead(button);
    if(bs != buttonState)
    {
        // the button state changed!
        buttonState = bs;

        if(bs == 1)
        {
            // ... AND has been pressed
            // (if you want to switch on releasing, compare against 0)
            // -> switch now your LED outputs appropriately
        }
    }
}

不过,从您的代码中,我不能完全确定所需的 LED 照明模式应该是什么样子,所以跳过这部分(直到您提供准确的描述)。

根据您的评论编辑:

有几种方法可以实现这种闪烁模式;使用您的布尔变量,您可以这样做(仅考虑布尔值,需要相应地设置信号):

if(redOn)
{
    redOn = false;
    greenOn = true;
}
else if(greenOn)
{
    greenOn = false;
    yellowOn = true;
}
else if(yellowOn)
{
    yellowOn = false;
}
else
{
    redOn = true;
}

上面的代码在黄色亮起后会留下一个暗相;如果你不想要一个,你可以简单地拥有:

else if(greenOn)
{
    // ...
}
else
{
    yellowOn = false; // actually don't need the variable, just set the GPIO
    redOn = true;
}

另一个变体是有一个计数器:

unsigned int ledState = 0;
void loop()
{
    if(buttonDetected) // see above
    {
        digitalWrite(red,    ledState == 0 ? HIGH : LOW);
        digitalWrite(green,  ledState == 1 ? HIGH : LOW);
        digitalWrite(yellow, ledState == 2 ? HIGH : LOW);
        ledState = (ledState + 1) % 3; // or 4, if you want a dark phase added!
    }
}
于 2022-02-02T17:30:26.230 回答