The very first project that got me started learning about microcontrollers was LED Tetherball. It was developed as a camp project for Burning Man, an interactive game folks could engage in while they wandered the city. It was a perfect learning project that got me exploring LEDs, batteries and sensors
You can see it in action on the playa at 1:10!
If you’re interested here is the code, and a link to the GitHub project.
[code]
/* My 2nd attempt at HSB and acceleromter control. XYZ axes are added together to make a value that is then mapped to the HUE. */ const int numReadings = 25; // Sets number of readings (smoothing amount. I chose a very high number to start with) // Setting up the smoothing int int readings[numReadings]; // the readings from the analog input int index = 0; // the index of the current reading int total = 0; // the running total int average = 0; // the average int brightnessValue = 0; // store a brightness value for constraining //Analog read pins for Accelerometer const int xPin = 0; const int yPin = 1; const int zPin = 2; // Outputs for RGB channels. I am using 12v Analog RGB Tape const int ledPinRed = 3; // Red LED connected to analogue out pin const int ledPinGrn = 5; // Green LED connected to analogue out pin const int ledPinBlu = 6; // Blue LED connected to analogue out pin int accelVal = 0; // store the value coming from the accelerometer // Constants to define the ranges. const int hueRedLow = 0; const int hueRedHigh = 255; const int hueBlue = 170; // The size of the angle of one sector (1/6 of a colour wheel), and of a complete // cycle of the colour wheel. const int angleMin = 0; const int angleSector = 60; const int angleMax = 360; const int brightMin = 0; const int brightMax = 255; // Work variables. // The accelValueHue value is mapped to the range 0 to 360 (degrees). int accelValueHue; // 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; // step variable, this is the speed the hue value increases int step = 1; // placeholders for the RGB values unsigned int r, g, b; void setup() { // set a baud rate for serial monitoring Serial.begin(9600); // initialize all the readings to 0: for (int thisReading = 0; thisReading < numReadings; thisReading++) readings[thisReading] = 0; // Set LED pins to output. pinMode(ledPinRed, OUTPUT); pinMode(ledPinGrn, OUTPUT); pinMode(ledPinBlu, OUTPUT); // Poteniometer analogue pin is an input. // pinMode(accelHue, INPUT); // pinMode for accelerometer pinMode(xPin, INPUT); pinMode(yPin, INPUT); pinMode(zPin, INPUT); // TODO: mode switch in a digital input. // pinMode(modeSwitchPin, INPUT); } void loop() { //read the analog values from the accelerometer and constrain the values unsigned int xRead = analogRead(xPin); //changed from const int to unsigned just to see what happened. Not sure if this matters or not really. unsigned int yRead = analogRead(yPin); unsigned int zRead = analogRead(zPin); /* This next bit defines accelVal as an average of the X, Y and Z inputs When using HSV Hue is what moves through the color spectrum as I understand it so there's only one value that you need to adjust I am adding up the values to give a single "movement" measurement */ accelVal = (xRead+yRead+zRead); // define accelHue as accelVal constrained to 500 through 1200 // This was determined by monitoring accelVal while hitting the ball // and identifying the higest and lowest values int accelHue = constrain(accelVal, 500, 1200); // This summing section is straight from Jason's code, I don't pretend to really know all it's details // subtract the last reading: total= total - readings[index]; // read from the sensor: readings[index] = accelHue; // add the reading to the total: total= total + readings[index]; // advance to the next position in the array: index = index + 1; // if we're at the end of the array... if (index >= numReadings) // ...wrap around to the beginning: index = 0; // calculate the average: average = total / numReadings; // The accelValueHue value is mapped to degrees - 0 to 300 - so max impact would take you halfway through the spectrum accelValueHue = map(analogRead(average), 500, 1200, 0, 300); // step defined as an ever increasing value step += 1; // Taking accelValueHue and defining hue { // Colour wheel mode (red to red, wrapped around in a cycle). hue = step + map(accelValueHue, angleMin, angleMax, hueRedLow, hueRedHigh); // loops the value around if (step > 360) { step -= 360; } if (hue > 360) { hue -= 360; } // Maps the accelVal to a Brighness var, mapped to 0-255 inverted) brightnessValue = constrain(accelVal, 1200, 500); brightness = map(brightnessValue, 1200, 500, 10, 255); } // Using HSBtoRGB to send to the RGB outputs HSBToRGB(hue, saturation, brightness, &r, &g, &b); analogWrite(ledPinRed, r); analogWrite(ledPinGrn, g); analogWrite(ledPinBlu, b); //Monitoring values. 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.print(" accelVal="); Serial.print(accelVal); Serial.print(" average="); Serial.print(average); Serial.print(" accelHue="); Serial.print(accelHue); Serial.println(""); delay(50); } // Flash Function prototype void Flash() { analogWrite(brightness, 255); delay(50); analogWrite(brightness, 0); delay(50); } // HSBtoRGB function // This function taken from here: // http://eduardofv.com/read_post/179-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; } } }
[/code]
Leave a Reply
You must be logged in to post a comment.