Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Fun with AI and swordfish basic

I have some tube lights with 300 leds for 50 watts but some only need one color red or blue the rest
do a wave of blue red green there 80 of tubes i used the esp 32 and wled for those
now back to making led tubes


 
Last edited:
here's a version of the SendByte() sub that would produce a lot better timing (based on that original AI code)

Code:
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

Timing is always going to be an issue with these, so something that uses hardware would be a lot better.
 
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 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
 
I been using these for years there ws2815b is what I’m using I have 9600 leds what I was saying is I wanted to use just a pic chips for some of the tubes there only one color but I’m using the same LEDs this lets me use the esp 32 for light shows
And just something simple for the solid colors
I just did the AI code for fun.

I have a working system for the tubes
I have a working code for XC 8
And I us wled for esp really awesome free sw28xx
LED control app for ESP
You can make led walls with it cool stuff
 
This don't add up the code on a 18f252 20 mhz crystal works the code on the 18f25q10 doesn't work its like the clock is running at16/4 not the 64/4 but im sure its running at 16 the 64/4 on rb6 i get 16 mhz clock out that pin

here is the code maybe jerry have look and tell me I'm nuts lol
Whats even harder to understand is I have removed a bunch of the nop and the code is not running as fast as the 20 mhz chip did.

Code:
'-------------------------------------------------------------------------------
' 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
 
Could you flash an LED for say 10 seconds (according to the specified clock frequency) and check the timing?
 
This the asm code it makes
Code:
?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
 
So, that's 6 instructions at 62.5ns each for a total of 375ns. Put that in a loop and it'll be about 400ns.

The send byte routine I posted in #22 will be faster than #31
 
Its like this the High part you can get right the low part you cant I cant get the period to be 800khz
But the 18f252 with a crystal same code less nop is dead on it

The one high is like 850ns the 0 high is 350ns but the low for both is like 4 to 5us with no nop.
 
Last edited:
I'm closer the 18f25q10 has some banking when it shifting the low bit it gets the high part fine but the low part the pin is low for a lot of time I got it to like 1.5 us so this part will have to be in asm the 18f252 blanks better

Code:
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
 
Im working on this
Code:
    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

It gets low bit a high of 300ns right but isn't sending any high bit high of 750 ns
 

Latest threads

New Articles From Microcontroller Tips

Back
Top