I just finished making a color sensor using an RGB LED and a photocell. The code works pretty well but I used the "brute-force" method and it's quite clunky and large. I would like to find methods to make this code smaller and a bit easier to read. The main issues are the many values that are stored and read/updated, and the large code that compares these values.
The way it works is in two stages, first is calibration, and the next is the repeating loop. The calibration consists of flashing each color individually on a colored item (for three items: blue, red, and green) and storing that value. In total this creates 9 values.
The next step is the loop that flashes the colors, reads the values for each flash, and compares these to the stored ones to determine what color the object is.
I believe my professor who made his own version used vectors or matrices for storing and comparing the values. I have no experience with vectors and matrices in Arduino and am not sure how exactly it would all work.
I am looking for methods or ways to make this code less chunky (and take up less space)
// This code uses an RGB LED and a photocell to make a color sensor for red, green, and blue objects
// During calibration, the red object is placed infront of the sensor, each color flashes once and the values
// corresponding to each color is recorded. This is repeated for the other two colors.
// In the loop, the colors flash and the sensor values for each color are then compared to a range of the
// calibration (stored) values. All new read values must be within the range for the determined color to return a valid color
#define SENSOR A3 // define pins for LEDs and sensor
#define BLUELED A2
#define GREENLED 8
#define REDLED 11
int redvalred = 0; // initialize integers for sensor values
int greenvalred = 0;
int bluevalred = 0;
int redvalgreen = 0;
int greenvalgreen = 0;
int bluevalgreen = 0;
int redvalblue = 0;
int greenvalblue = 0;
int bluevalblue = 0;
int redvaltest = 0;
int greenvaltest = 0;
int bluevaltest = 0;
void setup() {
pinMode(REDLED, OUTPUT); // setting the LEDs as outputs
pinMode(GREENLED, OUTPUT);
pinMode(BLUELED, OUTPUT);
digitalWrite(REDLED, HIGH); // turning the LEDs off
digitalWrite(GREENLED, HIGH);
digitalWrite(BLUELED, HIGH);
Serial.begin(9600); // open the serial monitor
calibrate(); // calling the calibrate function in setup to only run once
} // end of setup
void loop() {
test(); // calling the test function
} // end of loop
void calibrate() {
delay(3000); // time for first object to be placed infront of the sensor
digitalWrite(REDLED, LOW); // turn one color on, read and store sensor value. this is repeated for the red object but the next two LED colors
delay(50);
redvalred = analogRead(SENSOR);
digitalWrite(REDLED, HIGH);
digitalWrite(GREENLED, LOW);
delay(50);
greenvalred = analogRead(SENSOR);
digitalWrite(GREENLED, HIGH);
digitalWrite(BLUELED, LOW);
delay(50);
bluevalred = analogRead(SENSOR);
digitalWrite(BLUELED, HIGH);
delay(5000);
digitalWrite(REDLED, LOW); // reapted code but for green object
delay(50);
redvalgreen = analogRead(SENSOR);
digitalWrite(REDLED, HIGH);
digitalWrite(GREENLED, LOW);
delay(50);
greenvalgreen = analogRead(SENSOR);
digitalWrite(GREENLED, HIGH);
digitalWrite(BLUELED, LOW);
delay(50);
bluevalgreen = analogRead(SENSOR);
digitalWrite(BLUELED, HIGH);
delay(5000);
digitalWrite(REDLED, LOW); // repeated code but for blue object
delay(50);
redvalblue = analogRead(SENSOR);
digitalWrite(REDLED, HIGH);
digitalWrite(GREENLED, LOW);
delay(50);
greenvalblue = analogRead(SENSOR);
digitalWrite(GREENLED, HIGH);
digitalWrite(BLUELED, LOW);
delay(50);
bluevalblue = analogRead(SENSOR);
digitalWrite(BLUELED, HIGH);
delay(5000);
} // end of calibration
void test() {
digitalWrite(REDLED, LOW); // similar to calibration code but values are the test values
delay(50);
redvaltest = analogRead(SENSOR);
digitalWrite(REDLED, HIGH);
digitalWrite(GREENLED, LOW);
delay(50);
greenvaltest = analogRead(SENSOR);
digitalWrite(GREENLED, HIGH);
digitalWrite(BLUELED, LOW);
delay(50);
bluevaltest = analogRead(SENSOR);
digitalWrite(BLUELED, HIGH);
// comparing the test values to a range of the calibration values.
if (((redvaltest <= (redvalred*1.1)) && (redvaltest >= (redvalred*0.9)))
&& ((greenvaltest <= (greenvalred*1.1)) && (greenvaltest >= (greenvalred*0.9)))
&& ((bluevaltest <= (bluevalred*1.1)) && (bluevaltest >= (bluevalred*0.9)))) {
Serial.println("Red");
}
else {
if (((redvaltest <= (redvalgreen*1.1)) && (redvaltest >= (redvalgreen*0.9)))
&& ((greenvaltest <= (greenvalgreen*1.1)) && (greenvaltest >= (greenvalgreen*0.9)))
&& ((bluevaltest <= (bluevalgreen*1.1)) && (bluevaltest >= (bluevalgreen*0.9)))) {
Serial.println("Green");
}
else {
if (((redvaltest <= (redvalblue*1.1)) && (redvaltest >= (redvalblue*0.9)))
&& ((greenvaltest <= (greenvalblue*1.1)) && (greenvaltest >= (greenvalblue*0.9)))
&& ((bluevaltest <= (bluevalblue*1.1)) && (bluevaltest >= (bluevalblue*0.9)))) {
Serial.println("Blue");
}
else {
Serial.println("???");
}
}
}
delay(1000);
} // end of test