1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

電子工作メモ - NeoPixel RGB

Last updated at Posted at 2024-03-21

NeoPixel

  • 端子
pin 内容
S 信号線
V 電源
G グランド
  • 動作

    • GP16を信号線として使う

    • 8000000(8MHZ)= 125 nsec

    • 0 の場合

      • H: 220ns~380ns
      • L: 580ns~1µs
    • 1 の場合

      • H: 580ns~1µs
      • L: 580ns~1µs
    • RESET の場合

      • L: 280ns以上
    • 上位ビットからGRBの8x3=24ビット

  • 06.1_Neopixel/06.1_Neopixel.py

06.1_Neopixel.py
import time
from machine import Pin
from neopixel import myNeopixel

red    = (255, 0, 0)
green  = (0, 255, 0)
blue   = (0, 0, 255)
white  = (255, 255, 255)
close  = (0, 0, 0)
COLORS = [red, green, blue, white, close]

NUM_LEDS = 8
np = myNeopixel(NUM_LEDS, 16)
np.brightness(10) #brightness: 0 ~ 255

while True:
    for color in COLORS:
        np.fill(color[0], color[1], color[2])
        np.show()
        time.sleep(0.5)
neopixel.py
import array, time
from machine import Pin
import rp2

#PIO を使って表示する
@rp2.asm_pio(
    sideset_init=rp2.PIO.OUT_LOW,      # サイドセットの初期値はLOW
    out_shiftdir=rp2.PIO.SHIFT_LEFT,   # MSBから書き出す
    autopull=True,                     # 24bitを超えたら自動的にpullする
    pull_thresh=24
)
def ws2812():
    T1 = 2  # 250 nsec
    T2 = 5  # 625 nsec
    T3 = 8  # 1   μsec
    wrap_target()
    label("bitloop")
    out(x, 1)              .side(0)    [T3 - 1] # reset = 1μsec Lowにする
    jmp(not_x, "do_zero")  .side(1)    [T1 - 1] # 250nsec Highにする
    jmp("bitloop")         .side(1)    [T2 - 1] # 値1の場合、+625nsec(計875nsec) Highにする
    label("do_zero")
    nop()                  .side(0)    [T2 - 1] # 値0の場合、625nsec Lowにする
    wrap


class myNeopixel:
    def __init__(self, num_leds, pin, delay_ms=1):
        self.pixels = array.array("I", [0 for _ in range(num_leds)])
        self.state_machine = 0
        self.sm = rp2.StateMachine(
            self.state_machine,
            ws2812,
            freq=8000000,
            sideset_base=Pin(pin)
        )
        self.sm.active(1)
        self.num_leds = num_leds
        self.delay_ms = delay_ms
        self.brightnessvalue = 255

    def brightness(self, brightness = None):
        if brightness == None:
            return self.brightnessvalue
        else:
            if (brightness < 1):
                brightness = 1
        if (brightness > 255):
            brightness = 255
        self.brightnessvalue = brightness

    def set_pixel_line_gradient(self, pixel1, pixel2, left_r, left_g, left_b, right_r, right_g, right_b):
        if pixel2 - pixel1 == 0: return
    
        right_pixel = max(pixel1, pixel2)
        left_pixel = min(pixel1, pixel2)
        
        for i in range(right_pixel - left_pixel + 1):
            fraction = i / (right_pixel - left_pixel)
            red = round((right_r - left_r) * fraction + left_r)
            green = round((right_g - left_g) * fraction + left_g)
            blue = round((right_b - left_b) * fraction + left_b)
            
            self.set_pixel(left_pixel + i, red, green, blue)
    
    def set_pixel_line(self, pixel1, pixel2, r, g, b):
        for i in range(pixel1, pixel2+1):
            self.set_pixel(i, r, g, b)

    def set_pixel(self, pixel_num, r, g, b):
        blue = round(b * (self.brightness() / 255))
        red = round(r * (self.brightness() / 255))
        green = round(g * (self.brightness() / 255))

        self.pixels[pixel_num] = blue | red << 8 | green << 16
    
    def rotate_left(self, num_of_pixels):
        if num_of_pixels == None:
            num_of_pixels = 1
        self.pixels = self.pixels[num_of_pixels:] + self.pixels[:num_of_pixels]

    def rotate_right(self, num_of_pixels):
        if num_of_pixels == None:
            num_of_pixels = 1
        num_of_pixels = -1 * num_of_pixels
        self.pixels = self.pixels[num_of_pixels:] + self.pixels[:num_of_pixels]

    def show(self):
        for i in range(self.num_leds):
            self.sm.put(self.pixels[i],8)  # ワードは32ビットで24ビットしか使わないので8ビットシフトして渡す
        time.sleep_ms(self.delay_ms)
            
    def fill(self, r, g, b):
        for i in range(self.num_leds):
            self.set_pixel(i, r, g, b)
        time.sleep_ms(self.delay_ms)
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?