Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flicker caused by receiving too many bytes at once #180

Open
second-string opened this issue Nov 16, 2024 · 0 comments
Open

Flicker caused by receiving too many bytes at once #180

second-string opened this issue Nov 16, 2024 · 0 comments

Comments

@second-string
Copy link

I am seeing an issue where dmx_read will occasionally return more than 513 bytes. This is an issue because it's basically a partial packet at the front, then the next full 513 byte packet starting somewhere in the middle, which causes me to write zeroes to the DMX output and flickers the fixture.

Below is an example log where I have DMX input at ~40Hz. I see occasional errors which isn't great, but it's not the end of the world as I just drop those packets. I am blocking to wait on incoming packets with:
size_t num_bytes_rxd = dmx_receive_num(INPUT_DMX_NUM, &rx_metadata, 513, portMAX_DELAY);

If there is an error I don't call dmx_read and just loop back around to the blocking receive function. If there is a length less than 513 I log it, but I still handle the bytes to support non-full-length packets. There is a weird case where often dmx_receive_num will unblock with no error, but the size field of the metadata will be set to zero. I also skip the call to dmx_read in this case.

What's causing the issue is that occasionally, after receiving either an error or a zero length packet, the next call to dmx_recieve_num will return more than the 513 bytes that I pass in as an arg. My call to dmx_read guards against an overflow by not reading out more than the 513 buffer size, but as I said in the beginning it's a problem because the 513 bytes I do read out is partially some previous packet, and then partially the new packet.

I can add a guard that basically drops all packets received > 513, but that's throwing away a valid incoming packet which I'd prefer not to do.

(I'm only logging the first 6 bytes of the DMX packet if they don't match my expected test incoming packet, which starts with 0x00, 0xFF, 0xFF. That's why those are the only ones logged out)

Bildschirmfoto 2024-11-16 um 13 05 35

Here is roughly the code I'm using. I've taken some parts out that aren't relevant:

bool dmx_rx(uint8_t *rx_buffer, size_t rx_buffer_size) {
    dmx_packet_t rx_metadata   = {0};
    size_t       num_bytes_rxd = dmx_receive_num(INPUT_DMX_NUM, &rx_metadata, 513, portMAX_DELAY);
    if (rx_metadata.err != DMX_OK) {
            ESP_LOGW(TAG, "RXd dmx packet with err code 0x%02X, dropping", rx_metadata.err);
            return false;
    }

    if (rx_metadata.size < 513) {
        if (rx_metadata.size == 0) {
            ESP_LOGW(TAG, "RXd partion dmx packet but size is zero, continuing and skipping readout");
            return true;
        } else {
            ESP_LOGW(TAG,
                     "RXd partial dmx packet. metadata size: %zu, num_bytes_rxd:  %zu",
                     rx_metadata.size,
                     num_bytes_rxd);
        }
    }

    dmx_read(INPUT_DMX_NUM, rx_buffer, rx_buffer_size < num_bytes_rxd ? rx_buffer_size : num_bytes_rxd);

    if (rx_buffer[0] != 0 || rx_buffer[1] != 0xFF || rx_buffer[2] != 0xFF) {
        ESP_LOGD(TAG,
                 "rxd %zu bytes: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X",
                 num_bytes_rxd,
                 rx_buffer[0],
                 rx_buffer[1],
                 rx_buffer[2],
                 rx_buffer[3],
                 rx_buffer[4],
                 rx_buffer[5]);
    }

    return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant