Created
July 1, 2025 17:03
-
-
Save fxprime/4fa50b9eb515ab95b3cf2eddd3c0bebc to your computer and use it in GitHub Desktop.
ตัวอย่างโค้ดสำหรับการใช้งาน TCS3200 Sensor บน ESP32 พร้อมการปรับเทียบเซ็นเซอร์เพื่อให้สามารถอ่านค่าสีได้อย่างแม่นยำ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* ตัวอย่างโค้ดสำหรับการใช้งาน 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