Цикл while (1) в функции - работает ли?

Alexus-12
Offline
Зарегистрирован: 28.03.2014

Подскажите по следующему вопросу. Будет ли работать цикл while (1) в функции, которая вызывается из основной loop? Суть в следующем. Вызывается функция из loop, в этой функции организован цикл while (1), который должен ожидать нажатие кнопок и выбирать что делать дальше. Выход из while (1) происходит при нажатии на определенную кнопку что по идее должно вернуть управление основному циклу loop. Но почему-то не получается. Похоже что цикл while (1) просто игнорируется. Если в мою функцию (в которой есть цикл while (1)) добавить задержку, то видно, что сама функция вызывается, но цикл while (1) не обрабатывается, функция завершается без ожидания нажатия на кнопки и процесс возвращается обратно в  loop.

while (1) вообще доложен работать в функциях или он только в loop работает?

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Ничего не могу сказать по поводу while (1) в среде Arduino IDE, но у Вас в корне неверный подход. Заставлять микроконтроллер впустую гонять цикл в ожидании нажатия кнопки без возможности выполнять другие задачи - это плохая практика. Используйте прерывания. Пусть лучше гоняет loop (), а в обработчике прерывания выполняйте нужные Вам действия или вызывайте другие функции. Если в обработчике прерывания будете менять значения каких-то переменных, не забудьте объявить их с квалификатором volatile.

maksim
Offline
Зарегистрирован: 12.02.2012

while(1) - ничего вам не должен, это бесконечный цикл, а прервается он только от того, что вы сами его прерываете.

Jeka_M пишет:

... у Вас в корне неверный подход. ...

Если в программе больше ничего не делает, то зачем городить огород? 
Какая разница в каком бесконечном цикле крутиться в loop или while?

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

maksim пишет:

Если в программе больше ничего не делает, то зачем городить огород? 

Прикрутить несчастное прерывание это городить огород? А вдруг ему потом захочется расширить функционал. Кроме ожидания нажатия кнопки ещё что-нибудь выполнять.

maksim пишет:

Какая разница в каком бесконечном цикле крутиться в loop или while?

Не знаю... Это ж топикстартёру loop'a оказалось мало и он пытается нагородить еще один бесконечный цикл...

Alexus-12
Offline
Зарегистрирован: 28.03.2014

Тоесть реализовать ожидание нажатия на кнопки и действия по ним в цикле loop?

С прерываниями увы не знаю как работать.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014
maksim
Offline
Зарегистрирован: 12.02.2012

Jeka_M пишет:

Прикрутить несчастное прерывание это городить огород? 

Тем более прерывание, переподключать к конкретным выводам, борьба с дребезгом и это не есть огород против одного цикла?

Jeka_M пишет:

Не знаю... Это ж топикстартёру loop'a оказалось мало и он пытается нагородить еще один бесконечный цикл...

Вопрос к вам, почему не достаточно обычного цикла и обязательно крутить именно в loop? 

Jeka_M пишет:

А вдруг ему потом захочется расширить функционал. Кроме ожидания нажатия кнопки ещё что-нибудь выполнять.

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

Да и вопрос не в этом.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

странные обсуждения while (1).... похоже на 1-ое апреля.... 
while (1) вообще доложен работать в функциях или он только в loop работает?
...он ни чё не должен, кроме как озадачить МК - сколько ему это выполнять ? секунду, месяц, три года ?
это бессрочный режим работы для МК..... 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Тоесть реализовать ожидание нажатия на кнопки и действия по ним в цикле loop?

С прерываниями увы не знаю как работать.

while (1)  - замените на while (условие) - проверяемое/вычислямое условие внутри while (условие)

Alexus-12
Offline
Зарегистрирован: 28.03.2014

SU-27-16 пишет:

странные обсуждения while (1).... похоже на 1-ое апреля.... 
while (1) вообще доложен работать в функциях или он только в loop работает?
...он ни чё не должен, кроме как озадачить МК - сколько ему это выполнять ? секунду, месяц, три года ?
это бессрочный режим работы для МК..... 

Так в том то и дело, что он должен крутить цикл до бесконечности пока не будет выполнено определенное условие (в данном случае нажата кнопка, тогда цикл будет прерван командой break). Но он просто игнорируется. Почему-то программа его пропускает и просто завершает вызванную функцию, в которой этот цикл крутится. Я поэтому и спросил работает ли он в функции.

maksim
Offline
Зарегистрирован: 12.02.2012

Alexus-12 пишет:

Почему-то программа его пропускает и просто завершает вызванную функцию, в которой этот цикл крутится. Я поэтому и спросил работает ли он в функции.

Потому, что вы программе указываете, что бы она прервала цикл.

