Управление RGB диодами одной кнопкой

Доброго времени суток! Сильно не пинайте, но я только пытаюсь разобраться в Arduino. Решил сделать RGB фонарик, но что цвета переключались при коротком нажатии, при двойном включался стробоскоп, а при удержании пару секунд - выключался. Получилось кое-как сделать все режимы по кругу, а вот как нужно - никак не выходит. Понимаю что вопрос для понимающих элементарный, а для меня, к сожалению, пока нерешаемая задача))

#define BLED 3                                        //3 контакт для синего вывода RGB-светодиода
#define GLED 5                                        //5 контакт для зеленого вывода RGB-светодиода
#define RLED 6                                        //6 контакт для красного вывода RGB-светодиода
#define BUTTON 2                                       //2 контакт для кнопки

boolean lastButton = LOW;                              //предыдущее состояние кнопки
boolean currentButton = LOW;                           //текущее состояние кнопки
int ledMode = 0;                                       //статус  RGB-светодиода
int miganie = 30;

void setup()
{
  pinMode (BLED, OUTPUT);                              //Устанавливаем контакт BLED(Blue LED, т.е 3 контакт) как выход 
  pinMode (GLED, OUTPUT);                              //Устанавливаем контакт GLED(Green LED, т.е 5 контакт) как выход 
  pinMode (RLED, OUTPUT);                              //Устанавливаем контакт RLED(Red LED, т.е 6 контакт) как выход
  pinMode (BUTTON, INPUT);                             //Устанавливаем контакт BUTTON(т.е. 2 контакт) как вход(опционально)
}

void loop()
{
  currentButton = debounce(lastButton);                //считываем состояние кнопки с применением "антидребезга"
  if (lastButton == LOW && currentButton == HIGH)      //если кнопка была нажата
  {
    ledMode++;                                         //инкрементируем значение переменной
  }
  lastButton = currentButton;                          //сохраняем текущее состояние кнопки в предыдущее
  
  if (ledMode == 9) ledMode = 0;                      //если прошли по циклу все режимы свечения светодиода, делаем сброс до 0
  setMode(ledMode);                                   //изменить режим светодиода
}

/*
* Функция антидребезга
* принимает предыдущее значение кнопки и возвращает текущее состояние кнопки с подавлением дребезга контактов
*/
boolean debounce(boolean last)
{
  boolean current = digitalRead(BUTTON);             //считываем состояние кнопки
  if (last != current)                               //если есть изменения
  {
    delay(5);                                        //ждем 5мс
    current = digitalRead(BUTTON);                   //считываем состояние кнопки
  }
  return current;                                    //возвращаем, считанное состояние кнопки
}

/*
* Выбор режима работы светодиода
* Передача номера режима и его установка
* Функция ничего не возвращает
*/
void setMode(int mode)
{
  //Красный
  if (mode == 1)
  {
    digitalWrite(RLED, HIGH);
    digitalWrite(GLED, LOW);
    digitalWrite(BLED, LOW);
  }
  //Зеленый
  else if (mode == 2)
  {
    digitalWrite(RLED, LOW);
    digitalWrite(GLED, HIGH);
    digitalWrite(BLED, LOW);
  }
  //Синий
  else if (mode == 3)
  {
    digitalWrite(RLED, LOW);
    digitalWrite(GLED, LOW);
    digitalWrite(BLED, HIGH);
  }
  //Пурпурный(Красный + Синий)
  else if (mode == 4)
  {
    analogWrite(RLED, 255);
    analogWrite(GLED, 0);
    analogWrite(BLED, 255);
  }
  //Бирюзовый(Синий + Зеленый)
  else if (mode == 5)
  {
    analogWrite(RLED, 0);
    analogWrite(GLED, 255);
    analogWrite(BLED, 255);
  }
  //Жёлтый(Зеленый + Красный)
  else if (mode == 6)
  {
    analogWrite(RLED, 255);
    analogWrite(GLED, 255);
    analogWrite(BLED, 0);
  }
  //Белый(Красный + Зеленый + Синий)
  else if (mode == 7)
  {
    analogWrite(RLED, 255);
    analogWrite(GLED, 255);
    analogWrite(BLED, 255);
  }
  //Стробоскоп белый
  else if (mode == 8)
  {
    analogWrite(RLED, 255);
    analogWrite(GLED, 255);
    analogWrite(BLED, 255);
    delay(miganie);
    analogWrite(RLED, 0);
    analogWrite(GLED, 0);
    analogWrite(BLED, 0);
    delay(miganie);
  }
  //Выключен
  else
  {
    digitalWrite(RLED, LOW);
    digitalWrite(GLED, LOW);
    digitalWrite(BLED, LOW);
  }
}

Любой вопрос нерешаем, если не задан.

Самое простое для Вас сейчас - это найти готовую библиотеку для работы с кнопками, в которой реализовано определение и двойного нажатия и длинного нажатия и т.д.
Можете в неё заглянуть и посмотреть, как это реализовано. Если непонятно, то значит рано, разберётесь, когда опыта побольше будет. А пока используйте её как есть.

Прошу прощения) Помогите дописать чтоб работало короткое нажатие, длинное и удержание для выключения.

Это вопрос?

Одиночный и двойной клик

Удержание кнопки нажатой

1 лайк

Спасибо, буду вникать)

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

это миллисекунды. У вас 15 герца частота стробоскопа, не многовато ли?

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

Почему где-то digitalWrite, а где-то analogWrite используете?

В школе приучили не использовать одно и то же слово несколько раз в одной фразе.

1 лайк