### [ На русском ] ↔ [ English ]

- Пины ESP32 (GPIO)
- Команда "pin": Универсальный инструмент для работы с GPIO
- Отображение информации о пине
- Настройка режима пина
- Чтение/запись значений пина
- Последовательности импульсов, ШИМ и тайминги
- Сохранение/восстановление состояния пина
- Автоповтор команды (цикл)
- IO_MUX и GPIO Matrix
- Замечания о скорости выполнения
- Различные примеры

## ⇮ПИНЫ ESP32 (GPIO)

ESP32 имеет множество пинов ("пинов", "выходов" или "GPIO" — все эти термина используются в этой документации взаимозаменяемо), которые можно настроить как универсальные входы/выходы (GPIO) или назначить им специальные функции. Например, пин может выступать в роли линии TX для аппаратного UART-интерфейса или служить линией CLOCK для шины I2C.

Некоторые пины имеют системные роли и называются "бутстрап-пинами". Эти пины сообщают загрузчику, как инициализировать аппаратное обеспечение при запуске. Их можно использовать, если это не мешает процессу загрузки: если подключенное к такому пину внешнее устройство при включении питания и загрузке ESP32 не выдает сигналы в этот пин, то проблем не будет. Проблемы возникнут, если ваше устройство, подключеное к bootstrap пинам при старте системы выдаст туда что-то неожиданное: это действие сконфигурирует ESP32 в непредсказуемый режим (например, напряжение питания шины SPI0 может поменяться и сжечь вашу микросхему flash).

Некоторые пины зарезервированы для внутреннего использования. Например, пины 6–11 на большинстве плат с оригинальным ESP32 используются для доступа к внутренней flash-памяти. Взаимодействовать с этими пинами можно только если вы действительно понимаете, что вы делаете: ваш код должен быть размешен целиком в кэше, и это только одно из многих требований

Некоторые пины работают только на вход и не могут быть переконфигурированы в режим выхода.. Такие, например, встречаются в орининальном ESP32 (в ESP32S3, например, таких пинов нет).

Как узнать, какие пины можно использовать безопасно, а какие нет? Просто исполните команду "pin", без аргументов и увидите справочную информацию по пинам на вашей плате; Но обо всем по порядку.

## ⇮КОМАНДА "PIN": УНИВЕРСАЛЬНЫЙ ИНСТРУМЕНТ ДЛЯ РАБОТЫ С GPIO

В ESPShell вы можете управлять пинами с помощью команды "pin", которая используется как для отображения информации о конкретном пине, так и для его настройки.

Можно установить пин в состояние HIGH или LOW, отправлять различные последовательности импульсов, включать или отключать ШИМ, настраивать направление и режим пина, подтяжки, считывать и устанавливать цифровое и аналоговое значение и т.п.

В отличие от digitalRead(...), который не работает на пинах, используемых аппаратными интерфейсами (например, нельзя использовать `digitalRead()` на линиях I2C), ESPShell может читать цифровые значения на любом GPIO. Шелл использует низкоуровневый доступ к состояниям пинов, поэтому совершенно спокойно можно считывать значение пина, даже если на нём активен ШИМ или, скажем, UART0. Для этого используется команда "pin NUM read".

Команда "pin" принимает несколько аргументов, которые обрабатываются слева направо. Первый аргумент — номер пина, остальные — ключевые слова и/или дополнительные номера пинов для применения операций. Эти аргументы можно рассматривать как простую программу, выполняемую на указанных пинах.

Например, "pin 2 save out high load" — валидная команда с четырьмя аргументами/ключевыми словами. Она сохраняет состояние GPIO2 во внутреннем регистре, переводит пин 2 в режим OUTPUT, устанавливает его в HIGH и сразу восстанавливает исходное состояние.

Примеры команд "pin":

        pin 1 high 2 low
        pin 2 pwm 1000 0.5 delay 250 pwm 1000 0.25 delay 250 loop infinite

Команда "pin" может работать с одним или несколькими пинами одновременно. Пример ниже показывает команду, которая устанавливает пины 2 и 4 в HIGH, а пины 18 и 19 — в LOW:

    esp32#>pin 2 high 4 high 18 low 19 low

Здесь 2, 4, 18 и 19 — номера пинов, а "low" и "high" — ключевые слова. Ключевые слова могут встречаться несколько раз и в различных комбинациях в одной команде "pin", как показано в разделе с примерами ниже.

Теперь, собственно, команды:

## ⇮ОТОБРАЖЕНИЕ ИНФОРМАЦИИ О ПИНЕ

Чтобы отобразить информацию о произвольном пине: введите "pin", затем номер пина и нажмите <Enter>.

Пример ниже показывает базовую информацию о GPIO 0, 8, 1 и 4 (ESP32 DevKit):

    esp32#>pin 0
    % GPIO0 is unused, strapping pin
    % Mode: INPUT, PULL_UP,
    % Output is disabled
    % Input is done via IO MUX, (function: GPIO0)
    % Maximum drive current is 20 mA
    % Digital pin value is HIGH (1)
    %
    esp32#>pin 8
    % GPIO8 is reserved
    % Mode: INPUT, OUTPUT, PULL_UP,
    % Output is done via GPIO Matrix, provides path for signal ID: 2
    % Input is done via GPIO Matrix, connected signal IDs: 2,
    % Maximum drive current is 20 mA
    % Digital pin value is LOW (0)
    %
    esp32#>pin 1
    % GPIO1 is in use, configured as UART_TX
    % Mode: INPUT,  input is floating
    % Output is disabled
    % Input is done via IO MUX, (function: U0TXD)
    % Maximum drive current is 20 mA
    % Digital pin value is HIGH (1)
    %
    esp32#>pin 4
    % GPIO4 is unused
    % Mode: INPUT, PULL_DOWN,
    % Output is disabled
    % Input is done via IO MUX, (function: GPIO4)
    % Maximum drive current is 20 mA
    % Digital pin value is LOW (0)
    %
    esp32#>

Альтернативный способ - использовать команду "show pin NUM". Она эквивалентна команде "pin NUM" — обе отображают информацию о пине с номером NUM. Единственное отличие состоит в том, что команда "show pin" принимает несколько аргументов (номеров пинов), поэтому пример выше можно записать одной командой: "show pin 0 8 1 4".

Сколько пинов доступно на вашей плате ESP32? Чтобы узнать, какие пины существуют, а какие нет, можно использовать команду "pin" без аргументов:

Рис. 1: Вывод команды "pin" (на ESP32-WROOM32D Dev Module)

На скриншоте виден результат работы команды: список пинов, которые трогать НЕ НАДО ("Used by SoC") и список пинов, которые,в принципе, использовать можно, но необъодимо удостовериться, что эти пины не используются еще кем-то. Так, на скриншоте пины 1 и 3 помечены как доступные ("Available"), но на самом деле на этих пинах сконфигурирован UART0, использовать их нельзя.

## ⇮НАСТРОЙКА РЕЖИМА ПИНА

Команда pin используется для установки режима пина (например, PULL_UP/PULL_DOWN, INPUT/OUTPUT, OPEN_DRAIN) и его значения; эквивалент pinMode() и/или digitalRead()/digitalWrite()/analogRead().

Ключевое слово | Описание и примеры
--- | ---
NUMBER | pin НОМЕР_ПИНА Номер пина для работы. Первый аргумент команды "pin" — это номер пина. Этот номер пина может встречаться несколько раз в одной команде "pin". Пример ниже устанавливает пины 0, 1 и 2 в LOW:
                esp32#>pin 0 low 1 low 2 low
