Hundemeier / sacn

A simple ANSI E1.31 (aka sACN) module for python.
MIT License
47 stars 21 forks source link

Change DMX Data every Frame #20

Closed ruppscher closed 3 years ago

ruppscher commented 4 years ago

Hello Hundemeier, first of all thank you very much for this awesome tool! I would like to know if there is a smart way to change the DMX data that is sent every frame. For example, if the fps is set to 30, what would be the best way to program a one-second fade form value 255 to 0 in one DMX channel? I am playing around with timers that change the values 30 times a second and then the sACN sender picks up the changes and sends it out. I'm not sure if this is the best way to do it, there must be a better way. Thanks a lot for your help!

Hundemeier commented 4 years ago

If you want precise control over the packets when they are send out, the manual_flush feature can help. See the last paragraph in the Use/Sending chapter of the readme:

import sacn
import time

sender = sacn.sACNsender()
sender.start()
sender.activate_output(1)
sender.activate_output(2)
sender[1].multicast = True # keep in mind that multicast on windows is a bit different
sender[2].multicast = True

sender.manual_flush = True # turning off the automatic sending of packets
sender[1].dmx_data = (1, 2, 3, 4)  # some test DMX data
sender[2].dmx_data = (5, 6, 7, 8)  # by the time we are here, the above data would be already send out,
# if manual_flush would be False. This could cause some jitter
# so instead we are flushing manual
time.sleep(1) # let the sender initalize itself
sender.flush()
sender.manual_flush = False # keep maunal flush off as long as possible, because if it is on, the automatic
# sending of packets is turned off and that is not recommended
sender.stop() # stop sending out

So there are two options:

  1. Do not use the manual_flush feature (default). This means no fine grained control over the time when the packets are send out. But the Sender makes sure that the pre-defined FPS is not exceeded and the duration between each packet is approximately the same.
  2. Use manual_flush (see example above): this means total control over how much and when the packets are send (when the flush method is invoked). This may be the better way for your use-case if you have a timer that changes the DMX values for you, you set the dmx_data and then call flush(). Just keep in mind that when the fade effect is finished to turn of manual_flush again.

When using 1., there might be the problem that some values are dropped and/or send out after an additional delay of 33.3ms (30 FPS), if the call to dmx_data and the internal loop of the sender are not lined up in time.

So both methods should work, but 1 might introduce some problems like an uneven fade due to skipping a value provided via dmx_data.

ruppscher commented 4 years ago

Thank you for your quick reply! I tried both ways, the second one with manual_flush seems to be the better option as with the first one values are skipped.