Курс Arduino - Время и Random. Генерация случайных чисел на микроконтроллерах Регистр сдвига с линейной обратной связью

При программировании 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). До тех пор, пока вы точно не знаете, к чему может привести изменение…….