See http://mbed.org/users/allanw/notebook/controlling-high-power-rgb-led/

Dependencies:   mbed

main.cpp

Committer:
allanw
Date:
2010-11-02
Revision:
0:d18d3df9f06d

File content as of revision 0:d18d3df9f06d:

#include "mbed.h"
#include <cmath>

#define PERIOD 2000

float analog_avg(AnalogIn ain, int samples);
float exp_curve(float x, float a);
void HSVtoRGB( float *r, float *g, float *b, float h, float s, float v );

AnalogIn pot(p20);
PwmOut red(p23);
PwmOut green(p21);
PwmOut blue(p22);
PwmOut sync(p25);
DigitalOut out1(p30);

int main() {
    int period = PERIOD;
    float r, g, b;
    
    red.period_us(period);
    green.period_us(period);
    blue.period_us(period);
    sync.period_us(period);
    sync.pulsewidth_us(period/2);
    while (1) {
        /*float h = pot * 360.0f;
        HSVtoRGB(&r, &g, &b, h, 1, 0.1);
        red.pulsewidth_us(r * PERIOD);
        green.pulsewidth_us(g * PERIOD);
        blue.pulsewidth_us(b * PERIOD);*/
        
        for (float h = 0; h < 360; h += 0.1) {
            out1 = 1;
            out1 = 0;
            HSVtoRGB(&r, &g, &b, h, 1, exp_curve(analog_avg(pot,3), 4));
            
            red.pulsewidth_us(exp_curve(r,1.5) * PERIOD);
            green.pulsewidth_us(exp_curve(g,1.5) * PERIOD);
            blue.pulsewidth_us(exp_curve(b,1.5) * PERIOD);
            
            wait_us(1000);
        }
    }
}

float analog_avg(AnalogIn ain, int samples) {
    int sum = 0;
    
    for (int i = 0; i < samples; i++) {
        sum += ain.read_u16();
    }
    
    return (sum / samples) / ((float)0xFFFF);
}    
    
// returns a value between 0.0 and 1.0 for an input x of 0.0 to 1.0
// a affects how "exponential" this curve will be
float exp_curve(float x, float a) {
    return (exp(x*a)-1)/(exp(a) - 1);
}


void HSVtoRGB( float *r, float *g, float *b, float h, float s, float v )
{
	int i;
	float f, p, q, t;
	if( s == 0 ) {
		// achromatic (grey)
		*r = *g = *b = v;
		return;
	}
	h /= 60;			// sector 0 to 5
	i = floor( h );
	f = h - i;			// factorial part of h
	p = v * ( 1 - s );
	q = v * ( 1 - s * f );
	t = v * ( 1 - s * ( 1 - f ) );
	switch( i ) {
		case 0:
			*r = v;
			*g = t;
			*b = p;
			break;
		case 1:
			*r = q;
			*g = v;
			*b = p;
			break;
		case 2:
			*r = p;
			*g = v;
			*b = t;
			break;
		case 3:
			*r = p;
			*g = q;
			*b = v;
			break;
		case 4:
			*r = t;
			*g = p;
			*b = v;
			break;
		default:		// case 5:
			*r = v;
			*g = p;
			*b = q;
			break;
	}
}