element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Raspberry Pi
  • Products
  • More
Raspberry Pi
Raspberry Pi Forum RPI Pico as a NeoPixel - Tinkering
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Raspberry Pi to participate - click to join for free!
Featured Articles
Announcing Pi
Technical Specifications
Raspberry Pi FAQs
Win a Pi
Raspberry Pi Wishlist
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • Replies 22 replies
  • Subscribers 658 subscribers
  • Views 3700 views
  • Users 0 members are here
Related

RPI Pico as a NeoPixel - Tinkering

scottiebabe
scottiebabe over 1 year ago

I'd like to try and use a RPI Pico as NeoPixel (WS2812B serially programmable LED).

A WS2812B has 4 pins:

image

VDD, VSS, DIN, DOUT

Neopixels use a 24-bit pulse width modulated encoding. Each neopixel scrapes the first 24 bits off its input serial data stream and programs its LEDs based on this 24 bit RGB value. All remaining serial data is passed on to the next Pixel.

So, I would like to try and make a PIO statemachine(s) on the pico that would operate just like a neopixel.

First I need a test data stream. My Digilient Digital Discovery can output customs bitstreams. So I'll start with that.

First I generated a WS2812B bit stream in Matlab using a 1/3rd and 2/3rds pulse width encoding ( I have tried that before and know it works).

NeoPixels = [ 1, 2, bitshift(255,16) ];

d = dec2bin(NeoPixels,24)';
d = d(:) > '0';
n = length(d);

dat = [ ones(1,n); d'; zeros(1,n) ];
dat = uint8(dat(:));

fid = fopen('wdat.dat','w');
fwrite(fid,dat);
fclose(fid);

Now in Waveforms, I enable a custom pattern generator on pin27

image

Load in my binary data file

image

Set the clock rate to be 3 times the baudrate of 800 kbits/s = 2.4 MHz (Waveforms chooses the closest available frequency of 2.381 MHz)

image

Now when I click the trigger button,

image

I get a WS2812B data stream output on pin27.

Looping it over to input0 and running the logic analyzer

image

image

Looks good. I now have a test ws2812b test bitstream and a working logic analyzer (though I wish it had a decoder for WS2812B bit streams Disappointed ).

Connecting a small neopixel strip to my DD, we see

image

The first pixel is displaying blue at an intensity of 1/255 and the third is display green at full intensity.

I soldered two probe wires onto the first neopixel to capture the DIN and DO pins

image

Getting closer...

image

Reset or End of Frame Detection

The WS2812 signaling format signals an end of frame or reset by holding the line idle for a minimum of 50 us

image

So after my PIO state machine scrapes of the leading 24 bits of an incoming bit stream it needs to go into a pass through mode until the line has sat idle for 50 us.

Right now I am waiting ~16 us to signal an end of frame condition (that could of course be changed). I added some extra zeros in my matlab code to demonstrate the end of frame signal.

After seeing the line idle for greater than 16 us, the PIO re-arms for another display frame and scrapes of the first 24 bits

image

When the line is idle for less than 16 us, the PIO remains in a passthrough mode:

image

Micropython Code

# PicoPixel 2023-11-27 rev0
# Turn a RPI Pico into a NeoPixel
# Scottiebabe // sstobbe@2n3904blog.com
# https://community.element14.com/products/raspberry-pi/f/forum/54012/rpi-pico-as-a-neopixel---tinkering

# Note Pico uses 3V3 logic levels
# level translation needed for a 5V pixel string
#
# DIN : GP0
# DO  : GP1
import time
from machine import mem32, Pin, PWM
from rp2 import PIO


# PIO state machine for WS2812B functionality
@rp2.asm_pio(in_shiftdir=PIO.SHIFT_LEFT,fifo_join=PIO.JOIN_RX,out_init=([PIO.OUT_LOW]))
def ws2812b():
    # Load OSR with 256
    set(x,1)
    mov(isr,x)
    in_(null,8)
    mov(osr,isr)
    # Start in pass through mode waiting for an idle line
    jmp('passth')
    
    wrap_target()
    # Wait for rising edge
    label('sync')
    jmp(pin,'startsampling') # breakout of loop while line high
    jmp('sync')
    
    label('startsampling')
    set(x,23) # Number of bits to scrape/sample
    jmp('sample')
    label('sampling')
    wait(1,pin,0)
    label('sample')
    set(y,25)
    label('delaysample')
    jmp(y_dec,'delaysample')
    # Sample DIN 
    in_(pins,1)
    # Wait for falling edge
    wait(0,pin,0)
    # keep sampling until x = 0
    jmp(x_dec,'sampling')
    # Push 24-bit GBR to Rx FIFO
    push(noblock)
    
    # Passthrough DIN to DO until an end of frame
    # or reset condition is seen
    label('passth')
    mov(y,osr) # load y with OSR=1024
    label('passcount')
    mov(x,pins) # Read DIN
    mov(pins,x) # Write DIN value to DO
    jmp(pin,'passth') # if DIN is high reset y count back to 1024
    jmp(y_dec,'passcount') # wait until y decrements to zero
    wrap()

# Set system clock to 125 MHz
machine.freq(125_000_000)

time.sleep(0.1)

# Statemachine Sample Rate
Fs = 62_500_000
sm = rp2.StateMachine(0, ws2812b, freq=Fs, in_base=Pin(0),jmp_pin=Pin(0),out_base=Pin(1))
sm.active(1)



# Init PWM for onboard LED
led = PWM(Pin(25))
led.duty_u16(0)

while True:
    if sm.rx_fifo() > 0:
        GRBreq = sm.get()
        G = (GRBreq >> 16) & 0xFF
        R = (GRBreq >> 8) & 0xFF
        B = (GRBreq ) & 0xFF
        print('R: {}, G: {}, B: {}'.format(R,G,B))
        led.duty_u16(B<<15)

Posted as is, no guarantees. 

Also checkout the wonderful project by workshopshed for an alternative method using a WS2811 IC:  Jumbo DIY LED -- Episode 533  

  • Sign in to reply
  • Cancel
Parents
  • DAB
    DAB over 1 year ago

    Cool project.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
Reply
  • DAB
    DAB over 1 year ago

    Cool project.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube