While или не while ?

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Простой скетч , писал сам и запутался потому что не хочет работать правильно.

Бегущий огонек , должен остановиться в случайном месте и мигать. 

Но всегда останавливается на 10 . Если поменять while на if  то все значения правильные . Но мне нужен while .

Где ошибка ?

int duration;
int startled;

int l1 = 18;
int l2 = 3;
int l3 = 4;
int l4 = 5;
int l5 = 6;
int l6 = 7;
int l7 = 8;
int l8 = 9;
int l9 = 10;
int l10 = 11;
int l11 = 12;
int l12 = 13;
int l13 = 14;
int l14 = 15;
int l15 = 16;
int l16 = 17;

int lp[] = {l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16};
//int pin = 2;
void setup() {
  Serial.begin(9600);
  for (int i = 0; i < 16; i++) {
    pinMode(lp[i], OUTPUT);
    digitalWrite(lp[i], LOW);
  }
}

void loop() {
  duration = random(16);
  digitalWrite(lp[startled], HIGH);
  delay(150);
  digitalWrite(lp[startled], LOW);
  startled ++;
  if ( startled > 15 ) {
    startled = 0;
  }
  while (duration == 0 ) {
    Serial.print("startled   ");
    Serial.println(startled);
    digitalWrite(lp[startled], HIGH);
    delay(50);
    digitalWrite(lp[startled], LOW);
    delay(50);
  }



}

 

b707
Offline
Зарегистрирован: 26.05.2017

может дело в том, что random(x) при постоянном x всегда выдает одну и ту же последовательность

Попробуйте вывести значение duration в Сериал на каждом цикле

kalapanga
Offline
Зарегистрирован: 23.10.2016

Так и задумано. Вам это нужно: http://arduino.ru/Reference/RandomSeed

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

b707 пишет:

может дело в том, что random(x) при постоянном x всегда выдает одну и ту же последовательность

Попробуйте вывести значение duration в Сериал на каждом цикле

Если смотреть перед while то всегда 10. Стоит заменить while на if - значения случайные.

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

kalapanga пишет:

Так и задумано. Вам это нужно: http://arduino.ru/Reference/RandomSeed

С RandomSeed  тоже самое .

strarbit
Offline
Зарегистрирован: 12.06.2016

С того  if...else if...else это проверка условие
while это цикл и проверка условие
duration в while не имеет возможность получить новое значение от функция random. если duration == 0, то выполняется в while

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

strarbit пишет:

С того  if...else if...else это проверка условие
while это цикл и проверка условие
duration в while не имеет возможность получить новое значение от функция random. если duration == 0, то выполняется в while

Спасибо! Как же мне поступить в моем случае ?

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

Зачем вам этот while-то? 

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

sadman41 пишет:

Зачем вам этот while-то? 

Для того чтобы остановить все и моргать последним светодиодом .

Больше никакие действия не нужны.

strarbit пишет:

С того  if...else if...else это проверка условие
while это цикл и проверка условие
duration в while не имеет возможность получить новое значение от функция random. если duration == 0, то выполняется в while

Вы правы ! Спасибо еще раз!

Вот так работает почти как нужно. Буду доделывать . Главное помогли вычислить ошибку.

int duration;
int startled;

int l1 = 18;
int l2 = 3;
int l3 = 4;
int l4 = 5;
int l5 = 6;
int l6 = 7;
int l7 = 8;
int l8 = 9;
int l9 = 10;
int l10 = 11;
int l11 = 12;
int l12 = 13;
int l13 = 14;
int l14 = 15;
int l15 = 16;
int l16 = 17;

int lp[] = {l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16};
//int pin = 2;
void setup() {
  Serial.begin(9600);
  for (int i = 0; i < 16; i++) {
    pinMode(lp[i], OUTPUT);
    digitalWrite(lp[i], LOW);
  }
}
void loop() {
  //duration = random(16);
  digitalWrite(lp[startled], HIGH);
  delay(50);
  digitalWrite(lp[startled], LOW);
  startled ++;
  if ( startled > 15 ) {
    startled = 0;
  }
  while ( duration = random(16) == 0 ) {
    for (int i = 0; i <= 25; i++) {
      Serial.print("startled   ");
      Serial.println(startled);
      digitalWrite(lp[startled], HIGH);
      delay(50);
      digitalWrite(lp[startled], LOW);
      delay(50);
   
    }
  startled = 0;
  }

}

 

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

Ну, если надо, то...

const uint8_t l1 = 18;
const uint8_t l2 = 3;
const uint8_t l3 = 4;
const uint8_t l4 = 5;
const uint8_t l5 = 6;
const uint8_t l6 = 7;
const uint8_t l7 = 8;
const uint8_t l8 = 9;
const uint8_t l9 = 10;
const uint8_t l10 = 11;
const uint8_t l11 = 12;
const uint8_t l12 = 13;
const uint8_t l13 = 14;
const uint8_t l14 = 15;
const uint8_t l15 = 16;
const uint8_t l16 = 17;

uint8_t lp[] = {l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16};

