Rebel Tri Color Hue Knob

Hi,

I’m attempting to use the Luxeon Rebel LED Breakout - RGB Triple Play to fade through hues based on a potentiometer, and I have no idea where to begin. It’s super easy to do with BlinkM (so easy in fact it’s part of their sample code). Anyone use these with the driver boards? Any info would help.

I’ve assembled the kit based on the tutorial and uploaded the code. All works. Just wondering how to go about modifying the Arduino code and not fry the LED board (tutorial warns against PWMing this thing).

Thanks.

This portion of the sample code does the PWM of the LEDs to set the color.

		DDRB &= ~((1<<RED) | (1<<BLUE) | (1<<GREEN)); //set all LEDs on, pins are set as inputs

		for (a = 0; a < 255; a++)
		{
			if (a == red_count)  DDRB |= 1<<RED;//red off, PB3 set as output and low
			if (a == blue_count)  DDRB |= 1<<BLUE;//blue off, PB1 set as output and low
			if (a == green_count)  DDRB |= 1<<GREEN;//green off, PB2 set as output and low
			delay_us(20);
		}

The caution is against using the Arduino PWM output is because the output pin would cycle between being ON and a LOW and ON and a HIGH. An ON and HIGH output apparently results is a higher than desired current into the LED. So what’s done is a software implementation of PWM but instead of ON and HIGH, each LED’s control pin is set to a high impedance state (? set as input ?).

So you could use the above code and then, in a larger loop containing the above, read the voltage from the potentiometer and set the relative values of red_count, blue_count and green_count to get the hue you want. At least that’s the big picture, no doubt some other details need attending to.

Great, thanks.

I’ve been wondering which pins to set ADJ1, ADJ2, and ADJ3…in the sample code, I couldn’t find any info, but I had it working on pins 9, 10, & 11.

I found this whole PWM over driving the LEDs counter intuitive. There is scant explanation in the SFE pages at to why this is the case (no, “doesn’t play nice” doesn’t do it for me) so I spent some time looking at the datasheet. It looks like the driver board has a design flaw. The Adj pin is not a logic input. It is analog and should be driven at no more than 2.5V (which is 200% of the current set by the sense resistor). By using an NPN as an open collector driver, the internal pullup of the ZXLD1360 would limit the Adj voltage to VRef and thus not spike the current. The data sheet clearly spells this out. The chart on p13 doesn’t even show 5V. Perhaps an alternative approach would be a voltage divider but a transistor would work the same at 3.3 or 5V. One could argue that the ZXLD1360 should be been a little more designer friendly.

On the sense resistor, it looks like 330 mOhm would have been a safer choice than 150. Using an NPN driver would make 150 work ok, though.

The reason HiZ (yes, input) works is because Adj is pulled to VRef internally (about 1.25V) and the LED being driven at about 625 mA - supposedly within the LED specs.

Ok, so I have the pot switch outputting colors…with a few bugs. Namely, I can’t get all on at once (white).

I’m aware that their is probably a lot of excess junk in here, I pieced it together with another hue code. Here is the code.

#include <avr/io.h>

#include <avr/interrupt.h>



#define FOSC 16000000// Clock Speed

#define BAUD 115200

#define MYUBRR FOSC/8/BAUD-1



#define BLUE 1	//PB1

#define GREEN 2	//PB2

#define RED 3	//PB3

unsigned char a;

int potpin = 2;		  // POT connected to digital pin 2 - pos/neg are left and right connections on POT

float h;			   // Hue range
int h_int;			 // Hue color
int r = 0, g = 0, b = 0;	     // Default RGB values

int val = 0;			 // Set POT value to default 0

void h2rgb(float h, int& R, int& G, int& B); // Instantiate h2rgb and it's variables  a.k.a  Hue to RGB

void delay_us(uint8_t x);

void setup()			  // Run once, when the sketch starts
{
  Serial.begin(9600);	    // Begin the output of data to serial
}


