Работа с кнопкой, режим переключения работы

Тема в разделе "Arduino & Shields", создана пользователем Evgen-82, 15 июл 2015.

  1. Evgen-82

    Evgen-82 Нерд

    Добрый день, я только начинаю осваивать Arduino, и вот столкнулся с проблемой, нигде не могу найти объяснение как работать с кнопкой в режиме переключения программ, ну к примеру, 1 нажатие приводит к включению бегущих огней, 2 нажатие к реверсу бегущих огней, 3 включение к нарастающей линейки светодиодов, 4 нажатие к поочередному погасанию линейки светодиодов, 5 нажатие к миганию всех светодиодов. Всего светодиодов 5 шт. Как такое можно реализовать?
     
  2. Deniss

    Deniss Гик

    Принцип:
    переменная n при нажатии кнопки увеличивается на 1
    если n = 1 то ...
    если n = 2 то..
    ...
    если n > 6 то n = 1
     
  3. Evgen-82

    Evgen-82 Нерд

     
  4. Salk

    Salk Гик

    Тут совсем недавно, кстати, была похожая тема .
    Код в теме имеется. Там только действия реализованы другие, отличные от Ваших, но ничего не мешает их переписать на свои. Главное - механизм работы с кнопкой есть. Изучайте :) Будут вопросы по коду, пишите.
     
    Последнее редактирование: 15 июл 2015
  5. Evgen-82

    Evgen-82 Нерд

    Хорошо, спасибо!!!
     
  6. geher

    geher Гуру

    Примерно так:
    Код (Text):

    int n=1;
    void setup() {
       что-то тут инициализируется
    }
    void loop() {
       if (нажата кнопка) {
           ++n;
           if (n>5) n=1;
       }
        switch(n) {
           case 1:
               то, что делалось по варианту "бегущие огни"
               break;
           case 2:
               то, что делалось по варианту "реверс бегущих огней"
               break;
           и т.д. и т.п.
        }
      }

    }
     
     
  7. Salk

    Salk Гик

    Код рабочий, но "n" будет набегать больше одной позиции, если кнопку чуть дольше продержим зажатой, т.е. возможны проскоки режимов. Не стабильно :) По мне так лучше считать, что кнопка была зажата после её отжатия :)
     
  8. geher

    geher Гуру

    Логично. Собственно говоря, оно вполне вписывается в "if (нажата кнопка)"
    С другой стороны, если определять все-таки по нажатию, а в проверку нажатия кнопки вставить небольшой delay или измерение длительности нажатия при помощи millis(), то длительным нажатием можно будет быстро пропускать режимы.

    На самом деле тут масса вариантов обработки с различными нюансами. Потому и ограничился таким общим условием, не конкретизируя, как именно определяется нажатие кнопки.
     
  9. Deniss

    Deniss Гик

    Самый простой я говорил в той теме, на которую ссылались:
    В конце программы поставить while который ждет пока кнопка зажата....
     
  10. Lex_Silver

    Lex_Silver Нуб

    Всем доброго дня,

    Столкнулся с подобной проблемой – запуск/остановка мигания светодиодов с кнопки
    Мигание светодиодов сделал через массив ledPins[] = {2,3,4,5,6,7,8,9}
    Кнопку подключил на 12 вывод pinMode(12, INPUT);
    сделал целочисленную переменную для хранения состояния светодиодов int svet=0;
    припроверке выдает ошибку: invalid types 'int [8][char* ()(const char*, int)]' for array subscript
    Если я правильно понимаю – ардуино видит массив как символьный(char*), хотя он у меня указан как целочисленный (int).
    Пожалуйста, если не трудно, подскажите в чем не соответствие…
    вот скетч:
    /*
    Бегущие огни (пин-понг)+кнопка
    */
    int svet=0; // Заводим целочисленную переменную для хранения состояния светодиодов
    int ledPins[] = {2,3,4,5,6,7,8,9};//массив светодиодов
    void setup()
    {
    pinMode(12, INPUT);//Вывод кнопки
    int index;//номер активного светодиода в массиве
    for(index = 0; index <= 7; index++);
    {
    pinMode(ledPins[index],OUTPUT);
    }
    }
    void loop()
    {
    if (digitalRead(12)==1 && svet ==0); //Если с кнопки есть сигнал и мигания светодиодов нет
    {
    for(index = 0; index <= 7; index++);//запускаем мигание светодиодов по возрастанию
    {
    digitalWrite(ledPins[index], HIGH);
    delay(100);
    digitalWrite(ledPins[index], LOW);
    }
    for(index = 7; index >= 0; index--);//запускаеммиганиесветодиодовпоубыванию
    {
    digitalWrite(ledPins[index], HIGH);
    delay(100);
    digitalWrite(ledPins[index], LOW);
    }
    svet =1; // Записываем новое состояние
    while (digitalRead(12)); // Ждем когда отпустят кнопку
    delay(50); //защита от дребезга кнопки
    }
    if (digitalRead(12)==1 && svet ==1); //Если с кнопки есть сигнал и светодиоды мигают
    {
    digitalWrite(ledPins[2,3,4,5,6,7,8,9], LOW);//Гасим все светодиоды массива
    svet =0; // Записываем новое состояние
    while (digitalRead(12)); // Ждем, когда отпустят кнопку
    delay(50);//защита от дребезга кнопки
    }
    }

    С ардуино работаю всего несколько дней, поэтому прошу извинить за возможные грубые ошибки.
     
  11. Sindbad

    Sindbad Гик

    Вот это что?
    Код (C++):
    digitalWrite(ledPins[2,3,4,5,6,7,8,9], LOW);
    Какой опыт программирования у Вас?
     
  12. Lex_Silver

    Lex_Silver Нуб

    Вот это что?
    digitalWrite(ledPins[2,3,4,5,6,7,8,9], LOW); выключаю мигание светодиодов после повторного нажатия кнопки,
    Опыт программирования - как и писал, несколько дней...
    именно по этому решил начать учиться с ардуино...
     
  13. Sindbad

    Sindbad Гик

    Эта строчка, а точнее вот эта её часть:
    Код (C++):
    ledPins[2,3,4,5,6,7,8,9]
    в С++ не имеет смысла. Скорее всего именно на неё компилятор и ругается. В данном случае вместо
    Код (C++):
    digitalWrite(ledPins[2,3,4,5,6,7,8,9], LOW);
    надо писать что-то вроде
    Код (C++):
    for (int i=2;i<=9;i++) {
      digitalWrite(ledPins[i], LOW);
    }
    Апдейт: последний блок не более чем перевод синтаксически неверной записи в синтаксически корректную. Однако работать это не будет, т.к. противоречит остальному тексту программы. По смыслу программы, скорее всего, имеется в виду вот такой код:
    Код (C++):
    for (int i=0;i<=7;i++) {
      digitalWrite(ledPins[i], LOW);
    }
    Или эквивалентный ему, но без массива:
    Код (C++):
    for (int i=2;i<=9;i++) {
      digitalWrite(i, LOW);
    }
     
    Последнее редактирование: 20 янв 2016
  14. Lex_Silver

    Lex_Silver Нуб

    О уже лучше - проверку прошел! Спасибо.

    Правда при заливке на ардуино, при нажатии кнопки - запуска алгоритма мигания светодиодов:

    if (digitalRead(12)==1 && svet ==0); //Если с кнопки есть сигнал и мирцания светодиодов нет
    {
    for(i = 2; i <= 9; i++);//запускаем мигание светодиодов по возрастания
    {
    digitalWrite(ledPins, HIGH);
    delay(100);
    digitalWrite(ledPins, LOW);
    }
    for(i = 9; i >= 2; i--);//запускаем мигание светодиодов по убыванию
    {
    digitalWrite(ledPins, HIGH);
    delay(100);
    digitalWrite(ledPins, LOW);
    }

    Не происходит :(
     
  15. Sindbad

    Sindbad Гик

    Больше всего смущает то, что этот фрагмент не соответствует тому, что было в сообщении № 10

    И для вставки фрагментов кода надо кнопочку "<>" редактора сообщений использовать.
     
  16. Lex_Silver

    Lex_Silver Нуб

    попробовал преобразовал скетч, сделал его без массива:
    int i;//номер активного светодиода
    int svet=0; // Заводим целочисленную переменную для хранения состояния светодиодов

    void setup()
    {
    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(12, INPUT);//Вывод кнопки
    }

    void loop()
    {
    if (digitalRead(12)==1 && svet ==0); //Если с кнопки есть сигнал и мирцания светодиодов нет
    {
    for(i = 2; i <= 9; i++);//запускаем мигание светодиодов по возрастания
    {
    digitalWrite(i, HIGH);
    delay(100);
    digitalWrite(i, LOW);
    }
    for(i = 9; i >= 2; i--);//запускаем мигание светодиодов по убыванию
    {
    digitalWrite(i, HIGH);
    delay(100);
    digitalWrite(i, LOW);
    }
    svet =1; // Записываем новое состояние
    while (digitalRead(12)); // Ждем когда отпустят кнопку
    delay(50);//защита от дребезга кнопки
    }
    if (digitalRead(12)==1 && svet ==1); //Если с кнопки есть сигнал и светодиоды мигают
    {
    for(i = 2; i <= 9; i++)
    {
    digitalWrite(i, LOW);//Гасим все светодиоды
    }
    svet =0; // Записываем новое состояние
    while (digitalRead(12)); // Ждем, когда отпустят кнопку
    delay(50);//защита от дребезга кнопки
    }
    }

    но, все-равно после нажатия кнопки, как и писал - запуска мигания светодиодов не происходит
     
  17. DrProg

    DrProg Вечный нерд

    Код бы в специальное окно публиковать. Кавычки слева от флажка.
     
  18. Lex_Silver

    Lex_Silver Нуб

    спасибо за совет, постараюсь далее в сообщениях не тупить...
     
  19. Sindbad

    Sindbad Гик

    Попробуйте так:
    Код (C++):
    if (digitalRead(12)==HIGH && svet ==0)
     
  20. DrProg

    DrProg Вечный нерд

    Переделайте сейчас, тогда можно будет посмотреть его. А в таком виде мало кто будет глаза ломать.