node-dmx / dmx

DMX controller library for node.js
MIT License
297 stars 96 forks source link

Enttec Open DMX USB not working #93

Open moritzruth opened 4 years ago

moritzruth commented 4 years ago

In short, I have the same issue as #24. I'm using a Stairville CLB4 RGB Compact LED Bar 4. It indicated that it is not receiving any DMX data.

moritzruth commented 4 years ago

I just saw this comment, tried it out and it worked. Finally, after 4 hours...

Fensterbank commented 4 years ago

Hi @moritzruth,

thanks for that issue. I do not have the Enttec Open DMX USB device anymore, because it didn't work with that library. ;)

I just made the proposed changes in another branch. https://github.com/node-dmx/dmx/tree/fix-enttec-open-dmx-usb

Could you make a new clone of that library, fetch that branch, run npm install and test and confirm, that it is working now with your device without any further changes?

Thanks!

wiedi commented 4 years ago

There seems to be conflicting information about the way rts needs to be toggled. Likely there are two classes of devices out there that need rts either high or low?

Maybe we need an option for that. :/

moritzruth commented 4 years ago

@Fensterbank I can confirm it works now :) But I found out that the first rts doesn't matter. It's just the second rts that has to be false.

atoikka commented 4 years ago

I did some experimenting with the Enttec Open device, while sitting at home due to isolation. I had previously discarded it from an ongoing project due to node-dmx not working with it out of the box.

Starting point:

  1. Freestyler controls the lights well
  2. My node example does not work

I used USBPcap and Wireshark to determine the differences between Freestyler-controlled flow and Node.JS-controller flow. The serialport .set() call on Node.JS always fiddles with the RTS, DTR, CTS&DSR lines, because serialport does not provide fine-grained control over only BRK.

Using the hint above and to determine which messages actually are accepted by the fixtures, I set the refresh rate to 5Hz and defined 5 levels in the range which visibly alters my lights (around 80 to 240). I also used Picoscope to trace the differential signal (good to do this from the exposed Open board, but not without the right equipment during COVID isolation... heh).

This is setup-dependent, but I was not able to get a DMX decoder to decode the message when using setTimeout(..., 1). Instead, I brought down the delays using setImmediate(...). By doing this, some messages were accepted by the decoder, but not all. What stood out from the Freestyler/node-dmx comparison was that FreeStyler sends MAB (Mark after break) separately: image ^freestyler image ^node-dmx with serialport I implemented the same, and the number of messages accepted was improved.

But I found out that the first rts doesn't matter. It's just the second rts that has to be false. I found that when providing {brk: true, rts: true} at first, then {brk: false, rts: false}, I am able to get the decoder to react to all messages.

Now with the Node driver implementation as follows:

setControl(device, {brk: true, rts: true});
await setImmediateN();
setControl(device, {brk: false, rts: false});
await setImmediateN();
device.write([0]);
await setImmediateN();
device.write(self.universe);
device.drain();

async function setControl(device, opt) {
    return new Promise((resolve, reject) => {
        device.set(opt, err => {
            if (err) {
                reject(err);
            } else {
                resolve();
            }
        });
    });
}

async function setImmediateN() {
    await new Promise(resolve => setImmediate(resolve));
}

With 30Hz and this setup, I am able to get decent fades even with the DMX decoder (PWM, obviously no smooth transitions internally). The same solution works on my Linux box, but in that case, I did not have Picoscope to use, and tried to get rough measurements using process.hrtime(). On Linux, if awaiting device.set completion, it did not work. Once again, likely decoder-dependent since as far as I know, the break duration maximal duration is not spec-defined.

I would say... if someone plans to have a nice lightshow and be able to depend on it today and after 10 years of serialport+Windows updates, Enttec Open+Node+serialport is not the way to go. However if you need to get it working, you probably can. If someone validates my experience with the code above, I can make a PR as well.

cfadams commented 4 years ago

@Fensterbank I've been using rts: false in production for two years now with no issues so can recommend the fix-enttec-open-dmx-usb branch.

Also it's worth looking at the C# example provided by ENTTEC: https://dol2kh495zr52.cloudfront.net/download/examples/OpenDMX.cs

In particular in the initial initialisation, it appears flow control is switched off:

            status = FT_SetFlowControl(handle, (char)FLOW_NONE, 0, 0);
            status = FT_ClrRts(handle);

Hope this helps.