Команда, содержащая только числа в качестве аргументов (например, "pin 1 2 3"), является валидной, но ничего не делает.
out | pin НОМЕР_ПИНА out Установить пин в режим OUTPUT: эквивалент pinMode(pin, OUTPUT).
in | pin НОМЕР_ПИНА in Установить пин в режим INPUT: аналогично pinMode(pin, INPUT).
up | pin НОМЕР_ПИНА up Включить внутренний подтягивающий резистор (~45 кОм), флаг PULL_UP.
down | pin НОМЕР_ПИНА down Включить внутренний подтягивающий резистор(~45 кОм), флаг PULL_DOWN.
open | pin НОМЕР_ПИНА open Настроить пин на работу в режиме "open drain", OPEN_DRAIN.

Пример: сконфигурировать пин 2 как INPUT_PULLUP и OPEN_DRAIN

      esp32#>pin 2 in open up

Пример: сконфигурировать пин 2 как INPUT, PULL_DOWN и OUTPUT, а пин 4 - как INPUT

      esp32#>pin 2 in out down 4 in

Обратите внимание, что режим пина не добавляется к текущей конфигурации — он перезаписывается. Например, если мы установим пин 2 в OUTPUT с PULL_UP командой "`pin 2 out up`", а затем попытаемся добавить флаг INPUT с помощью "`pin 2 in`", пин 2 останется только с флагом INPUT.

Правильный способ применить несколько флагов — указать их все сразу, например: "`pin 2 in out up`". Если команда pin включает любое из упомянутых выше ключевых слов режима, текущий режим пина сначала сбрасывается, а затем применяется новый.

## ⇮ЧТЕНИЕ/ЗАПИСЬ ЗНАЧЕНИЙ ПИНА

Ключевое слово | Описание и примеры
--- | ---
read | pin НОМЕР_ПИНА read Выполняет цифровое чтение. Команда "`pin 2 read`" выполняет `digitalRead()` на пине 2 и показывает результат (HIGH или LOW). Пины, настроенные только на OUTPUT, будут временно переключены в INPUT/OUTPUT автоматически. В отличие от стандартного `digitalRead()`, эта команда может читать значение любого GPIO, независимо от его текущей конфигурации или использования — например, она может читать значения с пинов, используемых для UART или I2C.
    Пример: чтение значений GPIO#1.

      esp32#>pin 1 read
      % GPIO1 : logic 1

      esp32#>pin 1 read
      % GPIO1 : logic 0
      esp32#>
В примере выше пин 1 сначала возвращает "1", а затем "0". Это происходит потому, что на ESP32 GPIO1 обычно используется как UART_TX, а при выполнении команды происходит вывод данных через этот же пин.
aread | pin НОМЕР_ПИНА aread Выполняет аналоговое чтение. Эта команда настраивает однократное измерение АЦП на указанном пине и возвращает абсолютное значение АЦП. В зависимости от настройки АЦП, считываемые значения могут быть в диапазоне от 0 до 4095.
low | pin НОМЕР_ПИНА low Устанавливает логический "0" на пине.
high | pin НОМЕР_ПИНА high Устанавливает логическую "1" на пине (т.е. `digitalWrite(pin, HIGH)`). Оба ключевых слова `high` и `low` автоматически устанавливают режим OUTPUT для пина, если он ещё не установлен. Поэтому следующие команды функционально эквивалентны:
    "pin 2 high"
    "pin 2 out high"
toggle | pin НОМЕР_ПИНА toggle Инвертирует цифровое значение пина: 0 становится 1 и наоборот Пример: инвертировать пин 2 на максимальной скорости:
        esp32#>pin 2 toggle loop inf

Пример: сконфигурировать пин 2 как OUTPUT и установить на нем высокий уровень (HIGH)

      esp32#>pin 2 out high

Пример: прочитать цифровое, а затем и аналоговое значение с пина 36:

      esp32#>pin 36 read aread

## ⇮СИГНАЛЬНЫЕ ПОСЛЕДОВАТЕЛЬНОСТИ, PWM И ТАЙМИНГИ

Команда "pin" может использоваться для генерации ШИМ-сигналов, точных высокочастотных последовательностей импульсов (с модуляцией или без, для ИК-приёмников), а также для генерации сверхнизкочастотных сигналов

Ключевое слово | Описание и примеры
--- | ---
sequence NUM | pin НОМЕР_ПИНА sequence SEQUENCE_ID Передаёт предварительно заданную последовательность. Создаются они с помощью команды sequence и идентифицируются по ID номеру.
    Пример: Послать последовательность#5 на пин номер 2:

      esp32#>pin 2 seq 5
pwm FREQ DUTY | pin НОМЕР_ПИНА pwm FREQUENCY DUTY Включает ШИМ-выход на указанном выводе. `FREQ` — это частота в герцах, а `DUTY` — скважность. Оба параметра обязательны. Установка частоты в 0 отключает генерацию ШИМ. `DUTY` — это число с плавающей точкой в диапазоне (0..1).
    Пример: Включить ШИМ 5кГц , скважностью 50% на пине номер 2:

      esp32#>pin 2 pwm 5000 0.5
Примечание: хотя команда pwm делает то же самое, что и "`pin <PIN> pwm <FREQ> <DUTY>`", отдельная команда pwm предоставляет больше параметров для настройки.
delay NUM | pin НОМЕР_ПИНА delay MILLISECONDS Вставляет задержку в NUM миллисекунд перед выполнением следующего ключевого слова в последовательности команды "pin". Это может использоваться для создания простых временных шаблонов:
    Пример: Помигать светодиодиком, подключенным к пину номер 2, с частотой 0.5 Гц

      esp32#>pin 2 high delay 1000 low delay 1000 loop infinite &
Пример выше устанавливает на выводе 2 уровень HIGH на 1 секунду, затем LOW на 1 секунду, и повторяет цикл. Символ "&" запускает команду в фоновом режиме.

## ⇮СОХРАНЕНИЕ / ВОССТАНОВЛЕНИЕ СОСТОЯНИЯ ВЫВОДА, УДЕРЖАНИЕ СОСТОЯНИЯ

Можно временно сохранить состояние пина (т.е. режим, подтяжку, значение, функцию IOMUX), а затем восстановить его.

Ключевые слова "save" и "load" используются для сохранения и восстановления состояния вывода. Для хранения используется внутренний регистр, куда каждый раз сохраняется состояние пина: то есть новая операция save перезапишет предыдущую.

Также есть возможность зафиксировать (заморозить) выходное значение пина, чтобы предотвратить любые изменения. Все попытки записи кем угодно в пин будут игнорироваться, а значение на пине будет такое, какое было в момент заморозки. Однако, как только заморозка будет снята, все изменения, сделанные во время фиксации, будут применены немедленно. Для заморозки\разморозки используются ключевые слова "hold" и "release":

Ключевое слово | Описание и примеры
--- | ---
hold release | pin НОМЕР_ПИНА hold | release Замораживает выходное значение вывода. Замороженный вывод сохраняет своё значение даже после программной перезагрузки, если питание продолжает подаваться на чип. Однако полная перезагрузка с отключением питания (POWERUP) снимает заморозку.
    Пример: Заморозить значение на пине 2:

      esp32#>pin 2 hold
"pin X release" снимает заморозку с вывода, ранее зафиксированного с помощью "pin X hold", и применяет все изменения, сделанные в период заморозки.
    Пример: Разморозить пин 2:

      esp32#>pin 2 release
save load | pin НОМЕР_ПИНА save | load Сохраняет состояние вывода во внутренний регистр и восстанавливает его позже с помощью "load".
    Пример: Сохранить состояние пина 2, произвести чтение аналогового сигнала, восстановить состояние пина

      esp32#>pin 2 save aread load
"pin X load" восстанавливает ранее сохранённое состояние вывода. Пример выше демонстрирует использование ключевого слова "load".

## ⇮АВТОПОВТОР КОМАНДЫ "pin"

Команду "pin" можно зациклить для повторения: для этого используется ключевое слово loop, которое должно быть размещено в конце команды. Зацикленные команды можно прерывать, нажав клавишу <Enter> или с помощью команды "kill" (для остановки команд запущенных в фоновом режиме).

