Fads to Obsessions and Beyond...




Free domain for life, exceptional technical support, website transfer

WS2812 RGB LED

A WS2812 RGB LED is interfaced to a PIC18F248 microcontroller. A number of WS2812 LED's are daisy chained to demonstrate the communciations protocol/code for controlling and updating the colours of the LEDs.

The LED Matrix Sign project, required the control of 320 LED's. One solution is to use a component such as the MAX7221 which can enable control of 64 individual LED's via a convenient 3-wire serial interface. Multiple MAX7221 chips can be daisy chained, and thus the PIC microcontroller can control large numbers of LED's (up to 320 in the following test circuit/program) with only 3 output pins. However, this still requires a considerable amount of circuitry/components.

An alternative is the WS2812 which is a RGB LED providing 256 brightness levels with a possible 16777216 colors via an integrated control chip that only requires a single control line (three lines in total including 5V and ground). This means decorative lighting and other similar projects with greatly simplified/decreased wiring requirements compared to "stand alone" RGB and single colour LED's (discounting "trivial" applications such as single LED indicators etc). An example project that was enabled by the WS2812, due to only requiring three-wires for inter-connections, is the infinity mirror christmas tree decoration.

The following sections detail experiments/trials with the WS2812. The advantage of having a component with an integrated RGB/control chip is offset to a certain degree by the "restrictive" nature of the non-standard single-wire communications protocol used by the WS2812 - discussed further below. Some other advantages of the WS2812 from the datasheet:

    • Built-in signal reshaping circuit which means cascaded WS2812 chips do not received distorted communications wave-forms (ie no other circuitry required up to 5m between two WS2812 components).
    • Cascading port transmission signal by single line.
    • Each RGB pixel can achieve 256 brightness display, 16777216 color full color display, and scan frequency not less than 400Hz/s.
    • A precision internal oscillator and a 12V voltage programmable constant current control, effectively ensuring that the pixel point color and brightness are consistent

A disadvantage of the WS2812 is that the communication/control of the WS2812 requires tight timing constraints and therefore places restrictions on the type of microprocessors that can be used for interfacing.

However, as shown in the Testing/Experimental Results Section, these timing constraints are not as onerous as first appearance (but a relatively fast oscillator speed is still necessary).


The circuit consists of the usual minimum requirements for a PIC (PIC18 dealt with here) that is, power supply, oscillator (external crystal oscillator - 40MHz) and In-circuit serial programming (ICSP).

Circuit Operation

A typical "wall-wart" power-supply is used (a surplus laptop charger in this case) in conjunction with a voltage regulator (LM7805) to provide the regulated 5V required by the PIC microcontroller and the WS2812.

The WS2812 was purchased (from ebay - Hong Kong supplier) already mounted with the necessary current limiting resistor and by-pass capacitor (see Photographs Section). This makes the electrical connections trivial, simply require 5V and 'ground', with a connection from the desired PIC output pin to the DIN pin of the WS2812.

Multiple WS2812 are connected by 'daisy-chaining' the Dout pin of a WS2812 to the Din pin of the next WS2812. Obviously all the WS2812 5V pins need to be connected together (and to Vdd) and similarily with the 'ground' pins.

Power Supply for WS2812

As previously stated, WS2812 require 5V and 'ground', with multiple WS2812 being wired in parallel. The datasheet states that an individual WS2812 typically requires 18.5mA. The test circuit involving five (5) daisy-chained WS2812 (see Schematic and Photographs Sections) was measured to consume 80mA when each of the WS2812 had at least one LED energised.

This means if a 'large number' of WS2812 are to be used simultaneously (and it is also anticipated that many of LED's will be energised simultaneously) a seperate power supply for the WS2812 may be required. For example, 50 x WS2812, all with at least one LED energised, could be expected to require ~1A.

Software/Firmware

There is a lot of information and code libraries for WS2812 and Arduino (1), not so much for PIC microcontrollers as such. The majority of the information appears to concern the 'strict timing requirements' of the non-standard communication protocol which results in a myriad approaches trying to adhere precisely to the datasheet.

However, as highlighted by some authors (2), (3) careful consideration of the timing diagrams shows that the 0-bit pulse width (max of 500 ns) is the only difficult constraint (in terms of cycle times available when using 'low' frequency PIC microcontrollers). This allows simple 'bit-banging' routines to be used to drive the WS2812, although relatively fast microcontroller oscillator frequencies are necessary. I've successfully used 20MHz and above with the relevant microcontroller (didn't try lower frequencies).

The background to the communication timing diagrams for the WS2812 and the bit-banging routines is discussed in the Testing/Experimental Results Section.


Note: Image loading can be slow depending on server load.

  • WS2812 SchematicWS2812 Schematic

    Silver Membership registration gives access to full resolution schematic diagrams.

    WS2812 Schematic

This project did not require a PCB.

The construction was done using prototyping board. See the photographs and schematic diagram sections.

Qty Schematic Part-Reference Value Notes
Resistors
1R110K1/4W, 10% 
1R23301/4W, 10% 
Capacitors
2C1,C222pFCeramic 
1C30.33uF 
1C40.1uF 
Diodes
1D11N-4001 
5D2-D6WS2812RGB LED  datasheet
Integrated Circuits
1U1PIC18F248PIC microcontroller  datasheet
1U27805Linear Voltage Regulator  datasheet
Miscellaeous
1J1CONN-H55-pin connector for ICSP
1SW1SW-SPDT 
1X110MHzCrystal Oscillator
Description Downloads
WS2812 RGB LED - Bill of Materials Text File Download

The datasheet for the WS2812 (at least the versions that I could obtain) are woeful. The datasheet states that the data transfer protocol the WS2812 uses is "single NZR communication mode". A non-return-to-zero (NRZ) protocol is a binary code in which ones are represented by one significant condition, usually a positive voltage, while zeros are represented by some other significant condition, usually a negative voltage, with no other neutral or rest condition (4).

This is probably no more enlightening than the datasheet, and a review of reference (3) explaining the timing signals of the WS2812 is recommended - the following summarises this information.

Parameter Min (ns) Typical (ns) Max (ns)
Bit Value 0 , high voltage time200350500
Bit Value 1 , high voltage time550700 
Bit 0 or 1, low voltage time4506005,000
Data Latch, low voltage time6,000  

Using typically available oscillator frequencies and corresponding calculated instruction cycle times (see next table), this shows an oscillator frequency (and therefore corresponding applicable microcontroller) of 16MHz minimum is required, in order to achieve the minimum times listed in the above table using 'bit-banging' with 'for-next' C code constructs (otherwise you would have to resort to coding in assembler).

PIC Oscillator Freq. (MHz)10162040
Instruction Cycle Time (MHz)2.54510
Instruction Cycle Time (ns)400250200100

The following C code (CCS complier) uses a 'for-next' loop to 'bit-bang' the necessary 24 bits of information corresponding to a single RGB value required by a single WS2812 (40MHz oscillator frequency used). Since the 'low voltage time' of WS2812 data bits is a minimum of 450ns and a maximum of 5,000ns, the differing lengths of time introduced by 'over head' instructions due to the 'for-next' loop does not affect the communications with the WS2812 (as long as the cycle time is short enough - 100ns in the case of the 40MHz oscillator).

Code Snippet 1:


#include 
#zero_ram //all variables auto initialised to 0
#define RGBpin    PIN_B4

unsigned int32 LEDs_RGBdata;
int theColor;

void writeRGB() {
   //WS2812 expects blue then red then green byte order
   //RGBvalue = RRGGBB MSB->LSB
   int8 theBit; 

   for(theBit=0; theBit < 24; theBit++) {           
      if (bit_test(LEDs_RGBdata,23)) {
         output_high(RGBpin);
         delay_cycles(5);
         output_low(RGBpin);  
         delay_cycles(5);                 
      } else {
         output_high(RGBpin);
         delay_cycles(2);
         output_low(RGBpin);
         delay_cycles(8);
      }
      LEDs_RGBdata*=2;
   }         
   output_low(RGBpin); delay_us(10); //latch data
}

void main() {   
   while(TRUE){ 
      theColor++;
      if (theColor>3) {theColor=1;}
      switch (theColor) {
       case 1: LEDs_RGBdata = 0xFF0000;
               break;
       case 2: LEDs_RGBdata = 0x00FF00;
               break;
       case 3: LEDs_RGBdata = 0x0000FF;
               break;
      }
      writeRGB();
      delay_ms(2000);
   }
}  
   				

