aboutsummaryrefslogtreecommitdiffstats
path: root/klippy
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2020-10-21 12:23:18 -0400
committerKevin O'Connor <kevin@koconnor.net>2020-10-29 12:00:28 -0400
commit61337372158fd3a1876efa64a39d2c53c8a4a2cd (patch)
tree6c87caa8aab1932ce260967535f8a034dcbda42e /klippy
parent7263077db5a04f94bfe51c44984e37c0f05dfc8c (diff)
downloadkutter-61337372158fd3a1876efa64a39d2c53c8a4a2cd.tar.gz
kutter-61337372158fd3a1876efa64a39d2c53c8a4a2cd.tar.xz
kutter-61337372158fd3a1876efa64a39d2c53c8a4a2cd.zip
neopixel: Don't flush the lookahead queue on a SET_LED command
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'klippy')
-rw-r--r--klippy/extras/neopixel.py71
1 files changed, 39 insertions, 32 deletions
diff --git a/klippy/extras/neopixel.py b/klippy/extras/neopixel.py
index 422b849d..f21e5f6c 100644
--- a/klippy/extras/neopixel.py
+++ b/klippy/extras/neopixel.py
@@ -16,6 +16,7 @@ class PrinterNeoPixel:
def __init__(self, config):
self.printer = config.get_printer()
name = config.get_name().split()[1]
+ self.mutex = self.printer.get_reactor().mutex()
# Configure neopixel
ppins = self.printer.lookup_object('pins')
pin_params = ppins.lookup_pin(config.get('pin'))
@@ -74,34 +75,41 @@ class PrinterNeoPixel:
else:
elem_size = len(color_data)
self.color_data[(index-1)*elem_size:index*elem_size] = color_data
- def send_data(self, minclock=0):
- old_data, new_data = self.old_color_data, self.color_data
- if new_data == old_data:
- return
- # Find the position of all changed bytes in this framebuffer
- diffs = [[i, 1] for i, (n, o) in enumerate(zip(new_data, old_data))
- if n != o]
- # Batch together changes that are close to each other
- for i in range(len(diffs)-2, -1, -1):
- pos, count = diffs[i]
- nextpos, nextcount = diffs[i+1]
- if pos + 5 >= nextpos and nextcount < 16:
- diffs[i][1] = nextcount + (nextpos - pos)
- del diffs[i+1]
- # Transmit changes
- ucmd = self.neopixel_update_cmd.send
- for pos, count in diffs:
- ucmd([self.oid, pos, new_data[pos:pos+count]],
- reqclock=BACKGROUND_PRIORITY_CLOCK)
- old_data[:] = new_data
- # Instruct mcu to update the LEDs
- scmd = self.neopixel_send_cmd.send
- for i in range(8):
- params = scmd([self.oid], minclock=minclock)
- if params['success']:
- break
- else:
- logging.info("Neopixel update did not succeed")
+ def send_data(self, print_time=None):
+ with self.mutex:
+ old_data, new_data = self.old_color_data, self.color_data
+ if new_data == old_data:
+ return
+ # Find the position of all changed bytes in this framebuffer
+ diffs = [[i, 1] for i, (n, o) in enumerate(zip(new_data, old_data))
+ if n != o]
+ # Batch together changes that are close to each other
+ for i in range(len(diffs)-2, -1, -1):
+ pos, count = diffs[i]
+ nextpos, nextcount = diffs[i+1]
+ if pos + 5 >= nextpos and nextcount < 16:
+ diffs[i][1] = nextcount + (nextpos - pos)
+ del diffs[i+1]
+ # Transmit changes
+ ucmd = self.neopixel_update_cmd.send
+ for pos, count in diffs:
+ ucmd([self.oid, pos, new_data[pos:pos+count]],
+ reqclock=BACKGROUND_PRIORITY_CLOCK)
+ old_data[:] = new_data
+ # Instruct mcu to update the LEDs
+ minclock = 0
+ if print_time is not None:
+ minclock = self.mcu.print_time_to_clock(print_time)
+ scmd = self.neopixel_send_cmd.send
+ for i in range(8):
+ params = scmd([self.oid], minclock=minclock)
+ if params['success']:
+ break
+ else:
+ logging.info("Neopixel update did not succeed")
+ def send_data_bg(self, print_time):
+ reactor = self.printer.get_reactor()
+ reactor.register_callback(lambda et: self.send_data(print_time))
cmd_SET_LED_help = "Set the color of an LED"
def cmd_SET_LED(self, gcmd):
# Parse parameters
@@ -113,10 +121,9 @@ class PrinterNeoPixel:
transmit = gcmd.get_int('TRANSMIT', 1)
self.update_color_data(red, green, blue, white, index)
# Send command
- if not transmit:
- return
- print_time = self.printer.lookup_object('toolhead').get_last_move_time()
- self.send_data(self.mcu.print_time_to_clock(print_time))
+ if transmit:
+ toolhead = self.printer.lookup_object('toolhead')
+ toolhead.register_lookahead_callback(self.send_data_bg)
def load_config_prefix(config):
return PrinterNeoPixel(config)