Ключевое слово | Описание и примеры
--- | ---
loop | pin НОМЕР_ПИНА ... loop COUNT| infinite Повторяет всю команду `COUNT` раз. Ключевое слово "loop COUNT" должно быть в конце команды. `COUNT` - это число повторов команды или ключевое слово "infinite", что задает количество повторений равным 2^32-1, что фактически является бесконечным числом в большинстве случаев. Примеры:
        esp32#>pin 2 delay 1000 loop inf &   ← Фоновая команда, повторяется бесконечно
        esp32#>pin 2 delay 1000 loop 10 &    ← Фоновая команда, повторяется 10 раз

Пример: переключать пин 2 из состояния HIGH в LOW и обратно с максимальной скоростью:

      esp32#>pin 2 high low loop inf
      % Repeating whole command 4294967294 times, press <Enter> to abort
      % Key pressed, aborting..
      esp32#>

## ⇮IO_MUX и GPIO MATRIX

IO_MUX и GPIO_Matrix (с подчеркиванием или без) — это аппаратные блоки внутри микросхемы ESP32. Они используются для подключения выводов GPIO к периферийным аппаратным модулям внутри ESP32. Каждый пин может быть настроен на одну из пяти (или шести на некоторых моделях ESP32) функций. Пин может использоваться как обычный GPIO или выполнять специализированную функцию (например, UART TX). Команда "show iomux" отображает текущие соответствия между пинами и функциями:

Рис. 2: Вывод команды show iomux

- Текущая активная функция отображается инвертированным цветом (или помечается "*" на монохромных дисплеях).
- Пины, которые активно используются (т.е. имеют установленный драйвер), отмечены красным и знаком восклицания ("!").
- Пины, помеченные зелёным, являются только входными (не могут использоваться как выход).

На примере вывода выше видно, что GPIO0 назначен на функцию 0 (обычный GPIO0). Изменение его на функцию 2 не повлияет на поведение, так как обе функции соответствуют "простому GPIO" — Функция 0 маршрутизируется через IO_MUX, а функция 2 — через GPIO_Matrix.

Пины с 6 по 11, отмеченные красным на рисунке 2, используются для доступа к встроенной флеш-памяти.

IO_MUX обеспечивает немного более высокую производительность по сравнению с GPIO_Matrix. Однако GPIO_Matrix предоставляет большую гибкость, позволяя почти любую периферию подключать к почти любому пину. Использование GPIO_Matrix для сигналов флеш-памяти (вместо IO_MUX) добавляет небольшую задержку около 25 нс.

Если снова взглянуть на рисунок 2, вы заметите, что пины 1 и 3 установлены на функцию №0, которая соответствует UART0 TX и UART0 RX соответственно. Означает ли это, что только пины 1 и 3 можно использовать для настройки UART0?

Нет, не означает.

UART0 также может быть настроен через GPIO Matrix — именно это происходит, когда вы назначаете UART0 на пины, отличные от 1 и 3. Например, если мы хотим инициализировать UART0 на пинах 18 и 19, эти пины будут переведены в режим GPIO Matrix, что отображается выбором функции №2 (на ESP32; на других моделях ESP используется функция №1). После выбора режима GPIO Matrix, пины подключаются к периферийным сигналам UART0_RX и UART0_TX. Маршрутизация сигналов (т.е. подключение или отключение) может также выполняться вручную — см. ключевое слово "matrix" ниже.

Снова, рисунок 2 показывает, что если мы хотим инициализировать UART1 на его предпочтительных пинах (т.е. через IO_MUX, минуя GPIO Matrix), нужно использовать GPIO9 и GPIO10. Когда эти пины настроены на функцию №4, они становятся UART1_RX и UART1_TX. К сожалению, GPIO9 и GPIO10 уже используются для подключения к микросхеме флеш-памяти.

Что насчёт UART2? Если его инициализировать на пинах 16 и 17 с выбранной функцией №4, они становятся пинами высокоскоростного интерфейса UART. Таким образом, пины 16 и 17 являются предпочтительными для UART2. Создадим интерфейс UART2 и снова взглянем на таблицу IOMUX:

    esp32#>uart 2
    esp32-uart2>up 16 17 115200
    esp32-uart2>show iomux

Рис. 3: Вывод команды show iomux после инициализации UART2 на предпочтительных пинах

Что произойдёт, если мы инициализируем UART2 на пинах 18 и 19? Давайте посмотрим:

    esp32#>uart 2
    esp32-uart2>up 18 19 115200
    esp32-uart2>show iomux

Рис. 4: Вывод команды show iomux после инициализации UART2 на альтернативных пинах

На этот раз пины установлены на функцию №2, которая соответствует режиму GPIO Matrix, что приводит к немного более медленной работе UART. Если вы выполните команду `show pin 18 19`, то увидите, что пины 18 и 19 подключены к периферийным сигналам UART2_RX и UART2_TX:

    esp32-uart2>sh pin 18 19
    % GPIO18 is available, configured as UART_RX
    % Mode: INPUT, input is floating
    % Output is disabled
    % Input is done via GPIO Matrix, connected signal IDs: 198,
    % Maximum drive current is 20 mA
    % Digital pin value is LOW (0)
    %
    % GPIO19 is available, configured as UART_TX
    % Mode: INPUT, OUTPUT, input is floating
    % Output is done via GPIO Matrix, provides path for signal ID: 198
    % Input is done via GPIO Matrix
    % Maximum drive current is 20 mA
    % Digital pin value is HIGH (1)

## ⇮ЗАМЕЧАНИЯ О СКОРОСТИ ИСПОЛНЕНИЯ

Команда "pin" является интерпретатором; она не компилирует свои ключевые слова для более быстрой обработки. Вместо этого ключевые слова интерпретируются каждый раз при их выполнении, даже внутри циклов. Так насколько быстро это работает?

Вы можете провести простой эксперимент: соедините пины 2 и 4 перемычкой и выполните команду "pin 2 low high loop infinite &" и "count 4". Первая команда переключает пин 2 между высоким и низким состоянием в фоновом цикле, а вторая команда подсчитывает импульсы, поступающие на пин 4. На классическом ESP32, работающем на 240 МГц, этот эксперимент показывает частоту импульсов около 260 кГц. Однако добавление всего лишь 0-миллисекундной задержки значительно снижает скорость исполнения: команда "pin 2 low high delay 0 loop infinite &" дает сигнал частотой около 80 кГц.

Еще один важный момент: команды, такие как "pin 2 low high loop inf &", можно остановить только с помощью команды "kill -9". Это потому, что такие команды не содержат задержек, а задержки — это единственные точки, где команда "kill" (без "-9") может аккуратно прервать задачу. Для аккуратного завершения вы можете либо добавить задержку в 0 мс (что, как показано выше, значительно снижает производительность), либо использовать "kill -9", чтобы принудительно завершить задачу.

## ⇮ПРИМЕРЫ

Рассмотрим несколько простых примеров, демонстрирующих, как использовать команду "pin". Часто легче учиться на примерах, чем читать бесконечные таблицы и описания.

Пример 1. Отобразить информацию о GPIO4:

       esp32#>pin 4

Пример 2. Установить пин 33 в режим OUTPUT и INPUT, включить PULL_UP и установить пин в состояние HIGH:

       esp32#>pin 33 out in up high

Пример 3. Сохранить состояние пина, установить его в режим OUTPUT и HIGH, затем восстановить исходное состояние:

       esp32#>pin 33 save out high
       esp32#>pin 33 load

ПРИМЕЧАНИЕ: Установка пина в "low" или "high" автоматически устанавливает его в режим OUTPUT. Внутри шелла, ключевое слово "high" преобразуется в "out high". Поэтому вышеуказанную команду можно упростить до:

       esp32#>pin 33 save high
       esp32#>pin 33 load

Пример 4. Прочитать аналоговое значение с пина 33:

       esp32#>pin 33 aread

ПРИМЕЧАНИЕ: Команда "aread" использует функцию `analogRead()`, которая перенастроит пин как часть процесса чтения. После выполнения "pin 33 aread" пин будет перенастроен и может больше не отвечать на `digitalRead()`. Чтобы сохранить исходную конфигурацию, используйте "save" и "load":

       esp32#>pin 33 read save aread load

Аргументы обрабатываются слева направо. В данном случае сначала считается цифровое значение, затем состояние пина сохраняется, после чего выполняется аналоговое чтение и восстановление состояния.

Пример 5. Сохранить состояние пина, установить его в режим OUTPUT и HIGH на 250 мс, LOW на 100 мс, снова HIGH на 50 мс, затем восстановить исходную конфигурацию:

      esp32#>pin 33 save high delay 250 low delay 100 high delay 50 load

ПРИМЕЧАНИЕ: Хотя простые сигнальные последовательности можно создать с использованием "delay", эта команда обычно используется для базовых задач, таких как управление реле. Для более сложных сигналов рекомендуется использовать генератор импульсов или ШИМ. Одно из немногих мест, где оправдана генерация сигнала с помощью delay - это генерация сигналов с частотами ниже 1-2 герц: ШИМ на таких частотах недоступен.

ПРИМЕЧАНИЕ: Команду "pin" можно прервать во время длительных задержек (>3 секунд), нажав любую клавишу в терминале или отправив любой символ через Serial Monitor в Arduino IDE. Короткие задержки (менее трех секунд) не могут быть прерваны — вам нужно дождаться их завершения.

Пример 7. Установить пин 2 в HIGH, пин 3 в LOW, подождать 1 секунду, затем инвертировать состояния пинов:

      esp32#>pin 2 high 3 low delay 1000 2 low 3 high

Пример 8. Моргание светодиода на GPIO2 с задержкой 500 мс, 20 раз:

      esp32#>pin 2 high delay 500 low delay 500 loop 20

ПРИМЕЧАНИЕ: Когда используется ключевое слово "loop", команда "pin" становится прерываемой: нажатие любой клавиши в терминале или Serial Monitor в Arduino IDE прервет выполнение команды.

Пример 9. Моргание светодиода на GPIO2 при яркости 30%:

Для регулировки яркости используем ШИМ с частотой 5 кГц и скважностью 30%:

      esp32#>pin 2 pwm 5000 0.3 delay 500 pwm 0 0 delay 500 loop infinite

Как показано в приведенных примерах, некоторые команды "pin" могут потребовать длительного времени для выполнения. Команды с "loop", команды большими значениями "delay" могут выполняться десятки секунд или даже минуты. Вы можете прервать их в любой момент, нажав <Enter> в вашем терминале или Serial Monitor.

Пример 10. Отправить S.O.S. в Морзе, повторяя бесконечно:
(Морзе для SOS — ...---..., команда разделена на две строки для удобства чтения.)

      pin 2 h d 100 l d 100 h d 100 l d 100 h d 100 l d 300 h d 200 l d 100 h d 200
            l d 100 h d 200 l d 300 h d 100 l d 100 h d 100 l d 100 h d 100 l d 500 loop inf

Пример 12. Подключить периферийный сигнал 77 к постоянному "1", а сигнал 78 к постоянному "0":

      esp32#>pin 0x38 matrix in 77
      esp32#>pin 0x30 matrix in 78

Этот пример использует специальные виртуальные пины: 0x30 (постоянная 0) и 0x38 (постоянная 1). Эти пины могут использоваться как источники фиксированных логических уровней для команд "pin 0x30 matrix" и "pin 0x30 matrix".

Пример 13. Мониторинг аналогового сигнала на пине 36:

Используем ключевые слова "aread", "delay" и "loop" для создания простого аналогового монитора:

      esp32#>pin 36 aread delay 500 loop infinite

Эта команда работает в переднем плане и обновляет аналоговое значение каждые 500 мс. Можно, добавив символ &, запустить эту же команду в фоновом режиме, работать она будет так же (но можно будет пользоваться шеллом, пока она исполняется), но можно будет приостанавливать команду (см "suspend TASK_ID"),