Espressif ESP32 implementation of ANSI-ESTA E1.11 DMX-512A

Overview

esp_dmx

This library allows for transmitting and receiving ANSI-ESTA E1.11 DMX-512A using an Espressif ESP32. It provides control and analysis of the packet configuration and allows the user to read synchronously or asynchronously from the DMX bus. This library also includes tools for data error-checking to safely process DMX commands.

Installation

ESP-IDF

Clone this repository into your project's components folder. The library can be linked by putting #include "esp_dmx.h" at the top of your main.c file.

Quick-Start Guide

This library was written to look similar to the ESP-IDF UART implementation. To get started, call the following code in app_main() in your main.c file.

const dmx_port_t dmx_num = DMX_NUM_2;

// first configure the UART...
const dmx_config_t config = DMX_DEFAULT_CONFIG;
dmx_param_config(dmx_num, &config);

// then set the communication pins...
const int tx_io_num = 17, rx_io_num = 16, rts_io_num = 21;
dmx_set_pin(dmx_num, tx_io_num, rx_io_num, rts_io_num);

// and install the driver!
QueueHandle_t dmx_queue;
dmx_driver_install(dmx_num, DMX_MAX_PACKET_SIZE, 10, &dmx_queue, 
      ESP_INTR_FLAG_IRAM);

Before the user is able to read or write to the DMX bus, the driver mode must be set. Call dmx_set_mode() and pass either DMX_MODE_RX or DMX_MODE_TX. After the driver is installed DMX_MODE_RX is the default.

// configure for tx
dmx_set_mode(dmx_num, DMX_MODE_TX);

To write data to the DMX bus, two functions are provided. The function dmx_write_packet() writes data to the DMX buffer and dmx_tx_packet() sends the data out onto the bus. The function dmx_wait_tx_done() is used to block the task until the DMX bus is idle.

uint8_t data[DMX_MAX_PACKET_SIZE] = {0};
while (1) {
    // write to the packet and tx it
    dmx_write_packet(dmx_num, data, DMX_MAX_PACKET_SIZE);
    dmx_tx_packet(dmx_num);
    
    // do work here...

    // block until the packet is finished sending
    dmx_wait_tx_done(dmx_num, DMX_TX_PACKET_TOUT_TICK);
}

To read from the DMX bus, use the queue handle passed to dmx_driver_install(). The function dmx_read_packet() is provided to read from the driver buffer into an array.

dmx_event_t event;
while (1) {
    if (xQueueReceive(dmx_queue, &event, DMX_RX_PACKET_TOUT_TICK)) {
        // read the packet from the driver buffer into 'data'
        dmx_read_packet(dmx_num, data, DMX_MAX_PACKET_SIZE);
    }

    // do other work here...

}

That's it! For more detailed information on how this library works, keep reading.

What is DMX?

DMX is a unidirectional communication protocol used primarily in the entertainment industry to control lighting and stage equipment. DMX is transmitted as a continuous stream of packets using half-duplex RS-485 signalling with a standard UART port. DMX devices are typically connected using XLR5 in a daisy-chain configuration but other connectors such as XLR3 are common in consumer products.

Each DMX packet begins with a high-to-low transition called the break, followed by a low-to-high transition called the mark after break, followed by an eight-bit byte. This first byte is called the start code. The start-of-packet break, mark after break, and start code is called the reset sequence. After the reset sequence, a packet of up to 512 data bytes may be sent.

DMX imposes very strict timing requirements to allow for backwards compatibility with older lighting equipment. Frame rates may range from 1fps to up to approximately 830fps. A typical DMX controller transmits packets at approximately 44fps. DMX receivers and transmitters have different timing requirements which must be adhered to carefully to ensure commands are processed.

Today, DMX often struggles to keep up with the demands of the latest hardware. Its low data rate and small packet size sees it losing market popularity over more capable protocols. However its simplicity and robustness often makes it the first choice for small scale projects.

For in-depth information on DMX, see the E1.11 standards document.

Setup

Configuring and setting up the DMX driver should be familiar to those who have experience with the ESP-IDF UART driver. The functions dmx_param_config(), dmx_set_pin(), and dmx_driver_install() have similar behavior to uart_param_config(), uart_set_pin(), and uart_driver_install().

The DMX driver’s functions identify each of the UART controllers using dmx_port_t. This identification is needed for all the following function calls.

Setting Communication Parameters

Single Step

Call the function dmx_param_config() and pass it a dmx_config_t structure. It contains all the parameters needed to configure the DMX packet settings. In most situations, custom packet configuration isn't necessary. The macro DMX_DEFAULT_CONFIG is provided to simplify this process.

const dmx_config_t dmx_config = DMX_DEFAULT_CONFIG;
dmx_param_config(DMX_NUM_2, &dmx_config);

