===== Эксперимент 27. Электронная игральная кость =====
Проведем более сложный эксперимент. Создадим действующее и полезное устройство − электронную игральную кость. Она может быть очень полезной при игре в различные настольные игры. По нажатию на кнопку устройство будет генерировать случайное число в промежутке от 1 до 6 и показывать его на 7и сегментном индикаторе.
==== Схема эксперимента ====
Оставим собранную ранее схему без изменений.
{{ :products:esp-iot:exp11_sch.png?nolink |}}
//Рисунок 1. Электрическая принципиальная схема эксперимента//
Токоограничительные резисторы обязательны!
{{ :products:esp-iot:exp11_mont.png?direct&600 |}}
//Рисунок 2. Монтажная схема эксперимента//
==== Программный код эксперимента ====
from machine import Pin
import time
import random
_init()
button = Pin(0, Pin.IN)
state_old = 1
segments = [14, 13, 4, 5, 12, 16, 15] # ABCDEFG
for s in segments:
led = Pin(s, Pin.OUT).off()
digits = [
[1, 1, 1, 1, 1, 1, 0], # 0
[0, 1, 1, 0, 0, 0, 0], # 1
[1, 1, 0, 1, 1, 0, 1], # 2
[1, 1, 1, 1, 0, 0, 1], # 3
[0, 1, 1, 0, 0, 1, 1], # 4
[1, 0, 1, 1, 0, 1, 1], # 5
[1, 0, 1, 1, 1, 1, 1], # 6
[1, 1, 1, 0, 0, 0, 0], # 7
[1, 1, 1, 1, 1, 1, 1], # 8
[1, 1, 1, 1, 0, 1, 1], # 9
]
def bit_summ(data):
count = 0
while data:
count += data & 1
data >>= 1
return count
def draw_digit(digit):
for el in enumerate(digits[digit]):
if (el[1]):
Pin(segments[el[0]]).on()
else:
Pin(segments[el[0]]).off()
while True:
new_state = button.value()
if new_state == 0 and state_old == 1:
rand_bits = random.getrandbits(5)
rand_digit = bit_summ(rand_bits)
rand_digit+=1
draw_digit(rand_digit)
state_old = new_state
Импортируем библиотеку для работы со случайными числами
import random
Объявляем переменные и настраиваем кнопку.
button = Pin(0, Pin.IN)
state_old = 1
В переменной ''state_old'' будем хранить прошлое состояние кнопки.
Рассмотрим основной цикл программы:
while True:
new_state = button.value()
if new_state == 0 and state_old == 1:
rand_bits = random.getrandbits(5)
rand_digit = bit_summ(rand_bits)
rand_digit+=1
draw_digit(rand_digit)
state_old = new_state
В бесконечном цикле программа ждет нажатия на кнопку ''А'', сравнивая ее текущее состояние с логическим нулем, а предыдущее с логической единицей. Если это состояние обнаружено, то генерируем число, состоящее из 5 случайных битов:
rand_bits = random.getrandbits(5)
После выполнения этой строки в переменной ''rand_bits'' окажется число длинной 5 бит. Каждый бит может быть либо 0 либо 1. Минимальное число 0b00000 максимальное 0b11111, что в десятичной системе счисления от 0 до 31. Но нам для игральной кости нужно получить числа от 1 до 5. Чтобы получить число в нужном интервале проще всего сложить все биты между собой по отдельности. То есть найти сумму бит. Например в числе 0b10010 два единичных бита, значит сумма бит равна 2, а в числе 0b11101 сумма бит равна 4.
Чтобы просуммировать биты напишем функцию ''bit_summ'':
def bit_summ(data):
count = 0
while data:
count += data & 1
data >>= 1
return count
Функция принимает в качестве параметра число и возвращает сумму его бит. Но, как мы помним, мы генерируем 5 бит. Их сумма будет от 0 до 5, а нам нужно число от 1 до 6. Поэтому просто добавляем 1 к полученной сумме, чтобы получить число в требуемом интервале.
rand_digit = bit_summ(rand_bits)
rand_digit+=1
Полученное число выводим на индикатор с помощью функции ''draw_digit''.
draw_digit(rand_digit)
Данная функция полностью скопирована из предыдущего эксперимента без изменений, только тогда она называлась ''draw_time''
==== Дополнительные задания ====
* Добавь визуальный эффект, чтобы при нажатии на кнопку на дисплее пробегали несколько цифр, прежде чем выводился бы результат