Datak
Offline
Зарегистрирован: 09.10.2014

while(1) - хоть и выглядит на первый взгляд странно, используется достаточно часто. Просто программа так иногда получается понятнее - часть кода выделяется в отдельный структурный блок.
И да, правильно написали - выйти из этого блока можно в любой момент с помощью break, по определённому условию.

loop( ) - такая же функция как все остальные. И конечно, while можно использовать в любой функции.

В чём-то другом ошибка, ищите. Или код давайте сюда - посмотрим, а то что мы всё на словах... 

Alexus-12
Offline
Зарегистрирован: 28.03.2014

maksim пишет:

Потому, что вы программе указываете, что бы она прервала цикл.

Да указываю - только по нажатию кнопки.

Вот сама функция как выгдяжит. При нажатии 4-й кнопки цикл должен завершиться, но при обращении к функции цикл while (1) просто игнорируется.

void Main_menu (int y1, int y2)
{
  while (1) {
    display.clearDisplay(); // Очищаем дисплей
    display.setCursor(30,0); // Устанавливаем курсор
    display.print ("MENU");
    display.setCursor(4,10);
    display.print ("TEMP SETTINGS");
    display.setCursor(22,20);
    display.print ("SHEDULE");
    display.setCursor(4,30);
    display.print ("TIME SETTINGS");    

    display.drawRect(0, y1, 84, y2, BLACK);  

    display.display();

    AKeys.Refresh(analogRead(BUTTON));  
    if (AKeys.Key1() && !Key_Up_Old) {
      y1=y1-10; 
      y2;
    }
    if (AKeys.Key3() && !Key_Down_Old) {
      y1=y1+10; 
      y2;
    }
    if (AKeys.Key4() && !Key_Esc_Old) break;  // Выход из цикла
    
    Key_Up_Old = AKeys.Key1();
    Key_Down_Old = AKeys.Key3();
    Key_Esc_Old = AKeys.Key4();

  } // End while

} //End Main_menu

Может из-за того, что вход в саму функцию из основного цикла по этой же кнопке происходит....

maksim
Offline
Зарегистрирован: 12.02.2012

Происходит из за того что условие выполняется

if (AKeys.Key4() && !Key_Esc_Old) break; // Выход из цикла

Что вам мешает проверить это?

if (AKeys.Key4() && !Key_Esc_Old) 
{ 
    display.clearDisplay(); // Очищаем дисплей
    display.setCursor(0,0); // Устанавливаем курсор
    display.print ("EXIT");
​    while(1);
    break;  // Выход из цикла
}

А уж по какой причине это происходит известно только вам.

Alexus-12
Offline
Зарегистрирован: 28.03.2014

maksim пишет:

А уж по какой причине это происходит известно только вам.

Заменил кнопку входа в функцию на другую - и стало работать. Видно происходил конфликт с переменными, которые отслеживают нажатие кнопок поэтому условие выхода из цикла соблюдалось и цикл пропускался.

bwn
Offline
Зарегистрирован: 25.08.2014

Alexus-12 пишет:

maksim пишет:

А уж по какой причине это происходит известно только вам.

Заменил кнопку входа в функцию на другую - и стало работать. Видно происходил конфликт с переменными, которые отслеживают нажатие кнопок поэтому условие выхода из цикла соблюдалось и цикл пропускался.

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

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

to Datak
while(1) - хоть и выглядит на первый взгляд странно, используется достаточно часто. Просто программа так иногда получается понятнее - часть кода выделяется в отдельный структурный блок.
И да, правильно написали - выйти из этого блока можно в любой момент с помощью break, по определённому условию.

....вроде бы
while(условие) { .............; ................; ........................; изменение переменной входящей в условие; }
более читабельно ?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

SU-27-16, зависит от ситуации. Аналогично for(;true;) {...}, do {...} while(1), варианты есть разные. И даже банальный looper: ... goto looper; И каждый вариант по своему читабелен для автора, так что.. се ля ви.

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

на вкус и цвет - кода нет !
:)
.....будем толерантны к коду автора :)

Datak
Offline
Зарегистрирован: 09.10.2014

SU-27-16 пишет:

...вроде бы
while(условие) { .............; ................; ........................; изменение переменной входящей в условие; }
более читабельно ?

Иногда да, а иногда наоборот. Так что согласен:

kisoft пишет:

зависит от ситуации

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

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Например, если условий выхода несколько, перечисление их всех в скобках у while( ..... ) может выглядеть громоздко и непонятно.
аха :)
велик и могуч CPP....  паскаль отдыхает :(

Alexus-12
Offline
Зарегистрирован: 28.03.2014

Переделал программу по-другому, без while(1). Вместо него использую теперь основной цикл loop.

Всем спасибо за разъяснения.