Arduino Mega 2560: khi nào cần, sơ đồ chân theo chức năng, bốn cổng Serial, bản CH340 hay 16U2
Arduino Mega 2560 so với Uno, Nano, ESP32: khi nào cần, sơ đồ chân theo chức năng (I2C 20, 21, SPI 50–53), dùng bốn cổng Serial phần cứng cùng lúc, bản CH340 hay 16U2 và lỗi hay gặp.
Arduino Mega 2560 là mạch Arduino cỡ lớn dùng chip ATmega2560: cùng họ AVR 16 MHz với Uno và Nano nên code gần như dùng chung, nhưng có 54 chân số, 16 chân analog, 8 KB RAM và đặc biệt là bốn cổng Serial phần cứng. Bài này so sánh Mega với Uno, Nano, ESP32 để biết khi nào thật sự cần Mega, sơ đồ chân theo từng chức năng (I2C, SPI ở chỗ khác Uno), cách dùng cả bốn cổng Serial cùng lúc, và khác biệt giữa bản dùng chip USB 16U2 với bản CH340.
1. Mega 2560 so với Uno, Nano, ESP32

- Mega không nhanh hơn Uno: cùng 16 MHz, cùng kiến trúc 8 bit. Mega hơn ở số chân, số cổng Serial, bộ nhớ chương trình (256 KB) và RAM (8 KB so với 2 KB).
- Code viết cho Uno chạy được trên Mega, trừ những chỗ dùng thẳng chân I2C, SPI hoặc thanh ghi của ATmega328P.
- Nếu cần Wi-Fi, nhiều RAM hay tính toán nhiều, ESP32 rẻ hơn và mạnh hơn hẳn; chỉ lưu ý ESP32 dùng mức logic 3,3 V.
Nền tảng Arduino, cách cài IDE và cấu trúc setup(), loop() có ở bài Arduino là gì.
2. Sơ đồ chân theo chức năng

- I2C ở chân 20 (SDA), 21 (SCL), không phải A4, A5 như Uno. Bản Rev3 có thêm hai chân SDA, SCL cạnh chân AREF, nối chung với 20, 21.
- SPI ở chân 50–53, không phải 11–13. Shield SPI viết cho Uno thường lấy SPI qua đầu ICSP 6 chân nên vẫn chạy; shield nối thẳng vào 11–13 thì phải nối lại.
- Sáu chân có ngắt ngoài (2, 3, 18, 19, 20, 21), nhưng 18, 19 trùng Serial1 và 20, 21 trùng I2C: dùng cổng nào thì mất ngắt ở chân đó.
- Chân 3V3 chỉ cho khoảng 50 mA: không đủ cấp cho module Wi-Fi, RF; dùng ổn áp 3,3 V riêng.
3. Bốn cổng Serial cùng lúc

Uno chỉ có một cổng Serial phần cứng và cổng đó đã dùng cho USB; thêm thiết bị Serial phải dùng SoftwareSerial, chậm và dễ mất byte khi nhận nhanh hay khi có ngắt khác. Mega có sẵn Serial1, Serial2, Serial3 với bộ đệm và ngắt riêng, nên nối cùng lúc GPS, module RS-485, Bluetooth mà vẫn giữ cổng USB để in kết quả.
Chương trình dưới đây đọc từng dòng nhận từ Serial1..3 và in ra máy tính kèm tên cổng; gõ 2:noi dung ở Serial Monitor (115200, chọn New Line) để gửi một dòng ra Serial2. Mảng con trỏ CONG[] giúp xử lý ba cổng bằng cùng một hàm.
/*
PYWORLD.VN - Arduino Mega 2560 dùng cả bốn cổng Serial phần cứng: Serial (USB), Serial1 (TX1 18, RX1 19), Serial2 (16, 17), Serial3 (14, 15)
PYWORLD.VN - Dòng nhận từ Serial1..3 được in ra máy tính kèm tên cổng; gõ "2:noi dung" ở Serial Monitor để gửi ra Serial2; in RAM còn trống
PYWORLD.VN - Ví dụ nối: GPS vào Serial1 (9600), module RS-485 vào Serial2, Bluetooth HC-05 vào Serial3; nối chung GND, chú ý mức 5 V
*/
HardwareSerial *const CONG[] = {&Serial1, &Serial2, &Serial3};
const long TOC_DO[] = {9600, 9600, 9600};
const byte DAI_DONG = 80;
char dem[3][DAI_DONG + 1];
byte doDai[3] = {0, 0, 0};
int ramConTrong() {
extern int __heap_start, *__brkval;
int dinh;
return (int)&dinh - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
}
void nhanTuCong(byte i) {
while (CONG[i]->available()) {
char c = CONG[i]->read();
if (c == '\r') continue;
if (c == '\n' || doDai[i] >= DAI_DONG) {
dem[i][doDai[i]] = '\0';
if (doDai[i] > 0) {
Serial.print(F("[Serial"));
Serial.print(i + 1);
Serial.print(F("] "));
Serial.println(dem[i]);
}
doDai[i] = 0;
} else {
dem[i][doDai[i]++] = c;
}
}
}
void guiTuMayTinh() {
static char lenh[DAI_DONG + 1];
static byte n = 0;
while (Serial.available()) {
char c = Serial.read();
if (c == '\r') continue;
if (c != '\n' && n < DAI_DONG) {
lenh[n++] = c;
continue;
}
lenh[n] = '\0';
if (n >= 3 && lenh[1] == ':' && lenh[0] >= '1' && lenh[0] <= '3') { // dạng "2:noi dung"
byte i = lenh[0] - '1';
CONG[i]->println(lenh + 2);
Serial.print(F("-> Serial"));
Serial.print(i + 1);
Serial.print(F(": "));
Serial.println(lenh + 2);
} else if (n > 0) {
Serial.println(F("Lenh dang 1:..., 2:..., 3:..."));
}
n = 0;
}
}
void setup() {
Serial.begin(115200);
for (byte i = 0; i < 3; i++) CONG[i]->begin(TOC_DO[i]);
Serial.println(F("Mega 2560: 4 cong Serial san sang"));
Serial.print(F("RAM con trong: "));
Serial.print(ramConTrong());
Serial.println(F(" / 8192 byte"));
}
void loop() {
for (byte i = 0; i < 3; i++) nhanTuCong(i);
guiTuMayTinh();
}

