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

- Pulse pattern generation
- Basic concept: "tick", "level", and "pulse"
- Sending pulse sequences
- Bit strings
- Modulation & End-Of-Transmission
- Displaying information
- Examples

## ⇮ PULSE PATTERN GENERATION

ESP32 features a dedicated peripheral called RMT (Remote Control) for pulse train generation. Its primary purpose is to produce arbitrary signal patterns with high precision - down to 0.0125 microseconds.

It can be used as a general-purpose signal generator or for IR remote signal generation.

## ⇮ BASIC CONCEPT: "TICK", "LEVEL", AND "PULSE"

Pulse pattern generation is controlled using the "sequence SEQ_ID" and "pin PIN seq SEQ_ID" commands. The former defines a sequence of pulses to generate, while the latter transmits it. The sequence number (SEQ_ID) must be in the range 0-9, allowing up to 10 different sequences to be created. If more are needed, one can modify the SEQUENCE_NUM macro in espshell.h.

Before diving into commands and examples, let's clarify some terminology used throughout this document:

- Level: either logic "0" or logic "1" - a voltage level. A sequence can consist of levels or pulses.
- Pulse: two consecutive levels, e.g., "logic 1 for X nanoseconds, then logic 0 for Y nanoseconds." Pulses are used in IR protocols and Manchester encoding. Unlike levels, pulses can be modulated (modulation applies to either logic 1 or logic 0) to create IR-compatible signals like those used in the NEC protocol.
- Tick: a time unit used in sequences. Tick duration can range from 0.0125 us to 3.2 us and is defined by the user. When a sequence is created, its tick value defaults to 1 us.

Let's solve a simple task: suppose we want to generate a series of pulses on pin 2:

"Set pin 2 HIGH for 10 us, then LOW for 20 us, then HIGH for 30 us, and finally LOW for 100 us."

We begin by entering sequence configuration mode:

      esp32#>sequence 0
      esp32-seq0>

The command "sequence 0" creates an empty Sequence0 and enters sequence configuration mode. The shell prompt changes to "esp32-seq0>" to indicate the new mode. To exit, use "exit" or press `Ctrl+Z`.

First, set the resolution for the sequence - the so-called tick length:

      esp32#>sequence 0
      esp32-seq0>tick 1

By default, sequences are created with a 1 us tick, so the "tick 1" command is optional.

Now, input the sequence as a series of levels:

      esp32#>sequence 0
      esp32-seq0>tick 1
      esp32-seq0>levels 1/10 0/20 1/30 0/100

The "levels" command accepts arguments in the form "A/B", where A is "1" or "0", and B is the duration (1-32767 ticks). Use "show" to inspect the total sequence duration in ticks and microseconds. Tip: "1//" is a shorthand for "1/32767".

The command above means: set output HIGH for 10 ticks, LOW for 20 ticks, etc. Since we use a 1 us tick, the durations directly match the microsecond values.

## ⇮ SENDING PULSE SEQUENCES

Now that sequence 0 is configured, let's send it on 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

To send it 4 times in a row:

      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

NOTE: An alternative is to use the "pin 2 seq 0 loop 4" command.

## ⇮ BITS TO LEVELS, BITS TO PULSES

While you can define all levels manually, it becomes impractical for longer sequences. Instead, use the "bits", "one", and "zero" commands.

The "bits" command defines the bit stream, while "one" and "zero" specify how logic 1 and 0 are represented in terms of HIGH/LOW durations. Let's recreate the earlier pulse sequence:

"HIGH for 10 us, LOW 20 us, HIGH 30 us, LOW 100 us"

Shell commands:

      esp32#>sequence 0
      esp32-seq0>bits 1001110000000000
      esp32-seq0>one 1/10
      esp32-seq0>zero 0/10

"One" defines logic 1 as HIGH for 10 us, and "zero" defines logic 0 as LOW for 10 us. The bit stream encodes timing as follows:

      1          - HIGH for 10 us
      00         - LOW for 20 us
      111        - HIGH for 30 us
      0000000000 - LOW for 100 us

The "bits" command clears any previously set "levels", and vice versa. Once tick, bits, one, and zero are configured, levels are generated automatically and shown via "show":

      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 ....

The ESP32 RMT peripheral is designed for IR protocol encoding, where 1 and 0 are typically pulses rather than static levels. Pulses can be defined using "one" and "zero" with two durations each. For example, to encode:

- logic 1 as HIGH 150 us then LOW 50 us
- logic 0 as HIGH 50 us then LOW 150 us

      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)  ← total sequence time

## ⇮ MODULATION AND END-OF-TRANSMISSION

TBD

## ⇮ DISPLAYING INFORMATION

Use the "show sequence NUM" command to view a configured sequence. The command requires a sequence number (0-9).

Example output:

    esp32#>sh seq 0
          %
          % Sequence #0:
          % Resolution : 1.0000uS  (Frequency: 1000000 Hz)
          % Levels are
          % 1/50, 0/20, 1/100, 0/20, 1/100, 0/20, 1/50, 0/20,
          % 1/50, 0/20, 1/50, 0/20, 1/50, 0/20, 1/100, 0/20,
          % 1/50, 0/20, 1/100, 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
          esp32#>

## ⇮ EXAMPLES

Example: Blink an LED connected to GPIO2 at ~1 Hz.

Given a 1 Hz frequency, choose the longest possible tick and level durations. The maximum tick is 3.2 us. Define "one" and "zero" with the maximum length:

      esp32-seq0>tick 3.2
      esp32-seq0>one 1//
      esp32-seq0>zero 0//
      esp32-seq0>bits 111111111000000000111111111000000000

Note: The "/" symbol is a shortcut for "32767"

Exit sequence mode using "exit" or Ctrl+Z. You can also use short forms like "seq" and "ex".

To play the sequence (e.g., blink the LED on GPIO2):

      esp32-seq0>ex
      esp32#>pin 2 seq 0
      % Sending sequence 0 over GPIO 2

Several additional "sequence" commands are not covered here. Type "?" before a command name to explore further.

NOTE: By default, the "pin X sequence Y" command is blocking. To make it non-blocking, append the "&" flag (run in background).