Борьба с циклом while

Anytcent
Offline
Зарегистрирован: 16.07.2016

sadman41 пишет:

Не сильно наглядно. Имело бы смысл при объявлении локальных внутрицикловых переменных. А так - инициализировать до цикла, инкрементировать внутри цикла.  Будет понятней.

простите но я вас не совсем понял

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Борьба чёт вторую неделю уже продолжается. Кто поборол-то? Или всё ещё в клинче?

Anytcent
Offline
Зарегистрирован: 16.07.2016

ЕвгенийП пишет:

Борьба чёт вторую неделю уже продолжается. Кто поборол-то? Или всё ещё в клинче?

да пока не понятно. 

sadman41
Offline
Зарегистрирован: 19.10.2016

Anytcent пишет:

sadman41 пишет:

Не сильно наглядно. Имело бы смысл при объявлении локальных внутрицикловых переменных. А так - инициализировать до цикла, инкрементировать внутри цикла.  Будет понятней.

простите но я вас не совсем понял

for (byte x = 1, y = 255; x < y; x++, y--) { ... }

ЕвгенийП пишет:

Борьба чёт вторую неделю уже продолжается. Кто поборол-то? Или всё ещё в клинче?

За меня ответит Добронравов с Пахмутовой:

И вновь продолжается бой,
И сердцу тревожно в груди.
И Ленин - такой молодой,
И юный Октябрь впереди!
 

 

Anytcent
Offline
Зарегистрирован: 16.07.2016

#include <Arduino.h>
#include <U8x8lib.h>
#include <Wire.h>
#include "GyverButton.h"
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE); 

//Инициализация кнопок
GButton butt3(2); // SEL
GButton butt2(3); // NEXT
GButton butt1(4); // BACK

//Куча переменных создавались по мере необходимости
int i, j, k = 400, g, mxm, mnm, mxd, mnd, bfr = 0, flw = 1, pic = 0;
unsigned long time, timer = 0;

//Меню когда Pic = 1
char *menu1[]  = {
  "PARAMETERS",      // 0
  "DATA RECORD",     // 1
  "DISPLAY",         // 2
  "HELP",            // 3
  "PROJECT INFO"     // 4
};

//Массив куда записывается время выстрела
float sht[30];

//надпись сверху
void header()
{
  u8x8.setFont(u8x8_font_amstrad_cpc_extended_f);
  u8x8.inverse();
  u8x8.setCursor(4,0);  u8x8.print("ST v1.0");
}

//Настроички
void setup(void)
{
  butt1.setDebounce(10);  
  butt1.setTimeout(400);
  butt1.setClickTimeout(100);
  butt1.setType(LOW_PULL);
  butt1.setDirection(NORM_OPEN);
  butt2.setDebounce(10);  
  butt2.setTimeout(400);
  butt2.setClickTimeout(100);
  butt2.setType(LOW_PULL);
  butt2.setDirection(NORM_OPEN);
  butt3.setDebounce(10);  
  butt3.setTimeout(400);
  butt3.setClickTimeout(100);
  butt3.setType(LOW_PULL);
  butt3.setDirection(NORM_OPEN);
  u8x8.begin();
  u8x8.setFlipMode(0);
  pinMode(6, OUTPUT);
  digitalWrite(6, HIGH);
}

//Понеслась
void loop() 
{
  butt1.tick();
  butt2.tick();
  butt3.tick();
  
  time = millis();
//Если кнопка зажата, то переходим на уровень више
  if (butt3.isHold()) {
    if (butt3.isRelease()) u8x8.clear();
    if (pic >=1 && pic <= 10) pic = (j - 1) * 10;
  }
//Если двойное нажатие, то переходим на уровень ниже
  if (butt3.isDouble()) {
    if (butt3.isRelease()) u8x8.clear();
    if (pic>=100) pic = pic*0.1;
    else pic = 1;
  }
  
  switch (pic){
//--Приветствие pic = 0 -------------------------    
    case 0:
      u8x8.noInverse();
      u8x8.setFont(u8x8_font_px437wyse700b_2x2_r);
      u8x8.setCursor(3,1);  u8x8.print  ("by DA");
      u8x8.setCursor(1,4);  u8x8.print ("ST v1.0");
      delay(3000);
      u8x8.clear();
      pic = 1;
      j = 2;
      break;
//--Конец приветствия-----------------------------
//--Корневое меню pic = 1 ------------------------
    case 1:
      header();
      u8x8.noInverse();
      u8x8.setFont(u8x8_font_chroma48medium8_r);
      for (i=0; i <= 4; i++) {
        u8x8.setCursor(2,i+2); u8x8.print(menu1[i]);
      }
      u8x8.setCursor(1,j-1);  u8x8.print (" ");
      u8x8.setCursor(1,j);  u8x8.print (">");
      u8x8.setCursor(1,j+1);  u8x8.print (" ");
//----Перемещение курсора для pic = 1-------
      mxm = 6; mnm = 2; mxd = 0; mnd = 0; bfr = 0;
      if (butt2.isSingle()|| butt2.isStep()) { 
        j++;
        if ( j >= mxm+1 ) j = mxm;
      }
      if (butt1.isSingle()|| butt1.isStep()) {
        j--;
        if ( j <= mnm-1 ) j = mnm;
      }
//----Конец перемещения курсовра------------
      break;
//--Конец корневого меню--------------------
//--Изменение чуствительности аналогового входа 6, pic = 10
    case 10:
      header();
      u8x8.noInverse();
      u8x8.setFont(u8x8_font_chroma48medium8_r);
//----Изменение переменной FLOW(уровень)---
      if (butt1.isStep()) flw=flw-10;
      if (butt2.isStep()) flw=flw+10;
      if (butt1.isClick()) flw--;
      if (butt2.isClick()) flw++;
      if (flw<=0) flw = 1;
//----Конец изменения FLOW------------------
      u8x8.setCursor(1,3);  u8x8.print ("FLOW: "); u8x8.print (flw);
      break;
//---Конен изменения чуствительности аналогового входа 6
//----Регистрация хлопков Pic = 20---------------------
    case 20:   
      timer = time;
      u8x8.clear();     
      digitalWrite(6, LOW);
      delay(250);
      digitalWrite(6, HIGH);
//----Начало отсчета времени за которое происходит регистрация      
      while ((millis() - timer) <= 5000) {
        u8x8.setFont(u8x8_font_px437wyse700b_2x2_r);
        u8x8.setCursor(2,2);  u8x8.print  ((millis() - timer)*0.001);
//------Запись в массив SHT времени когда данные аналогового входа 6 выше уровня         
        if (analogRead(6) >= flw) {
          if (sht[bfr] > 0) bfr++;
          sht[bfr] = ((millis() - timer)*0.001);
        }
//------Конец записи в массив-----------------------        
      } 
      timer = 0;
      bfr = 0;
      pic = 1;
//----Конец отсчета времени регистрации-------------
      digitalWrite(6, LOW);
      delay(250);
      digitalWrite(6, HIGH);
      break;
//--Конец регистрации хлопков----------------------
//--Вывод на дисплей хлопков--------------------
    case 30:
      u8x8.setFont(u8x8_font_chroma48medium8_r);
      for (i=2, bfr=mnd; i<=6, bfr<=mxd; i++, bfr++) {
          u8x8.setCursor(1,i); u8x8.print(bfr+1); u8x8.print(":"); u8x8.print(sht[bfr]);
      }      
      break;
 //--Вывод на дисплей максимального значения с микрофона
     case 40:
      u8x8.setFont(u8x8_font_chroma48medium8_r);
      if (k < analogRead(6)){
        k = analogRead(6);
      }
      u8x8.setCursor(1,4); u8x8.print("Max flow:"); u8x8.print(k);
      break;
//--Конец вывода на дисплей хлопков-------------------
  }
}

с циклом while я так и не окончил борьбу, дело в том, что он теперь вообще отказывается работать, он должен зацикливаться пока millis() - timer не станет меньше 10000.

b707
Онлайн
Зарегистрирован: 26.05.2017

Anytcent пишет:

for (i=2, bfr=mnd; i<=6, bfr<=mxd; i++, bfr++) {
        
          u8x8.setCursor(1,i); u8x8.print(bfr+1); u8x8.print(":"); u8x8.print(sht[bfr]);
        
      }  

 

ну вот, о чем я и говорил.

Условие будет работать  не так, как вы думаете

Anytcent
Offline
Зарегистрирован: 16.07.2016

b707 пишет:

Anytcent пишет:

for (i=2, bfr=mnd; i<=6, bfr<=mxd; i++, bfr++) {
        
          u8x8.setCursor(1,i); u8x8.print(bfr+1); u8x8.print(":"); u8x8.print(sht[bfr]);
        
      }  

 

ну вот, о чем я и говорил.

Условие будет работать  не так, как вы думаете

я вас не понимаю, простите

b707
Онлайн
Зарегистрирован: 26.05.2017

Anytcent пишет:

я вас не понимаю, простите

в условии, записанном вот так

if ( i<=6, bfr<=mxd) {

тут часть, что до запятой - можно смело выкинуть, она ни на что не влияет.

Можете написать простенький скетчик с IF и проверить.

Почитайте описание оператора "запятая" в Си

Anytcent
Offline
Зарегистрирован: 16.07.2016

b707 пишет:

Anytcent пишет:

я вас не понимаю, простите

в условии, записанном вот так

if ( i<=6, bfr<=mxd) {

тут часть, что до запятой - можно смело выкинуть, она ни на что не влияет.

Можете написать простенький скетчик с IF и проверить.

Почитайте описание оператора "запятая" в Си

я понимю, что вернее было использовать &&, но в операторе if он работает отлично, а в цикле for нифига.

b707
Онлайн
Зарегистрирован: 26.05.2017

Anytcent пишет:

я понимю, что вернее было использовать &&, но в операторе if он работает отлично, а в цикле for нифига.

а если правильно записать? :)

Кроме того, так и не нашел в коде выше цикл while. который повторяется пока разница миллис и time не станет 10000 мс. такого цикла в этом коде банально нет.

Эта фраза вообще вынос мозга: "while теперь вообще отказывается работать, он должен зацикливаться пока millis() - timer не станет меньше 10000." Спросите почему? - да потому что по ходу выполнения кода разность millis() - timer  растет, а не уменьшается. Так что если оно сейчас "не меньше". то ждать "пока оно станет меньше"- придется 49 дней

Anytcent
Offline
Зарегистрирован: 16.07.2016

b707 пишет:

Anytcent пишет:

я понимю, что вернее было использовать &&, но в операторе if он работает отлично, а в цикле for нифига.

а если правильно записать? :)

Кроме того, так и не нашел в коде выше цикл while. который повторяется пока разница миллис и time не станет 10000 мс. такого цикла в этом коде банально нет.

case 20:   
      timer = time;
      u8x8.clear();     
      digitalWrite(6, LOW);
      delay(250);
      digitalWrite(6, HIGH);
//----Начало отсчета времени за которое происходит регистрация      
      while ((millis() - timer) <= 5000) {
        u8x8.setFont(u8x8_font_px437wyse700b_2x2_r);
        u8x8.setCursor(2,2);  u8x8.print  ((millis() - timer)*0.001);
//------Запись в массив SHT времени когда данные аналогового входа 6 выше уровня         
        if (analogRead(6) >= flw) {
          if (sht[bfr] > 0) bfr++;
          sht[bfr] = ((millis() - timer)*0.001);
        }
//------Конец записи в массив-----------------------        
      } 
      timer = 0;
      bfr = 0;
      pic = 1;
//----Конец отсчета времени регистрации-------------
      digitalWrite(6, LOW);
      delay(250);
      digitalWrite(6, HIGH);
      break;

5000 простите не 10000. 

по поводу правильности я не пойму о чем вы. Что я написал не так?

 

b707
Онлайн
Зарегистрирован: 26.05.2017

Anytcent пишет:

по поводу правильности я не пойму о чем вы. Что я написал не так?

 

что-то вы почти на каждый ответ пишете "не понимаю". Может магния попить для активации мозга? :)

Составьте правильно условие с лоическим оператором && и оно одинаково хорошо будет работать и в if и в while и for

Anytcent
Offline
Зарегистрирован: 16.07.2016

ну смотрите, приравнивается timer к переменной time. Далее от millis() отнимается timer и пока оно меньше или равно 5000 то выполняется цикл while. 

тут timer является ключевой переменной которая определяет до скольки будет повторяться цикл.

 

b707
Онлайн
Зарегистрирован: 26.05.2017

Anytcent пишет:

ну смотрите, приравнивается timer к переменной time. Далее от millis() отнимается timer и пока оно меньше или равно 5000 то выполняется цикл while.

ок. только это не "пока millis() - timer не станет меньше 10000.", а пока оно не станет больше

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Прямо Баллада о борьбе

... Мы же книги читали, пьянея от строк...

А вот не читают, не думают, не ищут похожие решенные задачи.

То ТС - составьте нормальный алгоритм Вашей программы (не такой - у меня есть 2 светодиода, 3 кнопки и микрофон - хочу....), а нормальный - если кнопка 1 будет в высоком уровне, то светит светодиод 1, если кнопка 2 будет в высоком уровне, то светит светодиод 2, если кнопка 3 будет в высоком уровне, то светят оба светодиода, а если у микрофона на вводе А1 порог превысит 500, то пофиг на кнопки.

sadman41
Offline
Зарегистрирован: 19.10.2016

Разве в AVR есть команда "пофиг"?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

sadman41 пишет:
Разве в AVR есть команда "пофиг"?

Нет - так создадим! Какие наши годы:

if(Pofig==TRUE){
здеся опрашиваем кнопки
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Насколько я понял - при пофиге как раз ничего опрашивать не нужно. Поэтому, для избавления от смысловых ошибок и облегчения алгоритма, предлагаю использовать вместо команды "пофиг" ее антогониста - "непофига".

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

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

Anytcent
Offline
Зарегистрирован: 16.07.2016

поясните пожалуйста. разве SWITCH CASE не есть аналог вашего ПОФИГ НАФИГ? 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Anytcent пишет:

поясните пожалуйста. разве SWITCH CASE не есть аналог вашего ПОФИГ НАФИГ? 

Не, ну тут вообще не о том - SWITCH CASE анализирует только одну переменную и без break просмотрит все варианты, а с break только первый совпавший.

Обход части программы интереснее делать if(), а вот внутри него уже изгаляться.

Anytcent
Offline
Зарегистрирован: 16.07.2016

mykaida пишет:

Anytcent пишет:

поясните пожалуйста. разве SWITCH CASE не есть аналог вашего ПОФИГ НАФИГ? 

Не, ну тут вообще не о том - SWITCH CASE анализирует только одну переменную и без break просмотрит все варианты, а с break только первый совпавший.

Обход части программы интереснее делать if(), а вот внутри него уже изгаляться.

последовав вашему совету, все перемел в If и вроде стало лучше, вот только есть небольшая проблема все равно в цикле WHILE когда использую внутри этого цикла IF, программа виснет. 

if (pic == 20){   
      digitalWrite(6, LOW);
      delay(250);
      digitalWrite(6, HIGH);
      timer = millis();
//----Начало отсчета времени за которое происходит регистрация      
      while (millis () - timer < 5000) {
        u8x8.setFont(u8x8_font_px437wyse700b_2x2_r);
        u8x8.setCursor(2,2); u8x8.print ((millis () - timer)*0.001);
//------Запись в массив SHT времени когда данные аналогового входа 6 выше уровня         
      //if (analogRead(A6) >= flw) {
        //if (sht[bfr] > 0) bfr++;
        //sht[bfr] = ((millis () - timer)*0.001);
      //}
//------Конец записи в массив-----------------------        
    } 
    bfr = 0;
    pic = 1;
//----Конец отсчета времени регистрации-------------
    digitalWrite(6, LOW);
    delay(250);
    digitalWrite(6, HIGH);

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Anytcent пишет:

 

последовав вашему совету, все перемел в If и вроде стало лучше, вот только есть небольшая проблема все равно в цикле WHILE когда использую внутри этого цикла IF, программа виснет. 

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

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

Anytcent
Offline
Зарегистрирован: 16.07.2016

mykaida пишет:

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

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

вот смотрите. Когда начинается код, PIC = 20 мы приравниваем переменную TIMER  к MILLIS. Далее я хочу чтобы программа зашла в цикл WHILE и не выходила с него пока не закончит условие. если я, как показывал ранее внутрь цикла WHILE помещаю этот IF (это условие нужно для того чтобы в массив SHT записывать время когда данные с датчика analogRead(A6) >= flw) то у меня не работает WHILE.  Я уже закоментировал этот IF  и у меня все хорошо все заработало. А если я раскоментирую, то он вылетает с цикла.