litbaza книги онлайнРазная литератураЭлектроника для начинающих (2-е издание) - Чарльз Платт

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 110 111 112 113 114 115 116 117 118 ... 128
Перейти на страницу:
где вы найдете секцию Random Numbers. Там вы обнаружите специально созданную для контроллера Arduino функцию под названием random().

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

А если вы желаете, чтобы последовательность начиналась с другого числа? Для этого есть другая функция ПОД названием randomSeed(), которая запускает генератор чисел в зависимости от состояния вывода микроконтроллера, который ни к чему не подключен. Как я уже упоминал ранее, «плавающий» логический вывод улавливает окружающее электромагнитное излучение, и вы никогда не узнаете, что от него ожидать. Поэтому значение randomSeed() может оказаться в полном смысле слова случайным, и его использование даст хороший результат, но следует помнить, что «плавающий» контакт нельзя задействовать для чего-либо еще.

Отложим ненадолго вопрос о начальном значении для генератора случайных чисел. Давайте предположим, что случайное значение генерирует функция random() и затем из него формируется число в качестве выходного значения программы имитации игральных костей. Как это реализовать?

Я думаю, игрок будет нажимать кнопку, и в этот момент отобразится случайно выбранная конфигурация точек на кубике. Готово! Затем, если вам нужно «кинуть кости» повторно, вы просто нажимаете кнопку еще раз, и появляется другая, выбранная случайным образом, комбинация точек на кубике.

Это нам подходит, но выглядит не очень правдоподобно. Люди могут задаться вопросом, на самом ли деле это случайное число? Полагаю, проблема в том, что пользователь лишен возможности управлять процессом.

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

Может быть, программа должна работать именно так, а не использовать функцию random()?

Она может вести отсчет от 1 до 6 снова и снова очень быстро – как микросхема счетчика в аппаратной версии игральных костей.

Но теперь возникают другие сложности. Когда программа считает от 1 до 6, а затем повторяет счет, микроконтроллеру, как я думаю, понадобится еще несколько микросекунд, чтобы вернуться к началу цикла. Поэтому число «6» всегда будет отображаться чуть дольше, чем другие числа.

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

Мне нравится этот план. Но что потом? Не придется ли добавить еще одну кнопку, чтобы перезапустить быстрое отображение чисел? Хотя, нет, это излишне: одна и та же кнопка выполнит обе операции. Нажмите, чтобы остановить, снова нажмите, чтобы перезапустить.

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

Алгоритм

Мне нравится составлять алгоритм в виде последовательности предложений, которые очень легко перевести на язык компьютера. Вот мой план алгоритма для программы, которую я назвал «Точные игральные кости». Имейте в виду то, что эти инструкции будут выполняться очень быстро, и в результате числа окажутся размытыми.

Основной цикл:

• Шаг 1. Выбрать случайное число.

• Шаг 2. Преобразовать его в конфигурацию точек на игральной кости и зажечь соответствующие светодиоды.

• Шаг 3. Проверить, нажата ли кнопка.

• Шаг 4. Если кнопка не нажата, вернуться к Шагу 1 и выбрать другое случайное число, чтобы быстро продолжить последовательность. Иначе…

• Шаг 5. Остановить индикацию на дисплее.

• Шаг 6. Подождать, пока игрок не нажмет кнопку повторно. После этого вернуться к Шагу 1 и повторить.

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

Нет, потому что некоторых инструкций не хватает. Шаг 2 говорит «зажечь соответствующие светодиоды», но нигде нет инструкции по их выключению!

Внимание!

Вы всегда должны помнить: компьютер делает только то, что вы ему приказываете.

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

Где она должна быть? Необходимо гасить дисплей пред выбором и отображением каждого нового числа. Поэтому правильное место для сброса дисплея находится в начале основного цикла. Добавим его так:

• Шаг 0. Выключить все светодиоды.

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

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

Обработка состояния кнопки

Что еще пропущено в списке шагов алгоритма? Кнопка.

Необходимо еще раз представить, какие действия я ожидаю от программы. На дисплее очень быстро сменяются числа. Игрок нажимает кнопку, чтобы остановить индикацию. Дисплей замирает, показывая текущее значение. На Шаге 6 микроконтроллер ждет неопределенно долго, пока игрок не нажмет кнопку снова, чтобы вновь запустить быстрое отображение.

Минуточку. Как игрок сможет нажать кнопку снова, не отпустив ее вначале?

На самом деле, если оставить текущий вариант алгоритма, то микроконтроллер будет делать следующее (учтите, что он выполняет задания очень-очень быстро):

• Программа говорит микроконтроллеру проверить кнопку.

• Микроконтроллер обнаруживает, что кнопка нажата.

• Дисплей замирает. Микроконтроллер ждет, когда кнопка будет нажата снова.

• Но он обнаруживает, что кнопка по-прежнему нажата, потому что игрок еще не успел отпустить ее.

• Микроконтроллер действует так: «Кнопка нажата, поэтому я должен возобновить быстрое отображение цифр».

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

Вот решение проблемы – дополнительный шаг в последовательности:

• Шаг 5А. Дождаться момента, когда игрок отпустит

1 ... 110 111 112 113 114 115 116 117 118 ... 128
Перейти на страницу:

Комментарии
Минимальная длина комментария - 20 знаков. Уважайте себя и других!
Комментариев еще нет. Хотите быть первым?