/* RGB cycle using an ultrasonic sensor. Author: Bryan Vermaat - 2016 See http://www.instructables.com/id/RGB-Distance-Dependant-Light for a usage of this code. This code is publicly available and may be edited/altered */ // The three primary colour LEDs, driven as analgue outputs (actually PWM, but // close enough for our analogue eyes). const int ledPinRed = 11; // Red LED connected to analogue out pin const int ledPinGrn = 10; // Green LED connected to analogue out pin const int ledPinBlu = 9; // Blue LED connected to analogue out pin const int trigPin = 13; const int echoPin = 12; //const int modeSwitchPin = 12; // The Hue potentiometer goes on an analogue pin, taking the pin from // 0V to 5V. const int potPinHue = 0; // Constants to define the ranges. const int hueRedLow = 0; const int hueRedHigh = 255; const int hueBlue = 170; // The minimal and maximal range for the ultrasonic sensor. const int rangeMin = 0; const int rangeMax = 200; const int brightMin = 0; const int brightMax = 255; // Work variables. // The potentiometer value is mapped to the range 0 to 360 (degrees). int valueHue; // The hue is the range 0 (red) to 170 (blue) in rainbow // mode or 255 (red) in colour wheel mode. // The brightness ranges from 0 (dark) to 255 (full brightness) int hue, brightness; // The saturation is fixed at 255 (full) to remove blead-through of different // colours. // It could be linked to another potentiometer if a demonstration of hue // is desired. const int saturation = 255; // The brightess of each LED (0 to 255). unsigned int r, g, b; void setup() { // Still need to set a baud rate, even for USB. Serial.begin(9600); // Set LED pins to output. pinMode(ledPinRed, OUTPUT); pinMode(ledPinGrn, OUTPUT); pinMode(ledPinBlu, OUTPUT); // Set the pins for the ultrasonic sensor. pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); } void loop() { // The Hue potentiometer value is mapped to degrees - 0 to 360 - for convenience. valueHue = map(MeasureDistance(), 0, 1023, 0, rangeMax); // Colour wheel mode (red to red, wrapped around in a cycle). hue = map(valueHue, rangeMin, rangeMax, hueRedLow, hueRedHigh); // The brightness is fixed at full for the colour wheel. This could be // linked to another poteniometer if that is a concept you wish to // demonstrate. brightness = 255; // Do the conversion. HSBToRGB(hue, saturation, brightness, &r, &g, &b); analogWrite(ledPinRed, r); analogWrite(ledPinGrn, g); analogWrite(ledPinBlu, b); Serial.print(" bright="); Serial.print(brightness); Serial.print(" hue="); Serial.print(hue); Serial.print(" red="); Serial.print(r); Serial.print(" green="); Serial.print(g); Serial.print(" blue="); Serial.print(b); Serial.println(""); delay(50); } // This function taken from here: // http://eduardofv.com/2011/01/15/arduino-rgb-led-hsv-color-wheel/ void HSBToRGB( unsigned int inHue, unsigned int inSaturation, unsigned int inBrightness, unsigned int *oR, unsigned int *oG, unsigned int *oB ) { if (inSaturation == 0) { // achromatic (grey) *oR = *oG = *oB = inBrightness; } else { unsigned int scaledHue = (inHue * 6); unsigned int sector = scaledHue >> 8; // sector 0 to 5 around the color wheel unsigned int offsetInSector = scaledHue - (sector << 8); // position within the sector unsigned int p = (inBrightness * ( 255 - inSaturation )) >> 8; unsigned int q = (inBrightness * ( 255 - ((inSaturation * offsetInSector) >> 8) )) >> 8; unsigned int t = (inBrightness * ( 255 - ((inSaturation * ( 255 - offsetInSector )) >> 8) )) >> 8; switch( sector ) { case 0: *oR = inBrightness; *oG = t; *oB = p; break; case 1: *oR = q; *oG = inBrightness; *oB = p; break; case 2: *oR = p; *oG = inBrightness; *oB = t; break; case 3: *oR = p; *oG = q; *oB = inBrightness; break; case 4: *oR = t; *oG = p; *oB = inBrightness; break; default: // case 5: *oR = inBrightness; *oG = p; *oB = q; break; } } } // Function to measure the distance using an HC-SR04 ultrasonic sensor long MeasureDistance(){ long duration, distance; digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = (duration/2) / 29.1; if (distance >= rangeMax || distance <= rangeMin){ Serial.println(" Out of set range. returning Max."); return rangeMax; } else { Serial.print(distance); Serial.println(" cm"); return distance; } }