If using a custom DMX configuration is desired, the dmx_config_t parameters can be set manually.

const dmx_config_t dmx_config = {
    .baud_rate = 250000, // typical baud rate   
    .break_num = 45,     // 180us 
    .idle_num = 5        // 20us
};
dmx_param_config(DMX_NUM_2, &dmx_config);

The break_num corresponds to the duration of the packet break and idle_num corresponds to the duration of the mark after break. Both values are set in units of time that it takes to send one bit at the current baud rate. If the current baud rate is 250k, it takes 4μs to send one bit. Setting break_num to 45 and idle_num to 5 in this example sets the break and mark after break to 180μs and 20μs respectively.

Multiple Steps

Parameters may be configured individually by calling the below dedicated functions. These functions are also useful if re-configuring a single parameter.

dmx_set_baud_rate(DMX_NUM_2, 250000);
dmx_set_break_num(DMX_NUM_2, 44);
dmx_set_idle_num(DMX_NUM_2, 3);

Each of the above functions has a _get_ counterpart to check the currently set value. For example, to check the current baud rate, call dmx_get_baud_rate().

Setting Communication Pins

Configure the physical GPIO pins to which the DMX port will be connected. To do this, call the function dmx_set_pin() and specify which GPIO should be connected to the TX, RX, and RTS signals. If you want to keep a currently allocated pin to a specific signal, pass the macro DMX_PIN_NO_CHANGE. This macro should also be used if a pin isn't used.

// set TX: IO16 (port 2 default), RX: IO17 (port 2 default), RTS: IO21
dmx_set_pin(DMX_NUM_2, DMX_PIN_NO_CHANGE, DMX_PIN_NO_CHANGE, 21);

Installing the Driver

After the communication pins are set, install the driver by calling dmx_driver_install(). The following parameters are passed to this function:

  • Size of the driver double-buffer
  • Size of the event queue
  • Handle to the queue
  • Flags to allocate interrupts

This function will allocate the necessary resources for the DMX driver. Note that the driver uses a double-buffer system. The driver will allocate twice the size of the passed buffer size argument.

QueueHandle_t dmx_queue;
const int buffer_size = DMX_MAX_PACKET_SIZE; // 513 bytes
// install DMX driver using an event queue
dmx_driver_install(DMX_NUM_2, buffer_size, 10, &dmx_queue, 0);

Once this step is complete, DMX devices can be connected to check for communication.

Reading and Writing

Setting Device Mode

DMX is a unidirectional protocol. This means that on the DMX bus only one device can transmit commands and many devices (typically up to 32) listen for commands. Therefore, this library permits either reading or writing to the bus but not both at once.

To set the driver mode call dmx_set_mode() and pass to it either DMX_MODE_RX or DMX_MODE_TX. After the driver is installed DMX_MODE_RX is the default.

// set the DMX driver to transmit mode
dmx_set_mode(dmx_num, DMX_MODE_TX);
// dmx_set_mode(dmx_num, DMX_MODE_RX); // don't need to rx now

If transmitting and receiving data simultaneously is desired, the user can install two drivers on two UART ports. It should be noted that this is an unusual use case. This library is not meant to act as a DMX optoisolator or splitter.

Reading

To read from the DMX bus, the event queue handle passed to dmx_driver_install() can be used to determine when a packet has been received. A dmx_event_t message will be posted to the event queue. Then the packet can be read from the DMX driver double-buffer into a user buffer using dmx_read_packet().

The macro DMX_RX_PACKET_TOUT_TICK can be used to block the task until a packet is received or a DMX timeout occurs.

// allocate a buffer that is the max size of a DMX packet
uint8_t data[DMX_MAX_PACKET_SIZE];

dmx_event_t event;
while (1) {
    if (xQueueReceive(dmx_queue, &event, DMX_RX_PACKET_TOUT_TICK) == pdTRUE) {
        // read back the size of the packet into our buffer
        dmx_read_packet(dmx_num, data, event.size);
    } else {
        // handle packet timeout...
    }
}

The dmx_event_t structure contains some helpful information about the packet that was received. Some of the information includes:

  • Packet errors
  • Start code
  • Size in bytes
  • Duration in microseconds

These values can be used to determine if the received data should be processed or ignored.

// if there are no errors and the start code is correct, read the packet
if (event.status == DMX_OK && event.start_code == DMX_SC) {
    dmx_read_packet(dmx_num, data, event.size);

    printf("Packet took %i microseconds!", event.duration);
}

This library offers tools to perform robust error-checking. For more information on errors, see the Error Handling section.

RX Timing Tool

