Моргаем светодиодом n-раз без Delay

Alex-ua04
Offline
Зарегистрирован: 28.11.2015

Приветствую всех. Нужна подсказка. Суть такова. При нажатии кнопки (без фиксаци) светодиоды должны моргнуть  n-раз (указано через переменную byte). При нажатии и удержании кнопки светодиоды моргают пока удерживается кнопка. Все это надо без delay. Перепробовал уже кучу вариантов, прочитал и перечитал множество статей на форуме и и в нете. Не работает. Вернее при постоянном нажатии моргает как и задумано, а от кратковременного нет. Пытался использовать оператор for, безрезультатно. Уже и пробовал библиотеку #include <TimeHelpers.h>  не работает в операторе for. Подскажите или лучше укажите что читать.

Вот рабочий скетч но с Delay; /*на лишниее переменые в заголовке не обращайте внимание это были наработки                                                  для продолжения написания скетча, но завис на этих 2 моргулях*/

 

#include <Bounce.h>
#define BUTTON1 8
#define BUTTON2 9
#define LED1 2
#define LED2 3
#define pressed_long 500 // долговременное нажатие = 0.5 секунды
 
boolean ledState = LOW; // состояние светодиода
byte buttonState1 = 0;
byte buttonState2 = 0;
byte k=2;

long interval = 600;           // интервал между включение/выключением светодиода (1 секунда)
long OnTime = 250; // длительность свечения светодиода (в миллисекундах)
long OffTime = 750; // светодиод не горит (в миллисекундах)
 
unsigned long previousMillis1 = 0;        // храним время последнего переключения светодиода
unsigned long pressed_moment; // момент нажатия кнопки
unsigned long previousMillis = 0; 

Bounce bouncer1 = Bounce( BUTTON1, 8);
Bounce bouncer2 = Bounce( BUTTON2, 9);

void setup() {
  pinMode(BUTTON1,INPUT);
  pinMode(BUTTON2,INPUT);
  pinMode(LED1,OUTPUT);
  pinMode(LED2,OUTPUT);
}

void loop()
{ 
   buttonState1 = digitalRead(BUTTON1);
  if (buttonState1 == HIGH) {  //если кнопка нажата
 
 unsigned long currentMillis = millis(); // текущее время в миллисекундах
    // если светодиод включен и светится больше чем надо
  if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
  {
    ledState = LOW; // выключаем
    previousMillis = currentMillis; // запоминаем момент времени
    digitalWrite(LED1, ledState); // реализуем новое состояние
  }
  else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
  {
    ledState = HIGH; // выключаем
    previousMillis = currentMillis ; // запоминаем момент времени
    digitalWrite(LED1, ledState); // реализуем новое состояние
  }
  }
   if(buttonState1 == LOW)
 { 
     ledState = LOW;
     digitalWrite(LED1, ledState); // реализуем новое состояние
  }
  if (bouncer1.update())
 { //если произошло событие
  if (bouncer1.read()==HIGH)
  { //если кнопка нажата
        pressed_moment = millis(); // запоминаем время нажатия
  }
  else
  { // кнопка отпущена
   if((millis() - pressed_moment) < pressed_long)
   { // если кнопка была нажата кратковременно
   for (int a=0;a<k;a++)
   {
   ledState = HIGH;
    digitalWrite(LED1, ledState);
  delay(500);
 ledState = LOW;
 digitalWrite(LED1, ledState);
  delay(500);
   
   }
   }
   else   { // кнопка удерживалась долго
       pressed_moment = 0; // обнуляем момент нажатия
   }
  }
 }
}

 

Alex-ua04
Offline
Зарегистрирован: 28.11.2015

может я слищком усложнил скетч, для такой незначительной задачи? Ардуину ( также как и Си) узучаю не так давно.

Штирлиц
Штирлиц аватар
Offline
Зарегистрирован: 13.06.2015

Нажатие кнопки -флаг подняли, если флаг-поднят,отработал блинк н-ое количество раз - сбросили флаг. Как-то так , навскидку.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Если что почитать, то "конечные автоматы".

По поводу флага: в данном случае - один из вариантов.

В более общем случае - переменная состояния, которая может принимать не 2 (как флаг), а несколько состояний. Например:

0 - исходное состояние.

нечетные от 1 до 2n-1 - светодиод включен.

четные от 2 до 2n-2 - светодиод выключен.

2n - финальное состояние.

По нажатию кнопки в состоянии 0 система переходит в состояние 1 и дальше последовательно проходит все состояния (в каждом задерживаясь на нужное время) вплоть до финального. Из финального сбрасывается в начальное.

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