esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
411 stars 26 forks source link

Dmx output component for light / fan #319

Open TheStaticTurtle opened 5 years ago

TheStaticTurtle commented 5 years ago

Describe the problem you have/What new integration you would like I have some max485 that I use to create dmx device for my light dmx is cool because its a bus system and require only 1 esp to control it I would really like an integration into esphome

Please describe your use case for this integration and alternatives you've tried: Add a dmx platform for controlling for example fan speed or light intesity/color may be a config could look like this :

light:
  - platform: dmx
    start_address: 0
    channel_pattern: RGBW
    name: "TestDMX_Light"
    output: output_component1

fan:
  - platform: dmx
    start_address: 0
    channel_pattern: D
    name: "TestDMX_Fan"
    output: output_component1

(D for dimmer) And I didn't try to use anything else for dimming the fan since I don't really like messing with high voltage

Additional context

OttoWinter commented 5 years ago

Related: https://github.com/esphome/esphome-core/issues/25

poldim commented 4 years ago

@OttoWinter Just trying to understand if I should attempt to build this or if it would be a waste of my time:

Does anything hardware or architecture wise that would prevent me from getting this to work?

OttoWinter commented 4 years ago

Does anything hardware or architecture wise that would prevent me from getting this to work?

No, it should work.

The library you pointed to however does not seem to support ESP devices, you probably need to use another one.

cupertinomiranda commented 4 years ago

Last couple of evenings I have been working on implementing support to DMX512 protocol.

Here is the code for further discussion and perhaps future merge request. Implementation was inspired by modbus code. Since DMX512 differs from standard UART, this implementation requires some hardware hack which uses a port to ground the data signal for protocol start sequence.

Example YML:

uart:
  tx_pin: D0
  rx_pin: D1
  stop_bits: 2
  baud_rate: 250000
  id: uart1

dmx512:
  id: dmx
  start_tx_pin: D6
  uart_id: uart1
  # TODO: add a update_every X seconds just in case something resets.
  # TODO: Currently I am sending a packet only when an update happens.

output:
  - platform: dmx512
    channel: 1
    double_channel: False
    universe: dmx
    id: dmx_1

light:
  - platform: monochromatic
    name: "Test Lights"
    output: dmx_1
    id: light_test
    default_transition_length: 2s
asmaps commented 4 years ago

Any news on this? I'd be interested in this feature as well. ESP8266 + MAX485 is exactly the setup I have. I'm using https://github.com/mtongnz/ESP8266_ArtNetNode_v2 at the moment, but it's not very reliable in my experience as I get frequent reboots of the esp with flickering of the lights included. Also I'm already using esphome and an integration into it would be awesome :-)

Tuckie commented 3 years ago

Also interested in DMX output support!

andyboeh commented 2 years ago

I'm also very much interested in DMX support and I had a look at the current solutions. All have their drawbacks:

For the software side, the additional transistor is by far the simplest solution. All other methods to generate the break signal (88us low on the Tx line) that I am aware of are more workarounds and would require some nasty changes to the UART component.

@OttoWinter I'd be interested in what you consider the simplest / cleanest solution, or in other words: How to best implement this?

jakosek commented 2 years ago

@andyboeh I'm on ESP32 too, look at dmx_no_uart branch. It uses most common ESPDMX library with no UART component as dependency. It should work both ESP32/8266. But still generates some stability issues...

IMO brake signal isnt problem at all, but sending DMX frame on every loop.

andyboeh commented 2 years ago

Ah, thanks for the hint, I didn't see your other branch! I'll have a look at it next weekend.

andyboeh commented 2 years ago

For testing purposes, I created a custom component for DMX512. It uses the internal UART and generates the break signal by detaching and attaching the pin from/to the pin matrix. It is limited to the ESP32 using the Arduino framework (it should also work using IDF, but this is untested. Requires a change in the config validation if you would like to try it).

Code, README and example: https://github.com/andyboeh/esphome-dmx512

For now, I didn't want to change anything on the ESPHome code, thus the TX Pin needs to be configured twice and you need to figure out which hardware UART is used (it defaults to 1, which is usually the case if serial logging is enabled).

I only did limited testing using a Lite-Puter DMX dimmer pack, I can't say anything about the stability.

someweisguy commented 2 years ago

@andyboeh this looks really awesome. I will find some time to play around with it!

I built a DMX library for ESP32 that runs on ESP-IDF and Arduino. Some of the feedback I received included interest in porting it to ESPHome. The issue for me is that I am completely new to the ESPHome environment and I'm still wrapping my head around how to get a custom component running. My library doesn't depend on any existing UART code - I wrote a completely new UART driver for it that runs on the ESP32 hardware. So my library doesn't depend on any existing UART driver. Any chance that could be helpful here? It doesn't run on ESP8266, but maybe it would allow for DMX input/output on an ESPHome release branch?

