ESP32 имеет специальный периферийный модуль генерации импульсных последовательностей, называемый RMT, основное назначение которого — создание произвольных сигналов с довольно высокой разрешающей способностью — до 0.0125 микросекунды (минимальная ширина импульса). Если вам "вручную" нужно создать какой-то цифровой сигнал, то RMT это то, что нужно.
Может использоваться как генератор сигналов общего назначения или для генерации ИК-сигналов дистанционного управления. Для второго случая предусмотрена так же модуляция нулей или единиц в вашем сконструированном сигнале.
Генерация импульсов осуществляется с помощью команд "sequence SEQ_ID" и "pin PIN seq SEQ_ID": первая команда задает последовательность импульсов, а вторая — запускает её на исполнение. Номер последовательности (SEQ_ID) должен быть от 0 до 9, то есть можно создать и использовать до 10 различных последовательностей. Если требуется больше, можно изменить макрос SEQUENCE_NUM в файле espshell.h.
Перед тем как перейти к описанию команд и примеров, рассмотрим основные термины:
Рассмотрим простую задачу: нужно сгенерировать несколько импульсов на выводе pin2 следующим образом:
"Установить pin2 в HIGH на 10 мкс, затем в LOW на 20 мкс, снова HIGH на 30 мкс, и наконец LOW на 100 мкс"
Начинаем с режима конфигурации последовательности:
esp32#>sequence 0 esp32-seq0>
Команда "sequence 0" создаёт пустую последовательность с номером 0 и переключает оболочку в режим конфигурации, что видно по изменению приглашения на "esp32-seq0>". Чтобы выйти из этого режима, используйте "exit" или нажмите Ctrl+Z.
Сначала установим разрешение последовательности, то есть "длину тика".
Выберем тик длиной 1 мкс:
esp32#>sequence 0 esp32-seq0>tick 1
По умолчанию тик уже равен 1 мкс, поэтому команду "tick 1" можно опустить.
Теперь зададим последовательность в виде уровней:
esp32#>sequence 0 esp32-seq0>tick 1 esp32-seq0>levels 1/10 0/20 1/30 0/100
Команда "levels" принимает параметры в формате "A/B", где A — это "1" или "0", а B — длительность уровня в тиках (от 1 до 32767). Для удобства можно использовать символ "/" как сокращение для 32767: "1//" то же самое, что "1/32767".
Команда выше означает: "лог.1 в течение 10 тиков, лог.0 — 20 тиков и т.д.". Поскольку мы установили тик равным 1 мкс, длительности получаются в микросекундах.
Теперь, когда последовательность 0 сконфигурирована, можно воспроизвести её на GPIO2:
esp32#>sequence 0 esp32-seq0>tick 1 esp32-seq0>levels 1/10 0/20 1/30 0/100 esp32-seq0>exit esp32#>pin 2 seq 0
Или отправить 4 раза подряд:
esp32#>sequence 0 esp32-seq0>tick 1 esp32-seq0>levels 1/10 0/20 1/30 0/100 esp32-seq0>exit esp32#>pin 2 seq 0 ← один раз esp32#>pin 2 seq 0 seq 0 seq 0 seq 0 ← 4 раза подряд
Примечание: есть и альтернативный способ отправить 4 раза — использовать команду "pin 2 seq 0 loop 4"
Хотя можно задавать уровни вручную, для длинных последовательностей это неудобно. Вместо этого можно использовать команды "bits", "one" и "zero", вместо прямого задания уровней через "levels".
Команда "bits" задаёт битовую строку, а команды "one" и "zero" определяют, как в уровнях выглядят лог.1 и лог.0. Например, мы хотим передать:
"HIGH 10 мкс, LOW 20 мкс, HIGH 30 мкс, LOW 100 мкс"
Команды будут такими:
esp32#>sequence 0 esp32-seq0>one 1/10 ← "Один" это HIGH на 10 тиков esp32-seq0>zero 0/10 ← "Ноль" это LOW на 10 тиков esp32-seq0>bits 1001110000000000
Здесь "1" означает HIGH на 10 мкс, а "0" — LOW на 10 мкс. Чтобы достичь нужной длительности, мы просто дублируем биты:
1 - HIGH на 10 мкс 00 - LOW на 20 мкс 111 - HIGH на 30 мкс 0000000000 - LOW на 100 мкс
Установка "bits" сбрасывает "levels" и наоборот. После задания "tick", "bits", "one" и "zero", уровни автоматически генерируются и могут быть просмотрены через "show":
esp32#>sequence 0 esp32-seq0>one 1/10 ← "Один" это HIGH на 10 тиков esp32-seq0>zero 0/10 ← "Ноль" это LOW на 10 тиков esp32-seq0>bits 1001110000000000 esp32-seq0>show % % Sequence #0: % Resolution : 1.0000uS (Frequency: 1000000 Hz) % Levels are : % 1/10, 0/10, 0/10, 1/10, 1/10, 1/10 .... < -- сгенерировано
Периферия ESP32, отвечающая за генерацию импульсов, изначально предназначена для ИК-протоколов, где 1 и 0 — это не просто уровни, а импульсы. Они настраиваются с помощью аргументов в командах "one" и "zero". Например:
Определим наш алфавит так: единица это HIGH на 150мкс, а затем LOW на 50 мкс; Ноль же определим наоборот: HIGH на 50 и LOW на 150 мкс. Передадим строчку битов 100111 используя указанный алфавит:
esp32#>seq 0 esp32-seq0>tick 1 esp32-seq0>one 1/150 0/50 esp32-seq0>zero 1/50 0/150 esp32-seq0>bits 100111 esp32-seq0>show % % Sequence #0: % Resolution : 1.0000uS (Frequency: 1000000 Hz) % Levels are : % 1/150, 0/50, 1/50, 0/150, 1/50, 0/150, 1/150, 0/50, % 1/150, 0/50, 1/150, 0/50, % Total: 12 levels, duration: 1200 ticks, (~1200 uS)
Обратите внимание на то, что команды one и zero в примере выше задают не уровень а импульс, но команда show показывает, что у нас заданы уровни. Так и должно быть: эти уровни были сгенерированы из алвавита и битовой строчки.
В разработке...
Команда "show sequence NUM" показывает информацию о последовательности под номером NUM. Всего доступно до 10 последовательностей, нумерация начинается с 0.
Пример вывода:
esp32#>sh seq 0 % % Sequence #0: % Resolution : 1.0000uS (Frequency: 1000000 Hz) % Levels are % 1/50, 0/20,1/50, 0/20,1/50, 0/20,1/50, 0/20,1/50, 0/20, ... % Total: 28 levels, duration: 1180 ticks, (~1180 uS) % Modulation : yes, "LOW" are modulated at 100Hz, duty 30.00% % Bit sequence is : (14 bits) "10011110101111" % Zero is 1/100 0/20 % One is 1/50 0/20 % Hold LOW after transmission is done
Пример: создать последовательность, при которой светодиод на GPIO2 мигает с частотой около 1 Гц.
Для частоты 1 Гц тик должен быть максимально возможным, а длительность 1 и 0 — максимальной. Максимальный тик — 3.2 мкс. Используем его и зададим максимальную длительность:
esp32-seq0>tick 3.2 esp32-seq0>one 1// esp32-seq0>zero 0// esp32-seq0>bits 111111111000000000111111111000000000
Знак "/" означает 32767.
Выйти из режима последовательности можно с помощью "exit" или Ctrl+Z. Можно использовать сокращения: "seq" вместо "sequence", "ex" вместо "exit".
Запускаем последовательность на пине. Если на pin2 подключен светодиод — он должен мигать:
esp32-seq0>ex esp32#>pin 2 seq 0 loop inf & ← "loop inf &" == "повторять бесконечно, в фоне" % Sending sequence 0 over GPIO 2
Есть и дополнительные команды категории "sequence", которые не описаны здесь. Посмотреть их можно с помощью "?" перед именем команды и нажатием Enter.
Примечание: по умолчанию команда отправки последовательности ("pin X sequence Y") является блокирующей. Чтобы сделать её неблокирующей, добавьте "&" в конце (запуск в фоновом режиме).