From 5cf2022bbc8e28c7f477c464f50df322e60ad38b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Tue, 2 Jan 2018 17:59:43 +0100 Subject: [PATCH] add a neopixel driver --- gex/PayloadBuilder.py | 4 ++++ gex/PayloadParser.py | 5 +++++ gex/__init__.py | 2 +- gex/units/Neopixel.py | 33 +++++++++++++++++++++++++++++++++ gex/units/Pin.py | 17 ----------------- main.py | 19 +++++++++++-------- 6 files changed, 54 insertions(+), 26 deletions(-) create mode 100644 gex/units/Neopixel.py delete mode 100644 gex/units/Pin.py diff --git a/gex/PayloadBuilder.py b/gex/PayloadBuilder.py index 70b8e6d..d9209aa 100644 --- a/gex/PayloadBuilder.py +++ b/gex/PayloadBuilder.py @@ -21,6 +21,10 @@ class PayloadBuilder: """ Add a uint16_t """ self.buf.extend((num&0xFFFF).to_bytes(length=2, byteorder=self.endian, signed=False)) + def u24(self, num:int): + """ Add a uint24_t (for use with RGB colors) """ + self.buf.extend((num&0xFFFFFF).to_bytes(length=3, byteorder=self.endian, signed=False)) + def u32(self, num:int): """ Add a uint32_t """ self.buf.extend((num&0xFFFFFFFF).to_bytes(length=4, byteorder=self.endian, signed=False)) diff --git a/gex/PayloadParser.py b/gex/PayloadParser.py index b2ab727..93e099b 100644 --- a/gex/PayloadParser.py +++ b/gex/PayloadParser.py @@ -45,6 +45,11 @@ class PayloadParser: slice = self._slice(2) return int.from_bytes(slice, byteorder=self.endian, signed=False) + def u24(self) -> int: + """ Read a uint24_t """ + slice = self._slice(3) + return int.from_bytes(slice, byteorder=self.endian, signed=False) + def u32(self) -> int: """ Read a uint32_t """ slice = self._slice(4) diff --git a/gex/__init__.py b/gex/__init__.py index e1db57a..526049d 100644 --- a/gex/__init__.py +++ b/gex/__init__.py @@ -7,9 +7,9 @@ from gex.Unit import Unit from gex.Client import Client # import all the units -from gex.units.Pin import Pin from gex.units.DOut import DOut from gex.units.DIn import DIn +from gex.units.Neopixel import Neopixel # General, low level diff --git a/gex/units/Neopixel.py b/gex/units/Neopixel.py new file mode 100644 index 0000000..890fdad --- /dev/null +++ b/gex/units/Neopixel.py @@ -0,0 +1,33 @@ +import gex + +class Neopixel(gex.Unit): + """ + Raw access to a neopixel strip. + """ + + def _type(self): + return 'NEOPIXEL' + + def get_len(self): + """ Get the neopixel strip length """ + resp = self.query(0x04) + pp = gex.PayloadParser(resp) + return pp.u16() + + def load(self, colors, reverse=True): + """ + Load colors to the strip. + + The numbers are normally 0xRRGGBB + If 'reverse' is false, they're treated as little-endian: 0xBBGGRR. + """ + pb = gex.PayloadBuilder(endian='big' if reverse else 'little') + for c in colors: + pb.u24(c) + self.send(0x01, pb.close()) + + def clear(self): + """ + Reset the strip (set all to black) + """ + self.send(0x00) diff --git a/gex/units/Pin.py b/gex/units/Pin.py deleted file mode 100644 index 690567b..0000000 --- a/gex/units/Pin.py +++ /dev/null @@ -1,17 +0,0 @@ -import gex - -class Pin(gex.Unit): - def _type(self): - return 'PIN' - - def on_event(self, event:int, payload): - pass - - def off(self): - self.send(0x00) - - def on(self): - self.send(0x01) - - def toggle(self): - self.send(0x02) diff --git a/main.py b/main.py index 1c8fcd5..d95339a 100644 --- a/main.py +++ b/main.py @@ -14,13 +14,6 @@ if False: client.bulk_write(gex.MSG_INI_WRITE, buf) -if False: - led = gex.Pin(client, 'LED') - - for i in range(0,10): - led.toggle() - time.sleep(.1) - if False: leds = gex.DOut(client, 'strip') @@ -48,7 +41,7 @@ if False: leds.toggle(0xFF) time.sleep(.1) -if True: +if False: btn = gex.DIn(client, 'btn') strip = gex.DOut(client, 'strip') @@ -56,3 +49,13 @@ if True: b = btn.read() strip.write((b << 2) | ((~b) & 1)) time.sleep(.02) + +if True: + neo = gex.Neopixel(client, 'npx') + + print('We have %d neopixels.\n' % neo.get_len()) + for i in range(0,512): + j = i if i < 256 else 255-(i-256) + neo.load([0x660000+j, 0x3300FF-j, 0xFFFF00-(j<<8), 0x0000FF+(j<<8)-j]) + time.sleep(.005) +