diff --git a/.vscode/extensions.json b/.vscode/extensions.json
deleted file mode 100644
index 080e70d08b9811fa743afe5094658dba0ed6b7c2..0000000000000000000000000000000000000000
--- a/.vscode/extensions.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-    // See http://go.microsoft.com/fwlink/?LinkId=827846
-    // for the documentation about the extensions.json format
-    "recommendations": [
-        "platformio.platformio-ide"
-    ],
-    "unwantedRecommendations": [
-        "ms-vscode.cpptools-extension-pack"
-    ]
-}
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index dc21fb8fd05fcdae6b30dbb054561d3409cc93b7..0000000000000000000000000000000000000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-    "files.associations": {
-        "optional": "cpp",
-        "istream": "cpp",
-        "ostream": "cpp",
-        "system_error": "cpp",
-        "array": "cpp",
-        "functional": "cpp",
-        "tuple": "cpp",
-        "type_traits": "cpp",
-        "utility": "cpp"
-    }
-}
\ No newline at end of file
diff --git a/include/settings.h b/include/settings.h
index 76575f25fa433c30d876e67afc3aa5b990bbdb51..4b40548bcdd25bee074fb35577ff20e828976bc9 100644
--- a/include/settings.h
+++ b/include/settings.h
@@ -16,13 +16,14 @@ typedef struct {
 } Rgb;
 
 typedef struct {
-  Rgb min = Rgb{255, 255, 255};
-  Rgb max = Rgb{0, 0, 0};
+  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,3 +35,9 @@ typedef enum {
     MODE_BREAK,
     MODE_COAST
 } MotorMode;
+
+typedef enum {
+    CALIBRATE_BLACK,
+    CALIBRATE_WHITE,
+    CALIBRATE_READY,
+} CalibrationState;
diff --git a/src/main.cpp b/src/main.cpp
index 455b0e0b3467747c4c84df8c917e69a7c14e1c3e..32da9013f26e8de0a5c3ff73a884ae06e073cb4a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -4,185 +4,307 @@
 #include "Adafruit_TCS34725.h"
 
 // Color sensor
-Adafruit_TCS34725 color_sensor_left = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_24MS, TCS34725_GAIN_4X);
-Adafruit_TCS34725 color_sensor_right = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_24MS, TCS34725_GAIN_4X);
+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
 
 bool prev_button_state = true; // nominal high
 int prev_button_press_time = 0;
 
 bool enable_line_follow = false;
-int calibration_state = -1; // 0 - black, 1 - white, -1 - calibration disabled
+bool enable_calibration = false; // Applies calibration on the rgb values
+CalibrationState calibration_state = CALIBRATE_BLACK;
 
-int left_red_threshold = 95;
-int right_red_threshold = 95;
+int left_red_threshold = 8;
+int right_red_threshold = 8;
 
 ColorSensorCal color_cal_left;
 ColorSensorCal color_cal_right;
 
-void setup() {
-  Serial.begin(115200);
-
-  pinMode(MOTOR_LEFT_PIN_1, OUTPUT);
-  pinMode(MOTOR_LEFT_PIN_2, OUTPUT);
-  pinMode(MOTOR_RIGHT_PIN_1, OUTPUT);
-  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!
-  }
+void setup()
+{
+    Serial.begin(115200);
+
+    pinMode(MOTOR_LEFT_PIN_1, OUTPUT);
+    pinMode(MOTOR_LEFT_PIN_2, OUTPUT);
+    pinMode(MOTOR_RIGHT_PIN_1, OUTPUT);
+    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!
+    }
 }
 
-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 = {};
-  getColorValues(left_color, right_color);
- 
-  // Serial.print("Left ");
-  // printRGB(left_color);
-  // Serial.print("\t");
-  // Serial.print("Right "); 
-  // printRGB(right_color);
-  // 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);
-    }
-  }
+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 = {};
+    getColorValues(left_color, right_color);
+
+    float left_hue = computeHue(left_color);
+    float right_hue = computeHue(right_color);
 
+    float left_red_error = left_hue > 180 ? 360 - left_hue : left_hue;
+    float right_red_error = right_hue > 180 ? 360 - right_hue : right_hue;
+
+    Serial.print("Left ");
+    printRGB(left_color);
+    Serial.print(" Hue: ");
+    Serial.print(int(left_hue));
+    Serial.print(" ");
+    Serial.print("Right ");
+    Serial.print("Hue: ");
+    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)
+        {
+            motorLeftForward(LEFT_MOTOR_SPEED);
+        }
+        else
+        {
+            motorLeftForward(0);
+        }
+
+        if (right_red_error > right_red_threshold)
+        {
+            motorRightForward(RIGHT_MOTOR_SPEED);
+        }
+        else
+        {
+            motorRightForward(0);
+        }
+    }
 }
 
