Neopixel LED Library

Viewed 98

Im' trying to create my own Library for the Neopixel Led strips, because there is no Library with the functions I need and I'm wondering how the LEDs work. In the Datasheet of the LEDs I found out that I have to send 24 Bit GRB color values in form of a square wave an make a pause of 50us between ever 24 bit.

Bit https://i.stack.imgur.com/SG30f.png

Period Times Of The Waves period times of the square wave

Now I'm wondering how I can translate those 24 bit GRB colors to a square wave with the help of a raspberry Pi.

Example01

import time
import RPi.GPIO as GPIO



us = 0
GPIO.setmode(GPIO.BOARD)

GPIO.setup(18, GPIO.OUT)

def microdelay(us):
    time.sleep(us/1e6)




def zero():
    GPIO.output(18, GPIO.HIGH)
    microdelay(0.4)
    GPIO.output(18, GPIO.LOW)
    microdelay(0.85)

def one():
    GPIO.output(18, GPIO.HIGH)
    microdelay(0.8)
    GPIO.output(18, GPIO.LOW)
    microdelay(0.45)


# Color Red : 0000 0000 1111 1111 0000 0000

if __name__ == "__main__":
    zero()
    zero()
    zero()
    zero()

    zero()
    zero()
    zero()
    zero()

    one()
    one()
    one()
    one()

    one()
    one()
    one()
    one()

    zero()
    zero()
    zero()
    zero()

    zero()
    zero()
    zero()
    zero()
    print("strip is red")

i get this output on console:

pi@raspberrypi:~/Libary testing $ sudo python3 LED_testing.py

LED_testing.py:9: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings. GPIO.setup(18, GPIO.OUT)

strip is red

pi@raspberrypi:~/Libary testing $

example02

import time


import RPi.GPIO as GPIO


GPIO.setmode(GPIO.BOARD)

GPIO.setup(18, GPIO.OUT)

def usleep(us: int):
  time.sleep(us/1e6)


def one():
    GPIO.output(18, GPIO.HIGH)
    usleep(0.8)
    GPIO.output(18, GPIO.LOW)
    usleep(0.45)



def zero():
    GPIO.output(18, GPIO.HIGH)
    usleep(0.4)
    GPIO.output(18, GPIO.LOW)
    usleep(0.85)




if __name__ == '__main__':

    for i in range(0, 862):
        # Green
        one()
        one()
        one()
        one()

        one()
        one()
        one()
        one()

        # Red
        one()
        one()
        one()
        one()

        one()
        one()
        one()
        one()

        # Blue
        one()
        one()
        one()
        one()

        one()
        one()
        one()
        one()

        usleep(50)
    print("strip is white")

console output: pi@raspberrypi:~/Libary testing $ sudo python3 LED_testing.py

LED_testing.py:7: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings. GPIO.setup(18, GPIO.OUT) strip is white

pi@raspberrypi:~/Libary testing $

1 Answers

a squarewave is just a graphical representation of a digital signal. Following table is important:

enter image description here

When you then look at the sequence chart:

enter image description here

You can see the following:

  • A 0 is represented by 0.4us High followed by 0.85us low
  • A 1 is represented bu 0.8us High followed by 0.45us low
  • A rest is a low signal for 50us or more

Hint: To sleep for 0.4 ms you could do the following:

import time

# sleep for 0.4us
time.sleep(0.4/1000000)

let's say you want to send the GBR value (255, 16, 12). that would translate in: 11111111001000000001100

in python, this could be done with bit operations:

def get_bits_from_grb(g: int, r: int, b: int) -> list:
  return list(bin(g<<16|r<<8|b).replace("0b", "")) 

Documentation states: Follow the order of GRB to sent data and the high bit sent at first.

'high bit sent first' means we send from left to right.

your code would be something among the lines of:

import time

def usleep(us: int):
  time.sleep(us/1e6)

def send_bit(signal_bit: bool):
  if signal_bit:
    GPIO.output(pin_number, GPIO.HIGH)
    usleep(0.8)
    GPIO.output(pin_number, GPIO.LOW)
    usleep(0.45)
  else:
    GPIO.output(pin_number, GPIO.HIGH)
    usleep(0.4)
    GPIO.output(pin_number, GPIO.LOW)
    usleep(0.85)

def send_rest():
  GPIO.output(pin_number, GPIO.HIGH)
  usleep(0.51) # should be more than 50us
  GPIO.output(pin_number, GPIO.LOW)

def send_bits(bit_list: list):
  for b in bit_list:
    send_bit(b)

bit_list = get_bits_from_grb(176, 106, 76)
send_bits(bit_list)
Related