Touch sensor TTP223B phát hiện ngón tay không phải bằng áp lực cơ học mà bằng thay đổi điện dung. IC TTP223B chuyên dụng đo self-capacitance liên tục, so sánh với baseline, và quyết định có chạm hay không. Bài này giải thích cơ chế vật lý và 2 chế độ hoạt động (momentary vs toggle) có thể cấu hình ngay trên module.
Nguyên Lý Hoạt Động
1. Capacitive Touch — Tụ Điện Ngón Tay
Pad cảm biến là điện cực dẫn điện (thường là đồng trên PCB):
Self-Capacitance Sensing:
Không chạm:
Pad ──[Cxo]── GND
Cxo = capacitance nền (vài pF, ổn định)
Có ngón tay:
Pad ──[Cxo + Cf]── GND
Cf = finger capacitance (thêm vào ~10-20pF)
→ Tổng điện dung tăng đáng kể
IC đo điện dung bằng cách:
1. Nạp điện tích Q vào pad trong thời gian cố định
2. Đo điện áp V = Q/C
3. C tăng (ngón tay) → V giảm
4. So sánh với ngưỡng baseline → kết luận có chạm
Tại sao ngón tay tạo điện dung? Da người là chất dẫn điện. Ngón tay ↔ Pad = 2 “bản tụ” cách nhau bởi lớp vỏ bảo vệ module (~1mm). Tụ điện này đủ lớn (~10-20pF) để IC phát hiện được.
2. IC TTP223B — Cấu Trúc Nội Bộ
TTP223B là IC CMOS chuyên dụng từ Tontek Design Technology:
TTP223B — Sơ đồ khối:
Pad ─────→ [Oscillator] ─→ [Counter] ─→ [Comparator]
│
[Baseline filter] ──────────────→ │
(cập nhật liên tục khi không chạm) │
↓
[Output logic]
│
Q (output)
Baseline calibration tự động:
- IC tự hiệu chỉnh baseline khi khởi động (~0.5 giây)
- Cập nhật baseline liên tục khi không có chạm (bù trôi do nhiệt độ, độ ẩm)
- Không chạm pad trong 0.5 giây đầu sau khi cấp nguồn — IC đang calibrate!
3. Hai Chế Độ Hoạt Động — Solder Pad A và B
Module TTP223 thường có 2 solder pad để cấu hình chế độ:
Mặt sau module (solder pad):
┌──────────────────────────────┐
│ Pad A ○ ○ Pad B │
│ (Toggle) (Active Level) │
└──────────────────────────────┘
Pad A — Chế độ Toggle (Latch):
- Mặc định (không hàn): Momentary — Q = HIGH khi chạm, LOW khi thả
- Hàn kín Pad A: Toggle — Q đổi trạng thái mỗi lần chạm (như công tắc bật/tắt)
Pad B — Mức Logic Output:
- Mặc định (không hàn): Active HIGH — Q = HIGH khi chạm
- Hàn kín Pad B: Active LOW — Q = LOW khi chạm
Tổ hợp phổ biến:
| Pad A | Pad B | Kết quả |
|---|---|---|
| Mở | Mở | Momentary, Active HIGH (mặc định) |
| Hàn | Mở | Toggle, Active HIGH |
| Mở | Hàn | Momentary, Active LOW |
| Hàn | Hàn | Toggle, Active LOW |
Thông Số Kỹ Thuật
| Thông số | Giá trị |
|---|---|
| Điện áp hoạt động | 2.0V – 5.5V |
| Dòng tiêu thụ | ~1.5mA (active), ~1μA (standby) |
| Thời gian phản hồi | 60ms max |
| Output | Active HIGH (mặc định) |
| Thời gian calibrate | ~0.5 giây sau khi cấp nguồn |
| Hoạt động qua vật liệu | Kính, nhựa mỏng (<10mm) |
| Số chân | 3 (VCC, GND, Q/SIG) |
Sơ Đồ Chân (Pinout)
TTP223 Module — Nhìn từ mặt trước (có pad cảm biến):
┌─────────────────────┐
(◯) │ [Pad cảm biến] │ ← Chạm vào đây
└─────────────────────┘
GND VCC SIG/Q
| Chân | Ký hiệu | Mô tả |
|---|---|---|
| GND | – | Mass |
| VCC | + | Nguồn 2.0V-5.5V |
| SIG/Q | Q | Output — HIGH khi chạm (mặc định) |
Kết Nối Phần Cứng
TTP223 với ESP32 DevKit V1
ESP32 DevKit V1 TTP223 Module
───────────────────── ─────────────────
3V3 ─────────────────→ VCC
GND ─────────────────→ GND
GPIO4 (Input) ─────────→ SIG/Q
GPIO4: input-capable, không phải strapping pin, an toàn.
Không cần INPUT_PULLUP — TTP223 output tích cực (active driver), không phải open-drain.
TTP223 với Arduino Uno
Arduino Uno TTP223 Module
───────────────────── ─────────────────
5V ─────────────────→ VCC
GND ─────────────────→ GND
Pin 2 (Input) ─────────→ SIG/Q
Code Arduino IDE
Code Đọc Touch Cơ Bản — Arduino Uno
/*
* Touch Sensor TTP223 — Đọc trạng thái chạm cơ bản
* Board: Arduino Uno
* Kết nối: VCC→5V, GND→GND, SIG→Pin2
*
* Mặc định (không hàn pad): Momentary, Active HIGH
* SIG = HIGH khi chạm, LOW khi không chạm
*/
const int TOUCH_PIN = 2;
const int LED_PIN = 13; // LED nội bộ để demo
void setup() {
Serial.begin(9600);
pinMode(TOUCH_PIN, INPUT); // Không cần PULLUP — output tích cực
pinMode(LED_PIN, OUTPUT);
Serial.println("=== Touch Sensor TTP223 ===");
Serial.println("Không chạm vào pad trong 0.5 giây đầu (IC calibrating)");
delay(600); // Chờ IC calibrate xong
Serial.println("Sẵn sàng — chạm vào pad!");
}
void loop() {
int touchVal = digitalRead(TOUCH_PIN);
if (touchVal == HIGH) {
digitalWrite(LED_PIN, HIGH); // LED sáng khi chạm
Serial.println("CHẠM!");
} else {
digitalWrite(LED_PIN, LOW);
}
delay(50); // Đọc 20 lần/giây
}
Code Touch Switch Interrupt — Arduino Uno
/*
* Touch Sensor — Interrupt: phát hiện chạm ngay lập tức
* Board: Arduino Uno
* Kết nối: VCC→5V, GND→GND, SIG→Pin2
*
* Dùng RISING trigger: SIG lên HIGH (= có chạm) → gọi ISR
*/
const int TOUCH_PIN = 2;
const int LED_PIN = 13;
volatile bool touchEvent = false;
bool ledState = false;
// ISR — gọi khi phát hiện chạm (SIG rising)
void onTouch() {
touchEvent = true;
}
void setup() {
Serial.begin(9600);
pinMode(TOUCH_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
delay(600); // Chờ TTP223 calibrate
// Trigger ISR khi SIG lên HIGH (RISING edge = bắt đầu chạm)
attachInterrupt(digitalPinToInterrupt(TOUCH_PIN), onTouch, RISING);
Serial.println("Touch Interrupt ready. Chạm để toggle LED.");
}
void loop() {
if (touchEvent) {
touchEvent = false;
ledState = !ledState; // Toggle LED
digitalWrite(LED_PIN, ledState ? HIGH : LOW);
Serial.print("Chạm! LED: ");
Serial.println(ledState ? "BẬT" : "TẮT");
}
}
Code Long-Press Detection — Arduino Uno
/*
* Touch Sensor — Phát hiện chạm ngắn vs chạm dài
* Ngắn (<500ms): toggle LED
* Dài (>500ms): reset / action khác
* Board: Arduino Uno
* Kết nối: VCC→5V, GND→GND, SIG→Pin2
*/
const int TOUCH_PIN = 2;
const int LED_PIN = 13;
const int LONG_PRESS_MS = 1000; // 1 giây = "long press"
bool ledState = false;
void setup() {
Serial.begin(9600);
pinMode(TOUCH_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
delay(600); // Chờ IC calibrate
Serial.println("Chạm ngắn: toggle LED | Chạm dài: tắt LED");
}
void loop() {
// Đợi có chạm (SIG = HIGH)
if (digitalRead(TOUCH_PIN) == HIGH) {
unsigned long pressStart = millis();
// Đợi thả (SIG về LOW) — đo thời gian giữ
while (digitalRead(TOUCH_PIN) == HIGH) {
delay(10);
// Báo hiệu đang hold (sau 800ms)
if (millis() - pressStart > 800) {
Serial.print(".");
}
}
unsigned long pressDuration = millis() - pressStart;
if (pressDuration >= LONG_PRESS_MS) {
// Chạm dài → tắt LED
ledState = false;
digitalWrite(LED_PIN, LOW);
Serial.println("\nChạm DÀI — LED tắt");
} else {
// Chạm ngắn → toggle
ledState = !ledState;
digitalWrite(LED_PIN, ledState ? HIGH : LOW);
Serial.print("Chạm ngắn (");
Serial.print(pressDuration);
Serial.print("ms) — LED: ");
Serial.println(ledState ? "BẬT" : "TẮT");
}
}
}
Code ESP32 — Touch Night Light
/*
* Touch Sensor TTP223 — ESP32, đèn ngủ thông minh
* Chạm để bật đèn 30 giây, chạm lại để tắt ngay
* Board: ESP32 DevKit V1
* Kết nối: VCC→3V3, GND→GND, SIG→GPIO4
* LED→GPIO5 (qua điện trở 220Ω)
*/
const int TOUCH_PIN = 4;
const int LED_PIN = 5;
const unsigned long AUTO_OFF_MS = 30000; // Tự tắt sau 30 giây
bool ledOn = false;
unsigned long ledOnTime = 0;
volatile bool touchEvent = false;
void IRAM_ATTR onTouch() {
touchEvent = true;
}
void setup() {
Serial.begin(115200);
pinMode(TOUCH_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
delay(600); // Chờ TTP223 calibrate
attachInterrupt(digitalPinToInterrupt(TOUCH_PIN), onTouch, RISING);
Serial.println("=== Night Light ===");
Serial.println("Chạm để bật đèn 30s | Chạm lại để tắt ngay");
}
void loop() {
unsigned long now = millis();
// Xử lý sự kiện chạm
if (touchEvent) {
touchEvent = false;
delay(50); // Nhỏ debounce
if (!ledOn) {
// Đèn đang tắt → bật
ledOn = true;
ledOnTime = now;
digitalWrite(LED_PIN, HIGH);
Serial.println("Bật đèn (30 giây)");
} else {
// Đèn đang bật → tắt ngay
ledOn = false;
digitalWrite(LED_PIN, LOW);
Serial.println("Tắt đèn sớm");
}
}
// Tự tắt sau 30 giây
if (ledOn && (now - ledOnTime >= AUTO_OFF_MS)) {
ledOn = false;
digitalWrite(LED_PIN, LOW);
Serial.println("Tự tắt sau 30 giây");
}
}
Kết Quả Mong Đợi
=== Touch Sensor TTP223 ===
Không chạm vào pad trong 0.5 giây đầu (IC calibrating)
Sẵn sàng — chạm vào pad!
CHẠM!
CHẠM!
CHẠM!
Ứng Dụng Thực Tế
| Ứng dụng | Chi tiết |
|---|---|
| Công tắc đèn cảm ứng | Toggle LED/relay khi chạm |
| Đèn ngủ tự tắt | Bật đèn 30 giây khi chạm |
| Bàn phím không lộ dây | Pad cảm biến sau mặt kính/nhựa |
| Wake-on-touch | Chạm để wake ESP32 từ deep sleep |
| Điều khiển nhạc | Chạm ngắn/dài cho next/prev |
Lưu Ý Khi Sử Dụng
1. Không chạm pad trong 0.5s đầu sau cấp nguồn
IC đang đo baseline calibration. Nếu tay chạm trong lúc này → IC baseline sai → không phát hiện chạm được. Code phải có delay(600) hoặc đợi tín hiệu calibration xong.
2. Nhiễu điện trường gây false positive
Đặt dây điện 220V gần pad → EMI gây kích hoạt nhầm. Giải pháp: nối mass mạch điện với đất vật lý, đặt module xa nguồn điện AC, thêm tụ 100nF từ VCC xuống GND.
3. Chạm qua vật liệu mỏng được
TTP223 phát hiện qua kính hoặc nhựa dày <10mm. Đây là ưu điểm lớn: lắp module bên trong sản phẩm, mặt ngoài sạch đẹp không lỗ.
4. Toggle mode — hàn Pad A
Nếu muốn “nhấn 1 lần bật, nhấn lần nữa tắt” mà không cần code xử lý toggle: hàn kín Pad A trên mặt sau module. Đơn giản hóa firmware nhưng không đọc được thời gian nhấn (long press).


