6

This is code that I used from | https://makersportal.com/blog/ws2812-ring-light-with-raspberry-pi-pico | and to begin, this worked great, however after stopping and running the code multiple times with thonny without issue, I then got the error:

"OSError: [Errno 12] ENOMEM"

I used the nuke.uf2 file to clear all the storage on my pi pico W however the error soon re-occurred after having run the file too many times. I am extremely confused and would love some help.

Thank you!

I tried using nuke.uf2 which was a temporary fix

###############################################################
# WS2812 RGB LED Ring Light Breathing
# with the Raspberry Pi Pico Microcontroller
#
# by Joshua Hrisko, Maker Portal LLC (c) 2021
#
# Based on the Example neopixel_ring at:
# https://github.com/raspberrypi/pico-micropython-examples
###############################################################
#
import array, time
from machine import Pin
import rp2

#
############################################
# RP2040 PIO and Pin Configurations
############################################
#
# WS2812 LED Ring Configuration
led_count = 12 # number of LEDs in ring light
PIN_NUM = 1 # pin connected to ring light
brightness = 0.2 # 0.1 = darker, 1.0 = brightest

@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT,
             autopull=True, pull_thresh=24) # PIO configuration

# define WS2812 parameters
def ws2812():
    T1 = 2
    T2 = 5
    T3 = 3
    wrap_target()
    label("bitloop")
    out(x, 1)               .side(0)    [T3 - 1]
    jmp(not_x, "do_zero")   .side(1)    [T1 - 1]
    jmp("bitloop")          .side(1)    [T2 - 1]
    label("do_zero")
    nop()                   .side(0)    [T2 - 1]
    wrap()


# Create the StateMachine with the ws2812 program, outputting on pre-defined pin
# at the 8MHz frequency
sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(PIN_NUM))

# Activate the state machine
sm.active(1)

# Range of LEDs stored in an array
ar = array.array("I", [0 for _ in range(led_count)])
#
############################################
# Functions for RGB Coloring
############################################
#
def pixels_show(brightness_input=brightness):
    dimmer_ar = array.array("I", [0 for _ in range(led_count)])
    for ii,cc in enumerate(ar):
        r = int(((cc >> 8) & 0xFF) * brightness_input) # 8-bit red dimmed to brightness
        g = int(((cc >> 16) & 0xFF) * brightness_input) # 8-bit green dimmed to brightness
        b = int((cc & 0xFF) * brightness_input) # 8-bit blue dimmed to brightness
        dimmer_ar[ii] = (g<<16) + (r<<8) + b # 24-bit color dimmed to brightness
    sm.put(dimmer_ar, 8) # update the state machine with new colors
    time.sleep_ms(10)

def pixels_set(i, color):
    ar[i] = (color[1]<<16) + (color[0]<<8) + color[2] # set 24-bit color
        
def breathing_led(color):
    step = 5
    breath_amps = [ii for ii in range(0,255,step)]
    breath_amps.extend([ii for ii in range(255,-1,-step)])
    for ii in breath_amps:
        for jj in range(len(ar)):
            pixels_set(jj, color) # show all colors
        pixels_show(ii/255)
        time.sleep(0.02)
#
############################################
# Main Calls and Loops
############################################
#
# color specifications
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
yellow = (255,255,0)
cyan = (0,255,255)
white = (255,255,255)
blank = (0,0,0)
colors = [blue,yellow,cyan,red,green,white]

while True: # loop indefinitely
for color in colors: # emulate breathing LED (similar to Amazon's Alexa)
breathing_led(color)
time.sleep(0.1) # wait between colors
Jason Aller
  • 3,541
  • 28
  • 38
  • 38
JohanW28
  • 63
  • 1
  • 4

2 Answers2

5

I just tripped over this myself.

The quick fix is to type machine.reset() into the Thonny console (you might need to type import machine first).

The issue is the line that initialises the state machine. The number of times that you can run it without hitting the error depends on the length of the PIO code (the ws2812() function), so I assume that for some reason it is not resetting the PIO memory which can only hold 32 instructions.

Your code has 4 PIO instructions, and in my tests it fails on the 9th run, so that adds up.

This seems to be specific to the Pico W, as exactly the same code on the same MicroPython nightly build works fine on a non-W Pico.

EDIT: Here's the problem - MicroPython doesn't reset PIO memory on the Pico W because it interferes with the Wireless driver.

EDIT: Another solution is to put rp2.PIO(0).remove_program() before the rp2.StateMachine line, to clear the PIO memory.

pdw
  • 884
  • 4
  • 5
0

Use the gc module:

import gc
gc.collect()
ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257