RGB LED strips

Hello,

Im newbie at Arduino and Im trying to make a group of led's fade from Green to Blue, stay some time at blue and them fade back to green again, and them the same with Red to Yellow. I`m using the library ShiftPWM by Elco Jacobs.

According to the color Picker of Illustrator, the hue on the HSV value for Green is around 100, and Blue is 200, so the the hue should fade from 100 to 200 to make the leds fade from green to blue. Until this part, okay. But them, the HSV value for Yellow is around 60 and Red is 0, so the hue should fade from 0 to 60 to change from red to yellow. But what is in fact happening here is that the hue 10 is already Yellow (and 60 is a lime-green). Because of this, the second transition was happening too abruptly. I kind corrected it making the delay time bigger, but I'm still puzzled about why the colors of my LED strips are not matching with the HSV color table. I feel like there is here something simple that I'm not being able to see.

Here is the code:

const int ShiftPWM_latchPin=11;

#define SHIFTPWM_NOSPI
const int ShiftPWM_dataPin = 12;
const int ShiftPWM_clockPin = 10; 


const bool ShiftPWM_invertOutputs = false; 


const bool ShiftPWM_balanceLoad = true;


#include <ShiftPWM.h>  


unsigned char maxBrightness = 255;
unsigned char pwmFrequency = 75;
int numRegisters = 2;
int num_groups_of_strips = numRegisters*8/3;


int total_outputs = numRegisters*8;

void setup(){
  Serial.begin(57600);

  ShiftPWM.SetAmountOfRegisters(numRegisters);

  ShiftPWM.SetPinGrouping (1); 
  
  ShiftPWM.Start(pwmFrequency,maxBrightness);
  ShiftPWM.SetAll(0);
}

int activeLED = 0;
int brightness = 255;
unsigned long startTime = 0;
      
void loop()

{


   // green to blue and blue to green

     
    for(int hue = 100; hue<=200; hue++) //fadind from greeen to blue
    {    
              
        if (hue != 200) 
        { 
          ShiftPWM.SetAllHSV(hue, 255, 255); 
          delay(20);
          Serial.print ("fading: "); 
          Serial.println(hue);
        }
        if (hue == 200)
        {
          ShiftPWM.SetAllHSV(200, 255, 255);    //blue
          delay(5000);
          Serial.print ("blue: ");
          Serial.println(hue);
        }

    }

 

         for(int hue = 200; hue>=100; hue--) //fadind from blue to green
    {    
             
        if (hue != 100) 
        { 
          ShiftPWM.SetAllHSV(hue, 255, 255); 
          delay(20);
          Serial.print ("fading: "); 
          Serial.println(hue);
        }
        if (hue == 100)
        {
          ShiftPWM.SetAllHSV(100, 255, 255);    //green
          delay(5000);
          Serial.print ("green: ");
          Serial.println(hue);
        }

    }

 


     // Red to yelloow and Yellow to Red

     
    for(int hue = 0; hue<=10; hue++) //fading from red to yellow
    {    
              
        if (hue != 10) 
        { 
          ShiftPWM.SetAllHSV(hue, 255, 255); 
          delay(50);
          Serial.print ("fading: "); 
          Serial.println(hue);
        }
        if (hue == 10)
        {
          ShiftPWM.SetAllHSV(10, 255, 255);    //yellow
          delay(5000);
          Serial.print ("yellow: ");
          Serial.println(hue);
        }

    }

 

         for(int hue = 10; hue>=0; hue--) //fading from yellow to red
    {    
             
        if (hue != 0) 
        { 
          ShiftPWM.SetAllHSV(hue, 255, 255); 
          delay(50);
          Serial.print ("fading: "); 
          Serial.println(hue);
        }
        if (hue == 0)
        {
          ShiftPWM.SetAllHSV(0, 255, 255);    //red
          delay(5000);
          Serial.print ("red: ");
          Serial.println(hue);
        }

    }
    
 }
                        
 

}

Thanks in advance!

First off your code is not posted correctly you should use the </> icon at the top left.
Next it will not compile, code never ends on an opening brace.

To answer your questions what you are not understanding is that the eye does not perceive colours in a linear fashion so you can not simply take the numbers in a HSV colour space and send them to an LED and expect them to be the same.

Google "gamma correction "

Thanks for you reply, Mike. I searched about gamma correction and now really makes sense why the fading is like this.

I tried to correct using this code, but I'm not seeing difference from before. Could you help me about what I am doing wrong?

int pinmap[64];
int gamma[256];

// gamma correction lookup
String commandBuffer = "";

// a string to hold incoming data
String command ="";
boolean stringComplete = false;


int gamma12(int i) {
    int result;
    result = pow(float(i)*16/4096,2.8)*256;
    // 'i' is a 8-bit source value, 0 to 255 and gamma  2.8
    return result;
}

What is wrong is that you are not posting all your code. So we can't see how you are applying it.

Also that floating point calculation returning the value to an int looks wrong. Print out the results and see what you are getting.

Sorry, it is the entire code:

const int ShiftPWM_latchPin=11; //Green

#define SHIFTPWM_NOSPI
const int ShiftPWM_dataPin = 12; //Blue
const int ShiftPWM_clockPin = 10; //Yellow


const bool ShiftPWM_invertOutputs = false; 


const bool ShiftPWM_balanceLoad = true;

int pinmap[64];
int gamma[256];

// gamma correction lookup
String commandBuffer = "";

// a string to hold incoming data
String command ="";
boolean stringComplete = false;


int gamma12(int i) {
    int result;
    result = pow(float(i)*16/4096,2.8)*256;
    // 'i' is a 8-bit source value, 0 to 255 and gamma  2.8
    return result;


    Serial.print ("result: "); 
    Serial.println(result);
}


#include <ShiftPWM.h>  

unsigned char maxBrightness = 255;
unsigned char pwmFrequency = 75;
int numRegisters = 2;
int num_groups_of_strips = numRegisters*8/3;
int total_outputs = numRegisters*8;



int Wall_0_Top = 3; // This is wall 0, top 3 strips // 3 is the first register, first 3 pins
int Wall_0_Bottom = 1; // This is wall 0, bottom 2 strips // 1 is the second register, second 3 pins


void setup(){
  Serial.begin(57600);

  ShiftPWM.SetAmountOfRegisters(numRegisters);

  ShiftPWM.SetPinGrouping (1); 
  
  ShiftPWM.Start(pwmFrequency,maxBrightness);
  ShiftPWM.SetAll(0);
}

    
void loop()

{ 

  // green to blue and blue to green

          
    for(int hue = 100; hue<=200; hue++) //fadind from greeen to blue
    {    
              
        if (hue != 200) 
        { 
          ShiftPWM.SetAllHSV(hue, 255, 255); 
          delay(20);
          Serial.print ("fading: "); 
          Serial.println(hue);
        }
        if (hue == 200)
        {
          ShiftPWM.SetAllHSV(200, 255, 255);    //blue
          delay(3000);
          Serial.print ("blue: ");
          Serial.println(hue);
        }

    }

 

         for(int hue = 200; hue>=100; hue--) //fading from blue to green
    {    
             
        if (hue != 100) 
        { 
          ShiftPWM.SetAllHSV(hue, 255, 255); 
          delay(20);
          Serial.print ("fading: "); 
          Serial.println(hue);
        }
        if (hue == 100)
        {
          ShiftPWM.SetAllHSV(100, 255, 255);    //green
          delay(3000);
          Serial.print ("green: ");
          Serial.println(hue);
        }

    }
   

     // Green to red


 for(int hue = 100; hue>=0; hue--) //fading from green to red
    {    
             
        if (hue != 0) 
        { 
          ShiftPWM.SetAllHSV(hue, 255, 255); 
          delay(20);
          Serial.print ("fading: "); 
          Serial.println(hue);
        }
        if (hue == 0)
        {
          ShiftPWM.SetAllHSV(0, 255, 255);    //red
          delay(3000);
          Serial.print ("red: ");
          Serial.println(hue);
        }

    }
    


     // Red to yellow and Yellow to Red

     
    for(int hue = 0; hue<=10; hue++) //fading from red to yellow
    {    
              
        if (hue != 10) 
        { 
          ShiftPWM.SetAllHSV(hue, 255, 255); 
          delay(90);
          Serial.print ("fading: "); 
          Serial.println(hue);
        }
        if (hue == 10)
        {
          ShiftPWM.SetAllHSV(10, 255, 255);    //yellow
          delay(3000);
          Serial.print ("yellow: ");
          Serial.println(hue);
        }

    }

         for(int hue = 10; hue>=0; hue--) //fading from yellow to red
    {    
             
        if (hue != 0) 
        { 
          ShiftPWM.SetAllHSV(hue, 255, 255); 
          delay(90);
          Serial.print ("fading: "); 
          Serial.println(hue);
        }
        if (hue == 0)
        {
          ShiftPWM.SetAllHSV(0, 255, 255);    //red
          delay(3000);
          Serial.print ("red: ");
          Serial.println(hue);
        }

    }

    // Red to Green


 for(int hue = 0; hue<=100; hue++) //fading from red to green
    {    
             
        if (hue != 100) 
        { 
          ShiftPWM.SetAllHSV(hue, 255, 255); 
          delay(20);
          Serial.print ("fading: "); 
          Serial.println(hue);
        }
        if (hue == 100)
        {
          ShiftPWM.SetAllHSV(100, 255, 255);    //green
          delay(3000);
          Serial.print ("green: ");
          Serial.println(hue);
        }

    }
    
 }

