Arduino là gì: bo mạch, Arduino IDE, code Arduino, setup() và loop(), Uno và Nano khác nhau
Arduino là gì: bo mạch, Arduino IDE, lõi và thư viện; code Arduino là C++; setup() và loop() được gọi từ đâu; chuyện gì xảy ra khi bấm Upload; so sánh Uno, Nano, Mega và giới hạn.
Arduino là cái tên người học điện tử, lập trình nhúng nào cũng gặp đầu tiên: bo mạch Arduino Uno, Arduino Nano, phần mềm Arduino IDE, "code Arduino". Nhưng Arduino không chỉ là một bo mạch. Bài này giải thích Arduino gồm những gì, "code Arduino" thực chất là ngôn ngữ gì, vì sao chương trình nào cũng có setup() và loop(), chuyện gì xảy ra khi bấm Upload, các bo phổ biến khác nhau ra sao và khi nào nên chuyển sang ESP32.
1. Arduino là gì

Arduino là một nền tảng mở để làm mạch điện tử có lập trình, ra đời năm 2005 ở Ý cho sinh viên thiết kế, những người không chuyên điện tử. Nền tảng gồm:
- Bo mạch: vi điều khiển đã có sẵn nguồn, thạch anh, cổng USB và chương trình nạp (bootloader). Thiết kế mạch được công bố công khai, nên có rất nhiều bo tương thích do các hãng khác sản xuất.
- Arduino IDE: phần mềm miễn phí để viết code, biên dịch, nạp vào bo và xem dữ liệu gửi lên qua Serial Monitor.
- Lõi (core) và các hàm có sẵn:
pinMode(),digitalWrite(),analogRead(),millis(),Serial… che bớt chi tiết thanh ghi của chip. - Thư viện và cộng đồng: hàng nghìn thư viện cho cảm biến, màn hình, động cơ, cài ngay trong IDE, kèm ví dụ mẫu.
Nhờ phần lõi, cùng một cách viết chạy được trên nhiều loại chip: ESP32, ESP8266 cũng có lõi Arduino riêng, nên người đã quen Arduino chuyển sang ESP32 rất nhanh.
2. "Code Arduino" là ngôn ngữ gì
Không có ngôn ngữ riêng tên Arduino. Code Arduino là C++, viết trong file đuôi .ino (gọi là sketch), dùng thêm các hàm của lõi Arduino. Ví dụ:
pinMode(13, OUTPUT): đặt chân 13 làm ngõ ra (để bật tắt LED).INPUT_PULLUPlà ngõ vào có điện trở kéo lên bên trong, hay dùng cho nút nhấn.digitalWrite(13, HIGH): đưa chân lên mức cao (5 V trên Nano, Uno).digitalRead()đọc mức của chân.analogRead(A0): đọc điện áp ở chân analog thành số 0–1023.millis(): số mili giây từ lúc chạy, dùng để đo thời gian mà không phải dừng chương trình.
Trước khi biên dịch, IDE tự thêm dòng #include <Arduino.h> và khai báo các hàm bạn viết, nên sketch ngắn gọn hơn chương trình C++ bình thường.
3. setup() và loop()

main() có sẵn trong lõi Arduino AVR (rút gọn phần USB).Mọi chương trình C/C++ đều bắt đầu từ hàm main(). Arduino viết sẵn hàm này trong lõi: nó khởi động bộ đếm thời gian, gọi setup() một lần, rồi gọi loop() lặp lại mãi mãi. Vì vậy:
- Đặt vào
setup()những việc làm một lần: cấu hình chân, mở Serial, khởi động cảm biến. - Đặt vào
loop()công việc lặp lại: đọc cảm biến, kiểm tra nút, điều khiển đầu ra. Hàm này nên chạy nhanh rồi thoát, để lần lặp sau đến sớm.
Chương trình dưới đây nháy LED có sẵn trên bo bằng millis() thay cho delay(), đồng thời đọc biến trở ở chân A0 mỗi 500 ms và đếm xem loop() đã chạy bao nhiêu lần trong khoảng đó. Nối biến trở: chân giữa vào A0, hai chân ngoài vào 5V và GND. Mở Serial Monitor ở 9600 baud để xem.
// PYWORLD.VN - Arduino nhập môn: setup() chạy một lần, loop() chạy mãi
// PYWORLD.VN - Nháy LED chân 13 bằng millis() (không dùng delay()) và in giá trị biến trở ở A0 mỗi 500 ms
// PYWORLD.VN - Viết cho Arduino Nano, Uno; sang bo khác thì đổi CHAN_LED, CHAN_BIEN_TRO và điện áp tham chiếu
const int CHAN_LED = 13; // LED "L" hàn sẵn trên Nano, Uno
const int CHAN_BIEN_TRO = A0; // chân giữa biến trở; hai chân kia nối 5V và GND
const unsigned long CHU_KY_NHAY_MS = 250;
const unsigned long CHU_KY_IN_MS = 500;
const long DIEN_AP_THAM_CHIEU_MV = 5000;
unsigned long lucDoiLed = 0;
unsigned long lucIn = 0;
bool ledSang = false;
unsigned long soVongLap = 0;
void setup() {
// Chạy một lần sau khi cấp điện hoặc nhấn RESET
pinMode(CHAN_LED, OUTPUT);
Serial.begin(9600);
Serial.println(F("setup() chay mot lan"));
}
void loop() {
// Chạy lặp lại mãi; không chờ ở đâu cả nên mỗi lần lặp rất nhanh
soVongLap++;
unsigned long bayGio = millis();
if (bayGio - lucDoiLed >= CHU_KY_NHAY_MS) {
lucDoiLed = bayGio;
ledSang = !ledSang;
digitalWrite(CHAN_LED, ledSang ? HIGH : LOW);
}
if (bayGio - lucIn >= CHU_KY_IN_MS) {
lucIn = bayGio;
int giaTri = analogRead(CHAN_BIEN_TRO); // 0..1023
long milliVon = (long)giaTri * DIEN_AP_THAM_CHIEU_MV / 1023;
Serial.print(F("A0 = "));
Serial.print(giaTri);
Serial.print(F(" ("));
Serial.print(milliVon);
Serial.print(F(" mV), loop() da chay "));
Serial.print(soVongLap);
Serial.println(F(" lan"));
soVongLap = 0;
}
}
Con số "loop() da chay" rất lớn cho thấy loop() quay rất nhanh khi không có delay(). Nếu thay đoạn nháy LED bằng delay(250), con số đó tụt xuống chỉ còn vài lần, và mọi việc khác (đọc nút, nhận lệnh Serial) cũng phải chờ theo.
4. Chuyện gì xảy ra khi bấm Upload

