TCS230 tidak pernah melaporkan sesuatu warna. Ia melaporkan satu nombor pada satu masa β satu frekuensi, melalui penapis mana yang anda pilih dengan dua pin β jadi satu bacaan warna ialah tiga pengukuran berturut-turut, dan sketch anda, bukan cip itu, yang menentukan apa maknanya. Set S0 HIGH, S1 LOW, ukur setiap channel dengan pulseIn(), dan kalibrasi dengan kad putih dahulu.
Apa sebenarnya yang diukur oleh sensor warna TCS230?
TCS230 membawa satu array fotodiod 8Γ8, dan 64 fotodiod itu tidak serupa: enam belas duduk di belakang penapis merah, enam belas di belakang hijau, enam belas di belakang biru dan enam belas lagi tanpa sebarang penapis. Hanya satu kumpulan disambung kepada penukar pada satu-satu masa, dan S2 serta S3 yang memilih kumpulan mana. Jadi tiada panggilan “baca warna” di sini β yang ada hanyalah pilih merah, ukur; pilih hijau, ukur; pilih biru, ukur.
Apa yang sampai di OUT pun bukan voltan. Penukar itu menukarkan arus foto kumpulan yang dipilih menjadi gelombang segi empat duti 50% yang frekuensinya berkadar dengan jumlah cahaya yang mendarat padanya, pada bekalan 2.7β5.5 V, menurut datasheet TAOS TCS230. Terang bermakna laju, gelap bermakna perlahan.
| S2 | S3 | Kumpulan fotodiod yang disambung |
|---|---|---|
| LOW | LOW | Merah |
| LOW | HIGH | Biru |
| HIGH | LOW | Clear β tiada penapis |
| HIGH | HIGH | Hijau |
S0 dan S1 pula membahagikan frekuensi itu ke bawah sebelum ia keluar daripada cip, dan tetapan inilah yang menentukan sama ada Arduino mampu mengukur gelombang itu langsung atau tidak.
| S0 | S1 | Penskalaan output | Frekuensi skala penuh | Separuh tempoh pada skala penuh |
|---|---|---|---|---|
| LOW | LOW | power down | β | β |
| LOW | HIGH | 2% | 10β12 kHz | 42β50 Β΅s |
| HIGH | LOW | 20% | 100β120 kHz | 4β5 Β΅s |
| HIGH | HIGH | 100% | 500β600 kHz | 0.8β1 Β΅s |
Rujukan pulseIn() Arduino mendokumenkan fungsi itu sebagai berfungsi pada denyut dari 10 Β΅s ke atas, dan nombor itulah yang memilih baris mana untuk anda. Pada 100%, bacaan terang hanyalah sepersekian daripada 10 Β΅s, jadi objek cerah semuanya runtuh menjadi satu nilai yang sama dan tidak bermakna. Pada 2% pula tiada apa yang terlalu laju, tetapi objek gelap meregangkan satu pengukuran sehingga milisaat, dan tiga daripadanya bagi setiap bacaan menjadi lag yang nampak. 20% meletakkan bacaan dalam bilik biasa pada julat puluhan mikrosaat; 4β5 Β΅s pada baris itu ialah skala penuh, satu tahap kecerahan yang empat LED modul ini sendiri tidak pernah capai daripada objek harian.
Senarai komponen β sensornya, satu skrin untuk memerhatinya, dan header serta jumper yang menyambung kepadanya
Parts list
| Item | Price | Qty | |
|---|---|---|---|
Soldering Service for Circuit Boards & Electronics - 10 Pins Soldering ServiceSOLSE10 | RM1.40 |
Modul TCS230 perlukan tepat 10 pin header disolder. Kalau anda lebih suka tidak menyolder sendiri, tambah servis solder 10 pin dan kami pasangkan jalur itu untuk anda.
Bagaimana cara menyambung TCS230 kepada Arduino Uno?
Modul TCS230 menampilkan dua baris 5-pinnya sebagai lubang tembus bersalut yang masih bogel, jadi kerja pertama ialah menyolder. Patahkan dua kepingan 5-hala daripada jalur male 40-pin 2.54 mm dalam senarai komponen dan tolak masuk dari sebelah kanta, supaya pinnya keluar di belakang dan tiada shell jumper duduk dalam laluan cahaya; panduan solder header kami menerangkan tekniknya, atau servis solder 10 pin menguruskannya kalau anda tiada besi solder.
Dua baris itu membawa pin yang berbeza dan berjalan dalam arah bertentangan, jadi baca silkscreen dan jangan mengagak ikut kedudukan: satu tepi berbunyi GND OUT S2 S3 VCC, satu lagi berbunyi VCC S1 S0 LED GND, masing-masing dengan pad segi empat pada pin 1. Baris-baris itu duduk pada tepi yang bertentangan pada board segi empat sama 33.2 mm, kira-kira 30 mm jaraknya β lebih lebar daripada rentang 28 mm merentasi dua bank breadboard mini, jadi modul ini tidak boleh mencangkung di atasnya. Guna Sensor Shield V5.0 pada Uno sebaliknya: ia menerbitkan semula setiap pin digital sebagai blok male tiga pin berlabel G, V dan S, berserta satu port IIC empat pin untuk OLED. Dengan pin male di kedua-dua hujung, kesemua dua belas sambungan menggunakan jumper female-to-female, dan wayar 20 cm membolehkan sensor itu tergantung ke mana sahaja anda halakan.
Pin bertanda LED bukan pin logik. Ia menghidupkan empat LED putih onboard modul itu, yang manualnya letakkan pada lebih kurang 25 mA kesemuanya, dan board itu sendiri mengesahkannya: perintang di sebelah setiap LED bertanda 331, bermakna 330 Ξ©, dan LED putih menjatuhkan kira-kira 3.1 V, jadi setiap cabang menarik (5 β 3.1) / 330 = 5.8 mA dan empat cabang β 23 mA. Datasheet ATmega328P membenarkan 40 mA bagi setiap pin I/O sebagai maksimum mutlak dan hanya menyatakan voltan output pin itu sehingga 20 mA sahaja. Ikat LED terus ke 5V dan biarkan lampu itu menyala β dan itulah juga yang dikehendaki oleh pengukuran warna.
Jumper SEL kuning pada shield, di sebelah terminal skru biru, menyalurkan kuasa kepada pin V blok digital daripada 5V Uno sendiri. Biarkan ia di tempat asalnya β cabut ia dan setiap pin V pada blok D0βD13 mati, dan itu nampak sungguh-sungguh macam sensor rosak, sedangkan yang hilang hanyalah satu jumper. Jangan sambung apa-apa pada terminal skru itu: bekalan luar dengan SEL masih terpasang akan mendarat terus pada rel 5V Uno.
| Pin modul (silkscreen) | Ke mana pada shield | Pin Uno di sebaliknya |
|---|---|---|
| TCS230 OUT | blok D8, S | D8 |
| TCS230 S0 | blok D4, S | D4 |
| TCS230 S1 | blok D5, S | D5 |
| TCS230 S2 | blok D6, S | D6 |
| TCS230 S3 | blok D7, S | D7 |
| TCS230 VCC | pin V mana-mana blok | 5V |
| TCS230 GND | pin G mana-mana blok | GND |
| TCS230 LED | pin V mana-mana blok yang kosong | 5V β jangan sekali pin digital |
| OLED GND | header IIC, β | GND |
| OLED VCC | header IIC, + | 5V |
| OLED SCL | header IIC, SCL | A5 |
| OLED SDA | header IIC, SDA | A4 |
Header OLED itu berjalan GND, VCC, SCL, SDA β ground dahulu, terbalik daripada susunan VCC-dahulu yang biasa β sementara port IIC shield pula berjalan SCL, SDA, β, +. Pasang empat sambungan itu satu demi satu, bukan sebagai riben lurus merentas. Headernya sampai sudah tersolder; panel yang sama inilah yang memacu menu OLED rotary encoder kami.