Code Snippet 2: Header file for above code snippet 1


    #include <18F248.h>
    #device adc=16
    
    #FUSES NOWDT      //No Watch Dog Timer
    #FUSES WDT128     //Watch Dog Timer uses 1:128 Postscale
    #FUSES HS         //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
    #FUSES NOBROWNOUT //No brownout reset
    #FUSES NOLVP      //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
    
    #use delay(clock=40000000)   
   				

The following code snippet 3 demonstrates how to send multiple RGB values to daisy-chained WS2812's (in this example 5 x WS2812).

Code Snippet 3:


#include 
#zero_ram //all variables auto initialised to 0

#define RGBpin    PIN_B4
#define NUM_LEDS  5 

unsigned int32 LEDs_RGBdata[NUM_LEDS];

void writeRGB() {
//WS2812 expects blue then red then green byte order
//RGBvalue = RRGGBB MSB->LSB
   int8 theBit;
   int8 theLED;
   unsigned int32 tempRGB;  

      for (theLED=0; theLED < NUM_LEDS; theLED++) {
         tempRGB=LEDs_RGBdata[theLED];
         for(theBit=0; theBit < 24; theBit++) {           
            if (bit_test(tempRGB,23)) {
               output_high(RGBpin);
               delay_cycles(5);
               output_low(RGBpin);  
               delay_cycles(5);                 
            } else {
               output_high(RGBpin);
               delay_cycles(2);
               output_low(RGBpin);
               delay_cycles(8);
            }
            tempRGB*=2;
         }
      }          
   output_low(RGBpin); delay_us(10); //latch data
}

void main() {
   unsigned int32 tempRGB;
   int i;
   
   LEDs_RGBdata[0]= 0xFF0000;
   LEDs_RGBdata[1]= 0x00FF00;
   LEDs_RGBdata[2]= 0x0000FF;
   LEDs_RGBdata[3]= 0xFF0000;
   LEDs_RGBdata[4]= 0x00FF00;    
      
   while(TRUE){ 
      writeRGB();
      tempRGB = LEDs_RGBdata[0]; //cycle colors
      for (i=0; i < NUM_LEDS; i++) {
         LEDs_RGBdata[i] = LEDs_RGBdata[i+1];         
      }
      LEDs_RGBdata[NUM_LEDS-1] = tempRGB;
      delay_ms(1000);     
   }
}
   		

The WS2812 were purchased (from ebay - Hong Kong supplier) already mounted with the necessary current limiting resistor and by-pass capacitor (see Photographs Section).

Electrical connections between daisy-chained WS2812 were made by soldering single strands of copper wire removed from a multi-core wound cable. This provided the necessary thin wires to hand-solder onto the rear pads of the WS2812 (see Photographs Section). This was sufficient for the testing purposes, however, a more robust solution (insulating the various connections to avoid accidential short-circuits) would be required for other projects.

Another consideration that would need to be taken into account (depending upon the number of WS2812 used in a project) that was not a concern in this testing scenario, is the overall power consumption of the parallel connected WS2812.

The test circuit involving five (5) daisy-chained WS2812 (see Schematic and Photographs Sections) was measured to consume 80mA when each of the WS2812 had at least one LED energised. This means if a 'large number' of WS2812 are to be used simultaneously (and it is also anticipated that many of LED's will be energised simultaneously) a seperate power supply for the WS2812 may be required. For example, 50 x WS2812, all with at least one LED energised, could be expected to require ~1A.

If interrupts are being used in a particular project, ensure that interrupts are temporarily disabled when the 'bit-banging' communication with the WS2812 is occuring.

Note: Video loading can be slow depending on server load.

The video below shows demonstration of five daisy-chained WS2812 'scrolling' through red, green and blue. The demonstration code is discussed in the sections above.

Comments/Questions

No comments yet.

Add Comment/Question

Only Logged-In Members can add comments

"If we could sell our experiences for what they cost us, we'd all be millionaires".

Please donate any amount to help with hosting this web site.

If you subscribe (only $2/annum) you can view the site without advertisements and get emails abouts updates etc.

X

Sorry!

Only logged-in users with correct Membership Level can download.


Membership starts at only $2, so join now!