Chip ATmega328P trên Nano không tự hiểu USB. Bo mạch có thêm một chip chuyển USB sang cổng nối tiếp (thường là CH340 ở bản giá rẻ), Windows thấy nó như một cổng COM. Khi nạp, IDE reset chip; bootloader (một chương trình nhỏ có sẵn ở cuối bộ nhớ Flash) nhận file mã máy qua cổng nối tiếp và ghi vào Flash, rồi chuyển sang chạy chương trình mới. Nếu báo lỗi ở bước biên dịch, đó là lỗi code; nếu lỗi ở bước nạp, thường do chọn sai cổng, sai bo, thiếu driver CH340 hoặc dây USB chỉ có lõi sạc.
5. Các bo Arduino phổ biến
| Bo | Chip | Flash / RAM | Chân | Hợp với |
|---|---|---|---|---|
| Uno R3 | ATmega328P, 16 MHz | 32 KB / 2 KB | 14 số (6 PWM), 6 analog | Học cơ bản, gắn shield |
| Nano | ATmega328P, 16 MHz | 32 KB / 2 KB | 14 số (6 PWM), 8 analog (A6, A7 chỉ đọc analog) | Cắm breadboard, mạch nhỏ |
| Mega 2560 | ATmega2560, 16 MHz | 256 KB / 8 KB | 54 số (15 PWM), 16 analog | Nhiều chân: máy in 3D, CNC |
| Pro Mini | ATmega328P, 8 hoặc 16 MHz | 32 KB / 2 KB | như Nano | Thiết bị nhỏ, chạy pin; nạp bằng mạch USB-serial rời |
| ESP32 (lõi Arduino) | ESP32 hai nhân, 240 MHz | 4 MB / 520 KB | khoảng 25 chân dùng được | Wi-Fi, Bluetooth, dự án IoT |
Hãng Arduino cũng có các bo đời mới dùng chip 32 bit (ví dụ Uno R4). Cách viết code vẫn như trên.

6. Arduino làm được gì, giới hạn ở đâu
Uno, Nano làm tốt các việc: đọc cảm biến, nút, biến trở; điều khiển LED, relay, servo, động cơ bước; hiện số lên màn hình LCD, OLED; giao tiếp UART, I2C, SPI. Giới hạn chính:
- RAM 2 KB: không đủ cho chuỗi dài, bộ đệm lớn, màn hình màu độ phân giải cao.
- Không có Wi-Fi, Bluetooth: muốn kết nối mạng phải gắn thêm module.
- Mức logic 5 V: nhiều module 3,3 V cần chuyển mức.
Dự án cần mạng, tính toán nhiều hơn hoặc nhiều bộ nhớ thì ESP32 hợp hơn mà vẫn viết bằng Arduino IDE. Xem chọn mạch ESP32 nào và cài ESP32 vào Arduino IDE.
7. Bắt đầu với Arduino
- Một Arduino Nano, dây USB có lõi dữ liệu, breadboard và dây cắm. Muốn bắt dây bằng vít thì dùng đế ra chân cho Nano.
- Làm theo bắt đầu với Arduino Nano CH340: sơ đồ chân, driver và nạp code.
- Dự án tiếp theo: màn hình OLED với Nano, LCD 1602 I2C với Uno.
8. Lỗi hay gặp
| Hiện tượng | Nguyên nhân thường gặp | Cách xử lý |
|---|---|---|
| Không thấy cổng COM | Thiếu driver CH340, dây USB chỉ có lõi sạc | Cài driver, đổi dây có dữ liệu |
| Nạp báo "not in sync" | Bo dùng bootloader cũ, sai cổng | Chọn Processor "ATmega328P (Old Bootloader)", kiểm tra cổng |
| Lỗi "was not declared in this scope" | Sai tên biến, hàm; thiếu thư viện | Kiểm tra chính tả, cài thư viện |
| Serial Monitor in ký tự lạ | Tốc độ baud khác với Serial.begin() | Chọn đúng 9600 (như chương trình) |
| Chương trình chạy một lúc rồi treo, reset | Hết RAM, nguồn yếu khi tải lớn | Dùng F("...") cho chuỗi, nguồn riêng cho tải |
9. Xem thêm
- Chọn bo mạch lập trình đầu tiên cho học sinh
- Các bài cùng loạt lộ trình: học lập trình nhúng bắt đầu từ đâu, ESP32 là gì, chọn Arduino, ESP32, STM32 hay Raspberry Pi, C cho vi điều khiển.
Xem thêm