Pages: [1]   Go Down
Author Topic: HSV to RGB conversion in Processing  (Read 1564 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 4
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a project where I'm triggering rgb led's to the beat of music. Initially I was doing it all on the arduino, with limited success, but due to time constraints I am now using the minim library in processing to do the beat detection. I have the beat detection working well now but I can't seem to get the hsv to rgb code working in processing. It seems trivial but I haven't done this sort of programming for some time. Almost thinking of just using the arduino to do hsv to rgb as it was working on there. 

Here is the code below, the hsv to rgb part is based on https://processing-js.lighthouseapp.com/projects/41284/tickets/788-hsv-to-rgb-function
Any help would be greatly appreciated.

Code:
import processing.serial.*;
import cc.arduino.*;
import ddf.minim.*;
import ddf.minim.analysis.*;

Arduino arduino;
int ledPinRed = 6;
int ledPinBlue = 7;
int ledPinGreen = 8;
int delayVal = 50;
int blnFade = 0;
int h_int;

int R=0, G=0, B=0;
int var_i;
float S=1, V, lightness, var_1, var_2, var_3, var_h, var_r, var_g, var_b;
float H;
float L =0.5;
float val = 0;


Minim minim;
AudioInput in;
BeatDetect beat;
 
float eRadius;

void setup()
{
//    println(Arduino.list());
  arduino = new Arduino(this, Arduino.list()[4], 57600);
  arduino.pinMode(ledPinBlue, Arduino.OUTPUT);
  minim = new Minim(this);
  // get a line in from Minim, default bit depth is 16
  in = minim.getLineIn(Minim.STEREO, 512);
  // a beat detection object song SOUND_ENERGY mode with a sensitivity of 10 milliseconds
  beat = new BeatDetect();
}

void draw()
{
    beat.detect(in.mix);

  if ( beat.isOnset() ) {
    int val = Math.round(random(360));
    hsvl2rgb(val, L, R, G, B);
 
    arduino.analogWrite(ledPinRed, R);
    arduino.analogWrite(ledPinBlue, G);
    arduino.analogWrite(ledPinGreen, B);
    delay(50);
  }
  else {
    //arduino.digitalWrite(ledPinBlue, Arduino.HIGH);
  }
}

void hsvl2rgb(float H, float L, int R, int G, int B)
{
  int var_i;
  float S=1, V, lightness, var_1, var_2, var_3, var_h, var_r, var_g, var_b;

  V = L * 2;                         // For the "darkness" of the LED
  if ( V > 1 ) V = 1;

  if ( S == 0 )                      //HSV values = 0 ÷ 1
  {
    R = Math.round(V * 255);
    G = Math.round(V * 255);
    B = Math.round(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 ;
    }

    if ( L > 0.5 )         // Adjusting the Lightness (whiteness)
    {
      lightness = ( L - 0.5 ) / 0.5;
      var_r += ( lightness * ( 1 - var_r ) );
      var_g += ( lightness * ( 1 - var_g ) );
      var_b += ( lightness * ( 1 - var_b ) );
    }

    R = Math.round((1-var_r) * 255);     // RGB results = 0 ÷ 255. Reversed for common anode RGB LED's
    G = Math.round((1-var_g) * 255);
    B = Math.round((1-var_b) * 255);
  }
}
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8967
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your global variables R, G, and B are passed into the function by value.  Your function has separate R, G and B variables that are not connected to the global variables.  Changing them in the function has no effect on the values of the variables passed in. 

You have two choices:  use the globals, not function arguments, or pass the variables by reference.

Using the globals:
Code:
int R=0, G=0, B=0;

void draw()
{
    hsvl2rgb(val, L);
 
    arduino.analogWrite(ledPinRed, R);
    arduino.analogWrite(ledPinBlue, G);
    arduino.analogWrite(ledPinGreen, B);
  }

void hsvl2rgb(float H, float L)
{
  int var_i;
  float S=1, V, lightness, var_1, var_2, var_3, var_h, var_r, var_g, var_b;

  V = L * 2;                         // For the "darkness" of the LED
  if ( V > 1 ) V = 1;

  if ( S == 0 )                      //HSV values = 0 ÷ 1
  {
    R = Math.round(V * 255);
    G = Math.round(V * 255);
    B = Math.round(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 ;
    }

    if ( L > 0.5 )         // Adjusting the Lightness (whiteness)
    {
      lightness = ( L - 0.5 ) / 0.5;
      var_r += ( lightness * ( 1 - var_r ) );
      var_g += ( lightness * ( 1 - var_g ) );
      var_b += ( lightness * ( 1 - var_b ) );
    }

    R = Math.round((1-var_r) * 255);     // RGB results = 0 ÷ 255. Reversed for common anode RGB LED's
    G = Math.round((1-var_g) * 255);
    B = Math.round((1-var_b) * 255);
  }
}


Pass by reference.  Changed the argument names to make it clearer that they are not the globals.
Code:
int R=0, G=0, B=0;

void draw()
{
    hsvl2rgb(val, L, R, G, B);
 
    arduino.analogWrite(ledPinRed, R);
    arduino.analogWrite(ledPinBlue, G);
    arduino.analogWrite(ledPinGreen, B);
  }

void hsvl2rgb(float H, float L, int &argR, int &argG, int &argB)
{
  int var_i;
  float S=1, V, lightness, var_1, var_2, var_3, var_h, var_r, var_g, var_b;

  V = L * 2;                         // For the "darkness" of the LED
  if ( V > 1 ) V = 1;

  if ( S == 0 )                      //HSV values = 0 ÷ 1
  {
    argR = Math.round(V * 255);
    argG = Math.round(V * 255);
    argB = Math.round(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 ;
    }

    if ( L > 0.5 )         // Adjusting the Lightness (whiteness)
    {
      lightness = ( L - 0.5 ) / 0.5;
      var_r += ( lightness * ( 1 - var_r ) );
      var_g += ( lightness * ( 1 - var_g ) );
      var_b += ( lightness * ( 1 - var_b ) );
    }

    argR = Math.round((1-var_r) * 255);     // RGB results = 0 ÷ 255. Reversed for common anode RGB LED's
    argG = Math.round((1-var_g) * 255);
    argB = Math.round((1-var_b) * 255);
  }
}
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Pages: [1]   Go Up
Jump to: