Correlate RGB Value with a changing variable

I want to link a speed (MPH) value to an RGB value for an LED. The goal is to have the RGB’s fade from color to color depending on the value of MPH. The speed readings are coming from a bike so the MPH value doesn’t get much greater than 40 MPH. Every 10 MPH the color will fade either one of the R,G, or B values up from 0 to 255, and fade down another value from 255 to 0 fading between colors as speed changes.

My idea was to have two byte variables with values of 0 to 255 that would change according to MPH and would be placed in the setColor() function which sets an RGB LED to an RGB value. Every 10 MPH (0-10, 11-21, 22-33, 34-44) I want to assign a value from 0-255. For example if the LED was set to be (255,0,0) at 0 MPH, from 0-10 MPH red values could decrease from 255 to 0 and simultaneously blue values increase from 0-255. From 11-21 MPH the blues could deacrease from 255 to 0 and simultaneously the green values could increase from 0 to 255. This would give the effect of the color fading from red to blue to green as the speed increases.

BTW A lot of this code is written to find bike speed using a reed switch and a magnet on the spokes of the wheel to measure wheel revolutions. Everything I am talking about is in void loop()

I do not know what way I should link both the variables rgbValueUp and rgbValueDown to the MPH variable.
As you can see I didn’t know what to write for rgbValueUp and rgbValueDown in the code. Any help would be very much appreciated.

int redPin = 11;
int greenPin = 10;
int bluePin = 9;

int reedPin = A0;

int MPH = 0;
float speedometer = 0;

long reedTime = 0;
int reedTimeDelta = 0;
boolean reedOn = false;

float wheelC = 215.5;   //circumference of wheel in centimeters

byte rgbValueUp;  //put into r,g, or b value in void setColor() to increase that value
byte rgbValueDown; //put into r,g, or b value in void setColor() to increase that value 



void setup()
{
Serial.begin(9600);
}

void loop()
{

rgbValueUp = 0; //??? must  increase as MPH increases
rgbValueDown = 0; //??? must decrease as MPH increases

if (MPH >= 0 && MPH <= 10) {


//between 0 and 10 MPH fade from red to blue
//As MPH increases: red value decreases from 255 to 0 and blue value increases from 0 to 255
//fully red at 0 MPH and fully blue at 10 MPH 
 
  setColor(rgbValueDown, rgbValueUp, 0);  



} else if (MPH > 10 && MPH <= 20) {


//between 10 and 20 MPH fade from blue to green
//As MPH increases between 10 and 20MPH: blue value decrease from 255 to 0 and green value //increases from 0 to 255
//fully blue at 10 MPH and fully green at 20 MPH

  setColor(0, rgbValueDown, rgbValueUp);  

  
}                                         
}


//sets the LED to an RGB value
void setColor (byte red, byte green, byte blue)
{
  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);
}




void checkSpeed() {

  speedometer = wheelC / reedTimeDelta;  //velocity = distance/time
  MPH = speedometer * 22.369;  //convesion from centimeters per milisecond to MPH
  
  int r = digitalRead(reedPin);
  if (r == 1 && reedOn == false) {
    reedOn = true;
    reedTimeDelta = millis() - reedTime;
    reedTime = millis();
  }
  else if (r == 0 && reedOn) {
    reedOn = false;
  }
  if (MPH < 1) {
    speedometer = 0;
  }
  Serial.println(MPH);
}

The setColor() function takes a red value, a green value, and a blue value.

Naming the variables using in the call rgbValueUp and rgbValueDown does not make sense. There is nothing about rgbValueUp that indicates that it holds a red value and there is nothing about rgbValueDown that indicates that it holds a green value in this call:

  setColor(rgbValueUp, rgbValueDown, 0);

You need to create a table. For MPH = 0, you want to show some color. For MPH = 1, you want to show some color. Populate the table for all values of MPH. Then, we might be able to help you determine a pattern.

You need to create a table. For MPH = 0, you want to show some color. For MPH = 1, you want to show some color. Populate the table for all values of MPH. Then, we might be able to help you determine a pattern.

What do you mean by a table? Do you mean make an array of RGB values for every single mile per hour from 0-40?

Thank you for your suggestion!

You can't code for something undefined. You have to know exactly what behaviour you expect, translate that into mathematical and logical terms, and then code. If you are asking for a second party's help, you also have to explain what you expect, very explicitly.

"link" something to something means many different things, depending on the interpretation.

So, how do you want the colours to change for different speeds?

The reasoning for rgbValueUp and rgbValueDown was to have a variable that could be placed inside setColor() in order easily change which colors correlate with which speeds.

rgbValueUp is supposed to start at 0 and rise to 255 on a 20 MPH interval. In other words each increasing mile per hour rgbValueUp increase approx 13 units (255/20).

rgbValueDown would start at 255 and decrease to 0 units on a 20 MPH interval meaning each MPH increase, rgbValueDown decreases by 13 units (255/20) until it reaches 0 units when MPH reaches the maximum MPH of the color sequence’s 20 MPH threshold.

By threshold I mean that every 20 MPH rgbValueUp moves from 0 to 255 and rgbValueDown moves from 255 to 0.

For example: If I wanted to fade from (0,0,255) to (0,255,0) in other words blue to green, between 0 and 20 MPH I would write in the code

if (MPH >= 0 && MPH <= 20) {


setColor(0,rgbValueUp,rgbValueDown); 

//for 0 MPH its all blue and at 20 its all green. green increases to 255 and blue decreases to 0

}

the point of these variables is so that colors that correspond with speed could easily be changed. It could just as easily go from red to blue

if (MPH >= 0 && MPH <= 20 {


setColor(rgbValueDown, 0, rgbValueUp); 

//at 0 MPH its all red and at 20 its all blue. red decreases to 0 and blue increases to 255

}

rgbValueUp and rgbValueDown is not color specific.

I just do not know how integrate the MPH variable into the variable declaration of rgbValueUp or rgbValueDown in order to assign a 0 to 255 number to it.

I just wanted to restate my thought process and hopefully clear up any confusion, but if I am tackling this obstacle in an inefficient way or you have any suggestions, please let me know!
:slight_smile:

Perhaps a floating modulo function would be handy:

float mod20 (float f)
{
  int i = ((int)floor (f)) / 20 * 20 ;
  return f-i ;
}

Then you can convert to suitable values:

(int) (mod20(speed) * 255 / 20.0)

or

(int) (255 - mod20(speed) * 255 / 20.0)

Can you please explain what you mean by a floating modulo function and how it would work? Thank you for your input!

-Skyler

Can you please explain what you mean by a floating modulo function

It's a modulo function that operates on floats.

and how it would work?

Just like the modulo operator operates on ints.