おことわり
この記事では Microchip ATMEGA2560 の真贋を判定していますが、あくまで「私の手元にある基板について」「私なりの基準で」判定したものに過ぎません。お手元の基板や一般に流通している製品にそのまま通用することを保証するものではありません。
事の発端
Original Prusa 3S+ を MK4S に upgrade した際、諸々の部品とあわせて Einsy RAMbo が余った
↓
メルカリで売る手もあるが、これはこれで遊べそうなので手元に置いておくことにしよう
↓
とはいえいきなり実機で遊ぶのは敷居が高い。見通しがよい(殺風景とも言う) 8-bit MCU で遊びたい気分でもあるので、まずは元になった Arduino MEGA 2560 をいじってみようか
↓
公式の基板はお高いので Amazon で安いものを探そう
↓
届いたけどこれニセモノ!?
↓
興味が出てきてしまい、色々買ってみた ←イマココ
色々な基板と載っているMCU
公式の Arduino MEGA 2560 Rev3 は秋月電子通商で買いました。他は Amazon で “Arduino MEGA 2560” で検索した結果のうち、送料なしで入手できるものを選んでいます。
Arduino MEGA 2560 Rev3
購入元: https://akizukidenshi.com/catalog/g/g107381/
製品情報: https://docs.arduino.cc/hardware/mega-2560/
まずは言わずと知れた公式の基板から。結局「どうせニセモノも混ざってるんやろ? 比較用にちゃんとしたものも買うといたろ」という意図で買いました。高いとか何だかんだ言っていますが、確実に信頼できます。



ELEGOO Arduino用 MEGA2560 R3ボード (黒)
購入元: https://www.amazon.co.jp/dp/B06Y4KZV1J
製品情報: 不明
昔は Arduino 関連の部品、最近は 3D printer で有名な ELEGOO brand の基板。青と黒が販売されており、今回はカッコいい黒を選びました。写真にはありませんが USB A-B cable が付属します。
この基板の ATMEGA2560 には妙な斑点があります。標記の書体も他と異なるうえ、縦方向に削ったような跡(?) もあり、怪しさバツグンですね。



KEYESTUDIO Mega 2560 R3 Plus マイコン ボード
購入元: https://www.amazon.co.jp/dp/B08V4RCRS2
黒の基板に黄色の樹脂部品という、かなり目立つ基板です。”Plus” と書いてある方は USB が Type-C となっており、GPIO を使いやすいよう独自の pin header を配置しています。写真にはありませんが、USB A-C cable が付属します。



KEYESTUDIO Mega 2560 R3 マイコン 開発ボード
購入元: https://www.amazon.co.jp/dp/B01COV7KRS
前項と同じく KEYESTUDIO brand の製品で、やはり目立つ基板です。USB-B 版は公式と同じ設計になっています。写真にはありませんが、USB A-B cable が付属します。



WINGONEER Mega 2560 PRO MINI
購入元: https://www.amazon.co.jp/dp/B07HBR257M
製品情報: 不明。たぶん何かの clone か、その子孫
Arduino form factor ではありませんが、まあ物は試しにと買ってみました。このMCUの marking だけ 2017年の PCN (GBNG-15KQFZ896) より古い仕様になっており、date code は 1345 (2013年の45週目、11月4〜10日) と書いてあります。SARS-CoV-2 やその他諸々による半導体不足のはるか以前の部品が今時流通しているとはとても思えないのですが……。