void loop()			   // Run over and over again
{
  val = analogRead(potpin);    // Read the pin and display the value
  h = ((float)val)/1024;	 // Get the range. pot value / 1024
  h_int = (int) 360*h;	   // Get the color hue by multiplying by 360

  h2rgb(h,r,g,b);		  // Call the h2rgb function passing it the hue value

  /*Serial.print("POT value: ");
  Serial.print(val);	     // Pot value
  Serial.print(" = Hue of ");
  Serial.print(h_int);	   // Color Hue value
  Serial.print(" degrees. RGB values: ");
  Serial.print(r);		 // Red value
  Serial.print(" ");
  Serial.print(g);		 // Green value
  Serial.print(" ");
  Serial.println(b);	     // Blue value */


DDRB &= ~((1<<RED) | (1<<BLUE) | (1<<GREEN)); //set all LEDs on, pins are set as inputs

for (a = 0; a < 255; a++)
{
  if (a == r)  DDRB |= 1<<RED;//red off, PB3 set as output and low
  if (a == b)  DDRB |= 1<<BLUE;//blue off, PB1 set as output and low
  if (a == g)  DDRB |= 1<<GREEN;//green off, PB2 set as output and low
  //delay_us(20);
}
}

/*void delay_us(uint8_t x)

{

  char temp;



  if (x == 0) temp = 1;

  else temp = x;



  TIFR2 |= 0x01;//Clear any interrupt flags on Timer2



  TCNT2 = 256 - temp;



  while(!(TIFR2 & 0x01));	

}*/

void h2rgb(float h, int& R, int& G, int& B) {

  // Used HSV --> RGB function
  // HSV - Hue, Saturation, Value
  // RGB - Red, Green, Blue - example (255,255,255)
  // Function below does a bunch of math to convert HSV values to RGB
  int var_i;
  float S=1, V=1, var_1, var_2, var_3, var_h, var_r, var_g, var_b;

  if ( S == 0 )			     //HSV values = 0 ÷ 1
  {
    R = V * 255;
    G = V * 255;
    B = V * 255;
  }
  else
  {
    var_h = h * 6;
    if ( var_h == 6 ) var_h = 0;	//H must be < 1
    var_i = int( var_h ) ;		//Or ... var_i = floor( var_h )
    var_1 = V * ( 1 - S );
    var_2 = V * ( 1 - S * ( var_h - var_i ) );
    var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) );

    if	( var_i == 0 ) {
	var_r = V     ;
	var_g = var_3 ;
	var_b = var_1 ;
    }
    else if ( var_i == 1 ) {
	var_r = var_2 ;
	var_g = V     ;
	var_b = var_1 ;
    }
    else if ( var_i == 2 ) {
	var_r = var_1 ;
	var_g = V     ;
	var_b = var_3 ;
    }
    else if ( var_i == 3 ) {
	var_r = var_1 ;
	var_g = var_2 ;
	var_b = V     ;
    }
    else if ( var_i == 4 ) {
	var_r = var_3 ;
	var_g = var_1 ;
	var_b = V     ;
    }
    else			 {
	var_r = V     ;
	var_g = var_1 ;
	var_b = var_2 ;
    }

    R = (1-var_r) * 255;			//RGB results = 0 ÷ 255
    G = (1-var_g) * 255;
    B = (1-var_b) * 255;
  }
}

Sine you’re printing out the diagnostics … where does the problem lie ? Is the pot getting you the proper value for white ? Are you getting the proper HSV value but not the correct RGB counts ? Are you getting equal RGB counts but the light isn’t white ?

I never get 255, 255, 255. One of the 3 is always 0, fading from one to the next.

I can’t say I’ve ever studied the HSV model of color but if all you’ve got is 1 pot, and it adjusts the hue “H”, isn’t that the expected result for most values of “S” ? That is “S” must be near zero to get white ?

http://upload.wikimedia.org/wikipedia/c … wgamma.png