Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved WS2812B support, fixed library import from 2 different trees, added demo to control neopixels with on/off and brightness control from tux touch pads #32

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
4 changes: 4 additions & 0 deletions configuration/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

# allow for quick repeated push of files after you modify them.
../examples/install.sh "$@"
5 changes: 3 additions & 2 deletions configuration/led.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
settings = { # LED panel or string
"apa106": False, # IoTuz and LoliBot use APA106 RGB LEDs
# "dimension": (1,),
"dimension": (8,), # Edge lit acrylic panel
# "dimension": (8,), # Edge lit acrylic panel
"dimension": (46,),
# "dimension": (8, 8),
# "dimension": (32, 8),
# "dimension": (32, 32),
# "neopixel_pin": 4, # TinyPICO
"neopixel_pin": 13, # Usually
"neopixel_pin": 19, # swagbadge SAO 1 bpttom row
marcmerlin marked this conversation as resolved.
Show resolved Hide resolved
# "neopixel_pin": 15, # Wemos OLED
# "neopixel_pin": 23, # IoTuz
"zigzag": False # For 2D panels
Expand Down
60 changes: 60 additions & 0 deletions examples/badge_np.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import time
from lib.aiko import led

# from examples.badge_np import run; run()

# this is set by aiko/led.py and configured in configuration/led.py
#num_np = 46
#np = neopixel.NeoPixel(machine.Pin(19), 46)

def wheel(pos):
# Input a value 0 to 255 to get a color value.
# The colours are a transition r - g - b - back to r.
if pos < 0 or pos > 255:
r = g = b = 0
elif pos < 85:
r = int(pos * 3)
g = int(255 - pos * 3)
b = 0
elif pos < 170:
pos -= 85
r = int(255 - pos * 3)
g = 0
b = int(pos * 3)
else:
pos -= 170
r = 0
g = int(pos * 3)
b = int(255 - pos * 3)
return (r, g, b)


def rainbow_cycle(num_np, wait):
for j in range(255):
for i in range(num_np):
pixel_index = (i * 256 // num_np) + j
led.pixel(wheel(pixel_index & 255), i)
led.write()
time.sleep(wait)


def run():
led.initialise()

time.sleep(25)

while True:
led.fill((255, 0, 0))
led.write()
time.sleep(1)

led.fill((0, 255, 0))
led.write()
time.sleep(1)

led.fill((0, 0, 255))
led.write()
time.sleep(1)

rainbow_cycle(led.length_get(), 0.001) # rainbow cycle with 1ms delay per step

15 changes: 12 additions & 3 deletions lib/aiko/led.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
#
# Usage
# ~~~~~
# import aiko.led
# aiko.led.initialise()
# aiko.led.pixel(aiko.led.red, 0, True)
# from lib.aiko import led
# led.initialise()
# led.pixel(aiko.led.red, 0, True)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kinda fascinated… aiko.led is imported and initialised by main.py, so we could kinda eliminate those lines; what do we get from the switch from aiko.led.pixel to led.pixel?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes and no, I ran this code from repl where it was not visible. There are some weird visibility issues between what's visible from repl and from code run by main.py.
I've had a lot of issues with led.dim being a different value when set from MQTT, or from code. I'm still trying to figure out why, it's very perplexing.
If you are experienced with micropython namespace issues, let me know and I'll share more details.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely clear on it either, it strikes me. I'd swear aiko is always imported on my REPL. Perhaps that's more to do the with limits of the soft reset inflicted by Control-D, though. (I've also noticed poor or zero reliability of MQTT hook-up after ^D, which I need to nut out.)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, clear now: we've got the double import problem (see PR-level convo here) and when main.py runs it's doing so with the same globals as the REPL. So, straight after booting you can see aiko, application, common, configuration, plugins, and a bunch of others even though you didn't import them. ^D kicks it all off again.

#
# MQTT commands
# ~~~~~~~~~~~~~
Expand Down Expand Up @@ -34,6 +34,7 @@
from neopixel import NeoPixel

import configuration.led
import configuration.main

import urandom
apa106 = False
Expand Down Expand Up @@ -73,6 +74,11 @@ def apply_dim(color, dimmer=None):
def fill(color):
np.fill(apply_dim((color[0], color[1], color[2])))

# write is needed if you use fill() or lots of pixel writes
# and then you decide to push the result.
def write():
np.write()

# Bresenham's line algorithm
def line(color, x0, y0, x1, y1):
x_delta = abs(x1 - x0);
Expand Down Expand Up @@ -130,6 +136,9 @@ def pixel_get(x=0):
x = length_x * (x // length_x + 1) - (x - length_x * (x // length_x)) - 1
return np[x]

def length_get():
return length

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aiko.led.length works… sure, it's not at all encapsulated, but bytes are scarce, no?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this was also to try namespace stuff, but this one is entirely useless, I removed it in my version.

def random_pixel(write=False):
pixel(random_color(), random_position(), write)

Expand Down