Sunday, March 21, 2010

March Madness Challenge - Day 21

Worked on the AnnoyAltron 2000 yesterday, the RGB didn't really have good color calibration. So I'm planning to hook a Potentiometer to the RGB LED, next to a Photoresistor on an analog port for the Arduino, and measure the brightness. Then find the correct resistance needed for mixing the RGB colors.

Hmmm.... interesting maybe this could be made automatic and not need a manual override. If it appears one is brighter than another after calibration a manual setting should be possible.

Well. After a bit of work I got the basics of this running. I ran to a very interesting set of issues. The RGB led I used is common anode vs common cathode. So after a while of confusion it was resolved that LOW is on, and HIGH is off for that configuration for the Arduino. That brought up the question of why does the AnnoyLatron work at all then. Turns, out I was writing analog values to RGB led. What that did was show values from dark to bright, as opposed to on and off values. So the larger the number the dimmer it got. Smaller the number the brighter it got. It worked in inverse. So for this kind of project it didn't matter too much. I'll go look at the code a little later and see if there were any other "interesting" things in there.

Anyway, once that was resolved the rest was pretty simple, but testing it out and making sure the basics were right took a lot of time. I also ended up with a few questions like how do the analog pins sample and return the values detected. I want to confirm that it's strictly a voltage reading. Then I started worrying about noise, and calibrating the calibrator. I had a potentiometer hooked to the pin 1 next the photoresistor pin 0. I pulled that off the bread board, and the values changed to be more consistent. Also, there was light in the room. I was treating that as a constant.

Things did stabilize. So I was getting decent readings, and I got some decent data on max brightness. However, there was a real problem with the detecting minimum brightness. I figured out a few obvious issues, but some where the min is being assigned a 0, and I can't tell if that is a real reading or not. Also, once maxs and mins are found I didn't provide a way to have maxs and mins readjust overtime and experimentation. THe program needs a reset to adjust as things change. So if I do add some potentiometers to calibrate the brightness, I would need to be able to find those new values without restarting.

Not perfect but way fun.



/*
* The RGB Calibrator
*
* Find, and monitor max brightness of red, green, and blue in an RGB led
*/


int redPin = 9; // LED connected to digital pin 9
int greenPin = 11;
int bluePin = 10;
int pins[] =
{
redPin, greenPin, bluePin
};
int i =0;

int photoPin = 0;
int potPin = 1;

int photoVal = -1;
int r,g,b = -1;
int rmax, gmax, bmax = 0;
int rmin, gmin, bmin = 1024;

long interval = 500;
long previousMillis = 0;

void setup()
{
Serial.begin(19200);
Serial.println("Setup done");

pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);

digitalWrite(redPin, LOW);
delay(1000);
digitalWrite(redPin, HIGH);

digitalWrite(greenPin, LOW);
delay(1000);
digitalWrite(greenPin, HIGH);

digitalWrite(bluePin, LOW);
delay(1000);
digitalWrite(bluePin, HIGH);

}


void loop()
{
if (i > 2) //The number of LEDS being measured
{
i = 0;
}

digitalWrite(pins[i], LOW);
photoVal = analogRead(photoPin);


switch (i)
{
case 0: //red led
r = photoVal;
rmin = min(rmin, r);
rmax = max(rmax, r);
break;
case 1: //green led
g = photoVal;
gmin = min(gmin, g);
gmax = max(gmax, g);
break;
case 2: //blue led
b = photoVal;
bmin = min(bmin, b);
bmax = max(bmax, b);
break;
default: //should not happen
break;

}

Serial.print(" photoVal: ");
Serial.print(photoVal);

Serial.print(" rmax: ");
Serial.print(rmax);
Serial.print(" gmax: ");
Serial.print(gmax);
Serial.print(" bmax: ");
Serial.print(bmax);

Serial.print(" rmin: ");
Serial.print(rmin);
Serial.print(" gmin: ");
Serial.print(gmin);
Serial.print(" bmin: ");
Serial.print(bmin);

Serial.print(" r: ");
Serial.print(r);
Serial.print(" g: ");
Serial.print(g);
Serial.print(" b: ");
Serial.println(b);

if (millis() - previousMillis > interval) {
previousMillis = millis();
digitalWrite(pins[i], HIGH);
i++;
}
}

No comments: