Arduino генератор случайных неповторяющихся чисел. Генерация случайных чисел на микроконтроллерах. Линейный конгруэнтный метод

При программировании Arduino бывают случаи, когда нужно получить число, которое заранее не будет известно ни программисту, пишущему скетч, ни пользователю, который будет использовать Arduino с такой программой. В данном случае на помощь приходит генератор случайных (а точнее псевдослучайных) чисел.



Для активации этого генератора достаточно использовать функции random() или randomSeed(). В данном материале будет показано, как работать с этими функциями, а также как избавиться от псевдослучайности при генерировании чисел.


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


Итак, функция random для генерирования псевдослучайных чисел может иметь до двух параметров и записываться как random(max) или random(min, max). Здесь параметр max, который является обязательным, задает верхнюю границу диапазона генерации псевдослучайных чисел. С помощью дополнительного параметра min можно задать нижнюю границу диапазона. В итоге функция вернет какое-то псевдослучайное число в промежутке от min до max-1.


Важно понимать, что при использовании функции random() каждый раз будет сгенерирован точно такой же список псевдо случайных чисел. Например, если вы сделаете игровой автомат, и при первом нажатии рукоятки выпадет выигрышная комбинация, то вы можете быть уверены, что если перезагрузите Arduino и нажмете на рукоятку еще раз, этот игровой автомат покажет такую же выигрышную комбинацию. Действительно, на Arduino не просто реализовать игровой аппарат с полностью случайной генерацией чисел, как это, например, реализовано в игровых аппаратах www.igrovye-apparati-vulcan.com/ , но можно частично решить проблему с помощью функции randomSeed().


Эта функция принимает значение (например, целочисленное), и использует число, чтобы изменить случайный список, генерируемый функцией random().Вы можете поместить randomSeed() в функцию настройки setup, а в бесконечном цикле loop использовать функцию random(). Но и в этом случае будет загвоздка, заключающаяся в том, что хотя последовательность случайных чисел будет отличаться при использовании функции randomSeed(),она все равно будет такой же каждый раз, когда будет запускаться скетч.


Единственным решением в таком случае может быть вариант с применением аналоговой периферии (АЦП) и соответствующей функции analogRead(). Если аналоговый ввод ни к чему не подключать, то есть оставить его «висеть» в воздухе, то благодаря шуму на этой линии можно получить действительно случайные числа. Тогда в настройке setup можно записать так randomSeed(analogRead(A0)). При условии, что аналоговый порт A0 никуда не подключен.

Время и рандом. Реакция

В этот раз мы узнаем, что такое «Случайные» значения, а также научимся работать со временем.

Нам понадобятся:

  • Кнопка тактовая
  • Пищалка
  • Провода соединительные «ПАПА- ПАПА»

Реакция

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

При нажатии на левую кнопку, раздается сигнал через «случайное» время. А при нажатии на правую, отмечается, сколько времени прошло с писка до нажатия на правую кнопу.

Кто скилловый – пробует сам, а мы смотрим на схему.

#define BUZ 8 #define START 9 #define STOP 7 int time; //Переменная для синхронизации void setup() { Serial. begin(9600); pinMode(START, INPUT_PULLUP); pinMode(STOP, INPUT_PULLUP); pinMode(BUZ, OUTPUT); } void loop() { if(digitalRead(START) == 0) // При нажатии на Кнопку СТАРТ.. { int start_time = millis();// Запомним время нажатия time = start_time; //Запишем его в глобальную переменную. int Rand = random(0, 4000); //Сгенерим "случайную" задержку time = time + Rand; //Прибавим время задержки delay(Rand); //Подождем tone(BUZ, 3000, 500); //Пищим! } if(digitalRead(STOP) == 0 && digitalRead(START) == 1)// При нажатии на кнопку СТОП... { int stop_time = millis(); //Запомним время остановки. time = stop_time - time; // Вычислим разницу во времени. Serial.println("Time: "); // Выведем время в Сериал. Serial.println(time); delay(1000); } } //Перед второй попыткой нажимай на кнопку СТАРТ снова.

Пояснения

int time; Переменным(не всем), при их обозначении, не обязательно задавать какое-либо значение. Эту переменную мы использовали для того, чтобы связать два оператора if.

В С++ переменные, объявленные внутри цикла, не будут доступны в других циклах, так как они действуют только внутри этого цикла. Это делается для того, чтобы предотвратить ошибки в программировании. Когда код программы разрастется, ты поймешь, о чем я говорю.

Чтобы переменная была доступна для нескольких операторов, нужно сделать ее глобальной. Т.е. объявить переменную вне функций.

millis(); Возвращает количество миллисекунд, прошедших с запуска программы.

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

random(min, max); Это генератор «случайных» чисел. Принимает два значения. Он генерирует число в диапазоне от min до max.

«Случайные» числа потому, что это определенная последовательность значений. Очень длинная, но одна и та же. Для того чтобы получать разные последовательности, стоит воспользоваться Random Seed();

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

Вывод

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

Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
Плата Arduino

Arduino Uno

1 В блокнот
Макетная плата Breadboard-half 1 В блокнот
Пьезоизлучатель Пассивный 1 В блокнот
Кнопка тактовая Без фиксатора 2 В блокнот
Соединительные провода "Папа-Папа" 1

randomSeed (seed)

Устанавливает значение, или начальное число, в качестве начальной точки функции random().

randomSeed (value); // задаѐт ‘value’ как начальное значение random

Поскольку Arduino не может создавать действительно случайных чисел, randomSeed позволяет вам поместить переменную, константу или другую функцию в функцию random, что помогает генерировать более случайные

«random» числа. Есть множество разных начальных чисел, или функций, которые могут быть использованы в этой функции, включая millis(), или даже analogRead() для чтения электрических шумов через аналоговый вывод.

random (max)

random (min, max)

Функция random позволяет вам вернуть псевдослучайное число в диапазоне, заданном значениями min и max.

value = random (100, 200); // задаѐт ‘value’ случайным

// числом между 100 и 200

Примечание: Используйте это после использования функции randomSeed(). Следующий пример создаѐт случайное число между 0 и 255 и выводит PWM

сигнал на PWM вывод, равный случайному значению:

int randNumber; // переменная для хранения случайного значения

int led = 10; // LED с резистором на выводе 10

void setup() {} // setup не нужен

randomSeed (millis()); // задаѐт millis() начальным числом

randNumber = random (255); // случайное число из 0 – 255 analogWrite (led, randNumber); // вывод PWM сигнала

delay (500); // пауза в полсекунды

Источник: Гололобов В. – С чего начинаются роботы. О проекте Arduino для школьников (и не только) – 2011

Related Posts

Serial.begin (rate) Открывает последовательный порт и задаѐт скорость для последовательной передачи данных. Типичная скорость обмена для компьютерной коммуникации - 9600, хотя поддерживаются и другие скорости. void setup () { Serial.begin…….

Все переменные должны быть задекларированы до того, как они могут использоваться. Объявление переменной означает определение типа еѐ значения: int, long, float и т.д., задание уникального имени переменной, и дополнительно ей…….

Хорошо, мы установили эту программу. Мы отладили «механизм» работы с модулем. И посмотрели несколько примеров. Но хотелось бы и самим создавать что-то полезное. Попробуем. Сначала закроем предыдущий проект. Для этого…….

Внимание! При работе с модулем Arduino в других средах разработки следует внимательно относиться к конфигурации микроконтроллера (Fuses). До тех пор, пока вы точно не знаете, к чему может привести изменение…….

  • Сергей Савенков

    какой то “куцый” обзор… как будто спешили куда то