GithubHelp home page GithubHelp logo

petabite / upixels Goto Github PK

View Code? Open in Web Editor NEW
14.0 2.0 1.0 1.21 MB

WS2812 RGB LED Strip Controller for MicroPython Enabled Micro-Controllers

Home Page: https://philipzha.ng/uPixels

License: MIT License

CSS 5.99% HTML 43.93% JavaScript 17.34% Python 32.75%
ws2812b micropython esp8266 rgbled ledstrips microcontrollers embedded-systems

upixels's Introduction

μPixels (microPixels)

logo

Addressable RGB LED Strip controller for MicroPython enabled micro-controllers

Contents

Features

  • Up and running in just three lines of code!

  • User-friendly interface hosted from the micro-controller itself!

  • Complete control over animations from delay time, color, brightness

  • Completely customizable animations and user interface which is written with just Python/HTML/CSS/JS!

  • Use with the user interface or programmatically using the Animations API

  • Call animations from the network!

  • Support for optional separate status indicator LED

    Out of the Box Animations:

    • Rainbow
    • Rainbow Chase
    • Bounce
    • Sparkle
    • Wipe
    • Chase
    • RGB Fade
    • Alternating Colors
    • Random Fill
    • Fill from Middle
    • Fill from Sides
    • Fill Strip
    • Christmas

Changelog

Release Changes Date
v2.0
  • Offical release of /execute API
  • add setStrip method
  • New rainbow chase + wipe + sparkle animations
  • Segment length on chase animation
12/31/2020
v1.2
  • New colors section
  • New Christmas lights animation
3/22/2020
v1.1
  • New status LED indicator
  • New startup animation
9/2/2019
v1.0
  • FIRST RELEASE!!
8/12/2019

Screenshots

Animations screen

Colors screen

Requirements

  • Micro-controller that supports MicroPython(like the NodeMCU ESP8266)
  • WS2812 Individually Addressable RGB LEDs
  • 3V3 to 5V Logic Level Shifter
  • A regular LED(optional)
  • 270 ohm resistor
  • 1000 μF capacitor
  • 5V Power Supply(The amperage depends on your project. Each LED draws about 60mA @ full brightness/completely white)
  • Wi-Fi network for your micro-controller to connect to(if you want to use the controller interface)
  • USB cable to transfer files to your micro-controller(depending on your situation)
  • More info on materials: Adafruit, Sparkfun

Dependencies

  • uWeb (get it from my repo here)

    MicroPython Libraries:

    • neopixel
    • uos
    • urandom
    • ujson
    • usocket

Schematic

The circuit diagram below is one possible configuration for μPixels.

schematic

Some Notes:
  • Depending on your board, you may not need the Logic Level Shifter. The NodeMCU ESP8266(which I used for testing) is a 3V3 board while the LED Strip is a 5V device so it is important that the 3V3 signal is converted to 5V so that everything works properly.
  • The power supply that you will need for your project will vary depending on the number of LEDS you want to drive(Rule of thumb: Each individual LED draws about 60mA @ full brightness/completely white). Refer to these resources to decide: Adafruit, Sparkfun
  • The capacitor between the terminals of the power supply helps to smooth the supply of power as power draw can change drastically.
  • It is important that all the grounds are connected together.
  • It is recommended to power the LED strip directly from the power source. Don't power the strip from the board. Your board might not be able to supply the necessary current and it will blow up 💥.
  • You may power the LEDs directly from the board if you only want to drive a few LEDs.

Setup

  1. Install MicroPython on your board if you have not already (ESP8266 installation)
  2. Install μWeb by following the INSTALLATION instructions on my repo.
  3. Head over to the releases tab on this repo. Download the source code for the latest version. Copy the μPixels project files to your board using the same method you used to copy the μWeb files. Make sure that you have transferred:
    • uPixels.css
    • uPixels.html
    • uPixels.js
    • uPixels.py
  4. Construct the circuit above (or a variation of it, depending on your board). You may also follow these hookup guides: Adafruit, Sparkfun
  5. Check out the Quick Start section for examples.
  6. Make sure you also have a boot.py for the initial setup of your board(ie: connecting to wifi) and main.py for the μPixels code.
  7. Power up your board.
  8. Navigate to your board's IP address on port 8000 using a web browser to access the UI(Ex: 192.168.100.48:8000)
  9. Enjoy the light show!

