Nội dung bài viết
Vũ Quang Huy Arduino có rất nhiều phiên bản khác nhau như Uno R3, Pro, Mega ... Mỗi phiên bản này lại sử dụng một loại vi điều khiển. Và cũng có trường hợp ngay cả một phiên bản mà sử dụng các loại vi điều khiển khác nhau. Chính vì tính linh động này, ta cần phải xác định được vi xử lý đang sử dụng để có hướng lập trình phù hợp.

Giới thiệu

Nhằm mục đích đáp ứng nhiều yêu cầu khác nhau của công việc, nhà sản xuất Arduino đã đưa ra cho người sử dụng rất nhiều tùy chọn khác nhau về kích thước, số lượng chân giao tiếp, bộ vi xử lý ... Tùy theo mỗi trường hợp mà ta có thể lựa chọn một Arduino board thích hợp với nhu cầu sử dụng của mình.

Ví dự như những thiết bị cần có kích thước nhỏ gọn thì Arduino Pro Mini hay Arduino Nano là lựa chọn đầu tiên. Trong khi đó, ở mức độ phổ thông thì ta có thể dùng Arduino Uno - cân bằng giữa hiệu năng và kích thước. Tuy nhiên, nếu yêu cầu cần phải xử lý nhiều dữ liệu và giao tiếp với nhiều thiết bị khác, Arduino Mega hay Due là ứng viên sáng giá.

Mỗi Arduino board như vậy lại sử dụng một loại vi điều khiển (microcontroller unit - từ nay tôi sẽ viết tắt là VDK) khác nhau: Arduino Uno R3 sử dụng VDK ATmega328P trong khi Arduino Mega sử dụng VDK ATmega2560. Mỗi loại VDK này lại có bộ nhớ, tốc độ xử lý, số chân giao tiếp ... khác nhau.

Vì vậy, đặt trường hợp khi viết thư viện cho nhiều loại Arduino board khác nhau, ta cần phải biết chính xác loại VDK đang sử dụng để có hướng lập trình phù hợp.

Tiền đề bài viết

Trong quá trình xây dựng dự án robot cho STDIO, tôi và anh La Kiến Vinh làm việc trên nhiều board Arduino khác nhau. Bài viết này ra đời nhờ sự gợi ý của anh về giải pháp nhận biết VDK đang thao tác.

Bạn đọc có thể tham khảo các bài viết khác cùng chuyên mục tại STDIO :: Arduino.

Đối tượng hướng đến

Bài viết dành cho các bạn đã có kiến thức về lập trình C++ và nắm được cơ bản về cách sử dụng Arduino.

Phương pháp xác định

Hầu hết các Arduino board đều sử dụng VDK sản xuất bởi Atmel, các VDK này thường được đặt tên bắt đầu với ATxxxxx như ATmega328P, ATtiny13 ... Tương ứng với mỗi VDK, ta đều có 1 mã cho chúng, gọi là signature code. Mã này không phải là duy nhất cho mỗi VDK, như là duy nhất cho mỗi dòng VDK

Với Arduino, ta có thể biết được loại VDK đang sử dụng bằng cách truy vấn 3 hằng số lần lượt là SIGNATURE_0, SIGNATURE_1SIGNATURE_2, tương ứng với 3 byte của signature code.

Bảng sau đây giải thích ý nghĩa của từng hằng số:

Hằng số Ý nghĩa Giá trị hợp lệ
SIGNATURE_0 Mã của hãng sản xuất

1E nghĩa là VDK này sản xuất bởi Atmel

SIGNATURE_1 Dòng VDK và bộ nhớ flash 9n - VDK AVR với 2n kB bộ nhớ
SIGNATURE_2 Mã của VDK Tên chính xác của VDK này

Dựa trên bảng này, đây là danh sách các signature code của một số VDK phổ biến được sản xuất bởi hãng Atmel:

Loại MCU Signature code
ATtiny13 1E9007
ATtiny2313 1E910A
ATmega48P 1E920A
ATmega8 1E9307
ATmega168 1E9406
ATmega32 1E9502
ATmega328P 1E950F
ATmega328-PU 1E9514
ATmega64 1E9602
ATmega644 1E9609
ATmega128 1E9702
ATmega1280 1E9703
ATmega2560 1E9801

Vậy ví dụ như ta truy vấn 3 hằng số và nhận được kết quả:

  • SIGNATURE_0 = 0x1E
  • SIGNATURE_1 = 0x98
  • SIGNATURE_2 = 0x01

Dựa theo bảng trên, ta biết được VDK đang sử dụng là ATmega2560 với bộ nhớ flash là 28 = 256 kB.

Code minh hoạ

Với Arduino Uno R3, trên thị trường có 2 phiên bản sử dụng 2 loại VDK khác nhau là ATmega328PATmega168. Đoạn code sau minh họa việc nhận biết 2 loại VDK này:

void setup()
{
	Serial.begin(9600);	
	char* mcuType;
	
	if (SIGNATURE_0 == 0x1E || SIGNATURE_0 == 0x00)
	{
		if (SIGNATURE_1 == 0x95 && SIGNATURE_2 == 0x0F)
		{
			mcuType = "ATmega328P";
		} 
		else if (SIGNATURE_1 == 0x94 && SIGNATURE_2 == 0x06)
		{
			mcuType = "ATmega168";
		} 
		else 
		{
			mcuType = "Unknown Atmel MCU"; 
		}
	} 
	else
	{
		mcuType = "Unknown MCU";
	}
	
	Serial.print("This Arduino using MCU: ");
	Serial.println(mcuType);
}

void loop() { 
	
}
THẢO LUẬN
ĐÓNG