Created
February 4, 2020 06:08
-
-
Save ericyd/2f54b4702ae0c3b851d656cce7d9c6d0 to your computer and use it in GitHub Desktop.
Arduino LEDs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Basically, an experiment right now | |
*/ | |
bool const DEBUG_NEXT_VALUE = false; | |
bool const DEBUG_CALCULATE_NEXT_VALUES = false; | |
struct RGB | |
{ | |
double r; | |
double g; | |
double b; | |
}; | |
class RGBFactory { | |
int nMax, nMin, saturationMax, saturationMin, range; | |
double rChannelOffset, gChannelOffset, bChannelOffset; | |
public: | |
RGBFactory(int xMin, int xMax, int satMin, int satMax) { | |
// define basic parameters | |
nMax = xMax; | |
nMin = xMin; | |
saturationMax = satMax; | |
saturationMin = satMin; | |
double n6th = (nMax - nMin) / 6; | |
double n12th = n6th / 2; | |
range = saturationMax - saturationMin; | |
// define each channel offset | |
rChannelOffset = n6th * 2 - n12th; | |
gChannelOffset = n6th * 6 - n12th; | |
bChannelOffset = n6th * 4 - n12th; | |
} | |
RGB calculateNextValues(double n) { | |
RGB rgb; | |
rgb.r = clip(rangeAdjust(position(n, rChannelOffset))); | |
rgb.b = clip(rangeAdjust(position(n, bChannelOffset))); | |
rgb.g = clip(rangeAdjust(position(n, gChannelOffset))); | |
if (DEBUG_CALCULATE_NEXT_VALUES) { | |
Serial.println("n: " + String(n) + "; rChannelOffset: " + String(rChannelOffset) + "; position(n, rChannelOffset): " + position(n, rChannelOffset) + "; rangeAdjust(...)" + rangeAdjust(position(n, rChannelOffset)) + "; clip(...):" + clip(rangeAdjust(position(n, rChannelOffset)))); | |
} | |
return rgb; | |
} | |
private: | |
// transformers convert the number to a channel value | |
// where a channel is one of red, green, or blue | |
double clip(double x) { | |
if (x < saturationMin) { | |
return double(saturationMin); | |
} | |
if (x > saturationMax) { | |
return double(saturationMax); | |
} | |
return x; | |
} | |
// range adjustment is slightly non-standard because sine functions can be negative | |
double rangeAdjust(double x) { | |
return double(x * double(range) + saturationMin + range) / 2; | |
} | |
// calculate the points position on a sine curve, where | |
// `x` is the input number that is being transformed | |
// `offset` is the phase offset of the point in the sine curve | |
// `nMax` is the wave amplitude | |
// `2 * PI` is the frequency in radians | |
// Ref: https://en.wikipedia.org/wiki/Sine_wave | |
double position(double x, double offset) { | |
return sin((2 * PI / nMax) * (x + offset)); | |
} | |
}; | |
int const RED_POT_PIN = A2; | |
int const GREEN_POT_PIN = A1; | |
int const BLUE_POT_PIN = A0; | |
int const RED_OUT_PIN = 3; | |
int const GREEN_OUT_PIN = 5; | |
int const BLUE_OUT_PIN = 6; | |
double nextValue; | |
double currentVal = 0; | |
unsigned long now; | |
unsigned long timeDifference = 0; | |
unsigned long lastTime = 0; | |
int slowDownFactor = 100; // name it like it is, right? | |
RGBFactory factory(0, 1000, 0, 255); | |
RGB nextRgb; | |
void setup() | |
{ | |
pinMode(RED_OUT_PIN, OUTPUT); | |
pinMode(GREEN_OUT_PIN, OUTPUT); | |
pinMode(BLUE_OUT_PIN, OUTPUT); | |
if (DEBUG_NEXT_VALUE || DEBUG_CALCULATE_NEXT_VALUES) { | |
Serial.begin(9600); | |
} | |
} | |
void loop() | |
{ | |
if (analogRead(BLUE_POT_PIN) > 500) { | |
// time-based | |
nextValue = analogRead(RED_POT_PIN); | |
now = millis(); | |
timeDifference = now - lastTime; | |
lastTime = now; | |
// pseudo code | |
currentVal = currentVal + (sqrt(double(timeDifference) * nextValue / slowDownFactor)); | |
// for time-based sweep through rainbox | |
nextRgb = factory.calculateNextValues(currentVal); | |
} else { | |
nextValue = analogRead(GREEN_POT_PIN); | |
// for manual sweep through rainbow | |
nextRgb = factory.calculateNextValues(nextValue); | |
} | |
if (DEBUG_NEXT_VALUE) { | |
Serial.println(String(nextValue) + " : " + String(nextRgb.r) + " : " + String(nextRgb.g) + " : " + String(nextRgb.b)); | |
} | |
analogWrite(RED_OUT_PIN, nextRgb.r); | |
analogWrite(GREEN_OUT_PIN, nextRgb.g); | |
analogWrite(BLUE_OUT_PIN, nextRgb.b); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment