roboforum.ru

Технический форум по робототехнике.
Текущее время: 30 ноя 2024, 05:03

Часовой пояс: UTC + 4 часа




Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
 Заголовок сообщения: чередование кнопкой
СообщениеДобавлено: 25 янв 2018, 09:13 
Не в сети

Зарегистрирован: 30 мар 2017, 09:35
Сообщения: 10
пытаюсь понять алгоритм работы с кнопкой...
идея у меня такая - вывести на экран показания с датчиков температуры, давления и т.д. с возможностью кнопкой поочередного листания этих данных на экране.
решил для начала попрактиковаться на динамиках с двумя тонами.
Код:
int regim = 1;
int flag = 0;

int buzzer1 = 9;
int buzzer2 = 10;

void setup()
{
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(buzzer1, OUTPUT); //объявляем пин как выход1
pinMode(buzzer2, OUTPUT); //объявляем пин как выход2
}

void loop()

{

  if (digitalRead(A0) == HIGH && flag == 0) //если кнопка нажата
    // и перемення flag равна 0 , то ...
  {
    regim++;
    flag = 1;

    //это нужно для того что бы с каждым нажатием кнопки
    //происходило только одно действие
    // плюс защита от "дребезга"  100%

    if (regim > 4) //ограничим количество режимов
    {
      regim = 1; //так как мы используем только одну кнопку,
      // то переключать режимы будем циклично
    }

  }

  if (digitalRead(14) == LOW && flag == 1) //если кнопка НЕ нажата
    //и переменная flag равна - 1 ,то ...
  {

    flag = 0; //обнуляем переменную "knopka"
  }



  if (regim == 1) //первый режим
  {
    digitalWrite(11, LOW); //выключаем все светодиоды
    digitalWrite(12, LOW);
   
    //здесь может быть любое ваше действие
  }
  if (regim == 2) //второй режим
  {
    digitalWrite(12, HIGH); //включае красный светодиод
    digitalWrite(11, LOW);
   
    tone (buzzer1, 261); //включаем на 261 Гц
  delay(500); //на 500 миллисекунд

  noTone(buzzer1); //выключаем динамик на 1 секунду
  delay(1000);

  tone(buzzer1, 493); //включаем на 493 Гц
  delay(500); //на 500 миллисекунд

  noTone(buzzer1);//выключаем динамик на 1 секунду
  delay(1000);


    //здесь может быть любое ваше действие
  }

  if (regim == 3) //третий режим
  {

    digitalWrite(11, HIGH); //включае зеленый светодиод
    digitalWrite(12, LOW);


    //здесь может быть любое ваше действие
  }

  if (regim == 4) //четвертый режим
  {

    digitalWrite(11, HIGH); //включаем светодиоды одновременно
    digitalWrite(12, HIGH);
    //здесь может быть любое ваше действие
  }

}

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: чередование кнопкой
СообщениеДобавлено: 25 янв 2018, 10:51 
Не в сети

Зарегистрирован: 14 янв 2015, 16:18
Сообщения: 235
Откуда: СПб
Здесь важно понимать, что второй режим выполняется примерно 3 секунды и в это время никакой реакции на кнопки не будет.
Чтобы выйти из второго режима надо:
-выждать более 3 секунд, чтобы сработал блок "если кнопка НЕ нажата"
-нажать кнопку и удерживать более 3 секунд для срабатывания блока "если кнопка нажата"


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: чередование кнопкой
СообщениеДобавлено: 25 янв 2018, 11:24 
Не в сети

Зарегистрирован: 26 мар 2008, 12:45
Сообщения: 326
Andrus
1. Вы наверняка не полностью прописали условия входа\выхода в условии if... Для нахождения ошибки пропишите в каждом или в ошибочном режиме строку Serial.println( здесь перечислите условия входа\ выхода из режима) и по этим значениям увидите какая из переменных мешает Вам выйти из режима.
2. Изменение режима возможно только при нажатии кнопки и flag ==0. Это условие у Вас только при включении и нажатии кнопки 1 раз. После этого программа не будет реагировать на кнопку, т.к flag = 1
Вам рекомендации:
- при работе с кнопками всегда проверяйте : если нажата , то дождитеcь когда она будет отпущена и только после этого переходите дальше. Среднее время дребезга кнопки 20-25 mc
if (нажата)
{
delay(25);
if (нажата) {}
далее по тексту
}
Будьте внимательны, прописываете все очень точно - цифровые входы Вы прописали на вход и выходб а вывод - А0 у Вас ни как не определен. Не зависимо от того, что написано в аннотациях или уроках по arduino прописывайте все очень скурпулезно и точно. Версии компиляторов по разному реагируют на формальное определение pin и в особенности на определение переменных.
Пока все. О результате отпишитесь
loox

Добавлено спустя 25 минут 49 секунд:
Да, обязательно подтяните вход с кнопкой либо резистором 5-10ком к плюсу или прграммно pullup


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: чередование кнопкой
СообщениеДобавлено: 25 янв 2018, 13:44 
Не в сети

Зарегистрирован: 14 янв 2015, 16:18
Сообщения: 235
Откуда: СПб
digitalRead(A0)
digitalRead(14)
A0 равно 14?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: чередование кнопкой
СообщениеДобавлено: 25 янв 2018, 19:33 
Не в сети

Зарегистрирован: 26 мар 2008, 12:45
Сообщения: 326
Да
но это не обозначает, что его не надо определять как вход и потягивать к плюсу.
loox


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: чередование кнопкой
СообщениеДобавлено: 26 янв 2018, 10:19 
Не в сети

Зарегистрирован: 30 мар 2017, 09:35
Сообщения: 10
указал, что кнопка А0 и является выходом.
int button = A0;
pinMode(button, INPUT);

__прописал после каждого действия сериал принт... в мониторе порта еще раз подтвердилось, что переменная цикла бузера при нажатии кнопки не прекращается.
__по пункту 2 не совсем понял... как все таки изменить режим? ведь у меня и так указано flag ==0
__кнопка подключена через резистор 10к.

digitalRead(A0)
digitalRead(14)
__ошибочка исправил.


Код:
int regim = 1;
int flag = 0;
int button = A0;
int buzzer1 = 9;


void setup()
{
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(buzzer1, OUTPUT); //объявляем пин как выход1
pinMode(button, INPUT);
  Serial.begin(9600);
}

void loop()

{

  if (digitalRead(A0) == HIGH && flag == 0) //если кнопка нажата
    // и перемення flag равна 0 , то ...

  {
    regim++;
    flag = 1;

    if (regim > 4) //ограничим количество режимов
    {
      regim = 1; //так как мы используем только одну кнопку,
      // то переключать режимы будем циклично
    }

  }

  if (digitalRead(A0) == LOW && flag == 1) //если кнопка НЕ нажата
    //и переменная flag равна - 1 ,то ...
  {

    flag == 0; //обнуляем переменную "knopka"
  }

  if (regim == 1) //первый режим
  {
    digitalWrite(11, LOW); //выключаем все светодиоды
    digitalWrite(12, LOW);
    Serial.println ("led 1 2 off");
   
    //здесь может быть любое ваше действие
  }
  if (regim == 2) //второй режим
  {
    digitalWrite(12, HIGH); //включае красный светодиод
    digitalWrite(11, LOW);
    Serial.println ("led1 off");
   
    tone (buzzer1, 261); //включаем на 261 Гц
  delay(300); //на 500 миллисекунд
Serial.println ("buz1 on");
  noTone(buzzer1); //выключаем динамик на 1 секунду
  delay(1000);
Serial.println ("buz1 off");
  tone(buzzer1, 493); //включаем на 493 Гц
  delay(300); //на 500 миллисекунд
Serial.println ("buz2 on");
  noTone(buzzer1);//выключаем динамик на 1 секунду
  delay(1000);
Serial.println ("buz2 off");

    //здесь может быть любое ваше действие
  }

  if (regim == 3) //третий режим
  {

    digitalWrite(11, HIGH); //включае зеленый светодиод
    digitalWrite(12, LOW);
Serial.println ("led2 on");

    //здесь может быть любое ваше действие
  }

  if (regim == 4) //четвертый режим
  {

    digitalWrite(11, HIGH); //включаем светодиоды одновременно
    digitalWrite(12, HIGH);
    //здесь может быть любое ваше действие
    Serial.println ("led 1 2 on");
  }
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: чередование кнопкой
СообщениеДобавлено: 26 янв 2018, 20:03 
Не в сети
Аватара пользователя

Зарегистрирован: 30 сен 2008, 18:49
Сообщения: 2681
Откуда: Где-то в Латинской Америке
Кнопка обязательно сработает, если ее держать нажатой более 3х секунд )))
Попадая во второй режим, программа все время висит на delay, выскакивая из него на микроскопическое время, чтобы проверить состояние кнопки. Именно в этот момент кнопка д.б. нажата, чтобы переключиться на следующий режим. Попробуйте использовать для кнопки прерывания, либо счетчики для пауз + delay(100), чтобы постоянно проверять состояние кнопки.
Или решить проблему так:

