Рандомное включение светодиодов
- Войдите на сайт для отправки комментариев
Вс, 23/02/2020 - 22:59
Здравствуйте.
Помогите решить задачку.
Нужно рандомно по очереди по одному включать 10 светодиодов каждые 5 секунд. И при необходимости, также рандомно по одному выключать.
функция "рандом" не подойдет, так как она может повторять значения из диапазона (от 1 до 10).
Хотя бы подскажите куда копать.
Подойдет, если не полениться и дописать пару строчек, обеспечивающих требуемые условия.
Я не знаю как исключить из диапазона рандома те светодиоды которые уже включены.
Хотя если подумать то наверное можно.
Но что-то в две строчки пока не помещаюсь, точнее далеко не в две)
Так а в чём именно проблема? Как узнать, включен ли светодиод по номеру, который вернул random? Заводите массив на 10 светодиодов. Заводите переменную - счётчик, которая хранит номер текущей ячейки для записи в массив. Как надо включить - начинаете бесконечный цикл, внутри которого: получаете рандомное число, проверяете, есть ли оно в ячейках до счётчика. Если есть - получаете новый random. Если нет - зажигаете светодиод, пишете номер, полученный random, в ячейку, на которую указывает счётчик, увеличиваете счётчик на 1, вываливаетесь из цикла. Проверяете - если счётчик равен 10 - зажгли все светодиоды.
Тушить - примерно в том же разрезе.
Похоже как люди садятся писать программу, то здравый смысл их оставляет.А может его и не было изначально. ведь живут же люди без здравого смысла и это не смертельно. Вот мне представляется можно выбрать один из вариантов. 1 тогда их можно выключить. 2 передернуть рандом еще раз.
Заводите массив на 10 светодиодов. Заводите переменную - счётчик,
Тушить - примерно в том же разрезе.
Спасибо, буду пробовать.
С массивом должно получиться компактнее.
Хорошая задача, интересная, в плане обучения и получения навыков разработки простейших алгоритмов. Удачи Вам :)
Так а в чём именно проблема? Как узнать, включен ли светодиод по номеру, который вернул random? Заводите массив на 10 светодиодов. Заводите переменную - счётчик, которая хранит номер текущей ячейки для записи в массив. Как надо включить - начинаете бесконечный цикл, внутри которого: получаете рандомное число, проверяете, есть ли оно в ячейках до счётчика. Если есть - получаете новый random. Если нет - зажигаете светодиод, пишете номер, полученный random, в ячейку, на которую указывает счётчик, увеличиваете счётчик на 1, вываливаетесь из цикла. Проверяете - если счётчик равен 10 - зажгли все светодиоды.
Тушить - примерно в том же разрезе.
Правильный - такой:
1. Заводим массив на 10 элементов.
2. Заносим в массив числа от 1 до 10.
3. Используя random (*) перемешиваем массив.
В результате у нас в массиве в случайном порядке будет 10 уникальных чисел, каждое - ровно по одному разу. И, самое главное, без всяких бесконечных циклов.
(*) Примечание: где взять случайное число в микроконтроллере - вопрос отдельный.
PS. Если нам нужна перемешанная колода карт, как мы будем поступать?
1. Соберем 100500 колод вместе, высыпаем в большую емкость, будем из емкости выбирать по одной карте, проверяя, не встретилась ли повторная.
2. Берем единственную колоду и тасуем ее.
А так сойдёт? Тренировка после 23-го.)
В бесконечных циклах меня смущает одно, их бесконечность в случае постоянного (или очень долгого) выпадания одних и тех же, выпадавших ранее, номеров. Пока не знаю, может на практике такого и не будет. По крайней мере, я представляю как это (вариант 1) реализовать.
Алгоритм с перемешиванием массива (вариант 2), мне изначально показался проще, пока не задумался, а как перемешать массив, не используя тот же бесконечный цикл? Пока ничего не придумал.
Это первая задача, где пришлось подумать. Было еще в те времена, когда интернета не было. Нужно было перемешать колоду карт. Быстро стало понятно, что проверять каждое случайное число на наличие в массиве можно будет очень долго, особенно ближе к концу заполнения. Крепко задумавшись пришел к правильному выводу, который тут уже рассказали. Нужно просто перемешать массив. Заполняете массив нужными значениями, делаете цикл желаемого размера, генерируете два случайных числа не больше размеров массива и меняете местами значения этих элементов массива. Длина цикла берется на глаз, чтобы точно быть больше размеров массива. Думаю, что для вашей задачи сто раз прогнать алгоритм будет достаточно.
В общем и целом, надо сначала подумать. И в нынешние времена это очень сложно, я знаю.
"Да что там думать - трясти надо!"
"Да что там думать - трясти надо!"
покажите где палка лежит.
#9
Так а в чём именно проблема?
Правильный - такой:
И тот, и другой алгоритм - правильный, потому что - рабочий. И тот, и другой алгоритм - не более, чем тренировка навыков. Лично я - подключил бы stl и поюзал бы random_shuffle, но говорить об этом новичку - только запутывать.
#9
разбираюсь.
если я правильно понял, пока не будут выполнены действия со всеми светодиодами, ничего больше делать нельзя. но это можно подправить.
но пока не могу понять, этот алгоритм рандомно включает выключенные светодиоды и выключает включенные?
а нужно, чтоб все включились, а потом при необходимости выключились.
может пока не разобрался с "back"
Я где-то в теме про наливатор выкладывал пример случайного перебора тостов, без повторения. Можно его и на числа переделать. Ссылку с планшета не дам, где-то на 8-10 странице. Паматри
Всё строго по ТЗ ТС.) "Полная" случайность - ещё пару строк.
Прибедняться не надо.)
Если нужен "случайный рандом":
А randomSeed() в размерности байта действительно имеет смысл?
Конечно. Только 256 псевдослучайностей думаю достаточно для индейца "нетренированный глаз"?
Я когда-то разбирался с этим randomSeed() - там и результат analogRead() оказался не пришитым к кобыле хвостом.
Да. Думаю из за того что аналог менялся незначительно. Вот если бы руку на этот вход положить...)
Зачем руку, можно зенер с резистором.
Привычка.) Рука по молодости помогала находить обрывы в CMOS цепях.)
А, я нашёл ту тему. analogRead() не хватало, чтобы "настоящую" энтропию засеять. Первое число всегда получалось кратным 7.
а если помножить время на analogRead(), ну и соответственно брать младшие разряды :)))))))))))
Ну если один из множителей имеет малую девиацию, то хоть на что его не множь - всё равно получится член.)
Что-то вчерашний день навеял: https://www.anekdot.ru/id/-1080619021/
+1. Я имел ввиду что второй множитель (время) без изменений. А ведь так оно и получается.)
Ну, rkit! Тут вроде как раздел для новичков... И если новички простой пример не могут одолеть, то вы их запугаете окончательно.
+1. Я имел ввиду что второй множитель (время) без изменений. А ведь так оно и получается.)
эх, согласен... но все одно для разных случаев может оказаться пригодным, при определенном допилинге. Рандом на МК штука неоднозначная, сложная и путей решения условно несколько...
А нельзя случайность запрограммировать? Например, рандомить в диапазоне 0-2, собирать из этих попыток длинные числа 0-255 потом делить на 25 (26) и получить истинно случайное от 1 до 10 скажем?
Нет, потому что числа будут повторяться при каждом запуске. Она (функция random()) потому и называется псевдо-рандомный генератор. Числа даже и с randomSeed(analogRead(0)) будут часто повторяться, потому что инициальное энтропийное число будет тем же самым, что и при предыдущих включениях. Их можно немножко разнообразить, подавая на аналоговый вход полупроводниковый шум, и для большинства любительских применений этого будет достаточно. Тема очень обширная и сложная.
Есть даже специальные модули для генерации рандома. https://www.aliexpress.com/item/32848297519.html
Для местного применения с ардуино - за глаза. Для шифрования банковских транзакций не подойдёт.
Ахренеть.
Какой кошмар! Столько усилий и соображалок чтоб сделать так, а не иначе, исключить любую случайность при программировании и вот итог - запрограммировать её нельзя!
А если серьёзно неужели нет скетчей если не про чистую случайность, то про иллюзию её?
Берём К155ЛА3 (для надёжности), делаем генератор на оч. большую частоту, с кривым кондёром и резистором и читаем выход на Ардуину. Не?
Берём К155ЛА3 (для надёжности), делаем генератор на оч. большую частоту, с кривым кондёром и резистором и читаем выход на Ардуину. Не?
не, "генератор белого шума" обычно на стабилитроне делают, погуглите... как выше написано - тема огромная.
Для домашнего применения - есть. https://github.com/sirleech/TrueRandom
Отключает ацп, включает, берёт последний бит, набирает из этих битов число. Но энтропия всё равно маленькая.
С генератором на 155ла3 не выйдет. Простейшее решение - использовать avalanche noise диода Зенера (#24), по-русски - стабилитрона. Можно и купить, вот фирменный чип для рандома http://www.fdk.com/cyber-e/pi_ic_rpg100.html
А вот более продвинутые хардварные решения для рандома https://www.idquantique.com/shop/online-shop/
Для задачи ТС это всё абсолютно не нужно :) #9 или #31 - отлично справится.
Алгоритм с перемешиванием массива (вариант 2), мне изначально показался проще, пока не задумался, а как перемешать массив, не используя тот же бесконечный цикл? Пока ничего не придумал.
всем большое спасибо за помощь.
информации получил предостаточно, буду разбираться и тестировать.
спасибо