WiFi server that drives low-level commands to the ESP32 RMT peripheral
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



WiFi server that drives low-level commands to the ESP32 RMT peripheral

NOTE: This code seems to work reliably and has all the features that I plan to implement. It is released.

The ESP32 receives an HTTP POST request and decodes commands contained in the request body. These commands control the RMT peripheral and drive an infrared LED. The commands are low-level mark and space commands. There is no protocol decode implemented in this application. This allows the RMT to transmit virtually any infrared protocol. Compiles with ESP-IDF

  • The HTTP POST request body consists of one or more text lines. Lines are separated by newline (\n) characters. Returns (\r) are allowed, but are ignored.
  • Each line consists of comma-separated values. There is one command on each line. Each line starts with one character that identifies the type of command for this line.

The intent is that a JavaScript program contained in an HTML file, running on a web browser and served by a host machine (not the ESP32) will create these low-level RMT commands and transmit them to the ESP32. An example HTML file is part of this repository. A real application will have its own repository.


The commands closely follow the RMT register/RAM definitions. Refer to the ESP32 documentation at http://esp32.net/ . Lines that do not follow these specifictions are silently ignored and the next line is processed.

  • c,[div],[high],[low]
    • Sets the RMT channel clock frequency and the carrier clock frequency and duty cycle.
    • [div]: RMT channel clock divider (RMT_DIV_CNT_CHn). Text representation of an integer between 1 and 255, inclusive. Defines the RMT channel clock division ratio. The channel clock is divided from the source clock. The ESP32 source clock is 80MHz.
    • [high] and [low]: High (RMT_CARRIER_HIGH_CHn) and low (RMT_CARRIER_LOW_CHn) duration of the carrier waveform. Text representation of integers between 1 and 65,535, inclusive. The unit of carrier_high/low is one source clock period.
  • t,[non-zero duration], ... ,0
    • Defines a sequence of durations of IR transmission bits, both modulated at the carrier frequency (mark) and idle (space).
    • [non-zero duration]: A text representation of a non-zero integer between -32,767 and 32,767, inclusive. These integers define the durations of transmit marks and spaces. A zero value denotes the end of the transmission sequence.
      • Positive integers create a burst of IR output (mark) at the carrier frequency, with duration of [non-zero-duration] channel clock periods.
      • Negative integers create a duration on the IR output with no carrier (space). The duration is in channel clock periods.
      • Positive and negative values do not need to be alternated. Either positive or negative values can follow a positive or negative value.
    • A zero value tells the RMT to stop the RMT transmission sequence. The last value on the line must be a zero. A zero anywhere else on the line will terminate the transmission sequence at that point. When terminated, a new RMT transmission can be started with a new command on a new line. There will be an indeterminate delay between consecutive RMT transmissions.
    • The RMT RAM can store a maximum of 128 duration values. If a line contains more than 128 values, the driver implements the RMT wrap-around mode to transmit the longer sequence. The terminating zero duration counts as one of the duration values.
  • d,[milliseconds delay]
    • [milliseconds delay]: Create a delay before decoding the next line. Used to create a realtively long gap between IR tramsmissions. Text representation of a positive non-zero integer of the number of milliseconds for the delay. Implemented with the FreeRTOS function:
      • vTaskDelay( milliseconds delay / portTICK_PERIOD_MS ); and has the limitations of that function. See the documentation for this function for the maximum possible delay, which depends on the tick period of your system and the data type used for this function. If your tick period is 1mS and the data type uses a 16-bit unsigned int, the maximum duration is about 65 seconds.


  • HTTP POST Request: A combination of request header and request body, sent to the ESP32. Your web browser automatically inserts a blank line between the header and body.
  • Request Header: Your browser creates most of this. Important options for this application are:
    • Request Type: POST. Needed to avoid CORS restrictions and to contain enough information for the ESP32.
    • Content-Type: text/plain. Needed to avoid CORS restrictions.
  • Request Body: One or more lines of text, following the format described above.
  • Lines: In this application, each line in the request body consists of multiple text values, separated by commas. All of the numbers transmitted to the ESP32 are text representations of decimal numbers. Each line is terminated by either:
    • a newline (\n), or
    • a return (\r) and a newline (\n), or
    • the end of the request body
  • Same-Origin-Policy: Keeps your compliant browser from fetching information from a different server than the original web page was served from. This is an important internet security feature.
  • CORS: Cross-Orgin-Resource-Sharing. A complex way to allow communications between different web hosts. This is the authorized way to skirt the Same-Origin-Policy. See the WiKi for more information.