Jump to content
43oh

RGB to HSV Conversion with MSP430G2231 - Help!


Recommended Posts

 

BLANK and XLAT latches data that is already in TLC's buffer and restarts PWM, this part must be perfectly timed. updateTLC sends data to TLC only when it is necessary, otherwise TLC will use whatever it already has in it's buffer.

So do you think the problem is with the value of timercounter when updateTLC() is called?

Because at the moment the code is running and it looks as though the same data is being used multiple times in a row before new data is being clocked in.

For example, its going  R ,Y, G R,Y ,G, R,Y, G     then its going Y,G,Y,G,Y, G and so on.

The rest of the code is modified to your original one:

TACTL = TASSEL_2 + MC_1 + ID_3; // SMCLK, up mode, /8 changed from ID_0;
...
void main(void)
{
	setup....

	_bis_SR_register(GIE);

	for(;
	{
			if (hue < 60)
			{
				HSV2RGB(&leds[z],&leds[z+8],&leds[z+16],hue,sat,val); // z = 0, sat, val = 255;
			}
			else if (hue...)
			.
                        .     
			.
			else
			{
				hue = 0;
			}
		hue++;
		_bis_SR_register(LPM0_bits);
	}
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A0(void)
{
	static const int Cnt = 0x08; // 0x08 when sat is 255
	// 4096 GS clock cycles have been generated, time to restart PWM
	P1OUT |= (BLANK_PIN);
	P1OUT |= (XLAT_PIN);
	P1OUT &= ~(XLAT_PIN);
	P1OUT &= ~(BLANK_PIN);
	// increase timer counter
	timerCounter++;
	if (timerCounter == Cnt) { // is it time to for next frame?
		updateTLC();			 // data was already prepared by main loop when it was awake last time
		timerCounter = 0;
		_bic_SR_register_on_exit(LPM0_bits); // wake up main loop so that it can prepare data for the next frame
	}
}
Link to post
Share on other sites
  • Replies 35
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Crash course pointers in C:   C only knows to types of things: 1) values 2) pointers every variable you use is either of these types, most primitive types are called-by-value for example a charac

G2231 (2K flash) is a bad choice of chip for this. Try a G2553 (16K flash) or maybe G2452 (8K flash).   Sent from my C3PO via Tapatalk    

If this is your full code (what are you trying to do in bounce()?), you don't need a full-lfedged HSV2RGB function     for( hue = 0 ; hue < 360 ; hue ++) // this is where the problem lies!      

Are you sure you are not overflowing some of your values?

Put the break point in HSV2RGB and see what's going on.

 

Here for example,

*r *= v;
*g *= v;
*b *= v;

or here

	unsigned char i, p, q, t;
	unsigned char fs;

	if (h < 60) i = 0;
	else if (h < 120) i = 1;
	else if (h < 180) i = 2;
	else if (h < 240) i = 3;
	else if (h < 300) i = 4;
	else if (h < 360) i = 5;
	else return;

	fs = ((h - i * 60) * s)/ 60;

FYI, here are two examples which use 8/16 bit RGB

http://www.ruinelli.ch/rgb-to-hsv

http://code.google.com/p/streumix-frei0r-goodies/wiki/Integer_based_RGB_HSV_conversion

Link to post
Share on other sites

I could kiss you on the mouth RobG! Since *r,*g and *b were being multiplied by 255 they were obviously becoming too large.

Shorts are 2 bytes aren't they? so 2^16 = 65536. Therefore in order for *r to stay within that it'd have to be below 65536/255 = 257. Correct me if I'm wrong (which I probably am :P) but isn't the max value of *r approx 4095?

Well using that calculation I've deduced that 65536/4095 = 16.004 therefore:

// seems to work, so my leds are cycling through the colour wheel at an acceptable brightness
*r *= v/25; // divided by 25 because it is slightly brighter than G and B
*g *= v/16;
*b *= v/16;
Link to post
Share on other sites

Good to hear.

Now when you have your function fixed, try speeding things up by changing TACTL's ID_x and timerCounter.

Try to figure out how many cycles are needed, HSV2RGB about 450, times 8 LEDs, ~4000. 

@16MHz that's 250us. You have 8 rows, 2ms, that would let you do 500fps!

Now you have to figure out how many cycles it takes to updateTLC, but I think you should be OK.

Link to post
Share on other sites

Sorry, my bad. I had assumed you used the timer to drive PWM out of the MSP directly, those support 16-bits. Ofcourse your shift register supports only 8 bits values, for which my suggested alterations did not account.

I think *r is in the range 0-255 before multiplying with v. So you should (in theory) multiply by v/255. however, that is always 0 except for v==255.

Maybe using

unsigned short R;

// do the fancy calculations, but with R instead of *r

R *= v;

*r = R / 256;

 

Will give you better results without resorting to expensive floating point code again.

 

Yet again, sorry or throwing you off like this.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...