どうやって偽物を識別するか
色々と手段はあるようですが、今回は以下の通りとしました。
- 外観
- Signature bytes
- Serial number
- IdCode (JTAG)
さすがにX線透過写真を撮る設備はありませんし、使う(もしくは返品する)つもりで買った基板のMCUを炙ったり削ったりするわけにはいきません。
外観
上述の通り、ELEGOO brand の基板だけは明らかに不審です。WINGONEER brand の表記は、古いものの正常に見えます。いや2013年の部品がイマドキ流通してるワケないだろ。
Signature bytes
AVR series には MCU の品種を示す register があります。Datasheet にも記載されており、ATMEGA2560 の場合は 0x1e, 0x98, 0x01 となっています。手元にある PICKit4 を使って avrdude で取得するときはこんな感じ。
avrdude -p m2560 -c pickit4_icsp -q -F -U signature:r:-:h
今回の5枚では以下の通りでした。
製品名 | Brand | Signature bytes |
---|---|---|
Arduino MEGA 2560 | Arduino | 0x1e, 0x98, 0x01 |
Arduino用 MEGA2560 R3ボード(黒) | ELEGOO | 0x1e, 0x98, 0x01 |
Mega 2560 R3 Plus マイコン ボード | KEYESTUDIO | 0x1e, 0x98, 0x01 |
Mega 2560 R3 マイコン 開発ボード | KEYESTUDIO | 0x1e, 0x98, 0x01 |
Mega 2560 PRO MINI | WINGONEER | 0x1e, 0x98, 0x01 |
いずれも問題ありませんね。次に行きましょう。
Serial number
ネタ元は SensorWiki という海外の web page です。Arduino で program を書き込んで調べる方法が示されていますが、ICSP header を使って avrdude で読み出すこともできます。また Arduino MEGA 2560 の基板はよく考えられた設計になっていて、ATMEGA16U2 の ICSP header も出ています。USB-UART 変換に ATMEGA16U2 を使っているものは、そちらも取得してみました。前項同様、PICKit4 と avrdude を使うとこんな感じです。
# ATMEGA2560 で serial number を読み出す
avrdude -p m2560 -c pickit4_icsp -q -F -U sernum:r:-:h
# ATMEGA32U4
avrdude -p m32u4 -c pickit4_icsp -q -F -U sernum:r:-:h
# ATMEGA328P
avrdude -p m328p -c pickit4_icsp -q -F -U sernum:r:-:h
# ATMEGA328PB
avrdude -p m328pb -c pickit4_icsp -q -F -U sernum:r:-:h
公式には「Classic AVR は ATMEGA328PB のみ対応。Modern AVR はほとんどの品種が対応」となっているものの、調べた範囲では動作しました。ただし ATMEGA2560 は公式には非対応なので、これが証拠になるかは微妙なところです。
製品名 | Brand | MCU | Serial number |
---|---|---|---|
Arduino MEGA 2560 | Arduino | ATMEGA2560 | 0x43,0x33,0x38,0x32,0x34,0x38,0xff,0x13,0x1,0xb |
Arduino MEGA 2560 | Arduino | ATMEGA16U2 | 0x34,0x34,0x39,0x35,0x35,0x36,0x15,0x14,0x20,0x1d |
Arduino用 MEGA2560 R3ボード(黒) | ELEGOO | ATMEGA2560 | 0x58,0xff,0xfd,0xff,0xfd,0xff,0xff,0xff,0xff,0xff |
Arduino用 MEGA2560 R3ボード(黒) | ELEGOO | ATMEGA16U2 | 0x43,0x33,0x31,0x32,0x39,0x35,0x15,0x8,0x26,0x23 |
Mega 2560 R3 Plus マイコン ボード | KEYESTUDIO | ATMEGA2560 | 0x6e,0x75,0x6e,0x6b,0x77,0x6f,0xff,0x0,0x8,0x2 |
Mega 2560 R3 マイコン 開発ボード | KEYESTUDIO | ATMEGA2560 | 0x6e,0x75,0x6e,0x6b,0x77,0x6f,0xff,0x0,0x12,0x7 |
Mega 2560 R3 マイコン 開発ボード | KEYESTUDIO | ATMEGA16U2 | 0x42,0x33,0x31,0x30,0x33,0x32,0x15,0x17,0x1b,0x5 |
Mega 2560 PRO MINI | WINGONEER | ATMEGA2560 | 0x58,0x33,0x30,0x32,0x33,0x38,0xff,0x13,0xc,0x10 |
参考資料 | ATMEGA328P | 0x32,0x32,0x36,0x39,0x39,0x36,0xff,0xc,0x37,0x1c | |
参考資料 | ATMEGA328PB | 0x4d,0x30,0x42,0x34,0x32,0x49,0x69,0x8,0x18,0x23 |
末尾 3bytes が wafer number と wafer 上の位置を示す座標になっています。ELEGOO の ATMEGA2560 だけ 0xFF が連続しており、際立っておかしな値になっています。同じ基板に載っている ATMEGA16U2 はそれっぽい値になっているのですが。
また、KEYESTUDIO の2製品は ATMEGA2560 の表記にある date code に26週間の開きがあるにもかかわらず、同じ lot 番号になっています。不自然ですね。
JTAG IdCode
ATMEGA2560 は JTAG boundary scan に対応しており、工場出荷時には有効になっています。ただし Arduino に載っているものは無効化されているため、fuse bit を変更して電源を入れ直す必要があります。
# JTAGEN を 0 にする (JTAGを有効にする)
avrdude -p m2560 -c pickit4_icsp -q -F -U hfuse:w:90:m
JTAG debugger には秋月電子通商のAE-FT232HLと OpenOCD を使いました。
openocd -s dir/of/scripts/ -f interface/ftdi/um232h.cfg -c "adapter speed 4500" -c "jtag newtap avr cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x5980103F"
正常に動作すれば以下のような出力になります。ついでに silicone revision も分かるんですが、この場合は 0x5 (Rev.F) ですね。
Open On-Chip Debugger 0.12.0 (2024-12-30-15:51)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
adapter speed: 4500 kHz
Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 4500 kHz
Info : JTAG tap: avr.cpu tap/device found: 0x5980103f (mfg: 0x01f (Atmel), part: 0x9801, ver: 0x5)
Warn : gdb services need one or more targets defined
一方、ここでボロを出した WINGONEER の基板はこんな感じ。
Open On-Chip Debugger 0.12.0 (2024-12-30-15:51)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
adapter speed: 4500 kHz
Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 4500 kHz
Info : JTAG tap: avr.cpu tap/device found: 0xffffff03 (mfg: 0x781 (<unknown>), part: 0xffff, ver: 0xf)
Warn : JTAG tap: avr.cpu UNEXPECTED: 0xffffff03 (mfg: 0x781 (<unknown>), part: 0xffff, ver: 0xf)
Error: JTAG tap: avr.cpu expected 1 of 1: 0x5980103f (mfg: 0x01f (Atmel), part: 0x9801, ver: 0x5)
Error: Trying to use configured scan chain anyway...
Error: avr.cpu: IR capture error; saw 0x00 not 0x01
Warn : Bypassing JTAG setup events due to errors
Warn : gdb services need one or more targets defined
なお fuse bit を戻す方法は以下の通り。
# JTAGEN を 1 にする (JTAGを無効にする)
avrdude -p m2560 -c pickit4_icsp -q -F -U hfuse:w:d0:m
まとめ
ということで、ここまでの結果をまとめてみました。
Arduino MEGA 2560 Rev3 | Arduino用 MEGA2560 R3ボード(黒) | Mega 2560 R3 Plus マイコン ボード | Mega 2560 R3 マイコン 開発ボード | Mega 2560 PRO MINI | |
---|---|---|---|---|---|
Brand | Arduino | ELEGOO | KEYESTUDIO | KEYESTUDIO | WINGONEER |
購入元 | 秋月電子通商 | Amazon | Amazon | Amazon | Amazon |
税(10%)込価格 | 6,920 | 2,639 | 2,699 | 2,699 | 2,139 |
USB-UART変換 | ATMEGA16U2 | ATMEGA16U2 | CP2102 | ATMEGA16U2 | WCH340G |
USB端子 | B | B | C | B | Micro-B |
MCU外観 | OK | 斑点・傷あり、字が細い | OK | OK | 表記が極端に古い |
Date Code | 2404RWB | 2401Y96 | 22435AS | 221747C | 1345 |
Signature bytes | OK | OK | OK | OK | OK |
S/N | 0x43,0x33,0x38,0x32,0x34,0x38,0xff,0x13,0x1,0xb | 0x58,0xff,0xfd,0xff,0xfd,0xff,0xff,0xff,0xff,0xff | 0x6e,0x75,0x6e,0x6b,0x77,0x6f,0xff,0x0,0x8,0x2 | 0x6e,0x75,0x6e,0x6b,0x77,0x6f,0xff,0x0,0x12,0x7 | 0x58,0x33,0x30,0x32,0x33,0x38,0xff,0x13,0xc,0x10 |
JTAG IdCode | 0x5980103f | 0x5980103f | 0x5980103f | 0x5980103f | 0xfffff03f |
判定 | OK | 偽物 | 偽物 | 偽物 | 偽物 |
その他の注意事項 | ICSPのsilkが間違い |
まさか互換基板3社4製品のすべてが偽物とは。Amazon Marketplace はなかなか刺激的です。こうやって開発基板として検証できればいいのですが、製品に組み込まれてしまうと厳しいものがあります。そんな素性の知れない、datasheet 通りに振る舞うかも分からない製品が普通に流通してるんじゃないかと思うと、なかなか怖いですね。
余談
Errata を意図的に踏むことで真贋を判定しようと思ったのですが、うまくいきませんでした。Datasheet によると、revision F は「ADC は differential mode で gain 200x で使えない」旨の記述があります。が、これがどうやっても再現しません。”Not Functional” って具体的に何なの。
とりあえず使った code を掲載しておきます。
#define F_CPU 16000000UL
#define BAUD 9600
#define MYUBRR (F_CPU/16/BAUD-1)
#define BUFFER_SIZE 100
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
void uart_init(unsigned int ubrr)
{
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
void adc_init()
{
ADMUX |= (1<<REFS0)|(1<<ADLAR);
ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADEN);
}
void uart_transmit(char* str)
{
int n = 0;
while(*(str + n) != '\0')
{
while ( !( UCSR0A & (1<<UDRE0)) );
UDR0 = *(str + n);
n++;
}
}
int main(void)
{
uart_init(MYUBRR);
adc_init();
int adc_value;
char buff[BUFFER_SIZE];
while(1)
{
// ADMUX = (ADMUX & 0xE0) | 0b11011; // Mode: Differential, Positive: ADC3, Negative: ADC2, Gain: 1x, Range: -5V .. 5V
// ADMUX = (ADMUX & 0xE0) | 0b01101; // Mode: Differential, Positive: ADC3, Negative: ADC2, Gain: 10x, Range: -500mV .. 500mV
ADMUX = (ADMUX & 0xE0) | 0b01111; // Mode: Differential, Positive: ADC3, Negative: ADC2, Gain: 200x, Range: -25mV .. 25mV
ADCSRA |= (1<<ADSC);
while( ADCSRA & (1<<ADSC) );
adc_value = ADC;
sprintf(buff, "ADC Value: %d\r\n", adc_value >> 6);
uart_transmit(buff);
_delay_ms(500);
}
}
コメントを残す