From 6e2bfef2f6099793f8a59b6331366b2ca6e09247 Mon Sep 17 00:00:00 2001 From: Daniel Qu <danielq987@gmail.com> Date: Mon, 16 Oct 2023 03:00:23 -0400 Subject: [PATCH] Refactor color sensor code to separate file --- include/color.h | 37 ++++++++++++ include/settings.h | 22 +------ src/color.cpp | 119 ++++++++++++++++++++++++++++++++++++ src/main.cpp | 147 ++------------------------------------------- 4 files changed, 163 insertions(+), 162 deletions(-) create mode 100644 include/color.h create mode 100644 src/color.cpp diff --git a/include/color.h b/include/color.h new file mode 100644 index 0000000..a56a205 --- /dev/null +++ b/include/color.h @@ -0,0 +1,37 @@ +#include <Arduino.h> + +#define LEFT_RED_HUE_THRESHOLD 8 +#define RIGHT_RED_HUE_THRESHOLD 8 + +typedef struct +{ + float r; + float g; + float b; +} Rgb; + +typedef struct +{ + Rgb min = Rgb{0, 0, 0}; + Rgb max = Rgb{255, 255, 255}; +} ColorSensorCal; + +typedef enum +{ + CALIBRATE_BLACK, + CALIBRATE_WHITE, + CALIBRATE_READY, +} CalibrationState; + +extern CalibrationState calibration_state; + +void setupColorSensor(); + +void printRGB(const Rgb &value); + +void getColorValues(Rgb &left_value, Rgb &right_value); + +float computeHue(const Rgb &rgb); + +void calibrateBlack(); +void calibrateWhite(); diff --git a/include/settings.h b/include/settings.h index 4b40548..20bf354 100644 --- a/include/settings.h +++ b/include/settings.h @@ -9,21 +9,7 @@ #define LEFT_MOTOR_SPEED 25 #define RIGHT_MOTOR_SPEED 25 -typedef struct { - float R; - float G; - float B; -} Rgb; - -typedef struct { - Rgb min = Rgb{0, 0, 0}; - Rgb max = Rgb{255, 255, 255}; -} ColorSensorCal; - -void printRGB(const Rgb& value); void checkButtonPress(); -void getColorValues(Rgb& left_value, Rgb& right_value); -float computeHue(const Rgb& rgb); // mode 0(default) - break, 1 - coast void motorLeftForward(int speed, bool mode = 0); @@ -34,10 +20,4 @@ void motorRightBackward(int speed, bool mode = 0); typedef enum { MODE_BREAK, MODE_COAST -} MotorMode; - -typedef enum { - CALIBRATE_BLACK, - CALIBRATE_WHITE, - CALIBRATE_READY, -} CalibrationState; +} MotorMode; \ No newline at end of file diff --git a/src/color.cpp b/src/color.cpp new file mode 100644 index 0000000..2a3021b --- /dev/null +++ b/src/color.cpp @@ -0,0 +1,119 @@ +#include <Arduino.h> +#include "color.h" +#include "Adafruit_TCS34725.h" + +// Initiate color sensor instances +static Adafruit_TCS34725 color_sensor_left = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_24MS, TCS34725_GAIN_4X); +static Adafruit_TCS34725 color_sensor_right = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_24MS, TCS34725_GAIN_4X); + +static TwoWire Wire2 = TwoWire(PC9, PA8); // I2C channel 3 for right sensor + +// Change this to CALIBRATE_READY if no calibration is required +CalibrationState calibration_state = CALIBRATE_BLACK; + +static ColorSensorCal color_cal_left; +static ColorSensorCal color_cal_right; + +void printRGB(const Rgb &value) +{ + Serial.print("R:"); + Serial.print(int(value.r)); + Serial.print(" G:"); + Serial.print(int(value.g)); + Serial.print(" B:"); + Serial.print(int(value.b)); +} + +void getColorValues(Rgb &left_value, Rgb &right_value) +{ + // Turn on LEDs + color_sensor_left.setInterrupt(false); + color_sensor_right.setInterrupt(false); + // Delay 50ms to read + delay(24); + color_sensor_left.getRGB(&left_value.r, &left_value.g, &left_value.b); + color_sensor_right.getRGB(&right_value.r, &right_value.g, &right_value.b); + // Turn off LEDs + color_sensor_left.setInterrupt(true); + color_sensor_right.setInterrupt(true); + + if (calibration_state == CALIBRATE_READY) + { + // Calibrate left color value + left_value.r = constrain(map(left_value.r, color_cal_left.min.r, color_cal_left.max.r, 0, 255), 0, 255); + left_value.g = constrain(map(left_value.g, color_cal_left.min.g, color_cal_left.max.g, 0, 255), 0, 255); + left_value.b = constrain(map(left_value.b, color_cal_left.min.b, color_cal_left.max.b, 0, 255), 0, 255); + + // Calibrate right color value + right_value.r = constrain(map(right_value.r, color_cal_right.min.r, color_cal_right.max.r, 0, 255), 0, 255); + right_value.g = constrain(map(right_value.g, color_cal_right.min.g, color_cal_right.max.g, 0, 255), 0, 255); + right_value.b = constrain(map(right_value.b, color_cal_right.min.b, color_cal_right.max.b, 0, 255), 0, 255); + } +} + +float computeHue(const Rgb &rgb) +{ + float red = rgb.r / 255; + float green = rgb.g / 255; + float blue = rgb.b / 255; + + float max_component = max(max(red, green), blue); + float min_component = min(min(red, green), blue); + + float hue; + + float diff = max_component - min_component; + + if (max_component == red) + { + hue = (green - blue) / (diff) + (green < blue ? 6.0 : 0); + } + else if (max_component == green) + { + hue = (blue - red) / (diff) + 2.0; + } + else + { + hue = (red - green) / (diff) + 4.0; + } + + return hue * 60; +} + +void setupColorSensor() +{ + // Color sensor setup + // Left sensor on pins SDA=D14 SCK=D15 (default I2C channel 1) + if (color_sensor_left.begin()) + { + Serial.println("Found left color sensor"); + } + else + { + Serial.println("Left color sensor not found"); + while (1) + ; + } + + // Right sensor on pins SDA=PC9 SCK=PA8 + if (color_sensor_right.begin(TCS34725_ADDRESS, &Wire2)) + { + Serial.println("Found right color sensor"); + } + else + { + Serial.println("Right color sensor not found"); + while (1) + ; + } +}; + +void calibrateBlack() +{ + getColorValues(color_cal_left.min, color_cal_right.max); +} + +void calibrateWhite() +{ + getColorValues(color_cal_left.max, color_cal_right.max); +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 32da901..e52ebd4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,24 +2,12 @@ #include <Wire.h> #include "settings.h" #include "Adafruit_TCS34725.h" - -// Color sensor -Adafruit_TCS34725 color_sensor_left = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_24MS, TCS34725_GAIN_60X); -Adafruit_TCS34725 color_sensor_right = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_24MS, TCS34725_GAIN_60X); -TwoWire Wire2 = TwoWire(PC9, PA8); // I2C channel 3 for right sensor +#include "color.h" bool prev_button_state = true; // nominal high int prev_button_press_time = 0; bool enable_line_follow = false; -bool enable_calibration = false; // Applies calibration on the rgb values -CalibrationState calibration_state = CALIBRATE_BLACK; - -int left_red_threshold = 8; -int right_red_threshold = 8; - -ColorSensorCal color_cal_left; -ColorSensorCal color_cal_right; void setup() { @@ -31,49 +19,13 @@ void setup() pinMode(MOTOR_RIGHT_PIN_2, OUTPUT); pinMode(USER_BTN, INPUT); - // Color sensor setup - // Left sensor on pins SDA=D14 SCK=D15 (default I2C channel 1) - if (color_sensor_left.begin()) - { - Serial.println("Found left color sensor"); - } - else - { - Serial.println("Left color sensor not found"); - while (1) - ; // halt! - } - - // Right sensor on pins SDA=PC9 SCK=PA8 - if (color_sensor_right.begin(TCS34725_ADDRESS, &Wire2)) - { - Serial.println("Found right color sensor"); - } - else - { - Serial.println("Right color sensor not found"); - while (1) - ; // halt! - } + setupColorSensor(); } void loop() { checkButtonPress(); - // For testing motor - // int motor_speed = map(ir_left_value, 0, 1023, 0, 255); - // Serial.println(motor_speed); - - // For testing motor - // if (!enable_line_follow) { - // motorLeftForward(LEFT_MOTOR_SPEED); - // motorRightForward(RIGHT_MOTOR_SPEED); - // } else { - // motorLeftBackward(LEFT_MOTOR_SPEED); - // motorRightBackward(RIGHT_MOTOR_SPEED); - // } - // Color sensor code Rgb left_color = {}; Rgb right_color = {}; @@ -95,33 +47,12 @@ void loop() Serial.print(int(right_hue)); printRGB(right_color); - // Serial.print(" Left min "); - // printRGB(color_cal_left.min); - // Serial.print(" Left max "); - // printRGB(color_cal_left.max); - // Serial.print(" Right min "); - // printRGB(color_cal_right.min); - // Serial.print(" Right max "); - // printRGB(color_cal_right.max); - Serial.print("\n"); // Enable line following if (enable_line_follow) { - // if (left_color.R < left_red_threshold) { - // motorLeftForward(LEFT_MOTOR_SPEED); - // } else { - // motorLeftForward(0); - // } - - // if (right_color.R < right_red_threshold) { - // motorRightForward(RIGHT_MOTOR_SPEED); - // } else { - // motorRightForward(0); - // } - - if (left_red_error > left_red_threshold) + if (left_red_error > LEFT_RED_HUE_THRESHOLD) { motorLeftForward(LEFT_MOTOR_SPEED); } @@ -130,7 +61,7 @@ void loop() motorLeftForward(0); } - if (right_red_error > right_red_threshold) + if (right_red_error > RIGHT_RED_HUE_THRESHOLD) { motorRightForward(RIGHT_MOTOR_SPEED); } @@ -141,16 +72,6 @@ void loop() } } -void printRGB(const Rgb &value) -{ - Serial.print("R:"); - Serial.print(int(value.R)); - Serial.print(" G:"); - Serial.print(int(value.G)); - Serial.print(" B:"); - Serial.print(int(value.B)); -} - // Check user button press void checkButtonPress() { @@ -171,7 +92,7 @@ void checkButtonPress() { // Calibrate black Serial.print("Calibrating black"); - getColorValues(color_cal_left.min, color_cal_right.min); + calibrateBlack(); // Transition to calibrate white calibration_state = CALIBRATE_WHITE; } @@ -179,7 +100,7 @@ void checkButtonPress() { // Calibrate white Serial.print("Calibrating white"); - getColorValues(color_cal_left.max, color_cal_right.max); + calibrateWhite(); // Transition to ready state calibration_state = CALIBRATE_READY; } @@ -187,62 +108,6 @@ void checkButtonPress() prev_button_state = current_button_state; } -void getColorValues(Rgb &left_value, Rgb &right_value) -{ - // Turn on LEDs - color_sensor_left.setInterrupt(false); - color_sensor_right.setInterrupt(false); - // Delay 50ms to read - delay(24); - color_sensor_left.getRGB(&left_value.R, &left_value.G, &left_value.B); - color_sensor_right.getRGB(&right_value.R, &right_value.G, &right_value.B); - // Turn off LEDs - color_sensor_left.setInterrupt(true); - color_sensor_right.setInterrupt(true); - - if (calibration_state == CALIBRATE_READY) - { - // Calibrate left color value - left_value.R = constrain(map(left_value.R, color_cal_left.min.R, color_cal_left.max.R, 0, 255), 0, 255); - left_value.G = constrain(map(left_value.G, color_cal_left.min.G, color_cal_left.max.G, 0, 255), 0, 255); - left_value.B = constrain(map(left_value.B, color_cal_left.min.B, color_cal_left.max.B, 0, 255), 0, 255); - - // Calibrate right color value - right_value.R = constrain(map(right_value.R, color_cal_right.min.R, color_cal_right.max.R, 0, 255), 0, 255); - right_value.G = constrain(map(right_value.G, color_cal_right.min.G, color_cal_right.max.G, 0, 255), 0, 255); - right_value.B = constrain(map(right_value.B, color_cal_right.min.B, color_cal_right.max.B, 0, 255), 0, 255); - } -} - -float computeHue(const Rgb &rgb) -{ - float red = rgb.R / 255; - float green = rgb.G / 255; - float blue = rgb.B / 255; - - float max_component = max(max(red, green), blue); - float min_component = min(min(red, green), blue); - - float hue; - - float diff = max_component - min_component; - - if (max_component == red) - { - hue = (green - blue) / (diff) + (green < blue ? 6.0 : 0); - } - else if (max_component == green) - { - hue = (blue - red) / (diff) + 2.0; - } - else - { - hue = (red - green) / (diff) + 4.0; - } - - return hue * 60; -} - // Left motor void motorLeftForward(int speed, bool mode) { -- GitLab