This library offers an option to measure break and mark after break timings of received data packets. This tool is much more resource intensive than the default DMX receive driver, so it must be explicitly enabled by calling dmx_rx_timing_enable().

The timing tool installs an edge-triggered interrupt on the specified GPIO pin. This library uses the ESP-IDF provided GPIO ISR which allows the use of individual interrupt handlers for specific GPIO interrupts. The interrupt handler works by iterating through each GPIO to determine if it triggered an interrupt and if so, it calls the appropriate handler.

A quirk of the default ESP-IDF GPIO ISR is that lower GPIO numbers are processed earlier than higher GPIO numbers. It is recommended that the DMX RX pin be shorted to a lower GPIO number in order to ensure that the DMX timing tool can run with low latency.

It is important to note that the timing tool requires a fast clock speed in order to maintain low latency. In order to guarantee accuracy of the timing tool, the ESP32 must be set to a CPU clock speed of at least 160MHz. This setting can be configured in sdkconfig.

Before enabling the timing analysis tool gpio_install_isr_service() must be called.

gpio_install_isr_service(ESP_INTR_FLAG_EDGE | ESP_INTR_FLAG_IRAM);
const int timing_io_num = 4; // lowest exposed pin on the Feather breakout board
dmx_rx_timing_enable(dmx_num, timing_io_num);

Break and mark after break timings are reported to the event queue when the timing tool is enabled. If the timing tool is disabled, either because dmx_rx_timing_disable() was called or because dmx_rx_timing_enable() was not called, the reported break and mark after break durations will default to -1.

dmx_event_t event;
if (xQueueReceive(queue, &event, DMX_RX_PACKET_TOUT_TICK) == pdTRUE) {
  // read back break and mark after break
  printf("The break was %ius, ", event.timing.brk);
  printf("and the mark after break was %ius.\n", event.timing.mab);
}

Writing

Writing to the DMX bus does not require the use of an event queue. To write to the DMX bus, dmx_write_packet() can be called. This writes data to the DMX driver but it does not transmit a packet onto the bus. In order to transmit the data that was written, dmx_tx_packet() can be called. When a packet is sent out onto the bus, its size will be the same as the buffer size that was passed to dmx_driver_install().

uint8_t data[DMX_MAX_PACKET_SIZE] = { 0, 1, 2, 3 };

dmx_set_mode(DMX_NUM_2, DMX_MODE_TX); // enable tx mode

// write the packet and send it out on the DMX bus
dmx_write_packet(DMX_NUM_2, data, MAX_PACKET_SIZE);
dmx_tx_packet(DMX_NUM_2);

Calling dmx_tx_packet() will fail if the DMX driver is currently transmitting a packet of DMX data. To ensure that packets are continuously sent, dmx_wait_tx_done() can be used.

uint8_t data[DMX_MAX_PACKET_SIZE] = { 0, 1, 2, 3 };

dmx_set_mode(DMX_NUM_2, DMX_MODE_TX); // enable tx mode

while (1) {
    // write and send the packet
    dmx_write_packet(DMX_NUM_2, data, MAX_PACKET_SIZE);
    dmx_tx_packet(DMX_NUM_2);

    // do other work here...

    // block until we are ready to send another packet
    dmx_wait_tx_done(DMX_NUM_2, DMX_TX_PACKET_TOUT_TICK);
}

The DMX driver will automatically check if the DMX transmission has timed out between sending the last packet and the current packet. If it has, it will simulate a DMX reset sequence in software before sending a new packet. Simulating the reset sequence uses inefficient busy-waiting to recreate a break and mark after break. ESP32 busy-waiting is imprecise at the microsecond resolution that is needed for the reset sequence. If the DMX task is not preempted it is usually precise within 30μs. Because this should only happen after sending the first packet and because 30μs is well within DMX timing requirements, this behavior is acceptable for this library.

Error Handling

On rare occasions, DMX packets can become corrupted. Errors can be checked by reading the status from the dmx_event_t structure. The error types are as follows:

  • DMX_OK occurs when the packet is received successfully.
  • DMX_ERR_IMPROPER_SLOT occurs when a slot is missing a start or stop bit.
  • DMX_ERR_PACKET_SIZE occurs when the number of data bytes received exceeds DMX_MAX_PACKET_SIZE
  • DMX_ERR_BUFFER_SIZE occurs when the driver buffer size is smaller than the number of packets received. This error will not occur if the driver buffer size is set to DMX_MAX_PACKET_SIZE.
  • DMX_ERR_DATA_OVERFLOW occurs when the UART hardware is not able to process data quickly enough and it overflows.

In most errors, the event size can be read to determine at which byte the error occurred. In every error condition except for DMX_ERR_BUFFER_SIZE the event start code will default to -1.

dmx_event_t event;
while (1) {
  if (xQueueReceive(queue, &event, DMX_RX_PACKET_TOUT_TICK)) {
    switch (event.status) {
      case DMX_OK:
        printf("Received packet with start code: %02X and size: %i\n",
          event.start_code, event.size);
        // data is ok - read the packet into our buffer
        dmx_read_packet(dmx_num, data, event.size);
        break;

      case DMX_ERR_IMPROPER_SLOT:
        printf("Received malformed byte at slot %i\n", event.size);
        // a slot in the packet is malformed - possibly a glitch due to the
        //  XLR connector? will need some more investigation
        // data can be recovered up until event.size
        break;

      case DMX_ERR_PACKET_SIZE:
        printf("Packet size %i is invalid\n", event.size);
        // the host DMX device is sending a bigger packet than it should
        // data may be recoverable but something went very wrong to get here
        break;

      case DMX_ERR_BUFFER_SIZE:
        printf("User DMX buffer is too small - received %i slots\n", 
          event.size);
        // whoops - our buffer isn't big enough
        // this code will not run if buffer size is set to DMX_MAX_PACKET_SIZE
        break;

      case DMX_ERR_DATA_OVERFLOW:
        printf("Data could not be processed in time\n");
        // the UART FIFO overflowed
        // this could occur if the interrupt mask is misconfigured or if the
        //  DMX ISR is constantly preempted
        break;
    }
  } else {
    printf("Lost DMX signal\n");
    // haven't received a packet in DMX_RX_PACKET_TOUT_TICK ticks
    // handle packet timeout...
  }
}

It should be noted that this library does not automatically check for DMX timing errors. This library does provide macros to assist with timing error checking, but it is left to the user to implement such measures. The following macros can be used to assist with timing error checking.

  • DMX_RX_PKT_DURATION_IS_VALID() evaluates to true if the packet duration is valid.
  • DMX_RX_BRK_DURATION_IS_VALID() evaluates to true if the break duration is valid.
  • DMX_RX_MAB_DURATION_IS_VALID() evaluates to true if the mark after break duration is valid.

DMX specifies different timing requirements for receivers and transmitters. In situations where it is necessary to check if transmitted timing values are valid, this library provides _TX_ versions of the above macros.

Finally, the following macros can be used in both transmit and receive scenarios.

  • DMX_BAUD_RATE_IS_VALID() evaluates to true if the baud rate is valid.
  • DMX_START_CODE_IS_VALID() evaluates to true if the start code is permitted in the DMX standard.

This library offers additional macros for common definitions in the DMX standard which can assist with error handling. These macros can be found in dmx_caps.h which is included with esp_dmx.h. These macros include various defined DMX timing requirements and DMX start codes. See dmx_caps.h for a list of these macros.

Additional Considerations

Hardware Specifications

ANSI-ESTA E1.11 DMX512-A specifies that DMX devices be electrically isolated from other devices on the DMX bus. In the event of a power surge, the likely worse-case scenario would mean the failure of the RS-485 circuitry and not the entire DMX device. Some DMX devices may function without isolation, but using non-isolated equipment is not recommended.

To Do

  • Reset-Sequence-First Mode. Allow for reset sequences to be sent first rather than using the UART hardware break circuitry.
  • Remote Device Management. Enable RDM compatibility for DMX transceivers.
  • Art-Net. Enable Art-Net compatibility using ESP-IDF Ethernet Driver.
