首页 文章

当我按下切换按钮时,如何以不同的方式闪烁LED?

提问于
浏览
0

我按照切换按钮试图使LED闪烁 . 如果我第一次按下第一个拨动开关,LED以5 Hz的频率闪烁,当我第二次按下切换按钮时,LED以6 Hz的频率闪烁,当我第三次按下时,LED熄灭 .

我尝试使用下面的程序,但它没有按我的意愿工作 .

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 7;     // the number of the pushbutton pin
const int ledPin =  6;      // the number of the LED pin
// variables will change:
int buttonState = 0;  

// variable for reading the pushbutton status
void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
   Serial.begin(9600); 
}

void loop() {
   int x=0; 
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  Serial.print(x);
  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH &&  x==0) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
    delay(1000);
    digitalWrite(ledPin, LOW);
     delay(1000);
    Serial.print(x);
  } else {
    // turn LED off:
    x = x+1;
  }
  if (buttonState == HIGH && x==1) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
    delay(2000);
    digitalWrite(ledPin, LOW); 
    delay(2000);
     Serial.print(x);

  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
    x = x+1;
  }
  if (buttonState == HIGH && x==2) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
    delay(3000);
    digitalWrite(ledPin, LOW);
    delay(3000);
     Serial.print(x);
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
    x = x+1;

  }
  if (buttonState == HIGH && x==3) {
    // turn LED off:
    digitalWrite(ledPin, LOW);
    x = 0;
  }
}

当我使用这个代码时,它适用于第一种情况,即LED在1000毫秒延迟时闪烁,但如果我切换开关它再次适用于第一个条件 . 如何使其执行第二个条件,即以2000毫秒的延迟闪烁?

4 回答

  • 0

    首先这是你的电路 . 我试过这个电路和代码并为我工作 . 我用中断检查按钮状态 . 毫安计算很简单 .

    频率= 1 /周期

    期间= Ton Toff

    6Hz = 1000毫斯/吨=> T = 166毫安

    166 = Ton Toff(%50占空比Ton = Toff)=> Ton = Toff = 83 millis

    enter image description here

    const int ledPin = 13;
    const int buttonPin = 2;
    int state = -1;
    bool willLightOn = false;
    
    unsigned long currentDelay = 0;
    unsigned long currentMillis = 0;
    unsigned long previousMillis = 0;
    
    void setup() {
      pinMode(ledPin, OUTPUT);
      pinMode(buttonPin, INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(buttonPin), changeState, FALLING);
    }
    
    void loop() {
      if(state % 3 == 0) { //6Hz 
        currentDelay = 83;
        willLightOn = true;
      } else if (state % 3 == 1) { //5Hz
        currentDelay = 100;
        willLightOn = true;
      } else if (state % 3 == 2) { //LED off
        currentDelay = 0;
        willLightOn = false;
        digitalWrite(ledPin, LOW);
      }
    
      currentMillis = millis();
        if (currentMillis - previousMillis >= currentDelay && willLightOn) {
            previousMillis = currentMillis;
            digitalWrite(ledPin, !digitalRead(ledPin));
        } 
    }
    
    void changeState() {
      state++;
    }
    
  • 0

    现在,您的逻辑在单个循环中检查x的值为3次 . 当x大于零时,下面的代码会切换光 . 按下按钮时,x的值会改变 .

    但是这里存在一个很大的问题:如果在处理器中发生了其他事情或者正在休眠时按下按钮(例如您想要使用的长延迟),则可能会忽略该按钮 . 因此,您可以更好地研究中断并使用它们实现此行为 .

    if (x > 0)
    {
        digitalWrite(ledPin, HIGH);
        delay(1000 * x);
        digitalWrite(ledPin, LOW);
    }
    if (buttonState == HIGH)
    {
        x++;
        if (x > 3)
            x = 0;
    }
    
  • 0

    您应该创建应用程序的全局状态 . 如果你以50hz / 60hz / off的速度闪烁,你可以记住这个状态 . 然后你可以使用开关来做正确的事情 .

    然后检查按钮是否按下并更改应用程序状态 .

    请参阅下面的示例:

    // constants won't change. They're used here to set pin numbers:
    const int buttonPin = 7;     // the number of the pushbutton pin
    const int ledPin =  6;      // the number of the LED pin
    // variables will change:
    int applicationState = 0;  
    bool lightOn = true;
    
    int currentDelay = 1000;
    
    unsigned long currentMillis = 0;
    unsigned long previousMillis = 0;
    
    // variable for reading the pushbutton status
    void setup() {
      // initialize the LED pin as an output:
      pinMode(ledPin, OUTPUT);
      // initialize the pushbutton pin as an input:
      pinMode(buttonPin, INPUT);
    }
    
    void loop() {
    
        if (digitalRead(buttonPin) == HIGH) {
            applicationState++;
            if(applicationState >= 3) {
                applicationState = 0;
            }
            delay(100);
        }
    
        switch(applicationState){
            case 0:
                currentDelay = 1000;
                lightOn = true;
                break;
            case 1:
                currentDelay = 2000;
                lightOn = true;
                break;
            case 2:
                digitalWrite(ledPin, LOW);
                lightOn = false;
                break;
        }
    
    
        currentMillis = millis();
        if (currentMillis - previousMillis >= currentDelay && lightOn) {
            previousMillis = currentMillis;
            digitalWrite(ledPin, !digitalRead(ledPin));
        }      
    }
    

    我希望你理解我试图用示例代码说的和演示 .

  • 0

    您的代码无法运行:

    • 您需要检查按钮状态是否发生变化,检测何时有边缘 . 并确保只检测一次边缘 .

    • 您必须重复循环闪烁直到按下按钮,然后您才能更改频率 .

    • 您必须在睡觉时检查按钮,否则当您按下按钮时程序无法识别 .

    要使其工作,您必须更改完整的程序 .

    #define BLINK_SLEEP_TIME <some value> // insert value for 16.6666ms
    
    //return 1 after a positive edge
    bool button_read(void)
    {
      static bool lastState=1; //set this to 1, so that a pressed button at startup does not trigger a instant reaction
      bool state = digitalRead(buttonPin);
      if(state != lastState)
        {
          state=lastState;
          return state;
        }
     return 0;
    }
    
    //Blink the LED with a given period, till button is pressed
    //Times are in x*16.666ms or x/60Hz
    //At least one time should be more than 0
    void blink(uint8_t ontime, uint8_t offtime) 
    {
      while(1)
      {
        for(uint8_t i=0;i<ontime;i++)
        {
          led_setOn();
          delay(BLINK_SLEEP_TIME);
          if(button_read())
          {
            return;
          }
        }
        for(uint8_t i=0;i<offtime;i++)
        {
          led_setOff();
          delay(BLINK_SLEEP_TIME);
          if(button_read())
          {
            return;
          }
        }
      }
    }
    
    const uint8_t time_table[][]=
    {
      {0,50},//LED is off
      {6,6}, //LED blinks with 5Hz, 60Hz/2/6=5Hz
      {5,5}, //LED blinks with 6Hz, 60Hz/2/5=6Hz
    }
    
    void endless(void)
    {
      uint8_t i=0;
      for(;;)
        {
          i++;
          if(i>2)
          {
            i=0;
          }
          blink(time_table[i][0],time_table[i][1]);
        }
    }
    

    更好的方法是使用硬件PWM模块并在按钮边缘之后更改值 .

相关问题