Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
products:laboratory_iot:exp28 [2021/04/25 16:11] labuser29products:laboratory_iot:exp28 [2024/11/15 13:32] (текущий) – [Программный код эксперимента] labuser30
Строка 3: Строка 3:
 Проведем более сложный эксперимент. Создадим действующее и полезное устройство − электронную игральную кость. Она может быть очень полезной при игре в различные настольные игры. По нажатию на кнопку устройство будет генерировать случайное число в промежутке от 1 до 6 и показывать его на 7и сегментном индикаторе.  Проведем более сложный эксперимент. Создадим действующее и полезное устройство − электронную игральную кость. Она может быть очень полезной при игре в различные настольные игры. По нажатию на кнопку устройство будет генерировать случайное число в промежутке от 1 до 6 и показывать его на 7и сегментном индикаторе. 
  
 +==== Схема эксперимента ====
 +Оставим собранную ранее схему без изменений.
 +{{ :products:esp-iot:exp11_sch.png?nolink |}}
 +//Рисунок 1. Электрическая принципиальная схема эксперимента//
 +
 +<WRAP center round alert 60%>
 +Токоограничительные резисторы обязательны!
 +</WRAP>
 +
 +{{ :products:esp-iot:exp11_mont.png?direct&600 |}}
 +//Рисунок 2. Монтажная схема эксперимента//
 +
 +==== Программный код эксперимента ====
 +
 +<file python Exp28.py[enable_line_numbers="2", start_line_numbers_at="1"]>
 +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
 +</file>
 +
 +Импортируем библиотеку для работы со случайными числами
 +<code python [enable_line_numbers="2", start_line_numbers_at="3"]>
 +import random
 +</code>
 +
 +Объявляем переменные и настраиваем кнопку.
 +<code python [enable_line_numbers="2", start_line_numbers_at="6"]>
 +button = Pin(0, Pin.IN)
 +state_old = 1
 +</code>
 +
 +В переменной ''state_old'' будем хранить прошлое состояние кнопки. 
 +
 +Рассмотрим основной цикл программы:
 +<code python [enable_line_numbers="2", start_line_numbers_at="42"]>
 +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
 +</code>
 +
 +В бесконечном цикле программа ждет нажатия на кнопку ''А'', сравнивая ее текущее состояние с логическим нулем, а предыдущее с логической единицей. Если это состояние обнаружено, то генерируем число, состоящее из 5 случайных битов:
 +<code python [enable_line_numbers="2", start_line_numbers_at="45"]>
 +        rand_bits = random.getrandbits(5)
 +</code>
 +
 +После выполнения этой строки в переменной ''rand_bits'' окажется число длинной 5 бит. Каждый бит может быть либо 0 либо 1. Минимальное число 0b00000 максимальное 0b11111, что в десятичной системе счисления от 0 до 31. Но нам для игральной кости нужно получить числа от 1 до 5. Чтобы получить число в нужном интервале проще всего сложить все биты между собой по отдельности. То есть найти сумму бит. Например в числе 0b10010 два единичных бита, значит сумма бит равна 2, а в числе 0b11101 сумма бит равна 4.
 +
 +Чтобы просуммировать биты напишем функцию ''bit_summ'':
 +<code python [enable_line_numbers="2", start_line_numbers_at="27"]>
 +def bit_summ(data):
 +    count = 0
 +    while data:
 +        count += data & 1
 +        data >>= 1
 +    return count
 +</code>
 +
 +Функция принимает в качестве параметра число и возвращает сумму его бит. Но, как мы помним, мы генерируем 5 бит. Их сумма будет от 0 до 5, а нам нужно число от 1 до 6. Поэтому просто добавляем 1 к полученной сумме, чтобы получить число в требуемом интервале.
 +
 +<code python [enable_line_numbers="2", start_line_numbers_at="46"]>
 +        rand_digit = bit_summ(rand_bits)
 +        rand_digit+=1
 +</code>
 +
 +Полученное число выводим на индикатор с помощью функции ''draw_digit''.
 +<code python [enable_line_numbers="2", start_line_numbers_at="48"]>
 +        draw_digit(rand_digit)
 +</code>
 +Данная функция полностью скопирована из предыдущего эксперимента без изменений, только тогда она называлась ''draw_time''
 +
 +==== Дополнительные задания ====
 +
 +<WRAP center round tip 60%>
 +  * Добавь визуальный эффект, чтобы при нажатии на кнопку на дисплее пробегали несколько цифр, прежде чем выводился бы результат
 +</WRAP>