In some cases, it is important to programmatically detect the micro-controller type, e.g., is it an ATmega328p or an ATmega2560? For example, when dealing with USART communication, we need to know the MCU type, because different MCUs have different number of USART ports and some of them even require different settings for USART communication. While currently it is not possible to programmatically read the Arduino type (e.g., is it an Arduino UNO or a MEGA2560?), we can still detect the used MCU type.
Every ATmega MCU (and not only) has a signature code. This is not unique for every single chip, but it is unique for every MCU type. The AVR programming environment, provides three constants, SIGNATURE_0
, SIGNATURE_1
, and SIGNATURE_2
representing the three bytes of the signature code. Therefore, detecting the MCU type is as simple as reading these three constants and compare their values with the known ones for the chip type(s). The following Arduino sketch detects if we use an Atmega328P or an ATmega2560 MCU and uses the serial console to show this information:
char *mcuType;
void setup() {
Serial.begin( 115200);
if ( SIGNATURE_0 == 0x1E || SIGNATURE_0 == 0x00) {
if ( SIGNATURE_1 == 0x95 && SIGNATURE_2 == 0x0F) {
mcuType = "ATmega328p";
} else if ( SIGNATURE_1 == 0x98 && SIGNATURE_2 == 0x01) {
mcuType = "ATmega2560";
} else {
mcuType = "Unknown Atmel";
}
} else {
mcuType = "Unknown";
}
}
void loop() {
Serial.print( "Your MCU type is: ");
Serial.println( mcuType);
}
The following table explains the meaning of the three bytes signature code:
Address | Constant | Code | Valid codes |
$00 | SIGNATURE_0 | Vendor code | $1E indicates manufactured by Atmel
$00 indicates the device is locked |
$01 | SIGNATURE_1 | Part family and flash size | $9n indicates AVR with 2^n kB flash memory |
$02 | SIGNATURE_2 | Part number | identifies the exact chip in the family |
A list with the signature codes of the most used Atmel (the company which produces the Arduino chip) MCUs is shown below:
MCU type | 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 |