Lập trình

Biến, vòng lặp, điều kiện - học 3 khái niệm nền qua ví dụ robot thật

7 phút đọc05/07/2026HocLapTrinhRobot
Biến, vòng lặp, điều kiện - học 3 khái niệm nền qua ví dụ robot thật

Ba viên gạch đầu tiên của mọi ngôn ngữ lập trình giảng qua ví dụ robot ESP32 chạy được - biến lưu trạng thái, if ra quyết định, for/while lặp hành vi. Trong bài viết này, chúng ta sẽ cùng tìm hiểu chi tiết và ứng dụng thực tế trong robot.

Ba viên gạch xây nên mọi chương trình

Gỡ bỏ lớp vỏ cú pháp, mọi chương trình — từ game triệu đô đến robot dò line — đều xây từ ba viên gạch: biến (ghi nhớ), điều kiện (lựa chọn) và vòng lặp (lặp lại). Học ba khái niệm này qua ví dụ robot có lợi thế không gì thay được: mỗi khái niệm trừu tượng lập tức hiện hình thành hành vi vật lý nhìn thấy được.

Mọi ví dụ dưới đây chạy trên ESP32 với LED (GPIO 2), nút nhấn (GPIO 15) và cảm biến siêu âm — phần cứng của bài Breadboard, điện trở, LED ở mục Kiến thức.

Biến - trí nhớ của robot

Biến là ô nhớ có tên, chứa một giá trị thay đổi được:

cpp
int speed = 150;              // tốc độ hiện tại của robot
long distance = 0;            // khoảng cách vừa đo (cm)
bool isRunning = false;       // robot đang chạy hay dừng?
float angle = 90.5;           // góc servo - cần số lẻ nên dùng float

Ba việc làm được với biến: gán (speed = 200;), đọc (ledcWrite(ENA, speed);) và biến đổi (speed = speed + 10; — với người mới, dòng này gây sốc: đây là phép gán "lấy giá trị cũ cộng 10 rồi cất lại", không phải phương trình toán).

Ví dụ robot: nút nhấn đổi trạng thái

cpp
bool ledOn = false;           // BIẾN nhớ trạng thái đèn

void loop() {
  if (digitalRead(15) == LOW) {      // nhấn nút
    ledOn = !ledOn;                  // lật trạng thái: bật thành tắt, tắt thành bật
    digitalWrite(2, ledOn);
    delay(250);                      // chống rung phím kiểu đơn giản
  }
}

Không có biến ledOn, robot không thể "nhớ" đèn đang bật hay tắt — biến chính là trí nhớ. Robot thật dùng hàng chục biến kiểu này: đang ở chế độ nào, đã gắp vật chưa, lần cuối thấy vạch là bao giờ.

Điều kiện - robot biết lựa chọn

Lệnh if cho chương trình rẽ nhánh theo tình huống:

cpp
if (distance < 20) {
  stopMotors();               // chỉ chạy khi khoảng cách dưới 20
} else if (distance < 50) {
  slowDown();                 // 20-49: chạy chậm
} else {
  goForward();                // từ 50 trở lên: chạy bình thường
}

Chuỗi if - else if - else được thử từ trên xuống, chọn nhánh ĐẦU TIÊN đúng rồi bỏ qua phần còn lại — hiểu điểm này tránh được lớp lỗi "điều kiện sau không bao giờ chạy vì điều kiện trước nuốt mất".

So sánh và kết hợp

PhépÝ nghĩaBẫy
==bằng nhauMột dấu = là phép gán! if (x = 5) luôn đúng và phá giá trị x
!=, <, >, <=, >=khác, nhỏ/lớn hơn
&&VÀ - cả hai cùng đúngif (x > 0 && x < 100)
(hai gạch đứng)HOẶC - một trong hai đúng
!phủ địnhif (!isRunning) — "nếu KHÔNG đang chạy"

Ví dụ robot: né vật thông minh hơn

cpp
bool leftClear = readDistanceAt(-45) > 30;
bool rightClear = readDistanceAt(45) > 30;

if (leftClear && rightClear) {
  turnRight();                       // cả hai thoáng: chọn phải mặc định
} else if (leftClear) {
  turnLeft();
} else if (rightClear) {
  turnRight();
} else {
  turnAround();                      // kẹt cả hai bên: quay đầu
}

Đây chính là "trí thông minh" của robot tránh vật cản — thuần túy là các lệnh if xếp đúng thứ tự ưu tiên.

Vòng lặp - sức mạnh của sự lặp lại

for - lặp số lần biết trước

cpp
// LED nháy SOS: 3 nháy ngắn
for (int i = 0; i < 3; i++) {
  digitalWrite(2, HIGH);
  delay(150);
  digitalWrite(2, LOW);
  delay(150);
}