Kenapa objek merah memberi bacaan merah yang PALING RENDAH?
Sebabnya pin OUT TCS230 itu diukur masanya, bukan dibaca nilainya. pulseIn(OUT, LOW) tidak mengukur cahaya β ia mengukur panjang separuh LOW gelombang segi empat itu dalam mikrosaat, iaitu separuh tempoh. Tempoh ialah 1 / frekuensi, jadi nombor yang anda dapat balik ialah 500000 / f: 25 pada 20 kHz, 100 pada 5 kHz.
Letakkan blok merah di bawah penapis merah dan ia memantulkan merah dengan kuat, jadi frekuensi memanjat, separuh tempoh mengecut, dan nombornya jadi lebih kecil. Channel yang paling sepadan ialah channel dengan kiraan mentah paling rendah: kiraan mentah daripada TCS230 mengukur kegelapan.

Bagaimana cara kalibrasi TCS230, dan kenapa kalibrasi itu keseluruhan projek ini?
Kiraan mentah TCS230 hanyut mengikut jarak, pencahayaan bilik dan kecerahan asal objek itu sendiri, jadi anda kunci dua hujungnya. Tetapkan ketinggian dahulu dan jangan sekali-kali ubah lagi β sekitar 10β30 mm daripada kanta sesuai untuk kebanyakan objek, cukup dekat untuk kon cahaya keempat-empat LED bertindih pada sasaran. Pada ketinggian itu, pegang kad putih dan catat tiga nombor mentahnya β yang terkecil anda akan lihat. Kemudian pegang sesuatu yang hitam matt dan catat nombor itu pula β yang terbesar.
map(raw, white, black, 255, 0) kemudian menukarkan kiraan mentah kepada 0β255. Perhatikan julat output ditulis terbalik: putih ialah nilai mentah yang kecil dan mesti mendarat pada 255. Satu argumen terbalik itulah yang meleraikan penyongsangan tadi.
Itu pun masih belum cukup, dan inilah langkah yang paling kerap dilangkau panduan lain. Alihkan objek 5 mm lebih jauh dan ketiga-tiga nilai ternormal mengecut serentak, sebab kurang cahaya yang kembali secara keseluruhan. Jadi bahagikan setiap satu dengan jumlah ketiga-tiganya: r = R / (R+G+B). Kecerahan terbatal dan hanya perkadaran yang tinggal. Sebuah blok merah yang tiga nilai 0β255nya berbunyi 210/70/60 pada jarak dekat memberi nisbah 617/205/176 per seribu; undurkan sampai bacaannya jadi 120/40/34 dan nisbahnya 618/206/175 β keputusan yang sama daripada nombor yang jauh berbeza, dan itulah sebabnya sebuah mesin pengasing kekal boleh diulang. Pembahagian integer memotong baki, jadi ketiga-tiganya tidak pernah betul-betul berjumlah 1000.
Empat LED putih yang mengelilingi kanta itu wujud atas sebab yang sama: sensor ini mengukur cahaya pantulan, jadi sumber cahaya yang berubah bermakna bacaan yang berubah. Biarkan ia menyala dan lindungi celah itu daripada cahaya bilik. Melihat nombor bergerak sambil objek lalu di bawah sensor berbaloi diluangkan beberapa minit di sini:

