Как сделать, чтобы светодиоды загорались один за другим в зависимости от того, как долго кнопка была нажата и удерживалась

В своем проекте я пытаюсь создать дисплей таймера со светодиодами, основанный на том, как долго кнопка была нажата и удерживалась.

Всего 8 светодиодов, при нажатии кнопки переключения загорается 1-й светодиод; продолжайте удерживать/нажимать кнопку, 2-й светодиод загорается через 1 секунду, 3-й светодиод загорается через 2 секунды и так далее. Таким образом, через 7 секунд после нажатия и удерживания кнопки загорятся все 8 светодиодов. Если в любой момент отпустить кнопку, все светодиоды погаснут.

Что-то не так с моим кодом, кажется, что таймер не работает (сохраняет время, когда кнопка была нажата) и вычисляет разницу во времени ("текущее время" - "время, когда кнопка нажата"), чтобы загоралась светодиод.

Мои коды:

 int current;
 long millis_held;      
 long prev_secs_held;
 unsigned long firstTime;     
 byte previous = LOW;    

 const int buttonPin = 13;

 void setup() {
 pinMode(buttonPin, INPUT);
 pinMode(2,OUTPUT) ;
 pinMode(3,OUTPUT) ;
 pinMode(4,OUTPUT) ;
 }

 void loop() {
 current = digitalRead(buttonPin);

 if (current == HIGH && previous == LOW) { 
 firstTime = millis();
 digitalWrite(2, HIGH);

 millis_held = (millis() - firstTime);

 if (millis_held >= 1000 && firstTime <2000){
 digitalWrite(3, HIGH);
 }

  if (millis_held >= 2000){
  digitalWrite(4, HIGH);
 }
 }

 else {
 digitalWrite(2, LOW);
 digitalWrite(3, LOW);
 digitalWrite(4, LOW);
 }
 }

Надеюсь, вы, ребята, можете помочь, большое спасибо.

, 👍2

Обсуждение

Мы не сможем вам помочь, не видя вашего кода., @StarCat

если я слишком долго ждал, прежде чем начать нажатие 1-й кнопки, то же самое происходит, когда все светодиоды загораются вместе... это указывает на то, что вы не ждете нажатия кнопки перед запуском таймера, @jsotola

Спасибо за ваш ответ, я добавил коды, над которыми я сейчас работаю, для вашей справки. Посмотрите, как вы можете помочь. Спасибо!, @Kelvin Ng

ваш код имеет неправильный отступ ... что затрудняет чтение кода и приводит к ошибкам во время разработки кода, @jsotola


2 ответа


Лучший ответ:

3

В вашем коде несколько ошибок.

В цикле первое условие if может оказаться не таким, как вы предполагали. Вы проверяете previous == low, но никогда не устанавливаете для предыдущего значение high. Поэтому эту проверку можно полностью убрать или немного изменить структуру кода и добавить previous = high.

Во-вторых, этот if тоже ошибочен:

if (millis_held >= 1000 && firstTime <2000){
    digitalWrite(3, HIGH);
}

Вы проверяете firstTime < 2000, что означает, что вам нужно нажать кнопку в течение 2 секунд после включения Arduino, иначе этот код не запустится.

Наконец, для запуска вам, вероятно, нужно установить firstTime = millis() только один раз, когда вы нажимаете кнопку, а не каждый раз, когда запускается loop() после этого, пока вы держите кнопку нажатой. Вам нужно будет переместить скобку в строке 32 в строку 22, то есть чуть выше else на строку выше millis_held = (millis() - firstTime); и затем добавьте previous = HIGH; в первый if.

Я предоставляю вам исправить свой код, так как это было бы хорошей практикой, чтобы получить некоторое представление о нем. Удачного кодирования!

Наконец вам все еще нужно добавить последние 5 светодиодов, но как только первые несколько заработают, все будет в порядке.

,

Большое спасибо за ваш совет, я думаю, что понял его, дайте мне немного времени, чтобы переварить и поработать над этим. Я вернусь к вам скоро. Ценю вашу помощь!!!, @Kelvin Ng


3

Большое спасибо Ananas_hoi, я наконец-то смог заставить свой код работать должным образом!! Следующий код показывает, что 4 светодиода загораются один за другим каждую секунду, когда кнопка нажата и удерживается:

int current;
long millis_held;      
unsigned long firstTime; 
byte previous = LOW;         

const int buttonPin = 13;

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(2,OUTPUT) ;  
  pinMode(3,OUTPUT) ;
  pinMode(4,OUTPUT) ;
  pinMode(5,OUTPUT) ; 
}

void loop() {
  current = digitalRead(buttonPin); 

  if (current == HIGH && previous == LOW) { 
     firstTime = millis();
     digitalWrite(2, HIGH);
     previous = HIGH;
  }
 
  millis_held = (millis() - firstTime);

  if (millis_held >= 1000 && previous == HIGH) {
      digitalWrite(3, HIGH);
     }
 
  if (millis_held >= 2000 && previous == HIGH) {
      digitalWrite(4, HIGH);
     }
 
  if (millis_held >= 3000 && previous == HIGH) {
      digitalWrite(5, HIGH);
     }


  if (current == LOW) {
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  previous = LOW;
 }
}
,

Спасибо за публикацию решения. (проголосовали.) Многие новые пользователи так не отдают. Таким образом, другие могут учиться на вашем проекте. Отступ в вашем ответе намного лучше, чем в исходном вопросе, но все же нуждается в некоторой очистке. Не могли бы вы сделать отступ в коде внутри скобок оператора if (current == low)? И для новых читателей было бы лучше, если бы вы убрали отступ исходного вопроса. Читать как есть довольно сложно., @Duncan C