Quick Start

Example application using the μPixels user interface:

from uPixels import uPixels

pixels = uPixels(4, 30) # init a μPixels object using Pin 4 and controlling a LED strip with 30 LEDS
pixels.startServer() # start the server that hosts the UI on port 8000

Example application using Animations API:

from uPixels import uPixels

pixels = uPixels(4, 30) # init a μPixels object on Pin 4 that is controlling a LED strip with 30 LEDS

for i in range(3):
    pixels.chase(ms=40, color=(100, 0, 0), direction='right') # do a chase animation three times with delay of 40ms, red color, going right.

pixels.randomFill(ms=150, color=None) # random fill animation with 150ms delay and random colors

See the docs below for usage of all the μPixels animations!


REST API Reference

After running uPixels.startServer(), the following routes will be available at the address and port set when uPixels was initialized(Default: 0.0.0.0:8000).

GET /

Response

  • Returns uPixels user interface(works best on a mobile browser)
  • Add this page to your phone's homescreen using Chrome(Android) or Safari(iOS) for an app-like experience(tutorial)!

POST /execute

  • Run animations from the Animations API and other methods via a POST request to this route from any device connected on the same network as your microcontroller.
  • All animations from the Animations API can be called from here as well as the setStrip, setSegment, and clear methods.
  • BEWARE of infinite loop animations. Once you start them, they can't be stopped unless you do a hard reset!

Parameters

  • This route takes a JSON body with an action and params to be passed to the action
  • Required:
    • action - (string) name of function/animation to be run(name must be same as method names in documentation)
    • params - (object) named params to be passed to the function(if no params, pass an empty object)
      • When color is needed, pass a color object with r, g, b values, such as
        {
          ...
          "color" : {
            "r": 100,
            "g": 100,
            "b": 100,
          }
        }
      • NOTE: For the altColors animation, pass a firstColor and secondColor object

Ex: To run the rainbow animation(w/ params), send a JSON body like this:

{
	"action": "rainbow",
	"params": {
		"ms": 10,
		"iterations": 1
	}
}

Ex: To run setStrip, which takes a color, send a JSON body like this:

{
	"action": "setStrip",
	"params": {
		"color": {
			"r": 255,
			"g": 50,
			"b": 50
		}
	}
}

Ex: To run clear, which takes no params, send a JSON body like this:

{
	"action": "clear",
	"params": {}
}

Response

  • On success, the response will have a 200 status with no body.
  • On error, the response will have a 400 status and will return an error message. Check the MicroPython WebREPL for a more detailed error message!

Documentation

Objects

uPixels.uPixels(pin, num_leds, address="0.0.0.0", port=8000)

Description

Initialize a uPixels object to control a LED strip with num_leds on pin. Address and port specifies where to host the UI.

Parameters
  • pin - (int) pin where the LED strip data line is connected
  • num_leds - (int) number of LEDS on strip
  • address - (str) address to listen on. Default: "0.0.0.0"
  • port - (int) port to listen on. Default: 8000

Attributes

  • uPixels.device_name - (str) name of device
  • uPixels.pin - (machine.Pin) pin object of board that LED is connected to
  • uPixels.np - (neopixel.NeoPixel) Neopixel object
  • uPixels.address - (str) address UI is hosted on
  • uPixels.port - (int) port UI is hosted on
  • uPixels.animation_map - (dict) mapping of animation names to their corresponding functions. Used when calling the animations from the UI.
  • uPixels.statusLED - (int) pin number of status LED indicator. Default: 5

Server Methods

uPixels.setDeviceName(name)

Description

Sets name of device

Parameters
  • name - (str) device name

uPixels.startServer()

Description

Serves the UI using the uWeb server on specified address and port


uPixels.app()

Description

Renders the UI template to client


uPixels.execute()

Description

Runs when uPixels receives a POST request from the client and executes the animation from uPixels.animation_map


uPixels.setStatusLED(pin)

Description

Set the pin number for the optional status LED indicator

Parameters
  • pin - (int) pin number where your LED is connected. NOTE: set this to False to disable the status LED indicator

uPixels.toggleServerStatusLED(status=1)

Description

Toggle the status LED indicator

Parameters
  • status - (int) state of the LED to set; 0 = off, 1 = on. Default: 1.

Animations API


uPixels.startupAnimation()

Description

Default startup animation played when uPixels is first initialized. Override this method to set a custom animation.


uPixels.chase(ms=20, color=None, segment_length=5, direction='right')

Description

Chase animation going left or right

Parameters
  • ms - (int) delay time in milliseconds. Default: 20
  • color - (tuple) RGB color for animation in the format (r, g, b). Default: None(random color)
  • segment_length - (int) number of LEDs to be used. Default: 5
  • direction - (str) direction of animation; 'left' or 'right'. Default: 'right'

uPixels.fillStrip(ms=25, color=None)

Description

Fill strip animation starting from the first LED

Parameters
  • ms - (int) delay time in milliseconds. Default: 25
  • color - (tuple) RGB color for animation in the format (r, g, b). Default: None(random color)

uPixels.fillFromMiddle(ms=40, color=None)

Description

Fill strip animation starting from the middle of the strip

Parameters
  • ms - (int) delay time in milliseconds. Default: 40
  • color - (tuple) RGB color for animation in the format (r, g, b). Default: None(random color)

uPixels.fillFromSides(ms=40, color=None)

Description

Fill strip animation starting from both ends

Parameters
  • ms - (int) delay time in milliseconds. Default: 40
  • color - (tuple) RGB color for animation in the format (r, g, b). Default: None(random color)

uPixels.randomFill(ms=150, color=None)

Description

Random filling of strip one LED at a time

Parameters
  • ms - (int) delay time in milliseconds. Default: 150
  • color - (tuple) RGB color for animation in the format (r, g, b). Default: None(random color)

uPixels.altColors(ms=125, firstColor=None, secondColor=None)

Description

Alternating colors every other LED on strip

Parameters
  • ms - (int) delay time in milliseconds. Default: 125
  • firstColor - (tuple) RGB color for first color in the format (r, g, b). Default: None(random color)
  • secondColor - (tuple) RGB color for second color in the format (r, g, b). Default: None(random color)

uPixels.bounce(ms=20, color=False)

Description

Bouncing animation of one LED from left to right and back

Parameters
  • ms - (int) delay time in milliseconds. Default: 20
  • color - (tuple) RGB color for animation in the format (r, g, b). Default: False(random color)

uPixels.rgbFade(ms=20)

Description

Fade of RGB values on whole strip

Parameters
  • ms - (int) delay time in milliseconds. Default: 20

uPixels.rainbow(ms=20, iterations=2)

Description

Cycle of colors in rainbow over entire strip

Parameters
  • ms - (int) delay time in milliseconds. Default: 20
  • iterations - (int) repetitions of animation

uPixels.rainbowChase(ms=50)

Description

Rainbow chase animation

Parameters
  • ms - (int) delay time in milliseconds. Default: 50

uPixels.wipe(ms=20, color=None)

Description

Wipe animation

Parameters
  • ms - (int) delay time in milliseconds. Default: 20
  • color - (tuple) RGB color for animation in the format (r, g, b). Default: None(random color)

uPixels.sparkle(ms=10, color=None)

Description

Sparkle animation

Parameters
  • ms - (int) delay time in milliseconds. Default: 10
  • color - (tuple) RGB color for animation in the format (r, g, b). Default: None(random color)

uPixels.clear()

Description

Clears entire strip


Helper Methods

uPixels.setStrip(color)

Description

Set entire strip to a color

Parameters
  • color - (tuple) RGB color in the format (r, g, b).

uPixels.setSegment(segment_of_leds, color)

Description

Set specified segments of LEDS to a color

Parameters
  • segment_of_leds - (list) positions of each individual LED to be set(Ex: [1, 4, 10] will set LEDS @ index 1, 4, and 10 to the color).
  • color - (tuple) RGB color in the format (r, g, b).

uPixels.randInt(lower, upper)

Description

Returns a random number between lower and upper(not including upper)

Parameters
  • lower - (int) lower bound
  • upper - (int) upper bound(this value is not included in the function)
Returns
  • (int) integer between lower and upper not including upper

uPixels.randColor()

Description

Return a random RGB tuple

Returns
  • (tuple) RGB tuple in form (r, g, b). Min: 0, Max: 255

uPixels.wheel(pos)

Description

Rainbow wheel function used in the rainbow animations

Parameters
  • pos - (int) position in wheel
Returns
  • (tuple) RGB tuple representing the position of the wheel

Additional Resources

Tested on

  • NodeMCU v3 (ESP8266)
  • WS2812b Individually Addressable RGB LEDs

Special Thanks

  • MaterializeCSS
  • Google Material Design Icons
  • Spectrum.js
  • noUiSlider.js
  • MicroPython
  • jQuery
  • jgarff - rpi_ws281x

upixels's People

Contributors

petabite avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

vtt-info

upixels's Issues

Asynchronous Fork

Hello,

I was in the process of creating a PR for this repo (which I love) to support asynchronous animations using uWeb-async. However, I couldn't get uWeb-async to work for me (I'd assume its a combination between my own user error and the new updates to the uasyncio library). I rewrote uPixels around the tinyweb library to resolve this. In order to not conflict with the uWeb ecosystem of uPixels, I've created a fork located here. Most of the changes I made were minor and could easily be implemented with uWeb-uasyncio if the library is working. Thank you for creating this library; I believe it gives everyone the right balance between "I want to program my own lights" and "I don't want to write too much code".

Brightness of Neopixels

First of all i think your integreation of the neopixel library to control it via web is the best and easiest i've seen so far and i'm looking forward to v2.0 with uasyncioversion of uWeb.

I was searching for a way do dimm brightness especially in rainbow 'mode' and come across your code but realized that brightness level does not apply to every mode. Do you think you are able to bring brightness level to every mode in a future version? So far i tried to change the rainbow code by myself but since i'm not really good at coding i failed. Searching for a library other than the standard neopixel library of micropython is difficult because google is mostly pointing to adafruits circuitpython and the libraries i've found on git which brings brightness control is either for a pyboard but i'm using an ESP8266 or too complicated for me since they don't have proper documentation.

Rainbow Chase animation indexes the array out of bounds

Hello,

First of all, great project !
I noticed the Rainbow Chase array would almost instantly freeze on my 70 LED strip on an RPI Pico W.

The error in the console is :

Traceback (most recent call last):
  File "uPixels.py", line 90, in execute
  File "uPixels.py", line 249, in rainbowChase
  File "neopixel.py", line 1, in __setitem__
IndexError: bytearray index out of range

Turns out on line 249 and 253 of uPixels.py, the self.np[i + q] instruction indexes the array out of bounds because :

  • for i in range(0, self.np.n , 3) will generate 69 as the max value
  • for q in range(3) will generate 0, 1 and 2
  • therefore self.np[i + q] can reach 70, 71, both out of bounds

The best solution I found was to add -2 to lines 247 and 252, like so :

for i in range(0, self.np.n - 2, 3):

And then everything works !

Use uweb-uasyncio

  • find a way to use uweb-uasyncio
  • why: so we can cancel infinite animations while they're running

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.