Addressable LEDs WS2813/WS2812

Status
Not open for further replies.
There's a video I watched it to times I didn't see where he was defining it.
**broken link removed**
on a 18f2550
 
Last edited:
Here the code fixed up thanks to some help from
Code:
#include "NeoCol.h"
#include <stdlib.h>
uint8_t NeoGreen [NeoNum];
uint8_t NeoBlue [NeoNum];
uint8_t NeoRed [NeoNum];
void NeoBit (uint8_t Data, int8_t BitCount)
{
    if ((Data >> BitCount) & 0x01)
    {
        NeoPin = 1; 
        _delay (6); 
        NeoPin = 0;
    }   
    else
    { 
        NeoPin = 1; 
        _delay (3); 
        NeoPin = 0; 
    } 
}
void NeoInit (void)
{
   uint8_t NeoPixel;
   for (NeoPixel = 0; NeoPixel < NeoNum; NeoPixel++)   
   {
      if (NeoPixel < 10)
         { NeoGreen[NeoPixel] = 0; NeoBlue[NeoPixel] = 0; NeoRed[NeoPixel] = 64; }
      else if ((NeoPixel >= 10) & (NeoPixel < 20))
         { NeoGreen[NeoPixel] = 0; NeoBlue[NeoPixel] = 64; NeoRed[NeoPixel] = 0; }
      else if ((NeoPixel >= 20) & (NeoPixel < 30))
         { NeoGreen[NeoPixel] = 0; NeoBlue[NeoPixel] = 64; NeoRed[NeoPixel] = 64; }
      else if ((NeoPixel >= 30) & (NeoPixel < 40))
         { NeoGreen[NeoPixel] = 64; NeoBlue[NeoPixel] = 0; NeoRed[NeoPixel] = 0; }
      else if ((NeoPixel >= 40) & (NeoPixel < 50))
         { NeoGreen[NeoPixel] = 64; NeoBlue[NeoPixel] = 0; NeoRed[NeoPixel] = 64; }
      else if ((NeoPixel >= 50) & (NeoPixel < NeoNum))
         { NeoGreen[NeoPixel] = 64; NeoBlue[NeoPixel] = 64; NeoRed[NeoPixel] = 0; }     
   }
}
void NeoDraw (void)
{
   uint8_t NeoPixel;
   int8_t BitCount;
   for (NeoPixel = 0; NeoPixel < NeoNum; NeoPixel++)
   {   
      for (BitCount = 7; BitCount >= 0; BitCount--)     
         NeoBit(NeoGreen[NeoPixel], BitCount);     
      for (BitCount = 7; BitCount >= 0; BitCount--)           
         NeoBit(NeoRed[NeoPixel], BitCount);           
      for (BitCount = 7; BitCount >= 0; BitCount--)     
         NeoBit(NeoBlue[NeoPixel], BitCount);     
   }
   //output_low (NeoPin);
}
void NeoRotate (void)
{
   uint8_t NeoPixel;   
   for (NeoPixel = 0; NeoPixel < NeoNum - 1; NeoPixel++)   
   {           
      NeoGreen[NeoPixel] = NeoGreen[NeoPixel + 1];
      NeoBlue[NeoPixel] = NeoBlue[NeoPixel + 1];
      NeoRed[NeoPixel] = NeoRed[NeoPixel + 1];
   }
   NeoGreen[NeoNum - 1] = NeoGreen[0];
   NeoBlue[NeoNum - 1] = NeoBlue[0];
   NeoRed[NeoNum - 1] = NeoRed[0]; 
}
void main()
{   
    OSCCON = 0;     // Use clock specified in config: 48MHz
    NeoPin = 0;     // Set data line to - initially
    TRISB = 0;      // Set port B to output
   
   NeoInit ();   
   while(1)
   {       
      NeoDraw ();
      NeoRotate ();
      __delay_ms (25);
   }
}

The header file
Code:
/*#include <18F2550.h>
#device ADC = 16
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(clock=48000000,crystal=20000000)
*/
// PIC18F2550 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config PLLDIV = 5       // PLL Prescaler Selection bits (Divide by 5 (20 MHz oscillator input))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 1       // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)
// CONFIG1H
#pragma config FOSC = HSPLL_HS  // Oscillator Selection bits (HS oscillator, PLL enabled (HSPLL))
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRT = ON        // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOR = OFF        // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (Minimum setting 2.05V)
#pragma config VREGEN = OFF     // USB Voltage Regulator Enable bit (USB voltage regulator disabled)
// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 128      // Watchdog Timer Postscale Select bits (1:128)
// CONFIG3H
#pragma config CCP2MX = OFF     // CCP2 MUX bit (CCP2 input/output is multiplexed with RB3)
#pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = OFF     // Stack Full/Underflow Reset Enable bit (Stack full/underflow will not cause Reset)
#pragma config LVP = OFF        // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)
// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)
// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 48000000     // Used by XC8 delay ms and us
#define NeoPin LATBbits.LATB0   // The data out pin for the LED
#define NeoNum 60               // Number of LEDs connected
//#define RAND_MAX 64
//#define ALL_OUT 0x00
//#define ALL_IN  0xFF
//#byte PORTA = 0xF80
 
