def send_command(add, com, comn=None): ''' Sends command on IR input is address and command ''' # RMT(channel=0, pin=4, source_freq=80000000, clock_div=24, carrier_freq=38222, carrier_duty_percent=50) remote = RMT(0, pin=Pin(4), clock_div=24, carrier_freq=38222) lst = list() add_leadpulse(lst) send_byte(add, lst) send_byte(~add, lst) send_byte(com, lst) # I identified some keys on Yamaha remote did not send exact invert of command, instead some bits were peculiar. # This deviated from NEC protocol, but work around was simple. # If peculiar code is present that's sent, otherwise inverted code is sent. if comn is None: send_byte(~com, lst) else: send_byte(comn, lst) add_endpulse(lst) remote.write_pulses(lst, start=1) remote.wait_done() del lst # Without deinit and reinitializing remote after every use, second use of remote will hang it. # This issue may have been resolved in MicroPython 1.13 or later. Not tested. # However using below command is a workaround that works :) remote.deinit()
class NeoPixel: def __init__(self, pin, pixel_count, rmt_channel=1, pixel_channels=3): self.rmt = RMT(rmt_channel, pin=pin, clock_div=4) # pixels stores the data sent out via RMT self.channels = pixel_channels single_pixel = (0, ) * pixel_channels self.pixels = [D_ZERO * (pixel_channels * CHANNEL_WIDTH)] * pixel_count # colors is only used for __getitem__ self.colors = [single_pixel] * pixel_count def write(self): # The bus should be idle low ( I think... ) # So we finish low and start high. pulses = tuple() for pixel in self.pixels: pulses += pixel pulses += (T_RST, ) # The last low should be long. self.rmt.write_pulses(pulses, start=1) self.rmt.wait_done() def __setitem__(self, pixel_index, colors): self_colors = self.colors self_pixels = self.pixels if isinstance(pixel_index, int): # pixels[0] = (r, g, b) self_colors[pixel_index] = tuple(colors) self_pixels[pixel_index] = tuple( clocks for bit in (D_ONE if ((channel >> bit) & 1) else D_ZERO for channel in colors for bit in range(CHANNEL_WIDTH - 1, -1, -1)) for clocks in bit) elif isinstance(pixel_index, slice): start = 0 if pixel_index.start is None else pixel_index.start stop = len( self.pixels) if pixel_index.stop is None else pixel_index.stop step = 1 if pixel_index.step is None else pixel_index.step # Assume that if the first colors element is an int, then its not a sequence # Otherwise always assume its a sequence of colors if isinstance(colors[0], int): # pixels[:] = (r,g,b) for index in range(start, stop, step): self_colors[index] = tuple(colors) self_pixels[index] = tuple( clocks for bit in (D_ONE if ((channel >> bit) & 1) else D_ZERO for channel in colors for bit in range(CHANNEL_WIDTH - 1, -1, -1)) for clocks in bit) else: # pixels[:] = [(r,g,b), ...] # Assume its a sequence, make it a list so we know the length if not isinstance(colors, list): colors = list(colors) color_length = len(colors) for index in range(start, stop, step): color = colors[(index - start) % color_length] self_colors[index] = tuple(color) self_pixels[index] = tuple( clocks for bit in (D_ONE if ((channel >> bit) & 1) else D_ZERO for channel in color for bit in range(CHANNEL_WIDTH - 1, -1, -1)) for clocks in bit) else: raise TypeError('Unsupported pixel_index {} ({})'.format( pixel_index, type(pixel_index))) def __getitem__(self, pixel_index): # slice instances are passed through return self.colors[pixel_index] def __len__(self): return len(self.colors)