Эксперимент 27. Электронная игральная кость

Проведем более сложный эксперимент. Создадим действующее и полезное устройство − электронную игральную кость. Она может быть очень полезной при игре в различные настольные игры. По нажатию на кнопку устройство будет генерировать случайное число в промежутке от 1 до 6 и показывать его на 7и сегментном индикаторе.

Схема эксперимента

Оставим собранную ранее схему без изменений. Рисунок 1. Электрическая принципиальная схема эксперимента

Токоограничительные резисторы обязательны!

Рисунок 2. Монтажная схема эксперимента

Программный код эксперимента

Exp28.py
  1. from machine import Pin
  2. import time
  3. import random
  4. _init()
  5.  
  6. button = Pin(0, Pin.IN)
  7. state_old = 1
  8.  
  9. segments = [14, 13, 4, 5, 12, 16, 15] # ABCDEFG
  10.  
  11. for s in segments:
  12. led = Pin(s, Pin.OUT).off()
  13.  
  14. digits = [
  15. [1, 1, 1, 1, 1, 1, 0], # 0
  16. [0, 1, 1, 0, 0, 0, 0], # 1
  17. [1, 1, 0, 1, 1, 0, 1], # 2
  18. [1, 1, 1, 1, 0, 0, 1], # 3
  19. [0, 1, 1, 0, 0, 1, 1], # 4
  20. [1, 0, 1, 1, 0, 1, 1], # 5
  21. [1, 0, 1, 1, 1, 1, 1], # 6
  22. [1, 1, 1, 0, 0, 0, 0], # 7
  23. [1, 1, 1, 1, 1, 1, 1], # 8
  24. [1, 1, 1, 1, 0, 1, 1], # 9
  25. ]
  26.  
  27. def bit_summ(data):
  28. count = 0
  29. while data:
  30. count += data & 1
  31. data >>= 1
  32. return count
  33.  
  34. def draw_digit(digit):
  35. for el in enumerate(digits[digit]):
  36. if (el[1]):
  37. Pin(segments[el[0]]).on()
  38. else:
  39. Pin(segments[el[0]]).off()
  40.  
  41.  
  42. while True:
  43. new_state = button.value()
  44. if new_state == 0 and state_old == 1:
  45. rand_bits = random.getrandbits(5)
  46. rand_digit = bit_summ(rand_bits)
  47. rand_digit+=1
  48. draw_digit(rand_digit)
  49. state_old = new_state

Импортируем библиотеку для работы со случайными числами

  1. import random

Объявляем переменные и настраиваем кнопку.

  1. button = Pin(0, Pin.IN)
  2. state_old = 1

В переменной state_old будем хранить прошлое состояние кнопки.

Рассмотрим основной цикл программы:

  1. while True:
  2. new_state = button.value()
  3. if new_state == 0 and state_old == 1:
  4. rand_bits = random.getrandbits(5)
  5. rand_digit = bit_summ(rand_bits)
  6. rand_digit+=1
  7. draw_digit(rand_digit)
  8. state_old = new_state

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

  1. rand_bits = random.getrandbits(5)

После выполнения этой строки в переменной rand_bits окажется число длинной 5 бит. Каждый бит может быть либо 0 либо 1. Минимальное число 0b00000 максимальное 0b11111, что в десятичной системе счисления от 0 до 31. Но нам для игральной кости нужно получить числа от 1 до 5. Чтобы получить число в нужном интервале проще всего сложить все биты между собой по отдельности. То есть найти сумму бит. Например в числе 0b10010 два единичных бита, значит сумма бит равна 2, а в числе 0b11101 сумма бит равна 4.

Чтобы просуммировать биты напишем функцию bit_summ:

  1. def bit_summ(data):
  2. count = 0
  3. while data:
  4. count += data & 1
  5. data >>= 1
  6. return count

Функция принимает в качестве параметра число и возвращает сумму его бит. Но, как мы помним, мы генерируем 5 бит. Их сумма будет от 0 до 5, а нам нужно число от 1 до 6. Поэтому просто добавляем 1 к полученной сумме, чтобы получить число в требуемом интервале.

  1. rand_digit = bit_summ(rand_bits)
  2. rand_digit+=1

Полученное число выводим на индикатор с помощью функции draw_digit.

  1. draw_digit(rand_digit)

Данная функция полностью скопирована из предыдущего эксперимента без изменений, только тогда она называлась draw_time

Дополнительные задания

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