-void printRGB(const Rgb& value) {
-  Serial.print("R:"); Serial.print(int(value.R));
-  Serial.print("\tG:"); Serial.print(int(value.G));
-  Serial.print("\tB:"); Serial.print(int(value.B));
+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() {
-  bool current_button_state = digitalRead(USER_BTN);
-  
-  // Trigger on falling edge
-  if(prev_button_state && !current_button_state && (millis() - prev_button_press_time > DEBOUNCE_TIME_MS)) {
-    prev_button_press_time = millis();
-    Serial.print("Pressed: ");
-    enable_line_follow = !enable_line_follow;
-  }
-  prev_button_state = current_button_state;
-
-  // calibration code
-  if(calibration_state == 0) {
-    // Calibrate black
-    Serial.print("Calibrating black; ");
-    getColorValues(color_cal_left.min, color_cal_right.min);
-    // Transition to calibrate white
-    calibration_state = 1;
-  } else if (calibration_state == 1) {
-    // Calibrate white
-    getColorValues(color_cal_left.max, color_cal_right.max);
-    // Transition back to calibrate black next button press
-    calibration_state = 0;
-  }
+void checkButtonPress()
+{
+    bool current_button_state = digitalRead(USER_BTN);
+
+    // Trigger on falling edge
+    if (prev_button_state && !current_button_state && (millis() - prev_button_press_time > DEBOUNCE_TIME_MS))
+    {
+        prev_button_press_time = millis();
+        Serial.print("Pressed: ");
+        if (calibration_state == CALIBRATE_READY)
+        {
+            enable_line_follow = !enable_line_follow;
+        }
+
+        // calibration code
+        if (calibration_state == CALIBRATE_BLACK)
+        {
+            // Calibrate black
+            Serial.print("Calibrating black");
+            getColorValues(color_cal_left.min, color_cal_right.min);
+            // Transition to calibrate white
+            calibration_state = CALIBRATE_WHITE;
+        }
+        else if (calibration_state == CALIBRATE_WHITE)
+        {
+            // Calibrate white
+            Serial.print("Calibrating white");
+            getColorValues(color_cal_left.max, color_cal_right.max);
+            // Transition to ready state
+            calibration_state = CALIBRATE_READY;
+        }
+    }
+    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 24ms 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);
+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) {
-  if (!mode) {
-    // Break
-    analogWrite(MOTOR_LEFT_PIN_1, 255);
-    analogWrite(MOTOR_LEFT_PIN_2, 255-speed);
-  } else {
-    // Coast
-    analogWrite(MOTOR_LEFT_PIN_1, 0);
-    analogWrite(MOTOR_LEFT_PIN_2, speed);
-  }
+void motorLeftForward(int speed, bool mode)
+{
+    if (!mode)
+    {
+        // Break
+        analogWrite(MOTOR_LEFT_PIN_1, 255);
+        analogWrite(MOTOR_LEFT_PIN_2, 255 - speed);
+    }
+    else
+    {
+        // Coast
+        analogWrite(MOTOR_LEFT_PIN_1, 0);
+        analogWrite(MOTOR_LEFT_PIN_2, speed);
+    }
 }
 
-void motorLeftBackward(int speed, bool mode) {
-  if (!mode) {
-    // Break
-    analogWrite(MOTOR_LEFT_PIN_2, 255);
-    analogWrite(MOTOR_LEFT_PIN_1, 255-speed);
-  } else {
-    // Coast
-    analogWrite(MOTOR_LEFT_PIN_2, 0);
-    analogWrite(MOTOR_LEFT_PIN_1, speed);
-  }
+void motorLeftBackward(int speed, bool mode)
+{
+    if (!mode)
+    {
+        // Break
+        analogWrite(MOTOR_LEFT_PIN_2, 255);
+        analogWrite(MOTOR_LEFT_PIN_1, 255 - speed);
+    }
+    else
+    {
+        // Coast
+        analogWrite(MOTOR_LEFT_PIN_2, 0);
+        analogWrite(MOTOR_LEFT_PIN_1, speed);
+    }
 }
 
 // Right motor
-void motorRightForward(int speed, bool mode) {
-  if (!mode) {
-    // Break
-    analogWrite(MOTOR_RIGHT_PIN_1, 255);
-    analogWrite(MOTOR_RIGHT_PIN_2, 255-speed);
-  } else {
-    // Coast
-    analogWrite(MOTOR_RIGHT_PIN_1, 0);
-    analogWrite(MOTOR_RIGHT_PIN_2, speed);
-  }
+void motorRightForward(int speed, bool mode)
+{
+    if (!mode)
+    {
+        // Break
+        analogWrite(MOTOR_RIGHT_PIN_1, 255);
+        analogWrite(MOTOR_RIGHT_PIN_2, 255 - speed);
+    }
+    else
+    {
+        // Coast
+        analogWrite(MOTOR_RIGHT_PIN_1, 0);
+        analogWrite(MOTOR_RIGHT_PIN_2, speed);
+    }
 }
 
-void motorRightBackward(int speed, bool mode) {
-  if (!mode) {
-    // Break
-    analogWrite(MOTOR_RIGHT_PIN_2, 255);
-    analogWrite(MOTOR_RIGHT_PIN_1, 255-speed);
-  } else {
-    // Coast
-    analogWrite(MOTOR_RIGHT_PIN_2, 0);
-    analogWrite(MOTOR_RIGHT_PIN_1, speed);
-  }
+void motorRightBackward(int speed, bool mode)
+{
+    if (!mode)
+    {
+        // Break
+        analogWrite(MOTOR_RIGHT_PIN_2, 255);
+        analogWrite(MOTOR_RIGHT_PIN_1, 255 - speed);
+    }
+    else
+    {
+        // Coast
+        analogWrite(MOTOR_RIGHT_PIN_2, 0);
+        analogWrite(MOTOR_RIGHT_PIN_1, speed);
+    }
 }
\ No newline at end of file