//------------------------Variable declaration & initialization----------------------------//
// For onboard LED //
#define ledPin 2
// For user input //
bool canRun1, canCalibrate, canCalibrate2;
int caliPos, cali2Input_1, cali2Input_2, cali2Input_3;
// For color sensor //
String mainColor;
//---------------------------------Callback functions-------------------------------------//
//---------------------------------------Setup-------------------------------------------//
void setup() {
Serial.begin(115200);
Serial.printf("______________________Setup starts_________________________\n");
pinMode(ledPin , OUTPUT);
Serial.printf("______________________Setup completes_________________________\n");
}
//----------------------------------------Loop--------------------------------------------//
void loop() {
UserInput();
if (canRun1 == true){
}
}
void UserInput(){
if (Serial.available()) {
String input_str = Serial.readString();
input_str.trim(); // remove "/n"
Serial.printf("You entered: %s\n" , input_str);
int input_int = input_str.toInt();
if (input_str != "0" && input_int == 0){
// input_str.toInt() will return 0 if input_str is not an integer .
return;
}
if (canCalibrate){
Calibrate(input_int);
canCalibrate = false;
return;
}
else if (canCalibrate2){
caliPos++;
canCalibrate2 = (caliPos != 3);
Calibrate2(input_int);
return;
}
switch (input_int){
case 0:
Serial.printf("Stop running\n");
canRun1 = false;
break;
case 1:
Serial.printf("Start running\n");
canRun1 = true;
break;
case 2:
Serial.printf("Enter your value for calibration:\n");
canCalibrate = true;
break;
case 3:
Serial.printf("Enter your value for calibration:\n");
Serial.printf("Enter red value:\n");
canCalibrate2 = true; caliPos = 0;
break;
default:
break;
}
}
}
void Calibrate(int num1){
switch (num1) {
case (1):
DefineColor(142, 93, 128);
break;
default:
break;
}
}
void Calibrate2(int num1){
switch (caliPos) {
case (1):
cali2Input_1 = num1;
Serial.printf("Enter green value:\n");
break;
case (2):
cali2Input_2 = num1;
Serial.printf("Enter blue value:\n");
break;
case (3):
cali2Input_3 = num1;
DefineColor(cali2Input_1, cali2Input_2, cali2Input_3);
break;
default:
break;
}
}
//--------------------------------Self-defined functions------------------------------------//
void DefineColor(int redVal, int greenVal, int blueVal){
Serial.printf("Original (R,G,B) = (%d, %d, %d)\n", redVal, greenVal, blueVal);
int avg = (redVal + greenVal + float(blueVal))/3;
Serial.printf("Average: %d\n", avg);
if (IsErrorAccept(redVal, avg) && IsErrorAccept(greenVal, avg) && IsErrorAccept(blueVal, avg)){
if (avg > 160){
mainColor = "white";
}
else if (avg > 80){
mainColor = "grey";
}
else{
mainColor = "black";
}
Serial.printf("Main color: %s\n", mainColor);
return;
}
// Define the largest, second largest and smallest number . //
int num1, num2, num3; // num1: smallest | num3: largest
if (redVal == greenVal){ // if any 2 values are equal .
if (redVal > blueVal){
redVal = 255;
greenVal = 255;
}
else{
redVal = 0;
greenVal = 0;
blueVal = 255;
}
}
else if (redVal == blueVal){
if (redVal > greenVal){
redVal = 255;
blueVal = 255;
}
else{
redVal = 0;
blueVal = 0;
greenVal = 255;
}
}
else if (greenVal == blueVal){
if (greenVal > redVal){
greenVal = 255;
blueVal = 255;
}
else{
greenVal = 0;
blueVal = 0;
redVal = 255;
}
}
else{
// Find the smallest number . //
int numList[] = {0, 0, 0, 0};
if ((redVal < greenVal) && (redVal < blueVal)){
num1 = redVal;
numList[1] = 1;
}
else if ((greenVal < redVal) && (greenVal < blueVal)){
num1 = greenVal;
numList[2] = 1;
}
else{
num1 = blueVal;
numList[3] = 1;
}
// Find the largest number . //
if ((redVal > greenVal) && (redVal > blueVal)){
num3 = redVal;
numList[1] = 3;
}
else if ((greenVal > redVal) && (greenVal > blueVal)){
num3 = greenVal;
numList[2] = 3;
}
else{
num3 = blueVal;
numList[3] = 3;
}
// Find the second largest number . //
if ((num1 < redVal) && (redVal < num3)){
num2 = redVal;
numList[1] = 2;
}
else if ((num1 < greenVal) && (greenVal < num3)){
num2 = greenVal;
numList[2] = 2;
}
else{
num2 = blueVal;
numList[3] = 2;
}
Serial.printf("num1: %d, num2: %d, num3: %d\n", num1, num2, num3);
num2 = num2 - num1 * ((num3 - num2) / (num3 - float(num1))); // remove white factor .
Serial.printf("White-filtered num2: %d\n", num2);
num2 = 255 * (num2 / float(num3)); // remove black factor .
Serial.printf("Black-filtered num2: %d\n", num2);
// Get the pure hue which has no white and black components . //
redVal = NewValue(1, num2, numList);
greenVal = NewValue(2, num2, numList);
blueVal = NewValue(3, num2, numList);
}
Serial.printf("Complete-filtered (R,G,B) = (%d, %d, %d)\n", redVal, greenVal, blueVal);
/*
Define color
yellow: (200~255, 255, 0) ~ (255, 255~200, 0)
orange: (255, 200~50, 0)
red: (255, 50~0, 0) ~ (255, 0, 0~100)
purple: (255, 0, 200~255) ~ (255~50, 0, 255)
blue: (50~0, 0, 255) ~ (0, 0~200, 255)
green: (0, 255, 150~0) ~ (0~200, 255, 0)
*/
if ((((redVal >= 200) && (redVal <= 255)) &&
(greenVal == 255) &&
(blueVal == 0)) ||
((redVal == 255) &&
((greenVal >= 200) && (greenVal <= 255)) &&
(blueVal == 0))){
mainColor = "yellow";
// yellow: (200~255, 255, 0) ~ (255, 255~200, 0)
}
else if ((redVal == 255) &&
((greenVal >= 50) && (greenVal <= 200))
&& (blueVal == 0)){
mainColor = "orange";
// orange: (255, 200~50, 0)
}
else if (((redVal == 255) &&
((greenVal >= 0) && (greenVal <= 50)) &&
(blueVal == 0)) ||
((redVal == 255) &&
(greenVal == 0) &&
((blueVal >= 0) && (blueVal <= 100)))){
mainColor = "red";
// red: (255, 50~0, 0) ~ (255, 0, 0~100)
}
else if (((redVal == 255) &&
(greenVal == 0) &&
((blueVal >= 200) && (blueVal <= 255))) ||
(((redVal >= 50) && (redVal <= 255)) &&
(greenVal == 0) &&
(blueVal == 255))){
mainColor = "purple";
// purple: (255, 0, 200~255) ~ (255~50, 0, 255)
}
else if ((((redVal >= 0) && (redVal <= 50)) &&
(greenVal == 0) &&
(blueVal == 255)) ||
((redVal == 0) &&
((greenVal >= 0) && (greenVal <= 200)) &&
(blueVal == 255))){
mainColor = "blue";
// blue: (50~0, 0, 255) ~ (0, 0~200, 255)
}
else if (((redVal == 0) &&
(greenVal == 255) &&
((blueVal >= 0) && (blueVal <= 150))) ||
(((redVal >= 0) && (redVal <= 200)) &&
(greenVal == 255) &&
(blueVal == 0))){
mainColor = "green";
// green: (0, 255, 150~0) ~ (0~200, 255, 0)
}
else{
mainColor = "undefined";
}
Serial.printf("Main color: %s\n", mainColor);
}
bool IsErrorAccept(int num1, int avg){
int error = abs(avg - num1)/float(avg)*100;
Serial.printf("Target number: %d, Error: %d%%\n", num1, error);
if (error > 10){
return false;
}
else{
return true;
}
}
int NewValue(int pos, int num2, int numList[]){
int val;
switch (numList[pos]) {
case (1):
val = 0;
break;
case (2):
val = num2;
break;
case (3):
val = 255;
break;
default:
break;
}
return val;
}