Here's a better video you can see there is more then one led this board has 4 i got it cheap from china to play around with.
 
I have a string of 10 LEDs that I can only turn on a few or all of them at the same time. What I would like to do is to turn on a specific LED only by passing the desired LED position to be turned on into a function. Anyone done this already?
Code:
#include "mcc_generated_files/mcc.h"
uint8_t ColorFontGREEN;
uint8_t ColorFontRED;
uint8_t ColorFontBLUE;
uint16_t CNT;
void clearLEDArray(void) {
    for (CNT = 0; CNT < 256; ++CNT) {
        SSP1BUF = 0;
        while (!SSP1STATbits.BF);
    }
}
/*
                         Main application
 */
void main(void)
{
  
    // initialize the device
    SYSTEM_Initialize();
    // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
    // Use the following macros to:
    // Enable the Global Interrupts
    //INTERRUPT_GlobalInterruptEnable();
    // Enable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptEnable();
    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();
    // Disable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptDisable();
    ColorFontRED = 50;
    ColorFontGREEN = 50;
    ColorFontBLUE = 100;
  
    while (1)
    {
        // Add your application code
      
        for (CNT = 0; CNT < 10; ++CNT) {
            SSP1BUF = ColorFontGREEN; //Green
            while (!SSP1STATbits.BF);
            SSP1BUF = ColorFontRED; //Red
            while (!SSP1STATbits.BF);
            SSP1BUF = ColorFontBLUE; //Blue
            while (!SSP1STATbits.BF);
        }
        __delay_ms(20);
    }
  
}
/**
 End of File
*/
 
You send out the bytes 0 ,0,0 is sent out for a led to be off I look at the code on mplabxpress.microchip.com
You send 3 bytes 000,255,000 set's led one to green fully on send the next 3 bytes 255,000,000 set's led 2 to red fully on. and so on.

To change color you add like 50,200,50

Code:
#include "mcc_generated_files/mcc.h"
#include "LED_Array.h"
/*
                         Main application
 */
void main(void) {
    SYSTEM_Initialize();
    //Load buffer with text
    loadBuffer((char *) "11111111111111111111 "); //<<< Enter the text you would like to be displayed here.
   
    //Select font color and intensity 
    ColorFontRED = 5;
    ColorFontGREEN = 50;
    ColorFontBLUE = 0;
    //Select background color and intensity 
    ColorBackRED = 0;
    ColorBackGREEN = 0;
    ColorBackBLUE = 0;
   
   
    while (1) {
        loadLEDArray();
        writeLEDArray();
       
        }
    }
/**
has buffer you set the bytes and it runs them
 

Attachments

  • 8x32_NeoPixel_RGB_LED.zip
    52.2 KB · Views: 156
Yes I understand, but this way I can only turn on the entire string. I want to be able to turn on only LED #5 and have the rest of them off.
 
You send out 10 24 bit packets the 9 of them would be 000 , 000, 000 the #5 would be say 000, 255, 000
 
Because it's a serial protocol you have to send out all the LEDs up to the one you want. However, I assume that previously LED 10 could have been turned on and so writing the whole string makes sense.

Edit, as Burt said.

Mike.
 
Ok, maybe I should rephrase. I understand what needs to be done. I'm just having issues figuring out how to do it in the program ie. write the code by modifying the one I already posted.
 
You didn't post all your code it's hard to see what it's doing without the include files.
 
It's basically the same as the example in microchips website.
 

Attachments

  • LEDStripTest.zip
    56.2 KB · Views: 142
Just write a function that writes the LEDs.
Code:
void DoIt(uint8_t lit){
uint8_t i;
    for(i=0;i<10;i++){
        if(i=lit)
            WriteLED(255,255,255)
        else
            WriteLED(0,0,0)
    }
}

Mike.
 
I tried this on a old 16f628a all in software using xc8 the leds came on set one color timing was off a little not a great lot but you can only set one color LOL

So I played a bit more the 16F628a ran out of code space.

I wish I was better at C learning tho.
 
Just write a function that writes the LEDs.
Code:
void DoIt(uint8_t lit){
uint8_t i;
    for(i=0;i<10;i++){
        if(i=lit)
            WriteLED(255,255,255)
        else
            WriteLED(0,0,0)
    }
}

Mike.

Thanks!
That worked, below is how I implemented.
Code:
    for(CNT = 1; CNT < 10; ++CNT){
        if(CNT == 8)
        {
            SSP1BUF = 255; //Green
            while (!SSP1STATbits.BF);
            SSP1BUF = 255; //Red
            while (!SSP1STATbits.BF);
            SSP1BUF = 255; //Blue 
            while (!SSP1STATbits.BF);
        }
        else
               
            SSP1BUF = 0; //Green
            while (!SSP1STATbits.BF);
            SSP1BUF = 0; //Red
            while (!SSP1STATbits.BF);
            SSP1BUF = 0; //Blue 
            while (!SSP1STATbits.BF);
    }
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…