- Nhớ nối chéo: TX của Mega vào RX của module, RX của Mega vào TX của module, và nối chung GND.
- Mega ra mức 5 V. Module chạy 3,3 V (HC-05, nhiều module GPS) chịu được mức 3,3 V từ TX của module vào RX của Mega, nhưng chân RX của module cần cầu chia áp (ví dụ 1 kΩ và 2 kΩ) để không nhận 5 V.
- Hàm
ramConTrong()cho biết RAM còn lại; mỗi cổng Serial dùng bộ đệm gửi và nhận 64 byte, bốn cổng tốn khoảng 600 byte RAM.
4. Khi nào cần Mega 2560

- Máy in 3D, CNC đời cũ dùng mạch RAMPS: firmware và shield làm sẵn cho Mega, nên Mega gần như là lựa chọn bắt buộc.
- Nhiều nút, đèn, relay: trước khi lên Mega, cân nhắc Nano kèm IC mở rộng 74HC595 (ngõ ra) hoặc PCF8574 (I2C), rẻ và ít dây hơn.
- Cần mạng, nhiều RAM: dùng ESP32. Dự án nhỏ gọn: dùng Arduino Nano.
5. Bản 16U2 hay CH340, nạp code
- Mega 2560 chính hãng dùng chip ATmega16U2 làm cổng USB; nhiều bản giá rẻ dùng chip CH340. Hai bản chạy như nhau, chỉ khác driver: Windows mới thường tự nhận CH340, máy cũ cần cài driver CH340.
- Trong Arduino IDE chọn Tools → Board → Arduino Mega or Mega 2560, Processor ATmega2560, rồi chọn đúng cổng COM.
- Cấp nguồn ngoài qua jack DC hoặc VIN từ 7–12 V; cao hơn thì ổn áp trên mạch nóng, nhất là khi lấy nhiều dòng từ chân 5V.
Lỗi nạp code (không thấy cổng COM, avrdude không đồng bộ) gần giống Nano, xem bài Arduino Nano không nạp được code; driver CH340 có ở bài bắt đầu với Arduino Nano CH340.
6. Lỗi hay gặp
| Hiện tượng | Nguyên nhân | Cách xử lý |
|---|---|---|
| Màn hình I2C chạy trên Uno, không chạy trên Mega | Nối vào A4, A5 như Uno | Nối SDA chân 20, SCL chân 21 |
| Module thẻ SD, RFID SPI không nhận | Nối vào 11–13 như Uno | Dùng 50–52 (MISO, MOSI, SCK) hoặc đầu ICSP |
| Không nhận được gì ở Serial1 | Nối TX vào TX, sai tốc độ, thiếu GND | Nối chéo TX–RX, đúng tốc độ module, nối GND |
| Nạp báo lỗi khi đang nối thiết bị ở chân 0, 1 | Chân 0, 1 dùng chung với chip USB | Chuyển thiết bị sang Serial1..3 |
| Chương trình chạy lạ khi thêm nhiều chuỗi | Hết RAM (chuỗi nằm trong RAM) | Bọc chuỗi bằng F(), kiểm tra ramConTrong() |
Bài cùng cụm chủ đề: sơ đồ chân Arduino Uno; Arduino Uno R4.
Xem thêm