RGB Module

Our range of tiny modules are designed to make it easy for you to quickly add functionality to your projects. [Module List]
Marcwolf
Posts:14
Joined:Thu Dec 08, 2011 2:20 am
RGB Module

Post by Marcwolf » Thu Dec 08, 2011 2:53 am

Hi.
In the PDF you mention about chaining the modules together.
Can you indicate via code how to select multiple modules

i.e.
2 Modules A & B
I want to turn on the red led in Module A, and the green one in Module B. How can I select A & B for the various commands.

Many thanks
Dave

User avatar
jonoxer
Freetronics Staff
Freetronics Staff
Posts:298
Joined:Sat Oct 15, 2011 11:31 am
Location:Melbourne, Australia
Contact:

Re: RGB Module

Post by jonoxer » Thu Dec 08, 2011 4:52 am

The example code only addresses a single module, but it can be extended quite easily to support multiple modules.

Near the top you'll see a line like this:

Code: Select all

#define STRIP_LENGTH 1 // Number of RGBLED modules connected
Change that number to suit. Oh, and when I was just looking at the example sketch to answer this question I discovered that I made a little mistake in it that would stop it working with more than 2 modules, so I've just fixed that! I had a line that read like this:

Code: Select all

for(int LED_number = 0; LED_number < 2; LED_number++)
What it should have said is this:

Code: Select all

for(int LED_number = 0; LED_number < STRIP_LENGTH; LED_number++)
Oops. Sorry!

The next thing to change depends on the end result you want to achieve. If all you want to do is drive the same colour to all modules in the string, you're done. The example code (with that minor fix above) should do the job, because it loops on the number of modules and pushes the colour out that many times to "step" them down the string.

If you want to drive different colours to each module in a string it's a little more work.

One basic concept to understand here is that the modules "daisy-chain" together, so that data you send into the first module ripples though from the output of the first module into the input of the second, and so on. You can think of it as a linear queue: you push something in one end, and everything else is pushed one step further along the queue. You can't "address" individual modules in a "I want to write colour X directly to module Y" style, you need to instead maintain a "frame" of colour values so that each slot in the frame corresponds to one module and you push the whole frame out to the string. If you want to change the colour of one specific module, you change the corresponding slot in the frame and then push it all out again.

I don't have example code to post for that right now (I don't have any hardware with me to test with, either), but Nathan Seidle has done almost exactly the same thing and you can see his example code here to drive random colours to a string of RGB LEDs:

http://www.sparkfun.com/datasheets/Comp ... xample.pde

That example code works just fine with our RGB LED module.

So for your specific requirement, I'd start with our example code and set the STRIP_LENGTH value to 2, then make a couple of changes in the "post_frame" function. You could either remove the loop in the function so that it only executes once, or as a quick hack you could change it so that the loop always finishes after one iteration like this:

Code: Select all

for(int LED_number = 0; LED_number < 1; LED_number++)
Then, in "loop()", you could do this:

Code: Select all

post_frame(1);  // Green
post_frame(0);  // Red
Remember that you're pushing values into a queue, so the first one you push will end up on the second module. If you want the first module red and the second module green, you need to push green first and then red so they end up on the correct modules.

You'd also need to remove the existing post_frame call and the incrementing frame position, but exactly what you do there will depend on the logic you need for driving this.

I hope that helps!
--
Jon

Marcwolf
Posts:14
Joined:Thu Dec 08, 2011 2:20 am

Re: RGB Module

Post by Marcwolf » Thu Dec 08, 2011 11:30 am

Hi Jon
Many many thanks for the extensive reply.

Sadly it looks like these modules will not do what I need. Which is a shame because they are very small and compact. I can still salvage them by removing the SMD from the back and interfacing directly with the LED

What I am trying to do is to make up a set of 'eyes' for an animatronic costume. these eyes can display 3 colors and 'blink' on and off to add realism. Because the colors will indicate the mood of the character I need to have better control than to ripple the colors though one eye to the next.

Again thanks for your help. I look forward to working with some of the other modules I have brought,. They are really great at making little projects out of.

Take Care
Dave

User avatar
jonoxer
Freetronics Staff
Freetronics Staff
Posts:298
Joined:Sat Oct 15, 2011 11:31 am
Location:Melbourne, Australia
Contact:

Re: RGB Module

Post by jonoxer » Fri Dec 09, 2011 12:07 am

Don't despair, I don't think you'll need to hack the modules: they can still do exactly what you need. When I said that the colours "ripple" from one module to the next, I didn't mean that it happens slowly: while the modules are receiving data they don't change their output, so if you have, say, 2 modules in a string and you want to change both their colours, you just crank out the two messages one after the other as I showed in that sketch and both modules will switch to the new colours as soon as comms takes a pause of more than 500uS (microseconds). So you'd never see it: both modules will change simultaneously.

So in your case the simplest thing would be to keep 2 local variables, one holding the colour for each eye. Then your program can change the values of those variables at will, and whenever you need to do an update you just call "post_frame()" twice in a row with the two values. Job done.

Or, a totally different way of doing it (but unnecessary) would be to connect them to separate digital pins and drive them in isolation to each other.

In short: the modules will do exactly what you're wanting.
--
Jon

Marcwolf
Posts:14
Joined:Thu Dec 08, 2011 2:20 am

Re: RGB Module

Post by Marcwolf » Fri Dec 09, 2011 12:28 am

Hi Jon
Many thanks for the advice. I'll give it a try
Take care
Dave

Michael
Posts:2
Joined:Sun Feb 12, 2012 9:07 pm

Re: RGB Module

Post by Michael » Sun Feb 12, 2012 9:18 pm

Hi everyone,
I have another question regarding the RGBLED: Full Color RGB LED Modules. Is it possible to vary the brightness of a particular LED module so that fading can be achieved? If so, how can this be implemented?

Michael

andrewduncan
Posts:24
Joined:Tue Dec 06, 2011 1:42 am
Location:Melbourne, AU

Re: RGB Module

Post by andrewduncan » Mon Feb 13, 2012 2:50 am

Hi Micheal, The colour and brightness of the module are set by the three (red, green and blue) primary colours. These colours are packed into a long variable. The byte order is 0xRRGGBB where RR is the red brightness, GG is the green brightness and BB is the blue brightness.

As an example I have hacked the example from the getting started page to fade from bright red to black. Hope that helps!

Code: Select all

int CKI = 2;
int SDI = 3;
int colour_id = 0;

#define STRIP_LENGTH 1 // Number of RGBLED modules connected
long strip_colors[16] = {
  0xFF0000,
  0xEE0000,
  0xDD0000,
  0xCC0000,
  0xBB0000,
  0xAA0000,
  0x990000,
  0x880000,
  0x770000,
  0x660000,
  0x550000,
  0x440000,
  0x330000,
  0x220000,
  0x110000,
  0x000000 };

void setup() {
  pinMode(SDI, OUTPUT);
  pinMode(CKI, OUTPUT);
}

void loop() {
  post_frame(colour_id); //Push the current color frame to the strip
  colour_id++;
  if(colour_id == 16) {
    colour_id = 0;
  }
  delay(100);
}

void post_frame (int colour_id) {
  for(int LED_number = 0; LED_number < STRIP_LENGTH; LED_number++)
  {
    long this_led_color = strip_colors[colour_id]; //24 bits of color data

    for(byte color_bit = 23 ; color_bit != 255 ; color_bit--) {
      //Feed color bit 23 first (red data MSB)

      digitalWrite(CKI, LOW); //Only change data when clock is low

      long mask = 1L << color_bit;
      //The 1'L' forces the 1 to start as a 32 bit number, otherwise it defaults to 16-bit.

      if(this_led_color & mask) 
        digitalWrite(SDI, HIGH);
      else
        digitalWrite(SDI, LOW);

      digitalWrite(CKI, HIGH); //Data is latched when clock goes high
    }
  }

  //Pull clock low to put strip into reset/post mode
  digitalWrite(CKI, LOW);
  delayMicroseconds(500); //Wait for 500us to go into reset
}

Michael
Posts:2
Joined:Sun Feb 12, 2012 9:07 pm

Re: RGB Module

Post by Michael » Tue Feb 14, 2012 2:26 am

Thankyou very much for your explanation and example code, that really helps.

lhalha
Posts:4
Joined:Sat Jun 09, 2012 1:22 pm

Re: RGB Module

Post by lhalha » Thu Jun 14, 2012 11:49 am

andrewduncan wrote: As an example I have hacked the example from the getting started page to fade from bright red to black. Hope that helps!
What I'm trying to do is programatically loop through every value 0-255 for each colour so I can get some nice clean fades happening. Basically I am making a sound pressure meter - I already have a nice one working with green, amber and red LEDs (using the very cool freetronics sound pressure meter).

The best I can get to work at the moment is simply incrementing the hex value:

strip_colors[0] = 0xFF0000;
strip_colors[0] ++ ;

but all this does is increment the blue bits. I'm having trouble working out how to increment hex values.

What I want to be able to do is produce a "lamp" containing a single RGB LED module that glows and pumps green / amber / red according to the sound pressure level.

Maybe this is mathematically impractical if there is no smooth transition from green to red. Maybe I need to be going from off to white?

User avatar
Simon
Posts:25
Joined:Wed May 02, 2012 2:40 am

Re: RGB Module

Post by Simon » Thu Jun 14, 2012 12:05 pm

lhalha wrote:The best I can get to work at the moment is simply incrementing the hex value:

strip_colors[0] = 0xFF0000;
strip_colors[0] ++ ;

but all this does is increment the blue bits. I'm having trouble working out how to increment hex values.
I assume that hex value is RGB, each colour represented by one byte?

If that's the case, incrementing by 1 each time will bring up the blue, then when you exceed 0xFF you'll overflow and increment green by one and reset blue to 0x00.

What you really want to do is something like this:

#define RED 0x010000;
#define GREEN 0x000100;
#define BLUE 0x000001;

Then you can:
strip_colors[0] += RED;
strip_colors[0] += GREEN;

etc.

This will still cause you problem when you overflow each colour from 0xFF but it's better than just incrementing by 1 each time.

Post Reply