Код:
void setup()
{
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(buzzer1, OUTPUT); //объявляем пин как выход1
pinMode(button, INPUT);
  Serial.begin(9600);
}

void loop()

{

  if (digitalRead(A0) == HIGH && flag == 0) //если кнопка нажата
    // и перемення flag равна 0 , то ...

  {
    regim++;
    flag = 1;

    if (regim > 4) //ограничим количество режимов
    {
      regim = 1; //так как мы используем только одну кнопку,
      // то переключать режимы будем циклично
    }

  }

  if (digitalRead(A0) == LOW && flag == 1) //если кнопка НЕ нажата
    //и переменная flag равна - 1 ,то ...
  {

    flag == 0; //обнуляем переменную "knopka"
  //}!!!!

  if (regim == 1) //первый режим
  {
    digitalWrite(11, LOW); //выключаем все светодиоды
    digitalWrite(12, LOW);
    Serial.println ("led 1 2 off");
   
    //здесь может быть любое ваше действие
  }
  if (regim == 2) //второй режим
  {
    digitalWrite(12, HIGH); //включае красный светодиод
    digitalWrite(11, LOW);
    Serial.println ("led1 off");
   
    tone (buzzer1, 261); //включаем на 261 Гц
  delay(300); //на 500 миллисекунд
Serial.println ("buz1 on");
  noTone(buzzer1); //выключаем динамик на 1 секунду
  delay(1000);
Serial.println ("buz1 off");
  tone(buzzer1, 493); //включаем на 493 Гц
  delay(300); //на 500 миллисекунд
Serial.println ("buz2 on");
  noTone(buzzer1);//выключаем динамик на 1 секунду
  delay(1000);
Serial.println ("buz2 off");

    //здесь может быть любое ваше действие
  }

  if (regim == 3) //третий режим
  {

    digitalWrite(11, HIGH); //включае зеленый светодиод
    digitalWrite(12, LOW);
Serial.println ("led2 on");

    //здесь может быть любое ваше действие
  }

  if (regim == 4) //четвертый режим
  {

    digitalWrite(11, HIGH); //включаем светодиоды одновременно
    digitalWrite(12, HIGH);
    //здесь может быть любое ваше действие
    Serial.println ("led 1 2 on");
  }
  }//!!!!!
}

Вариантов много.
Сама кнопка аппаратно тоже выполнена не правильно. Резистор 10к д.б. подключен между входным портом и + питания (либо использовать pinMode(X,INPUT_PULLUP)). А кнопкой соединять вход с минусом питания. В этом случае исключаются наводки на болтающуюся в воздухе входную ногу. Нажатие кнопки будет определяться LOW уровнем соответственно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: чередование кнопкой
СообщениеДобавлено: 26 янв 2018, 20:47 
Не в сети
Аватара пользователя

Зарегистрирован: 18 апр 2009, 22:18
Сообщения: 10668
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
прерывание на изменение и посматривая на время можно как избавлятся от дребезга, так и проверять, сколько времени кнопка нажата ("должна быть нажата минимум ...", "столько-то нажата это быстрое нажатие, делаем то-то", "вот столько это уже долгое нажатие, делаем ещё чего").
если нужно что бы выполнение действий в "режимах" прерывалось, можно этому немного помочь, написав упрощённый delay - в цикле проверять время и какой "флаг", который в прерывании менять. хотя это тоже не сильно лучше, по хорошему желателено хотя бы простенькая машина состояний или планировщик задач. для ардуины гугля не так уж и мало выдаёт, если в запрос добавлять чтот на подобии "yield", "scheduler", "tasks", "threads",...


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 

Часовой пояс: UTC + 4 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
phpBB SEO