andyboeh commented 2 years ago

@someweisguy I'm not too familiar with ESPHome either, so what I'm doing might be wrong as well. However, my assumption is that every component that uses a hardware UART needs to go through ESPHome's UART implementation. Otherwise, the UART assignment is going to be messed up in case the user configures an additional UART.

That said, the main problem with using the ESPHome UART component is that it doesn't have support for sending the break signal. That's the reason for the awkward double-configuration of the TX pin in my implementation.

Your library supports a lot more than what I wanted to achieve - my goal is to be able to dim the living room lights :)

cristianm commented 2 years ago

Also interested in DMX output support!

Tuckie commented 2 years ago

For the record, this is what I'm hoping to be able to use:

This makes for a very compact and simple setup that could be easily powered/embedded into a dmx fixture. The downside is I don't have any flexibility on the circuit. (no transistor)

klaernie commented 2 years ago

@andyboeh

I only did limited testing using a Lite-Puter DMX dimmer pack, I can't say anything about the stability.

I tried your external component against a chain of "4PCS DJ PAR Can 36 LED RGB Bühnenlicht DMX512 Disco Show Bühnenbeleuchtung DHL" (totally white label par lights) over about 25m and it works flawlessly, provided one terminates the DMX line. The component itself is really easy to use, and mapping dmx channels to light components is fairly easy. It could use a dedicated dmx light component that takes the channels directly, but it's not really needed to get a few lights to work.

jakosek commented 2 years ago

@andyboeh Great work! On my setup I use 128 GPIO from i2c mcp expanders + about 40 dmx channels. On my code ESP32 sometimes crash. After exception decode, problem is HardwareSerial.end() and begin(). With Your code so far no errors have occurred, but I modified max channel. With full 512ch frame, on my setup as above, there was API reconnections loop. Probably full frame takes too much time blocking main loop. Please consider adding setting for max channels, as DMX don't need full universe at once.

andyboeh commented 2 years ago

I have some kind of "throttling" functionality in the pipeline where it sends full frames only twice a second and not as fast as possible - I just haven't had the chance to test it (I'll push it afterwards). That would probably solve the problem as the .flush() calls are most of the time not needed. I'll try to make the "refresh rate" configurable.

Further, if I understood the protocol correctly, for new values it would be sufficient to only send the bytes up to the changed channel. That should improve the situation as well.

jakosek commented 2 years ago

only twice a second and not as fast as possible

no, no - it should be as fast as possible - You could try add some transition to light - higher fps is better.
According to dmx timing, full 512 channel frame "takes approximately 23 ms to send, corresponding to a maximum refresh rate of about 44 Hz", but from esphome docs there is info that loop() shouldn't block longer than 20ms. In theory nothing happens if take some longer, but in practice I have API reconnections.

andyboeh commented 2 years ago

no, no - it should be as fast as possible - You could try add some transition to light - higher fps is better.

Maybe I wasn't clear enough about that: Changed values, i.e. transitions, are of course sent as fast as possible! But refreshing old / already set values can be slower.

andyboeh commented 2 years ago

@jakosek I just pushed the promised update:

jsimonetti commented 2 years ago

@andyboeh Could you add an example board layout? I have been having trouble getting this to work.

klaernie commented 2 years ago

Could you add an example board layout? I have been having trouble getting this to work.

If it helps you, that's what is running well on my end: https://github.com/klaernie/esphome-configs/blob/main/dmx01.yaml

andyboeh commented 2 years ago

Could you add an example board layout?

What exactly do you mean, a schematic diagram? Or the configuration file? An example configuration file is provided in the github repository.

poldim commented 2 years ago

Could you add an example board layout?

What exactly do you mean, a schematic diagram? Or the configuration file? An example configuration file is provided in the github repository.

I’d love a schematic if you got one

andyboeh commented 2 years ago

I’d love a schematic if you got one

Please find attached the very simple schematic for the RS485 adapter that I'm using. A bit more background info: I use a WT32-ETH01 board that is plugged into a base board. On the base board is a 12-pin header where the RS485 adapter board is plugged into. The adapter board provides a RJ45 socket with the DMX signal. On the PCB, I also added a simple 3-pin screw terminal as an alternative. I went for a SP3485 because it was in stock at the fab. If I'm not mistaken, it is pin-compatible with a MAX3485.

rs485_adapter.pdf

jsimonetti commented 2 years ago

I'm pretty sure it's my electric skills that are failing me now :( I am trying to use one of these max485 boards: https://protosupplies.com/product/max485-ttl-to-rs-485-interface-module/ I hooked up the DI to the tx_pin and the DE to the enable_pin. I'm leaving the RE and RO floating. Unfortunately nothing happens. GND is connected to RJ45 pins 7 and 8, and A is pin 1, B is pin 2 (according to ESTA standard). I hope someone here knows this particular max485 TTL board and can give some pointers on how to use it. I don't have a scope unfortunately, so cannot debug further.

I do appreciate your work with this module! Me failing is obviously a problem from my end.

klaernie commented 2 years ago

@jsimonetti The things I'd try first are: check VCC on the max485 board. If it doesn't have enough voltage it can't put out enough voltage for the other side. Then, if you don't have a scope or logic analyzer you can try to swap a and b, measure continuity to the rj45 plug, and maybe even to the dmx out plug on your fixture. I'd also double check the ground and the address/settings of the fixture. Lastly you can only try a terminating resistor and make sure that the cable isn't too long. Oh, you did doublecheck your pin assignments, right, both in the dmx bus declaration and the uart?

But debugging this setup probably goes far beyond what's useful in this Github issue - so maybe drop by on the esphome discord, and we can discuss more in depth with more code and more pictures.

johanneswilkens commented 2 years ago

This is perfect! It's exactly what I need, one thing I noticed, when I used a 6 channel led par (R, G, B, UV, Dimmer, Strobe) all 6 channels need to be defined in the dmx component otherwise the fixture wont work. Other than that less than 5 minutes to set up with ESP32 and MAX3485, would be nice to be able to use it on UART1 of ES8266 as well since only TX is required. Now it's time for light components that support dimmer, strobe effect, rgba/rgb-uv/rgbaw/rgbaw-uv (or any combo of the previous channels to use any professional light fixture) or maybe even color wheel and xy position (for moving lights like moving heads and scanners)

andyboeh commented 2 years ago

@johanneswilkens I think that a port to the ESP8266 is doable, but I suspect that the frame rate will be limited. Next week, I should receive a new DMX dimmer and an RS485 adapter board, I can try to come up with some code.

jakosek commented 2 years ago

@andyboeh try some low level code from my first attempt on 8266: void DMX512::sendBreak() { SET_PERI_REG_MASK(UART_CONF0(SEROUT_UART), UART_TXD_BRK); delayMicroseconds(DMX_BREAK); CLEAR_PERI_REG_MASK(UART_CONF0(SEROUT_UART), UART_TXD_BRK); delayMicroseconds(DMX_MAB); }

andyboeh commented 2 years ago

Thanks, I'm going to do that! Since we need the UART number here as well, this approach fits my configuration example quite well. I just need to wait for the dimmer modules to be able to test it.

johanneswilkens commented 2 years ago

Would be cool, if needed I can test it with a string of multiple rgb fixtures to see how it handles more fixtures/channels.

andyboeh commented 2 years ago

I had a bit of time today and added completely untested support for the ESP8266 in the esp8266_support branch. Your yaml needs to look like this for testing it:

external_components:
  - source: github://andyboeh/esphome-dmx512@esp8266_support

It should work with the hardware UARTs 0 and 1.

nagyrobi commented 2 years ago

@andyboeh can you please suggest a yaml config to set up the ADJ VBAR PAK as an RGB light? It also has some effects, can those be added too?

andyboeh commented 2 years ago

I'm sorry, I can't help with specific devices that I don't know/have. You have to look at the manual of the device, figure out which channels correspond to which parameter and configure it accordingly. Plus, I only know about dimmers.

nagyrobi commented 2 years ago

Can you point me in the right direction please? In your repo I only see config example for the main component, but no example how to configure a dimmer relying on it.

johanneswilkens commented 2 years ago

@nagyrobi this is for a home brand par from thomann, i think this might help you.

external_components:
  - source: github://andyboeh/esphome-dmx512

uart:
  id: uart_bus
  baud_rate: 250000
  tx_pin: 5
  stop_bits: 2

dmx512:
  id: dmx
  uart_id: uart_bus
  enable_pin: 33
  tx_pin: 5
  uart_num: 1

output:
  - platform: dmx512
    channel: 1
    universe: dmx
    id: dmx_1
  - platform: dmx512
    channel: 2
    universe: dmx
    id: dmx_2
  - platform: dmx512
    channel: 3
    universe: dmx
    id: dmx_3
  - platform: dmx512
    channel: 4
    universe: dmx
    id: dmx_4
  - platform: dmx512
    channel: 5
    universe: dmx
    id: dmx_5
  - platform: dmx512
    channel: 6
    universe: dmx
    id: dmx_6

light:
  - platform: rgb
    name: "SePar RGB"
    red: dmx_1
    green: dmx_2
    blue: dmx_3
    id: RGB

  - platform: monochromatic
    name: "SePar UV"
    id: UV
    output: dmx_4

  - platform: monochromatic
    name: "SePar Dimmer"
    id: dimmer
    output: dmx_5

  - platform: monochromatic
    name: "SePar Strobe"
    output: dmx_6

I still need to find a way how to automatically control the dimmer when turning the rgb light on and use the strobe as effect, but for now this works, only problem is that the dmx address is hard coded, so maybe its possible to change that too, but I don't have that much experience in esphome and there is not much understandable documentation about how things work.

andyboeh commented 2 years ago

Can you point me in the right direction please? In your repo I only see config example for the main component, but no example how to configure a dimmer relying on it.

The complete example is in the file example_dmx.yaml, not in the README: https://github.com/andyboeh/esphome-dmx512/blob/esp8266_support/example_dmx.yaml

nagyrobi commented 2 years ago

Ah ok, didn't notice that, thank you.

nagyrobi commented 2 years ago

I'm leaving the RE and RO floating.

I connect both RE and RO to +3.3V and it works.

image

Connections like this:

MAX485-M RE & DE -> ESP32 +3.3V
MAX485-M VCC     -> ESP32 +3.3V
MAX485-M GND     -> ESP32 GND
MAX485-M DI      -> ESP32 GPIO5
MAX485-M A       -> XLR 3
MAX485-M B       -> XLR 2
MAX485-M GND     -> XLR 1

Don't forget of 120Ohm termination resistors. If your fixture has DMX IN and OUT ports, on the OUT port you should use a termination resistor between XLR pins 2 and 3. Similarly on MAX485-M, in parallel with A and B outputs.

nagyrobi commented 2 years ago

only problem is that the dmx address is hard coded, so maybe its possible to change that too

Seems like channel calculation based on address is not supported but can be worked around with manual calculation. You jut have to keep in mind when you set up your light fixtures that the next free address number on the bus can be the address of the previous light + the last channel number of that light. This way you can daisy chain them with XLR cables and use one single ESP to control them all.

So for example the ADJ VBar Pak can be used in various modes, if you set them up to 8-channel mode (to access all the effects) you can set the address of the first one 1, the next one to 9, the third one to 17, fourth one to 25, using the buttons on each fixture.

Then in the config you'd have channels for the first one from 1 to 8, the second one from 9 to 16, third one from 17 to 24, forth one from 25 to 32.

andyboeh commented 2 years ago

According to @nagyrobi my DMX component also works on the ESP8266. I pushed support for it to to the main branch and I'd be happy to hear your feedback!

nagyrobi commented 2 years ago

DMX with ESP8266:

0-02-05-a5419c34daefda4c74b549fde254c09677dfe7d6422aefa2a21e237b328e4adc_205f87b5dcefd2 0-02-05-6cfc79760fd0b70a42f56fe8abdfae59ca892aa581814f78cef36537584476f1_205f87b5dfbf54 0-02-05-657b70eef099143c1db1e2909f0ecd95189e1d2cf49d7c6eca67f9ea264fe331_205f87b5c92394 0-02-05-fae9364a57c738d3d7ac3e9a2313a0b4e390ecfb0fe29c30d12504ab52dda26a_205f87b5d871a4

daisy chained 4 fixtures, 8 DMX channels each

andyboeh commented 2 years ago

@nagyrobi fyi: The 120 Ohm resistor is already on the board (R7), at least according to the schematic (https://protosupplies.com/product/max485-ttl-to-rs-485-interface-module/). And there are pull-ups on RE and DE, so no need to connect anything unless you want to be able to disable the output.

johanneswilkens commented 2 years ago

Maybe also interesting to know for some people, there is also a 3v3 version of the max485 called max3485, so that one would be better for esp, also if you want to use the esp as slave for example then over time you won’t blow out the esp pins with 5V.

andyboeh commented 2 years ago

Yes, very true! I use the SP3485 which is the equivalent of Sipex.

nagyrobi commented 2 years ago

I use the MAX485-M at 3.3V only and it works (on another modbus device too).

nagyrobi commented 2 years ago

The 120 Ohm resistor is already on the board (R7)

Hm indeed. My previous experience a few weeks ago showed though that MODBUS communication CRC errors happen if I don't add the 120 Ohm resistor myself in parrallel with the connector.

andyboeh commented 2 years ago

I use the MAX485-M at 3.3V only and it works (on another modbus device too).

It's specified at 5V, so there is no guarantee that it works on 3.3V. Use the 3485 to be on the safe side.

Hm indeed. My previous experience a few weeks ago showed though that MODBUS communication CRC errors happen if I don't add the 120 Ohm resistor myself in parrallel with the connector.

Yeah, the exact value depends on your cables and your environment.

nagyrobi commented 2 years ago

@andyboeh this works so well. It's even possible to combine the various lights into partitions as single_light_ids and use them in sync, even on an 8266.

It's worth making this component as part of ESPHome @jesserockz