void setup() {
  uint8_t currentLedIdx, lastLedIdx;

  //Serial.begin(9600);
  for (uint8_t i = 0; i < sizeof(lp); i++) {
    pinMode(lp[i], OUTPUT);
    digitalWrite(lp[i], LOW);
  }

  randomSeed(A0);
  currentLedIdx = 0x00;
  //currentLedIdx = random(sizeof(lp));
  lastLedIdx = random(sizeof(lp));

  for (uint8_t i = 0; i < sizeof(lp); i++) {
    digitalWrite(lp[currentLedIdx], HIGH);
    delay(150);
    digitalWrite(lp[currentLedIdx], LOW);
    currentLedIdx = (currentLedIdx + 1) % sizeof(lp);
    if (currentLedIdx == lastLedIdx)
      break;
  }

  while (true) {
    digitalWrite(lp[lastLedIdx], HIGH);
    delay(50);
    digitalWrite(lp[lastLedIdx], LOW);
    delay(50);
  }
}

void loop() {}

 

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Sadman41, Спасибо большое !

Уменя еще 2 вопроса по вашему коду. 

Строка 29 randomSeed(A0) ,у меня это 14 нога и она настроена на выход . Зто никак не влияет на работу ?

И второе -  while (true) . Можете объяснить что это значит , как работает.

Ваш код в работе не проверял , смогу только завтра.

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

mobistrike пишет:

Уменя еще 2 вопроса по вашему коду. 

Строка 29 randomSeed(A0) ,у меня это 14 нога и она настроена на выход . Зто никак не влияет на работу ?

И второе -  while (true) . Можете объяснить что это значит , как работает.

Возьмите другую ногу, которая болтается в воздухе. Главное - чтобы в randomSeed прилетело более-менее случайное число. Тогда random() будет ходить разнообразней.

while (true) - бесконечный цикл. while работает пока условие выполняется, т.е. равно true.

mobistrike пишет:

Ваш код в работе не проверял , смогу только завтра.

Я тоже не проверял, но теоретически работать должно. Хотя я не особо понял, зачем вы завели кучу переменных, потом сослались на них в массиве...

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

sadman41 пишет:

 

Я тоже не проверял, но теоретически работать должно.

И снова здравствуйте !

Sadman41, по вашему коду - если randomSeed(A5); огонек всегда останавливается на l6,если randomSeed(A6) огонек всегда останавливается на l13 ,если randomSeed(A7) огонек всегда останавливается на l4.

Входы A5,A6,A7 висят в воздухе .

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

Ну... придется какой-то проводок ко входу приделать, чтобы лучше фонило ))

Можете просто в setup пустого скетча вставить randomSeed, и печать random(). Без randomSeed на каждом ребуте должно одно и то же печататься. С randomSeed(какой-то аналоговый выход) - разное. Подберите вход и проводок, чтобы разброс был по числам.

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

sadman41 пишет:

Ну... придется какой-то проводок ко входу приделать, чтобы лучше фонило ))

Можете просто в setup пустого скетча вставить randomSeed, и печать random(). Без randomSeed на каждом ребуте должно одно и то же печататься. С randomSeed(какой-то аналоговый выход) - разное. Подберите вход и проводок, чтобы разброс был по числам.

Запустил это 

long randNumber;

void setup(){
  Serial.begin(9600);
  randomSeed(analogRead(A5));
}

void loop(){
  randNumber = random(16);
  Serial.println(randNumber);

  delay(50);
}

С randomSeed имеем это

6
5
3
11
3
8
15
12
14
6
14
13
10
15
15
4
3
12
14
14
15
12
4
5
7
15
12
3
9
13
6
15
6

+++++++++++РЕБУТ 
15
8
1
15
2
7
8
3
0
6
2
8
7
14
14
14
1
11
2
12
13
0
9
12
9
11
4
2
14
12
9
5
6
12
11
15
15
6
0

Без него это 

7
1
9
10
2
8
8
14
3
13
8
5
12
2
3
7
7
1
8
4
15
1
13
5
8
5
11
6
8
7
9
2
8
3
2
1
3
13
3
5
15
0
1
РЕБУТ++++++++++++
7
1
9
10
2
8
8
14
3
13
8
5
12
2
3
7
7
1
8
4
15
1
13
5
8
5
11
6
8
7
9
2
8
3
2
1
3
13
3
5
15
0
1

Все в точности как вы сказали . Никаких проводков не паял .

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

Как до ардуины доберусь - проверю свой скетч на терминальном выводе.

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

Ну, вобщем, проблемы две: 
1) в randomSeed(A0) я почему-то забыл analogRead();
2) вызывать randomSeed с чтением аналогового пина после перевода его в OUTPUT (в массиве пины 14...17 - A0-A3) не слишком хорошая идея ;) Нужно делать это до данной процедуры - где-то прямо на 22-й строке.

После вышеуказанных исправлений всё бегает от нулевого элемента массива до случайного.

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

sadman41 пишет:

Ну, вобщем, проблемы две: 
1) в randomSeed(A0) я почему-то забыл analogRead();
2) вызывать randomSeed с чтением аналогового пина после перевода его в OUTPUT (в массиве пины 14...17 - A0-A3) не слишком хорошая идея ;) Нужно делать это до данной процедуры - где-то прямо на 22-й строке.

После вышеуказанных исправлений всё бегает от нулевого элемента массива до случайного.

sadman41, еще раз благодарю за помощь.