Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия |
products:laboratory_iot:exp26 [2020/05/17 21:08] – labuser29 | products:laboratory_iot:exp26 [2024/11/15 11:41] (текущий) – [Программный код эксперимента] labuser30 |
---|
| |
==== Схема эксперимента ==== | ==== Схема эксперимента ==== |
| Оставим схему, собранную на прошлом эксперименте. |
{{ :products:esp-iot:exp9_sch.png?nolink |}} | {{ :products:esp-iot:exp9_sch.png?nolink |}} |
//Рисунок 1. Электрическая принципиальная схема эксперимента// | //Рисунок 1. Электрическая принципиальная схема эксперимента// |
==== Программный код эксперимента ==== | ==== Программный код эксперимента ==== |
| |
<file python Exp25.py[enable_line_numbers="2", start_line_numbers_at="1"]> | <file python Exp26.py[enable_line_numbers="2", start_line_numbers_at="1"]> |
| from machine import Pin |
| import time |
| _init() |
| |
| 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 draw_time(digit): |
| for el in enumerate(digit): |
| if (el[1]): |
| Pin(segments[el[0]]).on() |
| else: |
| Pin(segments[el[0]]).off() |
| |
| |
| while True: |
| for digit in digits: |
| draw_time(digit) |
| time.sleep(1) |
</file> | </file> |
| |
| В этой программе мы записали номера выводов микроконтроллера, к которым подключены сегменты индикатора, в массив ''segments''. Порядок перечисления сегментов указан в комментарии в этой строке. |
| |
| <WRAP center round info 60%> |
| Комментарии используются в программах, чтобы записать какие либо пояснения к коду, и предназначены только для человека, который читает код. Комментарии никак не влияют на выполнение программы. В языке Python комментарий начинается с символа #. Также часто комментируют части кода, которые не должны исполняться, но удалять совсем их пока не нужно. |
| </WRAP> |
| |
| В строке 10 объявляем массив, в котором описываем цифры от 0 до 9 и какие сегменты должны светиться на индикаторе, чтобы эту цифру отобразить, а какие должны быть потушены. Для описания этого мы использовали двумерный массив. Это массив, у которого каждый из элементов является тоже массивом. Посмотрим внимательнее: элементом под индексом 0 у массива ''digits'' является массив ''[1, 1, 1, 1, 1, 1, 0]''. Это перечисление состояний сегментов для отображения цифры 0. Порядок перечисления соответствует порядку в массиве ''segments''. Это важно и потребуется нам для отображения цифр. |
| |
| В основном цикле программы мы перебираем все элементы массива ''digits'' с целью отображения на дисплее. |
| <code python [enable_line_numbers="2", start_line_numbers_at="32"]> |
| while True: |
| for digit in digits: |
| draw_time(digit) |
| time.sleep(1) |
| </code> |
| |
| Рассмотрим код функции ''draw_time'', которая предназначена для отображения цифры, передаваемой ей в качестве параметра. Начнем с того, что разберемся что именно передается функции в качестве входных данных. Ей передается один из элементов массива ''digits'', каждый элемент которого, как мы помним, сам является массивом, описывающим состояние сегментов. |
| |
| <code python [enable_line_numbers="2", start_line_numbers_at="24"]> |
| def draw_time(digit): |
| for el in enumerate(digit): |
| if (el[1]): |
| Pin(segments[el[0]]).on() |
| else: |
| Pin(segments[el[0]]).off() |
| </code> |
| |
| Получается, что функция получила данные о том какие сегменты ей нужно включить, а какие выключить. Соответственно она должна это исполнить. Для этого она проходит по всем элементам массива сегментов, как обычно, с помощью оператора ''in'', но в этот раз мы использовали еще оператор ''enumerate''. Обычно оператор ''in'' перебирая элементы массива записывает в переменную содержимое элемента массива, его значение, а ''enumerate(digit)'' создает последовательность кортежей, состоящих из индексов и значений. В кортеже ''el'' в элементе 0 оказывается индекс, а в элементе 1 значение. |
| |
| Номер индекса нам нужен, чтобы обратиться по нему к нужному сегменту, а его значение, чтобы знать что с ним делать − зажигать или тушить. |
| |
| <code python [enable_line_numbers="2", start_line_numbers_at="26"]> |
| if (el[1]): |
| Pin(segments[el[0]]).on() |
| else: |
| Pin(segments[el[0]]).off() |
| </code> |
| Если сегмент должен быть включен (''el[1]'' истинно), то нужно его зажечь. Номер пина, который нужно включить, записан в переменной ''segments'' в элементе с индексом, который мы берем из ''el[0]''. Именно поэтому мы сделали так, что последовательность пинов в массиве ''segments'' соответствует им в массиве ''digits'', чтобы у них были одинаковые индексы. |
| |
| Не совсем обычным является и то, как мы зажигаем сегменты. ''Pin(segments[el[0]]).on()''. Обычно мы создавали объект ''Pin'', записывали его в переменную и оперировали с ней. Сейчас мы сделали тоже самое, только не создавали отдельную переменную, а сделали все сразу. Просто нам не нужна эта переменная в будущем, поэтому мы ее не создавали и для краткости записи сделали так. |
| |
| <WRAP center round info 60%> |
| * [[https://younglinux.info/python/feature/enumerate|Подробнее об enumerate]] |
| * [[https://pythonworld.ru/tipy-dannyx-v-python/kortezhi-tuple.html|Подробнее о кортежах в Python]] |
| </WRAP> |
| ==== Дополнительные задания ==== |
| |
| <WRAP center round tip 60%> |
| Добавь к цифрам 0..9 еще буквы A, b, C d E F, чтобы секундомер переключал символы от 0 до F |
| </WRAP> |
| |