Sau khi đã quen với I2C ở Level 2 và bắt đầu tư duy “hệ thống” ở Level 3, chúng ta đến một cảm biến rất thú vị: TCS34725 – cảm biến đo màu cho ra dữ liệu RGB (và Clear), phù hợp cho các ứng dụng như:
- Nhận diện màu vật thể
- Phân loại sản phẩm (DIY conveyor mini)
- Robot line-following nâng cao
- Học xử lý tín hiệu & hiệu chuẩn màu
Bài này gồm 2 phần code:
- Đọc màu RGB local (Serial)
- Gửi dữ liệu RGB realtime lên IoTLabs Cloud MQTT
1. TCS34725 là gì?
TCS34725 là cảm biến màu có:
- Giao tiếp: I2C
- Dữ liệu: Red / Green / Blue + Clear (độ sáng tổng)
- Có tích hợp IR filter (giúp đo màu ổn định hơn)
- Thường đi kèm LED ánh sáng trắng trên module (hỗ trợ chiếu sáng vật thể)
📌 Địa chỉ I2C phổ biến: 0x29
2. Khi đo màu RGB, bạn cần lưu ý điều gì?
Đo màu “đúng” phụ thuộc nhiều vào môi trường:
- Ánh sáng phòng thay đổi → RGB thay đổi
- Khoảng cách sensor ↔ vật thể thay đổi → RGB thay đổi
- Bề mặt bóng/nhám khác nhau → RGB khác nhau
Vì vậy tư duy đúng khi làm IoT đo màu là:
- Dùng nguồn sáng ổn định (LED trên module)
- Giữ khoảng cách cố định
- Chuẩn hoá dữ liệu (scale hoặc normalize)
3. Chuẩn bị phần cứng & nối dây
Thiết bị
- ESP32-C3 SuperMini
- TCS34725 module (I2C)
Kết nối I2C (chuẩn series)
| TCS34725 | ESP32-C3 |
|---|---|
| VIN / VCC | 3.3V |
| GND | GND |
| SDA | GPIO8 |
| SCL | GPIO9 |
4. Kiểm tra I2C address
Bạn có thể dùng đoạn scan I2C (đã dùng ở Level 2).
Kỳ vọng sẽ thấy: 0x29.
5. Ví dụ 1: Đọc RGB local (Serial)
Thư viện
- Adafruit TCS34725
#include <Wire.h>
#include "Adafruit_TCS34725.h"
Adafruit_TCS34725 tcs = Adafruit_TCS34725(
TCS34725_INTEGRATIONTIME_50MS,
TCS34725_GAIN_4X
);
void setup() {
Serial.begin(115200);
Wire.begin(8, 9);
if (!tcs.begin()) {
Serial.println("TCS34725 not found");
while (1) delay(10);
}
Serial.println("TCS34725 ready");
}
void loop() {
uint16_t r, g, b, c;
tcs.getRawData(&r, &g, &b, &c);
Serial.print("R: "); Serial.print(r);
Serial.print(" | G: "); Serial.print(g);
Serial.print(" | B: "); Serial.print(b);
Serial.print(" | C: "); Serial.println(c);
delay(500);
}
📌 c (Clear) là tổng độ sáng, rất hữu ích để normalize.
6. Chuẩn hoá dữ liệu màu (RGB normalize)
Để dữ liệu ít phụ thuộc độ sáng, bạn có thể normalize:
rn = r / cgn = g / cbn = b / c
Ví dụ:
{
"ts": 1760000000,
"metrics": {
"r": 1234,
"g": 980,
"b": 650,
"c": 3120,
"rn": 0.39,
"gn": 0.31,
"bn": 0.21
}
}
👉 Khi hiển thị trên dashboard, bạn có thể vẽ:
- Raw RGB
- Hoặc normalized RGB (ổn định hơn)
7. Ví dụ 2: Gửi RGB realtime lên IoTLabs Cloud MQTT
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <Wire.h>
#include "Adafruit_TCS34725.h"
Adafruit_TCS34725 tcs = Adafruit_TCS34725(
TCS34725_INTEGRATIONTIME_50MS,
TCS34725_GAIN_4X
);
// ===== CONFIG =====
const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASS = "YOUR_PASS";
const char* MQTT_HOST = "mqtt.iotlabs.vn";
const int MQTT_PORT = 8883;
const char* MQTT_USER = "YOUR_MQTT_USER";
const char* MQTT_PASS = "YOUR_MQTT_PASS";
const char* MQTT_TOPIC =
"iotlabs/<orgId>/devices/<deviceId>/telemetry";
WiFiClientSecure net;
PubSubClient mqtt(net);
unsigned long lastSend = 0;
void connectWiFi() {
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
}
void connectMQTT() {
net.setInsecure();
mqtt.setServer(MQTT_HOST, MQTT_PORT);
while (!mqtt.connected()) {
mqtt.connect("esp32c3-tcs34725", MQTT_USER, MQTT_PASS);
delay(1000);
}
}
void setup() {
Serial.begin(115200);
Wire.begin(8, 9);
if (!tcs.begin()) {
Serial.println("TCS34725 not found");
while (1) delay(10);
}
connectWiFi();
connectMQTT();
}
void loop() {
if (!mqtt.connected()) connectMQTT();
mqtt.loop();
if (millis() - lastSend > 1000) {
lastSend = millis();
uint16_t r, g, b, c;
tcs.getRawData(&r, &g, &b, &c);
if (c == 0) return;
float rn = (float)r / (float)c;
float gn = (float)g / (float)c;
float bn = (float)b / (float)c;
long ts = millis() / 1000;
String payload = "{";
payload += "\"ts\":" + String(ts) + ",";
payload += "\"metrics\":{";
payload += "\"r\":" + String(r) + ",";
payload += "\"g\":" + String(g) + ",";
payload += "\"b\":" + String(b) + ",";
payload += "\"c\":" + String(c) + ",";
payload += "\"rn\":" + String(rn, 3) + ",";
payload += "\"gn\":" + String(gn, 3) + ",";
payload += "\"bn\":" + String(bn, 3);
payload += "}}";
mqtt.publish(MQTT_TOPIC, payload.c_str());
Serial.println(payload);
}
}
8. Kinh nghiệm thực tế để đo màu ổn định
- Dùng LED chiếu sáng cố định (nếu module có)
- Giữ khoảng cách sensor ↔ vật thể ổn định (5–15mm)
- Đặt hộp che sáng (mini enclosure) để tránh ánh sáng môi trường
- Dùng
rn/gn/bnthay vì raw để ổn định dashboard
9. Gợi ý dashboard realtime cho RGB
Gợi ý hiển thị:
- 3 card:
R,G,B - 1 card:
C(brightness) - 1 chart:
rn/gn/bntheo thời gian
👉 Bạn sẽ thấy ngay khi đưa vật có màu khác nhau vào.
10. Tổng kết Bài 22
Sau bài này, bạn đã:
- Đọc cảm biến màu TCS34725 qua I2C
- Làm quen dữ liệu multi-metric RGB
- Biết cách normalize màu theo độ sáng
- Gửi dữ liệu realtime lên IoTLabs Cloud MQTT


