Рандомные события в рамках заданной частоты.

Nanimonai

✩✩✩✩✩✩✩
9 Апр 2020
6
0
Добрый день.
Я новичок в делах ардуино. И это мой первый самостоятельный проект.

Хочу сделать гирлянду с рандомно-вспихивающими и тухнущими диодами. Данные о состояние диодов хочу хранить в массиве. Далее в цикле пробегать по данному массиву и, в зависимости от флага состояния диода, выполнять действия из switch'a. Вроде бы все ок, но возникли проблемы с задержкой вспышек. В момент полного затухания ставится флаг на ожидание и кидается рандом для определения задержки и значение заносится в массив. В блоке switch'a, который отрабатывает данную задержку есть сравнение, в котором сравнивается текущее сначение счетчика (так же хранится в массиве) и значение задержки выбранного при окончании затухания. Если больше или равно, то переключаемся в рост, если меньше, то добавляем единицу в текущее значение.

Вроде все логично, но в какой-то момент все вырождается в картину на скриншоте, как бы я не крутил лимиты в рандоме.


1586428482618.png

Делать переключение просто по рандому не хочется, хотя оно хоть как-то работает. Просто хочу управлять периодом задержки более точно.

Код следующий:
C++:
const int minVal = 40;
const int maxVal = 255;
const int maxInterval = 2000;

// Массив данных в диодах.
//0 - пин диода
//1 - состояние (0 : в покое, 1 : приростает, 2 : убывает)
//2 - текущее значение яркости
//3 - предыдущее значение (previousMillis)
//4 - interval
int pinArray[][5] = {
  {2, 0, 40, 0, 150}
  , {3, 0, 200, 0, 150}
  , {4, 0, 100, 0, 150}
};

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("val1 , val2 , val3");

}

void loop() {

  for (int i = 0; i < sizeof(pinArray) / sizeof(pinArray[0]); i++) { // идем по массиву светодиодов
    switch (pinArray[i][1]) {
      case 1:   // Увеличение яркости
        if (pinArray[i][2] >= maxVal) {
          pinArray[i][1] = 2; // Яркость достигла максимума, переключаем на затухание
        } else {
          pinArray[i][2] = pinArray[i][2] + 10; // Добавляем яркости
        }
        break;
      case 2: // Уменьшение яркости
        if (pinArray[i][2] <= minVal) {
          pinArray[i][1] = 0; // Ярсокость достигла минимума, переключаем в ждущий режим
          pinArray[i][4] = random(1000, maxInterval); // гененируем интервал задержки

        } else {
          pinArray[i][2] = pinArray[i][2] - 5; // Уменьшаем яркость
        }
        break;
      case 0: // Этап задержки

        if (pinArray[i][3] >= pinArray[i][4]) { // Сравниваем значение счетчика в массиве со сначением задержки, если счетчик больше, то переключаем в режим увеличения яркости
          pinArray[i][1] = 1;
        } else {
          pinArray[i][3]++; // Если счетчик меньше, то добавляем значение к нему.
        }

        break;
    }
    // Вывод графиков
    if (i == (sizeof(pinArray) / sizeof(pinArray[0])) - 1) {
      Serial.println(pinArray[i][2]);
    } else {
      Serial.print(pinArray[i][2]);
      Serial.print(",");
    }
  }
}
Пробовал с millis(). Вот вариант case:0 выглядит так:
C++:
    long currentMillis = millis();
        if (currentMillis - pinArray[i][3] >= pinArray[i][4]) {
          pinArray[i][1] = 1;
          pinArray[i][5] = currentMillis;
        }
Помогите придумать как это сделать красивее и простите за глупые вопросы. Если все это было на форуме, то ткните, пожалуйста, меня мордой туда.
 
Изменено:

kalobyte

★★★✩✩✩✩
1 Янв 2020
724
148
покажи видео
из твоего кода ничего непонятно и оформляй код в теге для кода и с подсветкой для языка
 
  • Лойс +1
Реакции: Shalom

Nanimonai

✩✩✩✩✩✩✩
9 Апр 2020
6
0
покажи видео
из твоего кода ничего непонятно и оформляй код в теге для кода и с подсветкой для языка
Видео чего? Тут пока схемы нет, голая плата. Это этап только генерации вспышек. Мониторю результат в плоттере.
 

kalobyte

★★★✩✩✩✩
1 Янв 2020
724
148
видео работы мигалки
что ты видиш в плоттере - это для тебя понятны только, т.к. только в твоей голове есть образ того, как должно работать и как работает неправильно
я не телепат, поэтому я понятия не имею, как должно работать и как работает неправильно, я просто тупо вижу 3 графика и они мне ни о чем не говорят

схема мне не нужна, я просто хочу видеть эти вспышки и пояснение, что с ними не так
 

Nanimonai

