create account

Persistence for adafruit neopixels on a raspi by cshields

View this thread on: hive.blogpeakd.comecency.com
· @cshields ·
$4.38
Persistence for adafruit neopixels on a raspi
[Adafruit neopixels](https://www.adafruit.com/category/168) provide an easy to use addressable RGB LED platform for the maker. I make use of their [8x pixel stick](https://www.adafruit.com/product/1426) in one of my projects to provide a visible status of various checks on a rasbperry pi. However, there's a catch..

![20200612 08.03.35.jpg](https://files.peakd.com/file/peakd-hive/cshields/5X7B2QLx-2020-06-122008.03.35.jpg)

The neopixels themselves and the [Python libraries that interface with them](https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel) have no persistence, nor can they be read. When you invoke the NeoPixel library's show() function, it will display the given state for all pixels and it is up to the programmer to know that state and set it accordingly. So, in this image, the third pixel is "off" right now and if I want to change only that pixel, I need to also set green for pixels 1 and 2, and blue for pixel 8, before running show() or else those 3 will disappear when the third pixel lights up. We need a way to store and recall the current state of all neopixels when changing one.

As with all aspects of programming there are a dozen ways to do any task, and I'm sure there are *better* ways. The method I chose for this case was to use Redis to store state.

![redislogo.png](https://files.peakd.com/file/peakd-hive/cshields/G85y4byO-redislogo.png)

[Redis](https://redis.io/) is described as an "in-memory data structure store, used as a database, cache and message broker". In our case we will use it as a very basic cache to store the state of the pixels. Since I am using this to show various states of the running system in the raspberry pi, there is no need for persistence beyond reboots, so the "in-memory" aspect is no problem.

To make this happen, redis must be installed and running 

```
sudo apt install redis-server; sudo systemctl enable redis-server; sudo systemctl start redis-server
```

In addition the redis python library must be installed and imported into your script. As part of the setup I also grab the current state of neopixels from redis if they exist, and setup some colors to match what the python library expects for convenience (some of these are tweaked to keep the brightness to my liking)

```
import redis, board, neopixel

PIXEL_COUNT = 8

pixels = neopixel.NeoPixel(board.D18, PIXEL_COUNT, auto_write=False)

r = redis.Redis(db=2, decode_responses=True)
oldlights = r.hgetall('neopixels')
newlights = r.hgetall('neopixels')

colors = {
    'RED': 0x030000,
    'GREEN': 0x000300,
    'BLUE': 0x000003,
    'YELLOW': 0x030300,
    'CYAN': 0x000303,
    'MAGENTA': 0x030003,
    'OFF': 0x000000,
}
```

The rest is pretty simple, a couple of convenience functions to set a specific pixel, set all pixels, and then the magic in the saving of them (if and only if the new settings differ from what is current, to avoid unnecessary blinks with pixel refreshing)

```
def set_light(lightid, color='OFF'):
    newlights[str(lightid)] = color

def fill(color='OFF'):
    for i in range(PIXEL_COUNT):
        set_light(i, color)

def save():
    global oldlights, newlights
    if oldlights != newlights:
        for lightid, color in newlights.items():
            pixels[int(lightid)] = colors[color]
        r.hmset('neopixels', newlights)
        pixels.show()
        oldlights = r.hgetall('neopixels')
```

With this in play as a lights library, setting one pixel while maintaining the rest would be done like so:

```
lights.set_light(2, "RED")
lights.save()
```

On boot, I have a simple function to fill all neopixels green, sleep for a second, and clear them out. This also ensures that the neopixels, powered externally, are not showing a status that itself persists beyond a reboot.

*Inspired by @themarkymark's recent post on the [circular neopixel board](https://peakd.com/technology/@themarkymark/have-fun-tinkering-with-arduino-using-the-circuit-playground) from adafruit.*
👍  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
properties (23)
authorcshields
permlinkpersistence-for-adafruit-neopixels-on-a-raspi
categoryhive-101583
json_metadata"{"app":"peakd/2020.05.5","format":"markdown","description":"How to keep persistent state of adafruit neopixels on a raspberry pi","tags":["electronics","technology","raspberrypi","python"],"users":["themarkymark"],"links":["https://www.adafruit.com/category/168","https://www.adafruit.com/product/1426","https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel","https://redis.io/","/@themarkymark","/technology/@themarkymark/have-fun-tinkering-with-arduino-using-the-circuit-playground"],"image":["https://files.peakd.com/file/peakd-hive/cshields/5X7B2QLx-2020-06-122008.03.35.jpg","https://files.peakd.com/file/peakd-hive/cshields/G85y4byO-redislogo.png"]}"
created2020-06-13 12:48:54
last_update2020-06-13 12:48:54
depth0
children0
last_payout2020-06-20 12:48:54
cashout_time1969-12-31 23:59:59
total_payout_value2.138 HBD
curator_payout_value2.245 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length3,964
author_reputation1,298,947,867,433
root_title"Persistence for adafruit neopixels on a raspi"
beneficiaries
0.
accountpeakd
weight500
max_accepted_payout1,000,000.000 HBD
percent_hbd0
post_id97,940,204
net_rshares11,027,169,716,653
author_curate_reward""
vote details (46)