Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
Sub SendByte(ByVal DataByte As Byte)
dim i as byte
For I = 0 To 7 ' Loop 8 times for 8 bits
' send bits msb to lsb
If DataByte.bits(7) = 1 Then ' Send a '1' bit
' Send 1-bit (T1H: ~0.8us HIGH, T1L: ~0.45us LOW)
' T1H: 4 instruction cycles (0.8us)
' T1L: 2-3 instruction cycles (0.4-0.6us)
WS2812BDataPin = 1
NOP ' 200ns
NOP ' 400ns
NOP ' 600ns
NOP ' 800ns (approx T1H)
WS2812BDataPin = 0
NOP ' 200ns
NOP ' 400ns (approx T1L)
Else ' Send a '0' bit
' Send 0-bit (T0H: ~0.4us HIGH, T0L: ~0.85us LOW)
' T0H: 2 instruction cycles (0.4us)
' T0L: 4-5 instruction cycles (0.8-1.0us)
WS2812BDataPin = 1
NOP ' 200ns
NOP ' 400ns (approx T0H)
WS2812BDataPin = 0
NOP ' 200ns
NOP ' 400ns
NOP ' 600ns
NOP ' 800ns (approx T0L)
NOP ' 1000ns (Optional, for slightly longer T0L if needed)
End If
DataByte = DataByte << 1
Next
End Sub
Nigel I’ve looked at clc I think I even got it to work once I was using MP Lab X online they had a tutorial. Can’t find it anymore. I’m just messing around with that AI.
I’m try clc when I find the chip that I had that got clc
If you're using Neopixels I don't think it makes any difference how many colours you use?.I been using esp but some of my led tubes only need to come on with one color so I figure I’ll try pic chips for that
'-------------------------------------------------------------------------------
' WS2812B Basic Control Example for Swordfish
' Microcontroller: PIC18F252
' Clock: 20MHz
'
' This code controls a WS2812B LED strip using software bit-banging.
' Timing is CRITICAL for WS2812B. The NOPs in SendByte are adjusted
' for a 20MHz clock (5 MIPS, 200ns per instruction cycle).
'
' You may need to fine-tune the NOP counts slightly for optimal performance
' with your specific LEDs and setup.
'-------------------------------------------------------------------------------
Device = 18F25q10
Clock = 64 ' MHz
' --- Configuration for PIC18F252 @ 20MHz ---
' Using INTRC as an option, but external crystal is more accurate for timing.
' Ensure your crystal and oscillator settings match your hardware.
'Config OSC = HSPLL ' High-Speed Crystal/Resonator with PLL (for higher speeds like 40MHz)
' If you are actually using a 20MHz crystal without PLL, use HS
' Config OSC = HS
'Config WDT = Off ' Watchdog Timer Off
'Config MCLRE = On ' Master Clear Enable
'Config PWRT = On ' Power-up Timer Enable
'Config BOR = On ' Brown-out Reset Enable
'Config LVP = Off ' Low-Voltage Programming Off (good practice for programming stability)
'Config CP0 = Off ' Code Protection Off
Include "intosc.bas"
Include "system.bas" ' for NOP macro
Config CLKOUTEN = ON
' --- Pin Definitions ---
Dim WS2812BDataPin As PORTC.2 ' **CHANGE THIS if you use a different pin**
' (e.g., PortB.0, PortA.5, etc.)
' --- WS2812B Parameters ---
Const NUM_LEDS As Byte = 1 ' **CHANGE THIS to the number of LEDs you have**
' Define the LED color data array (GRB format)
Dim LED_Data(NUM_LEDS * 3) As Byte ' 3 bytes per LED (Green, Red, Blue)
' --- Subroutines ---
' Subroutine to send a single byte (8 bits) to the WS2812B.
' This routine is highly time-sensitive and uses NOPs for precise delays.
' >>>>> Tuned for a 16MHz instruction clock (62.5ns per instruction cycle). <<<<<
Sub SendByte(ByVal DataByte As Byte)
Dim i As Byte
For i = 0 To 7 ' Loop 8 times for 8 bits
If DataByte.bits(7 - i) = 1 Then ' Send a '1' bit (T1H: ~800ns, T1L: ~450ns)
WS2812BDataPin = 1 ' Takes 1 cycle (62.5ns)
nop ' +62.5ns = 125ns
nop ' +62.5ns = 187.5ns
nop ' +62.5ns = 250ns
nop ' +62.5ns = 312.5ns
nop ' +62.5ns = 375ns
nop ' +62.5ns = 437.5ns
nop ' +62.5ns = 500ns
nop ' +62.5ns = 562.5ns
nop ' +62.5ns = 625ns
nop ' +62.5ns = 687.5ns
nop ' +62.5ns = 750ns (This is T1H, within spec)
WS2812BDataPin = 0 ' Takes 1 cycle (62.5ns)
'nop ' +62.5ns = 125ns
'nop ' +62.5ns = 187.5ns
' nop ' +62.5ns = 250ns
' nop ' +62.5ns = 312.5ns
'nop ' +62.5ns = 375ns (This is T1L, within spec)
' nop ' Added for buffer
Else ' Send a '0' bit (T0H: ~400ns, T0L: ~850ns)
WS2812BDataPin = 1 ' Takes 1 cycle (62.5ns)
nop ' +62.5ns = 125ns
nop ' +62.5ns = 187.5ns
nop ' +62.5ns = 250ns
nop ' +62.5ns = 312.5ns
nop ' +62.5ns = 375ns (This is T0H, within spec)
WS2812BDataPin = 0 ' Takes 1 cycle (62.5ns)
'nop ' +62.5ns = 125ns
'nop ' +62.5ns = 187.5ns
'nop ' +62.5ns = 250ns
' nop ' +62.5ns = 312.5ns
'nop ' +62.5ns = 375ns
' nop ' +62.5ns = 437.5ns
'nop ' +62.5ns = 500ns
'nop ' +62.5ns = 562.5ns
' nop ' +62.5ns = 625ns
'nop ' +62.5ns = 687.5ns
'nop ' +62.5ns = 750ns
' nop ' +62.5ns = 812.5ns (This is T0L, within spec)
End If
Next
End Sub
' Subroutine to send a single color (Green, Red, Blue) to the WS2812B.
' WS2812B expects GRB order.
Sub SendColor(ByVal Green As Byte, ByVal Red As Byte, ByVal Blue As Byte)
SendByte(Green)
SendByte(Red)
SendByte(Blue)
End Sub
' Subroutine to send all LED data from the buffer to the strip.
' This causes the LEDs to update their colors.
Sub ShowLEDs()
Dim i As Word
For i = 0 To (NUM_LEDS * 3 - 1) Step 3
SendColor(LED_Data(i), LED_Data(i + 1), LED_Data(i + 2))
Next
' Send the reset pulse (data line low for > 50us)
WS2812BDataPin = 0
DelayUS(60) ' Ensure at least 50us reset pulse (use Delay_us built-in)
End Sub
' Subroutine to set the color of a specific LED in the internal buffer.
' Colors are stored as Green, Red, Blue.
Sub SetLEDColor(ByVal LED_Index As Byte, ByVal Red As Byte, ByVal Green As Byte, ByVal Blue As Byte)
If LED_Index < NUM_LEDS Then
LED_Data(LED_Index * 3) = Green ' Store Green component
LED_Data(LED_Index * 3 + 1) = Red ' Store Red component
LED_Data(LED_Index * 3 + 2) = Blue ' Store Blue component
End If
End Sub
' --- Main Program ---
' temp variables
Dim i As Byte
Dim hue As Byte = 0
' Initialize the data pin as output low
Low(WS2812BDataPin)
' Clear all LEDs initially (set to off)
'For i = 0 To NUM_LEDS - 1
' SetLEDColor(i, 0, 0, 0) ' All Off
' Next
'ShowLEDs() ' Send all 'off' data to LEDs
' DelayMS(100) ' Small delay for LEDs to update
' --- Set some colors for demonstration ---
'SetLEDColor(0, 255, 0, 0) ' First LED Red
'SetLEDColor(1, 0, 255, 0) ' Second LED Green
'SetLEDColor(2, 0, 0, 255) ' Third LED Blue
'SetLEDColor(3, 255, 255, 0) ' Fourth LED Yellow (Red + Green)
'SetLEDColor(4, 0, 255, 255) ' Fifth LED Cyan (Green + Blue)
'SetLEDColor(5, 255, 0, 255) ' Sixth LED Magenta (Red + Blue)
'SetLEDColor(6, 255, 255, 255) ' Seventh LED White (Full Brightness)
'SetLEDColor(7, 10, 10, 10) ' Eighth LED Dim White
'ShowLEDs() ' Send the updated data to the LEDs
' --- Simple Animation Loop ---
While (true)
SetLEDColor(0, 255, 0, 0) ' First LED Red
'SetLEDColor(1, 0, 255, 0) ' First LED Red
'SetLEDColor(2, 0, 0, 255) ' First LED Red
'SetLEDColor(3, 0, 255, 0) ' First LED Red
'SetLEDColor(4, 0, 0, 255) ' First LED Red
'SetLEDColor(5, 255, 0, 0) ' First LED Red
'SetLEDColor(6, 0, 255, 0) ' First LED Red
'SetLEDColor(7, 0, 0, 255) ' First LED Red
'SetLEDColor(8, 255, 0, 0) ' First LED Red
'SetLEDColor(9, 255, 0, 0) ' First LED Red
'SetLEDColor(10, 255, 0, 0) ' First LED Red
'SetLEDColor(11, 255, 0, 0) ' First LED Red
'SetLEDColor(12, 255, 0, 0) ' First LED Red
'SetLEDColor(13, 255, 0, 0) ' First LED Red
'SetLEDColor(14, 255, 0, 0) ' First LED Red
'SetLEDColor(15, 255, 0, 0) ' First LED Red
'SetLEDColor(16, 255, 0, 0) ' First LED Red
'SetLEDColor(17, 255, 0, 0) ' First LED Red
'SetLEDColor(18, 255, 0, 0) ' First LED Red
'SetLEDColor(19, 255, 0, 0) ' First LED Red
ShowLEDs() ' Send the updated data to the LEDs.8..
End While
'End Program
?I000006_F000_000027_M000000 ; L#MK High(LED)
BSF LATC,2,0
BCF TRISC,2,0
?I000007_F000_000028_M000000 ; L#MK mydelay
NOP
?I000008_F000_000029_M000000 ; L#MK Low (LED)
BCF LATC,2,0
BCF TRISC,2,0
?I000009_F000_000030_M000000 ; L#MK mydelay
NOP
Sub SendByte(ByVal DataByte As Byte)
dim i as byte
For I = 0 To 7 ' Loop 8 times for 8 bits
' send bits msb to lsb
If DataByte.bits(7) = 1 Then ' Send a '1' bit
' Send 1-bit (T1H: ~0.8us HIGH, T1L: ~0.45us LOW)
' T1H: 4 instruction cycles (0.8us)
' T1L: 2-3 instruction cycles (0.4-0.6us)
WS2812BDataPin = 1
NOP ' 200ns
NOP ' 400ns
NOP ' 600ns
NOP ' 800ns (approx T1H)
WS2812BDataPin = 0
NOP ' 200ns
NOP ' 400ns (approx T1L)
Else ' Send a '0' bit
' Send 0-bit (T0H: ~0.4us HIGH, T0L: ~0.85us LOW)
' T0H: 2 instruction cycles (0.4us)
' T0L: 4-5 instruction cycles (0.8-1.0us)
WS2812BDataPin = 1
NOP ' 200ns
NOP ' 400ns (approx T0H)
WS2812BDataPin = 0
NOP ' 200ns
NOP ' 400ns
NOP ' 600ns
NOP ' 800ns (approx T0L)
NOP ' 1000ns (Optional, for slightly longer T0L if needed)
End If
DataByte = DataByte << 1
Next
End Sub
MOVF DataByte, W ; Load byte into W
MOVWF TempByte ; Store in working register
CLRF BitMask
BSF BitMask, 7 ; Start with MSB
SendBitLoop:
MOVF TempByte, W
ANDWF BitMask, W ; Test current bit
BTFSS STATUS, Z ; Skip if result is zero (bit is 1)
GOTO SendZero ; If zero, send 0
; Else fall through to send 1
SendOne:
BSF LATC, 2
NOP ; T1H ~700 ns
NOP
...
BCF LATC, 2
NOP ; T1L ~600 ns
...
GOTO Continue
SendZero:
BSF LATC, 2
NOP ; T0H ~350 ns
...
BCF LATC, 2
NOP ; T0L ~900 ns
...
Continue:
RRCF BitMask, F ; Shift to next bit
BTFSS STATUS, Z ; Done after 8 bits
GOTO SendBitLoop