✩✩✩✩✩✩✩
9 Апр 2020
6
0
видео работы мигалки
что ты видиш в плоттере - это для тебя понятны только, т.к. только в твоей голове есть образ того, как должно работать и как работает неправильно
я не телепат, поэтому я понятия не имею, как должно работать и как работает неправильно, я просто тупо вижу 3 графика и они мне ни о чем не говорят

схема мне не нужна, я просто хочу видеть эти вспышки и пояснение, что с ними не так
Вспышек нет. Диоды еще не прикручены, голая плата. Весь вывод в плоттер. Это значения, которые я буду в будущем передавать в диод. Должны быть всплески на графике (зажжение и затухание диода) в рандомное время, но при этом с ограничением по минимуму и максимуму между всплесками.
Примерно так.
1586442564509.png

Это сделано если в case 0: заменить код на:
C++:
 if (random(0, 100000) > 99900) {
          pinArray[i][1] = 1;
        }
Но в данном случае не угадаешь сколько может не гореть тот или иной диод (в конкретном случае, не появится всплеск на графике). Я же пытаюсь создать систему, при которой максимальный и минимальный период между работой диода (всплесками на графике) регулировался. В коде в ОП посте спустя некоторое время график вырождается в простые колебания, что на первом скрине.
 
Изменено:

Nanimonai

✩✩✩✩✩✩✩
9 Апр 2020
6
0
Да. Примерно. Тут, как я понял, мигают рандомно светодиоды в ленте с рандомной частотой?
Попробую еще немного ясности внести.
В общем я хочу сделать группу светодиодов в которой каждый загорается и гаснит в рандомное время, но просо рандомом определять сейчас загорится или нет не хочу. Нужно контролировать минимум и максимум времени между вспышками.
 
Изменено:

kalobyte

★★★✩✩✩✩
1 Янв 2020
724
148
с рандомной частотой?
частота одинаковая, просто в рандомных местах зажигаются и рандомные цвета, но плавного наростания яркости нет

Нужно контролировать минимум и максимум времени между вспышками.
и в чем гимор? подключи ленту и смотри на реальных диодах
 

Nanimonai

✩✩✩✩✩✩✩
9 Апр 2020
6
0
Очень похоже. Буду разбираться как оно работает на будущее.

В итоге доделал свой код. Просто забыл обнулить переменную счетчика. Сделал это на 39 строке.
C++:
const int minVal = 40;
const int maxVal = 255;
const int minInterval = 500;
const int maxInterval = 1000;

// Массив данных в диодах.
//0 - пин диода
//1 - состояние (0 : в покое, 1 : приростает, 2 : убывает)
//2 - текущее значение яркости
//3 - предыдущее значение (previousMillis)
//4 - interval
int pinArray[][5] = {
  {2, 0, 40, 0, 150}
  , {3, 0, 200, 0, 150}
  , {4, 0, 100, 0, 150}
};

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("val1 , val2 , val3");

}

void loop() {

  for (int i = 0; i < sizeof(pinArray) / sizeof(pinArray[0]); i++) { // идем по массиву светодиодов
    switch (pinArray[i][1]) {
      case 1:   // Увеличение яркости
        if (pinArray[i][2] >= maxVal) {
          pinArray[i][1] = 2; // Яркость достигла максимума, переключаем на затухание
        } else {
          pinArray[i][2] = pinArray[i][2] + 10; // Добавляем яркости
        }
        break;
      case 2: // Уменьшение яркости
        if (pinArray[i][2] <= minVal) {
          pinArray[i][1] = 0; // Ярсокость достигла минимума, переключаем в ждущий режим
          pinArray[i][3] = 0; // Вот тут забыл обнулить счетчик.
          pinArray[i][4] = random(minInterval, maxInterval); // гененируем интервал задержки

        } else {
          pinArray[i][2] = pinArray[i][2] - 5; // Уменьшаем яркость
        }
        break;
      case 0: // Этап задержки

        if (pinArray[i][3] >= pinArray[i][4]) { // Сравниваем значение счетчика в массиве со сначением задержки, если счетчик больше, то переключаем в режим увеличения яркости
          pinArray[i][1] = 1;
        } else {
          pinArray[i][3]++; // Если счетчик меньше, то добавляем значение к нему.
        }

        break;
    }
    // Вывод графиков
    if (i == (sizeof(pinArray) / sizeof(pinArray[0])) - 1) {
      Serial.println(pinArray[i][2]);
    } else {
      Serial.print(pinArray[i][2]);
      Serial.print(",");
    }
  }
}
Тред можно закрывать)
 

kalobyte

★★★✩✩✩✩
1 Янв 2020
724
148
покажи тогда график, чтобы и другим было понятно
 

Nanimonai

✩✩✩✩✩✩✩
9 Апр 2020
6
0
Рандомные всплески на графике где количество времени между каждым всплеском для каждого графика находится в заданных рамках.
1586497507919.png