The serial monitor is printing just the hue changing.

red: 0
fading: 0
fading: 1
fading: 2
fading: 3
fading: 4
fading: 5
fading: 6
fading: 7
fading: 8
fading: 9
yellow: 10
fading: 10
fading: 9
fading: 8
fading: 7
fading: 6
(...)

And where exactly is the part of the code where you think gamma correction is being applied? I can't spot it.

I didn't actually understand this code, so I've just copied it and though the gamma correction was something to be settled before the void loop and it would be applied on the rest. (by the way I took it from this blog Goggin's Arduino: The Duino Light Controller - Slave Module)

Should I also include the following code on the void setup?

  for (int pin = 0; pin <= total_outputs; pin+=1) {
               pinmap[pin]=total_outputs-1;
          }
        
        //5,3,7,6,4,2,1,0,8,9,10,11,12,13,14,15,16
        pinmap[0]=5;
        pinmap[1]=3;
        pinmap[2]=7;
        pinmap[3]=6;
        pinmap[4]=4;
        pinmap[5]=2;
        pinmap[6]=1;
        pinmap[7]=0;
        pinmap[8]=8;
        pinmap[9]=9;
        pinmap[10]=10;
        pinmap[11]=11;
        pinmap[12]=12;
        pinmap[13]=13;
        pinmap[14]=14;
        pinmap[15]=15;
        pinmap[15]=16;

    for (int fadeValue = 0 ; fadeValue <= 255; fadeValue +=1) {
        gamma[fadeValue] = gamma12 (fadeValue);
    }

How can I apply the gamma correction on the fading?

Thanks for the patience with my beginner-stupid questions :slight_smile:

Basically you can't apply it with the code you are using. This is because you are using a method in your library to take in the HSV colour values and set the LED with it.

You need to write a function to convert the HSV value into an RGB value. Then you apply the gamma correction to each one of the three colour components separately and then use your library to set these new modified RGB values to the LEDs.

It might be that gamma correction is too heavy for your original problem. The main reason why the LEDs do not match the theoretical HSV values is in fact two fold.

  1. The HSV to RGB conversion in the library is quite crude dealing only as it does with integer values.
  2. The LED colours themselves do not correspond to the mathematically pure RGB colours.

The eye is not equally as sensitive to all colours hence colours like yellow occupy a small range and those like blue a large range.

Read up on HSV here.

Since the appearance of the led's now are good enough for my purpose, I will let this correction to the future, when I have more time for improving my code. Thanks a lot!

LED ON/OFF using TWO push button need coding help me

Kichu:
LED ON/OFF using TWO push button need coding help me

Start your own thread.
Read the how to use the forum sticky.
Give a better description of what you want to do and your hardware .
Post the code you have written so far.