Comments
  • Serial Monitor output is only the character

    Serial Monitor output is only the character "null"

    Hi.

    First of all many thanks for this great library you provided. It looks really awesome!

    I tried to run your "DMXWrite" example on my machine but unfortuantely the serial monitor output is just garbage. I use VSCodium and PlatformIO and your instructions in the README were very helpful. I checked that I use the right monitor speed (115200) but still I only get the "null" character (U+2400) back. I traced it back to line 43 "dmx_param_config(dmxPort, &dmxConfig);" as if I remove it (and all of the depending code) the problem does not appear anymore. Not sure if this is helpful as I'm also overwhelmed with the internal clockworks of your library.

    Any help would be very appreciated.

    Thanks, quirsh

    bug question 
    opened by quirsh 19
  • Won't compile for esp32-C3

    Won't compile for esp32-C3

    Attempted to build for the esp32-C3 and it fails with a compiler error as was suspected in the FIXME: comment on line 17 in the driver.h file. The eps32-C3 only has two UARTS which is why it fails. I adjusted the #define but it still won't compile due to a different uart_struct.h file (in the esp-idf/components/esp32c3/include/soc dir) being used.

    I attempted to make appropriate changes to the data structure members and was able to get it to compile. However, I have not yet succeeded in getting it to work. It does run and install the driver, but no activity on the io pins (yet). Most of the data structure member differences had similar equivalent member names between the two different uart_struct.h files. However, there did not seem to be an equivalent member for tick_ref_always_on. I made a wild guess on this one and I plan to revisit my changes in the areas where I changed tick_ref_always_on to another member (mem_clk_en).

    bug 
    opened by txbugeater 18
  • Incompatibility with LittleFS (Cache disabled but cached memory region accessed)

    Incompatibility with LittleFS (Cache disabled but cached memory region accessed)

    I find that if I try to write a file with LitteFS whilst received DMX I get a Guru Meditation Error.

    The backtrace is corrupted so I can't fully see exactly where this is happening :

    Guru Meditation Error: Core  1 panic'ed (Cache disabled but cached memory region accessed). 
    
    Core  1 register dump:
    PC      : 0x400e692c  PS      : 0x00060035  A0      : 0x40086abc  A1      : 0x3ffbf22c  
    A2      : 0x00000078  A3      : 0x3ffbdcc0  A4      : 0x00000020  A5      : 0x3ffbdcbc  
    A6      : 0x3ffbc2f8  A7      : 0x00000001  A8      : 0x8008165c  A9      : 0x00000078  
    A10     : 0x3ffbdcbc  A11     : 0x3ffbc45c  A12     : 0x3ffbf244  A13     : 0x3ffbdcbc  
    A14     : 0x3ffc4608  A15     : 0x84022044  SAR     : 0x00000017  EXCCAUSE: 0x00000007  
    EXCVADDR: 0x00000000  LBEG    : 0x400865a9  LEND    : 0x400865b1  LCOUNT  : 0x00000027  
    
    
    Backtrace:0x400e6929:0x3ffbf22c |<-CORRUPTED
      #0  0x400e6929:0x3ffbf22c in uart_ll_write_txfifo at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/hal/esp32/include/hal/uart_ll.h:235
          (inlined by) uart_hal_write_txfifo at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/hal/uart_hal_iram.c:40
    
    
    
    
    ELF file SHA256: 0000000000000000
    
    Rebooting...
    

    I am using a ESP WROVER-E and have the DMX being received on UART1 (But I have also tried it on UART2 and there is no difference).

    I'm using the Arduino Framework which reports to be using ESP-IDF v4.4.1-1-gb8050b365e

    bug 
    opened by bensuffolk 10
  • pin assignment for ESP32 & 485

    pin assignment for ESP32 & 485

    Thanks for nice library. I tried using example as it is DMXRead

    using Arduino ide & compile is OK.

    but cannot detect DMX signal and found cannot go through both following if statement ...

    • if (xQueueReceive(queue, &packet, DMX_RX_PACKET_TOUT_TICK)) {
    • } else if (dmxIsConnected) {

    pin diagram is followed by here https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/uart.html#circuit-a-collision-detection-circuit

    but, is my wire connection wrong ? esp32 - max485 dmx wiring

    or is there something I should amend on example code ?

    documentation question 
    opened by nada0302 10
  • dmx_receive returns too early and data size is wrong

    dmx_receive returns too early and data size is wrong

    I am experimenting with the v3.0 release branch and am seeing some strange behavior.

    • The dmx_receive method returns too early. In my experiment it is returning at ~150hz (Max hz of dmx is ~44hz).
    • The size that is reported by dmx_receive is random. I.e. after a re-boot it will return a different size. The size never changes.

    From my understanding of the documentation dmx_receive should block until a new dmx frame is returned but somehow this is not the case.

    Am I missing something? This feels like I am not initializing something correctly. The received data is correct, i.e. when I move the fader on the dmx sender I can see the correct value in the buffer.

    The code below produces the following output:

    ...
    E (15660) main: 15.675053: hz: 154.513034, ret: 255, data: 7
    ...
    
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "freertos/queue.h"
    #include "esp_dmx.h"
    #include "esp_log.h"
    #include "esp_system.h"
    
    #define TX_PIN 17 // the pin we are using to TX with
    #define RX_PIN 16 // the pin we are using to RX with
    #define EN_PIN 21 // the pin we are using to enable TX on the DMX transceiver
    
    static const char *TAG = "main";
    static uint8_t data[DMX_MAX_PACKET_SIZE] = {};
    
    void dmxTask(void *unused)
    {
        ESP_ERROR_CHECK(dmx_set_pin(DMX_NUM_2, TX_PIN, RX_PIN, EN_PIN));
        ESP_ERROR_CHECK(dmx_driver_install(DMX_NUM_2, DMX_DEFAULT_INTR_FLAGS));
        int count = 0;
    
        while (true)
        {
            dmx_event_t event;
            size_t ret = 0;
            ret = dmx_receive(DMX_NUM_2, &event, DMX_TIMEOUT_TICK);
            if (ret)
            {
                // Check that no errors occurred.
                if (event.err == ESP_OK)
                {
                    count++;
    
                    const double currentTimS = esp_timer_get_time() / 1000000.0;
                    ESP_LOGE(TAG, "%f: hz: %f, ret: %d", currentTimS, (count / currentTimS), ret);
                    dmx_read(DMX_NUM_2, data, event.size);
                }
                else
                {
                    ESP_LOGE(TAG, "dmx error: %s", esp_err_to_name(event.err));
                }
            }
        }
    }
    
    void app_main()
    {
        TaskHandle_t dmxTaskHandle = NULL;
        // TODO determine real stack usage and reduce later
        xTaskCreatePinnedToCore(dmxTask, "DMX_TASK", 10240, NULL, 2, &dmxTaskHandle, 1);
        if (!dmxTaskHandle)
        {
            ESP_LOGE(TAG, "Failed to create dmx task");
        }
    }
    
    bug 
    opened by arneboe 9
  • Compilation problem in platformIO

    Compilation problem in platformIO

    Hi, your library look fine ! I am curently testing it, no problem in the arduino IDE but in platformIO I have this error messages : .pio/libdeps/esp32doit-devkit-v1/esp_dmx/src/esp_dmx.h:12:28: fatal error: hal/gpio_types.h: No such file or directory .pio/libdeps/esp32doit-devkit-v1/esp_dmx/src/dmx_types.h:19:3: error: unknown type name 'uart_sclk_t'

    opened by arpschuino 9
  • How to use with Platform.IO / Arduino Framework

    How to use with Platform.IO / Arduino Framework

    Hi, I am trying for hours to get this to work with Platform.IO and the Arduino Framework. Do you know how I could mix this esp-idf component withing my existing Arduino project or do you know if there is a platform.io lib for this repo?

    enhancement question 
    opened by ellogwen 7
  • very slow execution of the rest of the code

    very slow execution of the rest of the code

    Hi, sorry to disturb you again ! is it possible to bypass this verification : if (xQueueReceive(queue, &packet, DMX_PACKET_TIMEOUT_TICK) "The macro DMX_PACKET_TIMEOUT_TICK can be used to block the task until a packet is received or a DMX timeout occurs." So I don't want to block the execution of the rest of my code !

    question 
    opened by arpschuino 6
  • Unable to build

    Unable to build

    I cloned this into the components folder of my project and attempted to build. I am getting an error ../components/esp_dmx/include/dmx_caps.h:7:10: fatal error: soc/uart_caps.h: No such file or directory

    I am unable to find a file soc/uart_caps.h either on my local install of ESP-IDF or on Espressifs Github. Does this library require a specific version of ESP-IDF? Am I missing a setup step? Do I need to create this file?

    For context: I am attempting to get DMX up and running on an existing project with other functionalities. I was able to build and flash before attempting to add this library. I am using ESP-IDF version v4.4-dev-1404-gc13afea63 on Linux.

    bug 
    opened by AndrewBHarmon 6
  • VSCode and Platformio

    VSCode and Platformio

    Great work Mitch, thank you. This is not an issue with the current code and IDE, but related to another IDE. I tried to run this project from VSCode with Platformio and I get some errors for missing datatypes (like uart_sclk_t). In your instructions you are clear about using the latest framework. Because I am using the arduino framework I cannot use the latest espidf framework which is certainly causing the missing datatype errors. Have you used VSCode with Platformio successfully with your project?

    documentation question 
    opened by berlinrob 5
  • Helper functions for rdm discovery response

    Helper functions for rdm discovery response

    I added some helper functions that I need to make the device discoverable via RDM.

    The example was tested using the "Botex Dr. RDM | DMX RDM Tester" and it works.

    Do you think it would make sense to add basic rdm stuff like discovery, getting/setting the dmx address etc. directly to the esp_dmx.h? Imo there is no need for the user to implement the basic stuff himself.

    opened by arneboe 4
  • Using esp_dmx for reading and writing at the same time

    Using esp_dmx for reading and writing at the same time

    I tried to set up a device that patches DMX data. So i tried receiving and sending at the same time (with two different RS485 converters, one for rx and one for tx). But it does not work very well in parallel. DMX read errors come up frequently. I combined the read and write examples in some way. But what is the recommended method to receive data on one DMX input and send it (with changes) to another DMX output?

    opened by Pit1966 1
  • ESP-IDF v5 Support

    ESP-IDF v5 Support

    This adds support for the newly released ESP-IDF v5. This addition primarily features the new GPTimer API for controlling the hardware, high-resolution timer. The high-resolution timer is used for RDM timing specification as well as DMX break and mark-after-break.

    opened by someweisguy 3
  • Supporting esp-idf 5.x+

    Supporting esp-idf 5.x+

    The current version does not build on esp-idf v5.0 (and 5.1). Release v5.0 is out of beta and is currently the most recent supported version for all chips.

    I've made some small changes to release/2.0 to get it successfully building over at https://github.com/stonegray/esp_dmx/commit/e340115e76c1c9c575490157ba69f72156755b44 and assume many of these changes can be ported forward to the master version. This isn't PR-ready as I don't think it will build on IDF v4.4, which is currently the default.

    I'm not sure I've implemented sclk_freq correctly, and if this can properly use the reference clock instead of the default. Some abstraction to ensure its not possible to read or write the baud etc. with the wrong frequency might be a good idea.

    Espressif has a migration guide for moving from v4.4 to v5 (possibly incomplete, I didn't see the changes to uart_hal_set_baudrate and friends there)

    enhancement 
    opened by stonegray 8
Releases(v3.0.0-beta)
  • v3.0.0-beta(Nov 27, 2022)

    This is a pre-release of version 3.0!

    This version brings several new changes to esp_dmx including:

    • Remote Device Management support
    • RDM Controller API
    • FreeRTOS Task Notification support for much quicker context switching
    • Improved DMX driver which allows for custom mark-before-break time
    • Much more simplified DMX API
    • Smaller driver memory footprint
    • Updated documentation

    Note that this is a PRE-release so some features may not work as intended. The DMX features in this library should remain relatively stable but RDM features are subject to change with future releases. Please assist in the development of this library by submitting bug reports to the issues page.

    Source code(tar.gz)
    Source code(zip)
  • v2.02(Aug 19, 2022)

  • v2.0.1(Jun 8, 2022)

  • v2.0(Jun 7, 2022)

    Version 2.0 is here!

    This update adds support for ESP32-S2, S3, and C3. It also adds updates to make the API easier for Arduino users to understand as well as setting the stage for RDM support, which will hopefully come in v3.0! Please read the updated README for more information on how this library works.

    Source code(tar.gz)
    Source code(zip)
  • v1.1.4(Mar 20, 2022)

    NOTE: This is a re-release of v1.1.4 because some library metadata was not updated in the original release.

    This release fixes an bug that results in a crash when using WiFi alongside this library. Thanks to @chaosloth for finding and fixing the issue!

    What's Changed

    • Added IRAM_ATTR to hal.h functions to avoid crash when WIFI not conne… by @chaosloth in https://github.com/someweisguy/esp_dmx/pull/14

    New Contributors

    • @chaosloth made their first contribution in https://github.com/someweisguy/esp_dmx/pull/14

    Full Changelog: https://github.com/someweisguy/esp_dmx/compare/v1.1.3...v1.1.4

    Source code(tar.gz)
    Source code(zip)
  • v1.1.3(Dec 10, 2021)

    This patch fixes a few issues:

    • Arduino no longer displays null characters on the serial monitor when using this library
    • Fixed a problem where dmx_write_slot() would not write the proper value
    Source code(tar.gz)
    Source code(zip)
  • v1.1.2(Oct 15, 2021)

    Changes:

    • Update ESP-IDF examples with proper comment headers
    • Update Arduino examples with proper #include <Arduino.h> for convenience for PIO users
    • Additions to the README to clarify important features of the library
    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Sep 20, 2021)

  • v1.1.0(Sep 12, 2021)

    This release supports Arduino! Please note that in order to use this library on Arduino, you must use Arduino-ESP32 v2.0.0 or newer. Instructions for how to install the Arduino-ESP32 framework can be found in the readme.

    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Jul 17, 2021)

  • v1.0.1(Jan 30, 2021)

    Added some bugfixes. This update does not break any existing code. See the changes below:

    • Fixed spelling and formatting errors in README
    • Force DMX interrupt allocation in dmx_driver_install() to be in IRAM
    Source code(tar.gz)
    Source code(zip)
Owner
null
ESP32-Skid-Steer - Bruder Catepillar Skid Steer model converted to RC, controlled by an ESP32 with 2 analog joysticks and a receiver that is an ESP32 on the model.

ESP32-Skid-Steer Bruder Catepillar Skid Steer model converted to RC, controlled by an ESP32 with 2 analog joysticks and a receiver that is an ESP32 on

null 6 Oct 27, 2022
Additional components for ESP-IDF, maintained by Espressif

Espressif IDF Extra Components This repository aims to store ESP-IDF extra components which have been seperated and uploaded into IDF Component Manage

Espressif Systems 37 Jan 4, 2023
The ESP-BOX is a new generation AIoT development platform released by Espressif Systems.

中文版本 ESP-BOX AIoT Development Framework Important Note: We recommend updating the ESP32-S3-BOX firmware when you first receive the product to have the

Espressif Systems 160 Dec 29, 2022
an implementation of the ansi c standard library that makes sense when ur stoned, tired, or otherwise inebriated

eli5 c stdlib an implementation of the ansi* c standard library that makes sense when ur stoned, tired, or otherwise inebriated * apparently this (htt

Ellen Körbes 7 Oct 13, 2021
null 313 Dec 31, 2022
Allows for multiple SwitchBot buttons and curtains to be controlled via MQTT sent to ESP32. ESP32 will send BLE commands to switchbots and return MQTT responses to the broker. Also supports Meter/Temp Sensor

SwitchBot-MQTT-BLE-ESP32 Switchbot local control using ESP32. no switchbot hub used/required. works with any smarthub that supports MQTT https://githu

null 343 Dec 27, 2022
AnalogWrite for ESP32 and ESP32-S2 with LEDC PWM. Includes PWM Phase Control, DAC and Smart GPIO resource management.

analogWrite() ESP32 Installation Instructions This library was tested using using the ESP32 Arduino IDE Boards Manager installation method. Stable rel

null 36 Jan 5, 2023
ESP32 + GitHub Actions + Husarnet. A boilerplate project for ESP32 allowing in-field firmware update using GitHub Actions workflow.

esp32-internet-ota ESP32 + GitHub Actions + Husarnet. A boilerplate project for ESP32 allowing in-field firmware update using GitHub Actions workflow.

Husarnet 31 Sep 22, 2022
Semantic version library written in ANSI C

semver.c Semantic version v2.0 parser and render written in ANSI C with zero dependencies. Features Standard compliant (otherwise, open an issue) Vers

Tom 170 Nov 28, 2022
ASMotor is a portable and generic assembler engine and development system written in ANSI C99

ASMotor is a portable and generic assembler engine and development system written in ANSI C99 and licensed under the GNU Public License v3. The package consists of the assembler, the librarian and the linker. It can be used as either a cross or native development system.

null 42 Nov 18, 2022
My ANSI C solutions for Advent of Code.

ansi-adventure My optimized ANSI C solutions for Advent of Code. I tried favoring speed and performance the most here than most advent of code repos.

2 Dec 12, 2021
SDK for building cross-platform desktop apps in ANSI-C

NAppGUI Cross-Platform C SDK. Build portable desktop applications for Windows, macOS and Linux, using just C. Quick start in Windows Prerequisites Vis

Francisco García Collado 242 Jan 2, 2023
In DFS-BFS Implementation In One Program Using Switch Case I am Using an Simple And Efficient Code of DFS-BFS Implementation.

DFS-BFS Implementation-In-One-Program-Using-Switch-Case-in-C Keywords : Depth First Search(DFS), Breadth First Search(BFS) In Depth First Search(DFS),

Rudra_deep 1 Nov 17, 2021
And ESP32 powered VU matrix using the INMP441 I2S microphone

ESP32-INMP441-Matrix-VU This is the repository for a 3D-printed, (optionally) battery-powered, WS2812B LED matrix that produces pretty patterns using

null 56 Jan 2, 2023
ESP32 based DIY word clock project

Wordclock ESP32 based DIY wordclock project TL;DR: check out this ✨ demo video ✨ Another take on the classic DIY word clock. This one requires a laser

null 41 Dec 26, 2022
ESP32 software USB host through general IO pins. We can connect up to 4 USB-LS HID (keyboard mouse joystick) devices simultaneously.

esp32_usb_soft_host esp32 USB-LS pure software host thru general IO pins. Up to 4 HID devices simultaneously. board ~$3 :https://www.aliexpress.com/pr

Samsonov Dima 313 Jan 1, 2023
Trial port of the rtf_433 Library for use with OpenMQTTGateway on a ESP32 and a CC1101 Transceiver

This is an attempt at creating an Arduino library for use on ESP32 boards with a CC1101 transceiver with the device decoders from the rtl_433 package.

Northern Man 92 Jan 3, 2023
ESP32(8266?) WebSerialServer

ESP_WebSerial 使用ESP32开发板制作的串口调试工具,无需客户端,支持移动端操作. 使用此工具+手机即可完成一些简单的串口调试工作,比如说交换机设备. ProtoType 0 ProtoType 1 ProtoType 2 WebGui V1.1 WebGui V1.2 更新日志 20

null 10 Jan 24, 2022
A Walkie-Talkie based around the ESP32 using UDP broadcast or ESP-NOW

Overview We've made a Walkie-Talkie using the ESP32. Explanatory video Audio data is transmitted over either UDP broadcast or ESP-NOW. So the Walkie-T

atomic14 259 Dec 31, 2022