WSD2811 led time code in C, optimize further

Thread Starter

Vindhyachal Takniki

Joined Nov 3, 2014
594
1. I am using WSD2811 to run led in series. I am using C-code for programming. My below code is working by carefully adjusting some of NOP instructions.

2. 100 leds are working fine on WSD2811, my code is in C, so no issues. Dont want to write in assembly.

3. Below is my code, in which I check each bit of red/green/blue by if/else, then make pin high/low

4. Want to know if there any other way I can optimize code in c language or better way to do that in C-language.

5. Please dont suggest to write in assembly or if code is already working why to change.

I want to write in C only, & check if there any way I can further optimize code in C language.

Again by current code, my leds are working fine


Code:
static void ws2811_rgb_write(uint8_t red, uint8_t green , uint8_t blue) 
{
//R1
    if(red & 0x80U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    } 
///   
   
//R2
    if(red & 0x40U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }    
/// 

//R3
    if(red & 0x20U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }     
///     
   
//R4
    if(red & 0x10U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }     
/// 

//R5
    if(red & 0x08U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }     
///   

//R6
    if(red & 0x04U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }  
///    

//R7
    if(red & 0x02U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }    
///   

//R8
    if(red & 0x01U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }    
///   


   
   
//R1
    if(green & 0x80U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    } 
///   
   
//R2
    if(green & 0x40U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }    
/// 

//R3
    if(green & 0x20U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }   
///     
   
//R4
    if(green & 0x10U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }      
/// 

//R5
    if(green & 0x08U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }     
///   

//R6
    if(green & 0x04U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }     
///    

//R7
    if(green & 0x02U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }     
///   

//R8
    if(green & 0x01U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }     
///       

   
   
   
//R1
    if(blue & 0x80U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    } 
///   
   
//R2
    if(blue & 0x40U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }    
/// 

//R3
    if(blue & 0x20U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }     
///     
   
//R4
    if(blue & 0x10U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }     
/// 

//R5
    if(blue & 0x08U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }     
///   

//R6
    if(blue & 0x04U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }    
///    

//R7
    if(blue & 0x02U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }     
///   

//R8
    if(blue & 0x01U)
    {
        LED_PIN_HIGH();
    } 
    else
    {
        LED_PIN_LOW();
    }    
///       
   
     
 
}
 

nsaspook

Joined Aug 27, 2009
13,086
Write (and learn about writing) your C code in a structured manner so it's easy to understand and debug in code and data-flow. Unless there is a 'true' problem with code speed or size don't worry much about C source code optimization. Excessive source code optimization usually obscures the HLL human language structure and rarely results in better object code from a good compiler (that will turn your nice source code into an assembly language mess of tables and gotos as the optimized solution).
 
Last edited:

danadak

Joined Mar 10, 2018
4,057
Basically you have said if any one of 3 high order bits set turn red led on, otherwise off.

So this is all you need
Code:
    if(red & 0xE0U)
    {
        LED_PIN_HIGH();
    }
    else
    {
        LED_PIN_LOW();
    }
Or also written -

Code:
if (red & 0xE0U) ? LED_PIN_HIGH() : LED_PIN_LOW();
You mention using NOPs to establish timing ? That sounds like an
interrupt driven timer would get you more predictable timing intervals.


Regards, Dana.
 
Last edited:

Sensacell

Joined Jun 19, 2012
3,432
Other than taking up less memory, there is no point in optimizing this.
Make a small tight loop out of it.

Your MCU cannot do anything else while this code runs.
The timing of the WSD2811 is not forgiving, interrupts that run concurrently will likely hose your timing.


https://www.edn.com/design/led/4438797/Tips-and-tricks-for-driving-WS2811-LED-strips---Part-1


I have had success using DMA to output SPI data, using the PIC32. This makes it a hardware thing that can run in the background, with perfect glitch-free timing. A look-up table generates bytes that have patterns of 1's and 0's to emulate the PWM timing required.
 
Top