Đọc câu thần chú for (int i = 0; i < 3; i++): tạo biến đếm i từ 0; còn nhỏ hơn 3 thì làm thân vòng; xong mỗi vòng tăng i thêm 1. Biến i dùng được bên trong — ví dụ servo quét radar:

cpp
for (int angle = 0; angle <= 180; angle += 5) {
  servoWrite(angle);                 // servo quay từng nấc 5 độ
  delay(50);
  Serial.println(readDistanceCm()); // đo khoảng cách tại mỗi góc
}

Mười một dòng code = một radar quét — khoảnh khắc "wow" kinh điển của lớp học robot.

while - lặp đến khi điều kiện sụp

cpp
// tiến đến khi cách tường đúng 10 cm
while (readDistanceCm() > 10) {
  goForward();
}
stopMotors();

while hợp với "lặp đến khi sự kiện xảy ra" — không biết trước bao nhiêu vòng. Cẩn thận vòng lặp vô hạn ngoài ý muốn: nếu cảm biến hỏng trả mãi 400 cm, robot húc tường không bao giờ dừng — robot tử tế thêm giới hạn thời gian:

cpp
unsigned long start = millis();
while (readDistanceCm() > 10 && millis() - start < 5000) {
  goForward();                       // tối đa 5 giây rồi bỏ cuộc
}

Vòng lặp lồng nhau

cpp
// nháy đèn báo hiệu: 3 hồi, mỗi hồi 5 nháy
for (int round = 0; round < 3; round++) {
  for (int blink = 0; blink < 5; blink++) {
    digitalWrite(2, HIGH); delay(100);
    digitalWrite(2, LOW);  delay(100);
  }
  delay(1000);                       // nghỉ giữa các hồi
}

Vòng ngoài chạy 1 lần thì vòng trong trọn vẹn 5 lần — tổng 15 nháy. Nắm được nhịp này là nắm được ma trận LED, quét bàn phím, mọi cấu trúc hai chiều.

Bài tập tổng hợp - trạm đèn giao thông cảm biến

Đề: đèn (LED) bật khi có vật trong 30 cm liên tục 2 giây, tắt khi vật rời đi. Dùng cả ba viên gạch:

cpp
unsigned long detectedSince = 0;     // BIẾN: mốc thời gian phát hiện

void loop() {
  long d = readDistanceCm();

  if (d < 30) {                      // ĐIỀU KIỆN: có vật
    if (detectedSince == 0) detectedSince = millis();
    if (millis() - detectedSince > 2000) {
      digitalWrite(2, HIGH);         // đủ 2 giây liên tục mới bật
    }
  } else {
    detectedSince = 0;               // vật rời: reset đếm
    digitalWrite(2, LOW);
  }
}                                    // VÒNG LẶP: chính loop() lặp mãi

Giải được bài này không cần nhìn đáp án nghĩa là ba viên gạch đã nằm trong tay — sẵn sàng cho bài Hàm và thư viện ở mục Kiến thức, viên gạch thứ tư giúp code không thành mì spaghetti.

Câu hỏi thường gặp

Vì sao dùng == mà không phải = trong if?

= là gán (đổ giá trị vào biến), == là so sánh (hỏi hai bên có bằng nhau). if (x = 5) gán 5 vào x rồi coi 5 là "đúng" — điều kiện luôn thỏa, lỗi không báo biên dịch, tìm mòn mắt. Mẹo phòng: viết hằng số bên trái if (5 == x) — gõ nhầm một dấu = sẽ báo lỗi ngay.

for và while dùng cái nào?

Biết trước số lần (nháy 3 cái, quét 0-180 độ): for. Lặp theo sự kiện (đến khi chạm tường, đến khi hết vạch): while. Về lý thuyết hai loại thay được nhau — chọn loại đọc lên tự nhiên nhất.

Có nên học thuộc cú pháp không?

Không cần chủ đích — gõ nhiều tự thuộc. Thứ đáng luyện là đọc to được ý nghĩa: nhìn for (int i = 0; i < 5; i++) bật ra "lặp 5 lần". Khi tư duy chạy trước, cú pháp chỉ là gõ phím; ngược lại thuộc lòng cú pháp mà không có tư duy thì đề bài mới vẫn trắng giấy.

Blockly có ba viên gạch này không?

Đầy đủ — khối "biến", "nếu-thì-không thì", "lặp lại" ánh xạ 1-1 với bài này. Ai học Blockly trước sẽ nhận ra mọi thứ quen thuộc, chỉ khác vỏ — đúng như lộ trình trong bài Blockly vs code C++ ở mục Kiến thức.

Tài nguyên tải về

Tải bản PDF của bài viết để in giáo án hoặc gửi trước cho học viên.

Tải PDF
Chia sẻ bài viết