Skip to content

Instantly share code, notes, and snippets.

@fxprime
Created July 1, 2025 17:03
Show Gist options
  • Save fxprime/4fa50b9eb515ab95b3cf2eddd3c0bebc to your computer and use it in GitHub Desktop.
Save fxprime/4fa50b9eb515ab95b3cf2eddd3c0bebc to your computer and use it in GitHub Desktop.
ตัวอย่างโค้ดสำหรับการใช้งาน TCS3200 Sensor บน ESP32 พร้อมการปรับเทียบเซ็นเซอร์เพื่อให้สามารถอ่านค่าสีได้อย่างแม่นยำ
/**
* ตัวอย่างโค้ดสำหรับการใช้งาน TCS3200 Sensor บน ESP32
* พร้อมการปรับเทียบเซ็นเซอร์เพื่อให้สามารถอ่านค่าสีได้อย่างแม่นยำ
*
* วิธีการต่อสาย:
* | ESP32 Pin | TCS3200 Pin |
* |------------|-------------|
* | 3.3v | Vcc |
* | GND | GND |
* | 3.3v | LED |
* | 3.3V | S0 |
* | GND | S1 |
* | 26 | S2 |
* | 25 | S3 |
* | 14 | OUT |
*
* วิธีการใช้งาน:
* 1. เชื่อมต่อสายตามตารางด้านบน
* 2. อัพโหลดโค้ดนี้ไปยัง ESP32
* 3. เปิด Serial Monitor ที่ baudrate 115200
* 4. กด 'y' เพื่อเริ่มการปรับเทียบเซ็นเซอร์ โดยวางเซ็นเซอร์บนพื้นผิวสีขาว
* 5. กด 'n' เพื่อข้ามการปรับเทียบ
* 6. เซ็นเซอร์จะเริ่มอ่านค่าสีและแสดงผลใน Serial Monitor
* หมายเหตุ: ค่าที่อ่านได้จะถูกปรับเทียบตามการปรับเทียบที่ทำไว้
* ค่าที่แสดงใน Serial Monitor จะประกอบด้วย:
* - Clear: ค่าความสว่างโดยรวม
* - Red: ค่าความเข้มของสีแดง
* - Green: ค่าความเข้มของสีเขียว
* - Blue: ค่าความเข้มของสีน้ำเงิน
* หากมีการปรับเทียบแล้ว ค่าที่แสดงจะถูกแปลงเป็นช่วง 0-255
* หากยังไม่ได้ปรับเทียบ ค่าที่แสดงจะเป็นค่าดิบที่อ่านได้จากเซ็นเซอร์
* การปรับเทียบจะช่วยให้การอ่านค่าสีมีความแม่นยำมากขึ้น
*
*
* @author Thanabadee Bulunseechart ([email protected])
* @version 0.1
* @date 2025-07-01
*
* @copyright Copyright (c) 2025 Website: https://www.modulemore.com
*
*/
#include <Arduino.h>
#define S2 26
#define S3 25
#define sensorOut 14
/*Define int variables*/
int Red = 0;
int Green = 0;
int Blue = 0;
int Clear = 0;
int getBlue();
int getGreen();
int getRed();
int getClear();
bool isCalibrated = false;
int rmax, gmax, bmax;
int rmin, gmin, bmin;
void doCalibration();
void waitInput();
void setup()
{
pinMode(S2, OUTPUT); /*Define S2 Pin as a OUTPUT*/
pinMode(S3, OUTPUT); /*Define S3 Pin as a OUTPUT*/
pinMode(sensorOut, INPUT); /*Define Sensor Output Pin as a INPUT*/
Serial.begin(115200); /*Set the baudrate to 115200*/
Serial.println("This is TCS3200 Calibration Code");
delay(100);
bool ready = false;
while (!ready) {
Serial.println("Press y to calibrate the TCS3200 sensor.");
Serial.println("Press n to skip calibration.");
waitInput();
if (Serial.available()) {
char input = Serial.read();
if (input == 'y' || input == 'Y') {
doCalibration();
isCalibrated = true;
ready = true;
} else if (input == 'n' || input == 'N') {
isCalibrated = false;
ready = true;
} else {
Serial.println("Invalid input. Please enter 'y' or 'n'.");
}
}
delay(100);
}
// rmax = 1100;
// gmax = 1000;
// bmax = 870;
// rmin = 135;
// gmin = 250;
// bmin = 270;
}
void loop()
{
if(isCalibrated) {
Clear = getClear();
Red = map(getRed(), rmax, rmin, 0, 255);
Green = map(getGreen(), gmax, gmin, 0, 255);
Blue = map(getBlue(), bmax, bmin, 0, 255);
}else{
Clear = getClear();
Red = map(getRed(), 255, 0, 0, 255);
Green = map(getGreen(), 255, 0, 0, 255);
Blue = map(getBlue(), 255, 0, 0, 255);
}
Serial.print("Calibration Status: ");
if(isCalibrated) {
Serial.print("Calibrated ");
} else {
Serial.print("Not Calibrated ");
}
Serial.print("Clear = ");
Serial.print(Clear);
Serial.print(" ");
Serial.print("Red = ");
Serial.print(Red);
Serial.print(" ");
Serial.print("Green = ");
Serial.print(Green);
Serial.print(" ");
Serial.print("Blue = ");
Serial.print(Blue);
if(isCalibrated) {
//Convert to HSV
float r = constrain(Red / 255.0,0,1);
float g = constrain(Green / 255.0,0,1);
float b = constrain(Blue / 255.0,0,1);
float hue, saturation, value;
float max_val = max(r, max(g, b));
value = max_val;
float min_val = min(r, min(g, b));
float delta = max_val - min_val;
saturation = (max_val > 0.0) ? delta / max_val : 0.0;
if(delta > 0.0) {
hue = max_val == r ? (g - b) / delta : (max_val == g ? 2.0 + (b - r) / delta : 4.0 + (r - g) /delta);
hue *= 60.0;
if(hue < 0.0)
hue += 360.0;
}
else hue = 0.0;
Serial.print(" ");
Serial.print("HSV: ");
Serial.print("H = ");
Serial.print(hue); // Print hue in degrees
Serial.print(" ");
Serial.print("S = ");
Serial.print(saturation * 100); // Print saturation as percentage
Serial.print("% ");
Serial.print("V = ");
Serial.print(value * 100); // Print value as percentage
Serial.print("% ");
//Color Name Detection
// include black and white detection
// Fine color name detection based on HSV
if (value < 0.1) {
Serial.print("Color: Black");
} else if (saturation < 0.1) {
Serial.print("Color: White");
} else if (hue < 15 || hue > 345) {
Serial.print("Color: Red");
} else if (hue >= 15 && hue < 45) {
Serial.print("Color: Orange");
} else if (hue >= 45 && hue < 75) {
Serial.print("Color: Yellow");
} else if (hue >= 75 && hue < 165) {
Serial.print("Color: Green");
} else if (hue >= 165 && hue < 255) {
Serial.print("Color: Cyan");
} else if (hue >= 255 && hue < 285) {
Serial.print("Color: Blue");
} else if (hue >= 285 && hue < 345) {
Serial.print("Color: Magenta");
} else {
Serial.print("Color: Unknown");
}
}
Serial.println("");
delay(100);
}
int getRed()
{
digitalWrite(S2, LOW);
digitalWrite(S3, LOW);
return pulseIn(sensorOut, LOW);;
}
int getGreen()
{
digitalWrite(S2, HIGH);
digitalWrite(S3, HIGH);
return pulseIn(sensorOut, LOW);
}
int getBlue()
{
digitalWrite(S2, LOW);
digitalWrite(S3, HIGH);
return pulseIn(sensorOut, LOW); ;
}
int getClear()
{
digitalWrite(S2, HIGH);
digitalWrite(S3, LOW);
return pulseIn(sensorOut, LOW); ;
}
void waitInput() {
while (!Serial.available()) {
delay(100); // Wait for user input
}
}
void doCalibration() {
Serial.println("Starting calibration...");
Serial.println("Please place the sensor on a white surface for calibration.");
Serial.println("Press any key to continue...");
waitInput();
// Read the values multiple times to get an average
int r = 0, g = 0, b = 0, c = 0;
for (int i = 0; i < 10; i++) {
r += getRed();
g += getGreen();
b += getBlue();
c += getClear();
delay(100); // Wait for a short period before the next reading
}
rmin = r / 10;
gmin = g / 10;
bmin = b / 10;
Serial.print("White complete! \n");
Serial.print(" - Min R: "); Serial.println(rmin);
Serial.print(" - Min G: "); Serial.println(gmin);
Serial.print(" - Min B: "); Serial.println(bmin);
while(Serial.available()) {
Serial.read(); // Clear any remaining input
}
Serial.println("Please place the sensor on a dark surface for calibration.");
Serial.println("Press any key to continue...");
waitInput();
// Read the values multiple times to get an average
r = 0; g = 0; b = 0; c = 0;
for (int i = 0; i < 10; i++) {
r += getRed();
g += getGreen();
b += getBlue();
c += getClear();
// Wait for a short period before the next reading
delay(100);
}
rmax = r / 10;
gmax = g / 10;
bmax = b / 10;
Serial.print("Dark complete! ");
Serial.print("Max R: "); Serial.println(rmax);
Serial.print("Max G: "); Serial.println(gmax);
Serial.print("Max B: "); Serial.println(bmax);
Serial.println("Calibration complete!");
Serial.println("You can now read colors accurately.");
Serial.println("Press any key to exit calibration mode.");
waitInput();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment