class Signal – управление и считывание внешних устройств ввода-вывода

Класс Signal – это простое расширение класса Pin. В отличие от Pin, который может находиться только в «абсолютных» состояниях 0 и 1, Signal может находиться в состояниях «активировано» (включено) или «деактивировано» (выключено), при этом будучи инвертированным (активный низкий уровень) или нет. Иными словами, он добавляет к функциональности Pin поддержку логической инверсии. Хотя это может показаться простым дополнением, именно это нужно для поддержки широкого спектра простых цифровых устройств способом, переносимым между разными платами, что является одной из главных целей MicroPython. Независимо от того, есть ли у разных пользователей светодиод с активным высоким или активным низким уровнем, нормально разомкнутое или нормально замкнутое реле – вы можете разработать единое, красиво выглядящее приложение, которое работает с каждым из них, и зафиксировать различия в аппаратной конфигурации в нескольких строках файла конфигурации вашего приложения.

Пример:

from machine import Pin, Signal

# Suppose you have an active-high LED on pin 0
led1_pin = Pin(0, Pin.OUT)
# ... and active-low LED on pin 1
led2_pin = Pin(1, Pin.OUT)

# Now to light up both of them using Pin class, you'll need to set
# them to different values
led1_pin.value(1)
led2_pin.value(0)

# Signal class allows to abstract away active-high/active-low
# difference
led1 = Signal(led1_pin, invert=False)
led2 = Signal(led2_pin, invert=True)

# Now lighting up them looks the same
led1.value(1)
led2.value(1)

# Even better:
led1.on()
led2.on()

Ниже приведено руководство о том, когда следует использовать Signal, а когда Pin:

  • Используйте Signal: если вы хотите управлять простыми устройствами включения/выключения (включая программный PWM!) такими как светодиоды, многосегментные индикаторы, реле, зуммеры, или считывать простые двоичные датчики, такие как нормально разомкнутые или нормально замкнутые кнопки, подтянутые к высокому или низкому уровню, герконы, датчики влажности/пламени и т. д. и т. п. Подводя итог, если у вас есть реальное физическое устройство/датчик, требующее доступа к GPIO, вам, скорее всего, следует использовать Signal.

  • Используйте Pin: если вы реализуете протокол или шину более высокого уровня для связи с более сложными устройствами.

Разделение между Pin и Signal вытекает из приведённых выше сценариев использования и архитектуры MicroPython: Pin обеспечивает наименьшие накладные расходы, что может быть важно при реализации протоколов методом bit-banging. Но Signal добавляет дополнительную гибкость поверх Pin ценой небольших накладных расходов (гораздо меньших, чем если бы вы вручную реализовывали различия между устройствами с активным высоким и активным низким уровнем на Python!). Кроме того, Pin – это низкоуровневый объект, который необходимо реализовывать для каждой поддерживаемой платы, тогда как Signal – это высокоуровневый объект, который появляется бесплатно, как только реализован Pin.

Если сомневаетесь, попробуйте Signal! Ещё раз: он предлагается, чтобы избавить разработчиков от необходимости обрабатывать скучные различия, такие как сигналы с активным низким и активным высоким уровнем, и позволить другим пользователям делиться вашим приложением и наслаждаться им, вместо того чтобы расстраиваться из-за того, что оно у них не работает просто потому, что их светодиоды или реле подключены немного иначе.

Конструкторы

class machine.Signal(pin_obj: Pin, *, invert: bool = False)
class machine.Signal(*pin_args: Any, invert: bool = False, **pin_kwargs: Any)

Создаёт объект Signal. Есть два способа его сконструировать:

  • Обернуть существующий объект Pin – универсальный способ, работает на любой плате.

  • Передать аргументы конструктора Pin напрямую – те же позиционные и именованные аргументы, которые принимает Pin, передаются во внутренне создаваемый Pin. Доступно на многих, но не на всех платах.

Аргументы:

  • pin_obj – существующий экземпляр Pin для оборачивания.

  • pin_args / pin_kwargs – аргументы, передаваемые конструктору Pin при встроенном создании базового вывода.

  • invert – если True, сигнал инвертируется (активный низкий уровень).

Методы

value(x: Any = None, /) int | None

Этот метод позволяет устанавливать и получать значение сигнала в зависимости от того, передан аргумент x или нет.

Если аргумент опущен, то этот метод получает уровень сигнала: 1 означает, что сигнал активирован (активен), а 0 – сигнал неактивен.

Если аргумент передан, то этот метод устанавливает уровень сигнала. Аргумент x может быть чем угодно, что преобразуется в логическое значение. Если он преобразуется в True, сигнал активен, иначе он неактивен.

Соответствие между активным состоянием сигнала и фактическим логическим уровнем на базовом выводе зависит от того, инвертирован сигнал (активный низкий уровень) или нет. Для неинвертированного сигнала активному состоянию соответствует логическая 1, неактивному – логический 0. Для инвертированного сигнала с активным низким уровнем активному состоянию соответствует логический 0, а неактивному – логическая 1.

on() None

Активировать сигнал.

off() None

Деактивировать сигнал.