From 81dec0c9ab78374d97c27ae97cad97b35b42c804 Mon Sep 17 00:00:00 2001
From: Patrick Blitz
Date: Sun, 8 Dec 2019 00:06:29 +0100
Subject: [PATCH 1/2] Added a distinction to work on a micro:bit.
---
p9813.py | 194 +++++++++++++++++++++++++++++--------------------------
1 file changed, 103 insertions(+), 91 deletions(-)
diff --git a/p9813.py b/p9813.py
index fbc294c..213b1be 100644
--- a/p9813.py
+++ b/p9813.py
@@ -24,95 +24,107 @@
SOFTWARE.
"""
-from machine import Pin
-#from time import sleep_us
-
class P9813:
- def __init__(self, pin_clk, pin_data, num_leds):
- self.pin_clk = pin_clk
- self.pin_data = pin_data
- self.num_leds = num_leds
- self.pin_clk.init(Pin.OUT)
- self.pin_data.init(Pin.OUT)
- self.reset()
-
- def __setitem__(self, index, val):
- offset = index * 3
- for i in range(3):
- self.buf[offset + i] = val[i]
-
- def __getitem__(self, index):
- offset = index * 3
- return tuple(self.buf[offset + i] for i in range(3))
-
- def fill(self, color):
- for i in range(self.num_leds):
- self[i] = color
-
- def reset(self):
- self.buf = bytearray(self.num_leds * 3)
- # Begin data frame 4 bytes
- self._frame()
- # 4 bytes for each led (checksum, blue, green, red)
- for i in range(self.num_leds):
- self._write_byte(0xC0)
- for i in range(3):
- self._write_byte(0)
- # End data frame 4 bytes
- self._frame()
-
- def write(self):
- # Begin data frame 4 bytes
- self._frame()
-
- # 4 bytes for each led (checksum, blue, green, red)
- for i in range(self.num_leds):
- self._write_color(self.buf[i * 3], self.buf[i * 3 + 1], self.buf[i * 3 + 2])
-
- # End data frame 4 bytes
- self._frame()
-
- def _frame(self):
- # Send 32x zeros
- self.pin_data(0)
- for i in range(32):
- self._clk()
-
- def _clk(self):
- self.pin_clk(0)
- #sleep_us(1) # works without it
- self.pin_clk(1)
- #sleep_us(1) # works without it
-
- def _write_byte(self, b):
- if b == 0:
- # Fast send 8x zeros
- self.pin_data(0)
- for i in range(8):
- self._clk()
- else:
- # Send each bit, MSB first
- for i in range(8):
- if ((b & 0x80) != 0):
- self.pin_data(1)
- else:
- self.pin_data(0)
- self._clk()
-
- # On to the next bit
- b <<= 1
-
- def _write_color(self, r, g, b):
- # Send a checksum byte with the format "1 1 ~B7 ~B6 ~G7 ~G6 ~R7 ~R6"
- # The checksum colour bits should bitwise NOT the data colour bits
- checksum = 0xC0 # 0b11000000
- checksum |= (b >> 6 & 3) << 4
- checksum |= (g >> 6 & 3) << 2
- checksum |= (r >> 6 & 3)
-
- self._write_byte(checksum)
-
- # Send the 3 colours
- self._write_byte(b)
- self._write_byte(g)
- self._write_byte(r)
+ def __init__(self, pin_clk, pin_data, num_leds, is_mircobit):
+ self.pin_clk = pin_clk
+ self.pin_data = pin_data
+ self.num_leds = num_leds
+ self.is_mircobit = is_mircobit
+ if (not is_mircobit):
+ from machine import Pin
+ self.pin_clk.init(Pin.OUT)
+ self.pin_data.init(Pin.OUT)
+ else:
+ from microbit import *
+ self.reset()
+
+ def __setitem__(self, index, val):
+ offset = index * 3
+ for i in range(3):
+ self.buf[offset + i] = val[i]
+
+ def __getitem__(self, index):
+ offset = index * 3
+ return tuple(self.buf[offset + i] for i in range(3))
+
+ def fill(self, color):
+ for i in range(self.num_leds):
+ self[i] = color
+
+ def reset(self):
+ self.buf = bytearray(self.num_leds * 3)
+ # Begin data frame 4 bytes
+ self._frame()
+ # 4 bytes for each led (checksum, blue, green, red)
+ for _ in range(self.num_leds):
+ self._write_byte(0xC0)
+ for _ in range(3):
+ self._write_byte(0)
+ # End data frame 4 bytes
+ self._frame()
+
+ def write(self):
+ # Begin data frame 4 bytes
+ self._frame()
+
+ # 4 bytes for each led (checksum, blue, green, red)
+ for i in range(self.num_leds):
+ self._write_color(
+ self.buf[i * 3], self.buf[i * 3 + 1], self.buf[i * 3 + 2])
+
+ # End data frame 4 bytes
+ self._frame()
+
+ def _frame(self):
+ # Send 32x zeros
+ self._write_bit(0)
+ for _ in range(32):
+ self._clk()
+
+ def _clk(self):
+ if (self.is_mircobit):
+ self.pin_clk.write_digital(0)
+ self.pin_clk.write_digital(1)
+ else:
+ self.pin_clk(0)
+ self.pin_clk(1)
+
+ def _write_byte(self, b):
+ if b == 0:
+ # Fast send 8x zeros
+ self._write_bit(0)
+ for _ in range(8):
+ self._clk()
+ else:
+ # Send each bit, MSB first
+ for _ in range(8):
+ if ((b & 0x80) != 0):
+ self._write_bit(1)
+ else:
+ self._write_bit(0)
+ self._clk()
+
+ # On to the next bit
+ b <<= 1
+
+
+ def _write_bit(self,bit):
+ if (self.is_mircobit):
+ self.pin_data.write_digital(bit)
+ else :
+ self.pin_data(bit)
+
+ def _write_color(self, r, g, b):
+ # Send a checksum byte with the format "1 1 ~B7 ~B6 ~G7 ~G6 ~R7 ~R6"
+ # The checksum colour bits should bitwise NOT the data colour bits
+ checksum = 0xC0 # 0b11000000
+ checksum |= (b >> 6 & 3) << 4
+ checksum |= (g >> 6 & 3) << 2
+ checksum |= (r >> 6 & 3)
+
+ self._write_byte(checksum)
+
+ # Send the 3 colours
+ self._write_byte(b)
+ self._write_byte(g)
+ self._write_byte(r)
From d3d2643567e4fda00e5f3a008bc2f4c7430833d4 Mon Sep 17 00:00:00 2001
From: Patrick Blitz
Date: Sun, 8 Dec 2019 00:06:47 +0100
Subject: [PATCH 2/2] extended the readme for micro:bit usage
---
README.md | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 58 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index d0584c8..f434bdb 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ pin_clk = Pin(5, Pin.OUT)
pin_data = Pin(4, Pin.OUT)
num_leds = 10
-chain = p9813.P9813(pin_clk, pin_data, num_leds)
+chain = p9813.P9813(pin_clk, pin_data, num_leds, False)
# set the first LED to red
chain[0] = (255, 0, 0)
@@ -45,13 +45,13 @@ chain.reset()
See [p9813_examples.py](p9813_examples.py) and [examples](examples/) for more.
-## Parts
+### Parts
* [WeMos D1 Mini](https://www.aliexpress.com/store/product/D1-mini-Mini-NodeMcu-4M-bytes-Lua-WIFI-Internet-of-Things-development-board-based-ESP8266/1331105_32529101036.html) $4.00 USD
* [Grove - Chainable RGB LED](https://www.seeedstudio.com/Grove-Chainable-RGB-LED-p-850.html) $3.90 USD
* [Grove Male Jumper Cable](https://www.seeedstudio.com/Grove-4-pin-Male-Jumper-to-Grove-4-pin-Conversion-Cable-%285-PCs-per-Pack%29-p-1565.html) $2.90 USD
-## Connections
+## #Connections
WeMos D1 Mini | Grove Chainable RGB LED
------------- | -----------------------
@@ -69,13 +69,67 @@ DO | DI (white)
VCC | VCC (red)
GND | GND (black)
-## Links
+### Links
* [WeMos D1 Mini](https://wiki.wemos.cc/products:d1:d1_mini)
* [micropython.org](http://micropython.org)
* [Adafruit Ampy](https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy)
* [P9813 datasheet](https://raw.githubusercontent.com/SeeedDocument/Grove-Chainable_RGB_LED/master/res/P9813_datasheet.pdf)
+## Example for BBC micro:bit
+
+### Software Setup - mu
+
+* Download and setup the [mu editor](https://codewith.mu/).
+* Copy the `p9813.py` file from this repository into your `mu` code directory (usually ```USER_DIR/mu```)
+* Create a new file with the code below
+* Flash it to the micro:bit. **This will fail, the mirco:bit will display an error message**
+* Go into the files section of mu and copy the `p9813.py` file over.
+* micro:bit will restart and it should work
+
+### Software Setup - micro:bit editor
+
+* go to the [micro:bit python editor](https://python.microbit.org/v/2.0)
+* select `Load/Save`
+* Unfold the *Project Files* at the bottom of the pop-up
+* Select *Add File* and select the `p9813.py` file from this repo
+* paste the sample code below
+* flash the mirco:bit
+
+### Example Script
+
+```python
+from microbit import *
+from p9813 import P9813
+
+pin_clk = pin14
+pin_data = pin0
+
+num_leds = 2
+chain = P9813(pin_data, pin_clk, num_leds, True)
+
+# set the first LED to red
+chain[0] = (255, 0, 0)
+
+# set the second LED to green
+chain[1] = (0, 255, 0)
+
+# write data to all LEDs
+chain.write()
+sleep(200)
+# make all LEDs red
+chain.fill((255,0,0))
+chain.write()
+sleep(2000)
+# turn off all LEDs
+chain.reset()
+```
+
+### Parts:
+* [micro:bit](https://microbit.org/)
+* [mirco:bit groove shield](https://www.seeedstudio.com/Grove-Shield-for-micro-bit-v2-0.html)
+* [Grove - Chainable RGB LED](https://www.seeedstudio.com/Grove-Chainable-RGB-LED-p-850.html)
+
## License
Licensed under the [MIT License](http://opensource.org/licenses/MIT).