Macam mana rupa sketch Arduino untuk TCS230?
Sketch TCS230 ialah tiga bacaan, satu normalisasi, satu nisbah, kemudian padanan terdekat dengan rujukan anda sendiri. Pasang Adafruit SSD1306 dan Adafruit GFX Library daripada Library Manager dahulu. Setiap nombor dalam dua blok kalibrasi itu hanyalah nilai sementara β jalankannya, baca baris raw dalam Serial Monitor pada 9600, tampal nombor anda sendiri.
// Sensor warna TCS230 + OLED SSD1306 0.96" pada Arduino Uno.
// Pendawaian: OUT -> D8, S0 -> D4, S1 -> D5, S2 -> D6, S3 -> D7,
// VCC -> 5V, GND -> GND, LED -> 5V (jangan sekali pin digital: ~25 mA).
// OLED SCL -> A5, SDA -> A4, VCC -> 5V, GND -> GND.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDR 0x3C // silkscreen tulis 0x78; itu bentuk 8-bit, 0x78 >> 1 = 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const uint8_t PIN_S0 = 4;
const uint8_t PIN_S1 = 5;
const uint8_t PIN_S2 = 6;
const uint8_t PIN_S3 = 7;
const uint8_t PIN_OUT = 8;
// ---- LANGKAH 1: kalibrasi anda sendiri, dalam mikrosaat mentah (R, G, B) --
// Pegang kad PUTIH pada jarak kerja anda, baca baris "raw" dalam Serial
// Monitor, tampal tiga nombor itu di sini. Ulang dengan bahan HITAM matt.
const uint16_t WHITE_RAW[3] = { 26, 30, 25 };
const uint16_t BLACK_RAW[3] = { 240, 265, 230 };
// ---- LANGKAH 2: nisbah rujukan x1000, diukur pada objek ANDA SENDIRI ------
// Cetak baris ratio sambil memegang setiap objek, kemudian tampal triplet di sini.
const int16_t REF[4][3] = {
{ 560, 235, 205 }, // merah
{ 235, 520, 245 }, // hijau
{ 205, 270, 525 }, // biru
{ 333, 333, 334 } // putih / kelabu
};
const char *const NAME[4] = { "RED", "GREEN", "BLUE", "WHITE" };
// Satu pengukuran. S2/S3 memilih kumpulan fotodiod mana yang disambung kepada
// penukar; pulseIn mengukur separuh LOW gelombang segi empat duti 50%, jadi
// nombor yang dipulangkan ialah separuh tempoh - LAGI banyak cahaya, LAGI kecil nombornya.
uint16_t readRaw(uint8_t s2, uint8_t s3) {
digitalWrite(PIN_S2, s2);
digitalWrite(PIN_S3, s3);
delay(10); // beri penapis baharu masa untuk stabil
unsigned long us = pulseIn(PIN_OUT, LOW, 50000UL);
if (us == 0 || us > 50000UL) return 50000; // tamat masa: pada praktiknya hitam
return (uint16_t)us;
}
// Tukar separuh tempoh mentah menjadi 0-255 "berapa banyak warna ini kembali".
// Julat output ditulis terbalik dengan sengaja: putih ialah nilai mentah yang
// KECIL dan mesti mendarat pada 255.
uint8_t normalise(uint16_t raw, uint16_t white, uint16_t black) {
long v = map((long)raw, (long)white, (long)black, 255L, 0L);
return (uint8_t)constrain(v, 0L, 255L);
}
void setup() {
pinMode(PIN_S0, OUTPUT);
pinMode(PIN_S1, OUTPUT);
pinMode(PIN_S2, OUTPUT);
pinMode(PIN_S3, OUTPUT);
pinMode(PIN_OUT, INPUT);
digitalWrite(PIN_S0, HIGH); // S0 HIGH, S1 LOW = penskalaan output 20%,
digitalWrite(PIN_S1, LOW); // skala penuh 100-120 kHz - yang pulseIn mampu ukur
Serial.begin(9600);
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println(F("No SSD1306 at 0x3C - check SDA/SCL and 5V"));
for (;;) { }
}
display.setTextColor(SSD1306_WHITE);
}
void loop() {
uint16_t raw[3];
raw[0] = readRaw(LOW, LOW); // kumpulan penapis merah
raw[1] = readRaw(HIGH, HIGH); // kumpulan penapis hijau
raw[2] = readRaw(LOW, HIGH); // kumpulan penapis biru
uint8_t rgb[3];
for (uint8_t i = 0; i < 3; i++) {
rgb[i] = normalise(raw[i], WHITE_RAW[i], BLACK_RAW[i]);
}
// Nisbah, bukan aras. Membahagi dengan jumlahnya membuang "berapa terang" dan
// mengekalkan hanya "warna apa", dan itulah yang kekal bila objek beralih.
uint16_t sum = (uint16_t)rgb[0] + rgb[1] + rgb[2];
if (sum == 0) sum = 1;
int16_t ratio[3];
for (uint8_t i = 0; i < 3; i++) {
ratio[i] = (int16_t)((1000L * rgb[i]) / sum);
}
// Rujukan terdekat dalam ruang nisbah: jarak kuasa dua, yang terkecil menang.
uint8_t best = 0;
int32_t bestDist = 2147483647L;
for (uint8_t k = 0; k < 4; k++) {
int32_t d = 0;
for (uint8_t i = 0; i < 3; i++) {
int32_t e = (int32_t)ratio[i] - REF[k][i];
d += e * e;
}
if (d < bestDist) { bestDist = d; best = k; }
}
Serial.print(F("raw "));
for (uint8_t i = 0; i < 3; i++) { Serial.print(raw[i]); Serial.print(' '); }
Serial.print(F(" rgb "));
for (uint8_t i = 0; i < 3; i++) { Serial.print(rgb[i]); Serial.print(' '); }
Serial.print(F(" ratio "));
for (uint8_t i = 0; i < 3; i++) { Serial.print(ratio[i]); Serial.print(' '); }
Serial.print(F(" -> "));
Serial.println(NAME[best]);
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 0);
display.println(NAME[best]);
display.setTextSize(1);
display.setCursor(0, 24);
display.print(F("R ")); display.print(rgb[0]);
display.print(F(" G ")); display.print(rgb[1]);
display.print(F(" B ")); display.println(rgb[2]);
display.setCursor(0, 40);
display.print(ratio[0]); display.print(F(" / "));
display.print(ratio[1]); display.print(F(" / "));
display.println(ratio[2]);
display.setCursor(0, 54);
display.print(F("fit ")); display.print(bestDist);
display.display();
delay(200);
}
Ia dikompil menjadi 16,160 bait flash dan 587 bait pemboleh ubah global β tetapi display.begin() menuntut 1024 bait lagi untuk frame buffer semasa ia berjalan, dan angka itu tidak pernah ditunjukkan oleh IDE, jadi kos SRAM yang sebenar ialah kira-kira 1611 daripada 2048 bait Uno. Angka fit pada paparan itu ialah jarak kuasa dua rujukan yang menang: kecil bermakna padanan yang yakin, besar bermakna padanan yang meragukan. Satu pemeriksaan waras semasa kalibrasi: kalau kad putih memulangkan nilai mentah di bawah lebih kurang 10, anda sudah sampai ke lantai pulseIn() β angkat sensor sedikit, atau turun ke penskalaan 2%. Itu bermakna S0 LOW dan S1 HIGH β menaikkan S1 sahaja meninggalkan S0 pada HIGH, iaitu baris 100%, dan itu memendekkan lagi denyutnya.
Kesilapan biasa yang kami nampak daripada pelanggan sebenar
Objek merah memberi nombor merah paling rendah, jadi sensor itu nampak macam tersalah wayar. Wayarnya betul. pulseIn() memulangkan separuh tempoh, jadi lebih banyak cahaya memberi denyut yang lebih pendek. Normalkan dahulu sebelum membandingkan apa-apa.
Bacaan melompat setiap kali ada tangan lalu di atasnya. Cahaya bilik sedang sampai kepada objek itu bersama-sama LED modul sendiri. Pengelas ini hanya sestabil pencahayaannya: tetapkan ketinggian, lindungi celahnya.
Semua warna dikelaskan sama, atau semuanya terbaca hitam. Selalunya salah satu daripada tiga: jalur header itu tidak pernah disolder dan jumper hanya tersandar dalam lubang, jumper SEL shield sudah tercabut jadi pin V sensor mati, atau pin LED dibiarkan tidak bersambung dan tiada apa yang menyuluh objek itu.
Objek yang asing pun tetap dinamakan, dengan penuh yakin. Padanan terdekat tiada kes tolak: ia memulangkan rujukan yang paling hampir daripada empat rujukan anda, apa sahaja yang anda angkat, jadi blok kuning pun tetap mendarat pada salah satu daripadanya. Catat di mana fit duduk untuk objek yang anda tahu, dan tolak apa-apa yang lebih teruk daripada itu β satu salur UNKNOWN lebih baik daripada salur yang salah.
Ia menjadi di atas meja tetapi gagal pada rig. Kalibrasi terikat pada jarak. Rakam semula putih, hitam dan setiap nisbah rujukan pada ketinggian yang benar-benar digunakan oleh mesin siap itu.
Soalan Lazim
Adakah TCS230 sama dengan TCS3200?
Untuk sketch anda, ya. Kedua-duanya berkongsi model pengaturcaraan dan susunan pin yang sama β penskalaan S0/S1, pemilihan penapis S2/S3, frekuensi pada OUT β jadi kod untuk mana-mana satu berjalan tanpa diubah di sini. Board ini ialah yang biasa disenaraikan sebagai GY-31, dengan silkscreen Color Sensor merentasi belakangnya.
Perlukah saya solder modul TCS230?
Ya β dua baris 5-pinnya ialah lubang tembus bersalut yang menerima header male 2.54 mm. Senarai komponen sudah memasukkan jalur 40-pin untuk dipatahkan dua kepingan 5-hala, atau tambah servis solder 10 pin dan kami pasangkan.
Kenapa pin LED mesti ke 5V dan bukan ke pin digital?
Ia memacu empat LED putih melalui perintang 330 Ξ©, lebih kurang 23β25 mA kesemuanya β melebihi 20 mA yang masih dinyatakan oleh datasheet ATmega328P untuk voltan output sesuatu pin, dan hampir dengan maksimum mutlaknya 40 mA. Pencahayaan yang berterusan pun lebih sesuai untuk pengukuran.
Kenapa sensor ini perlukan kad putih sebelum ia berfungsi?
TCS230 mengukur cahaya pantulan, jadi kiraan mentahnya bergantung pada jarak dan pencahayaan bilik sama banyak seperti pada warna. Satu bacaan putih dan satu bacaan hitam pada jarak kerja anda memberi map() dua hujung skalanya.
Boleh tak ia bezakan biru cair daripada biru tua?
Boleh, tapi hanya kalau anda kekalkan kecerahan dalam kiraan. Nisbah memang sengaja membuang kecerahan, jadi biru pucat dan biru pekat pada rona yang sama mendarat pada triplet yang serupa. Simpan jumlah pra-nisbah 0β255 di sebelah setiap rujukan sebagai ujian kedua.
Pengelas warna ialah mata sebuah mesin pengasing, bukan keseluruhan mesin itu. Panduan motor stepper 28BYJ-48 kami merangkumi lengannya, dan projek robot line follower pula menunjukkan jenis penderiaan optik yang satu lagi β pantulan, cerah lawan gelap.
Kemas kini terakhir Ogos 2026. Tersangkut? Chat dengan kami di WhatsApp.



TCS230 Color Sensor Module Light to Frequency Converter RGB Detection for Arduino DIY Projects Robotics
0.96β OLED Display Module Blue White Screen I2C IIC Serial 128X64 LCD Display Board - 0.96' OLED WHITE
Arduino Uno Compatible SMD UNO R3 with Type B Cable - ATMEGA328P with CH340G-Microcontroller Project
Sensor Shield V5.0 Arduino Uno R3 Shield For Arduino Protoype Application
40pcs Dupont Wire 10cm 20cm 30cm for Breadboard DIY Experiment Jumper Wire Breadboard wire - DUPONT WIRE F-F 20CM
2.54mm Pin Header Female Male Single Row Header 40P Connector Black White Red Yellow Green Blue - 40P MALE HEADER
Soldering Service for Circuit Boards & Electronics - 10 Pins Soldering Service