とある事情から、ATmega32U2をArduino化する必要があり、いろいろと困っておりましたが、解決したので記録を兼ねてご報告。
まずATmega32U2がArduinoになるのか、ということですが、「ATmega32U2にはADCもI2Cもない」。アナログ入力がないわけです。それらが揃っているのはU4のほう。U4はArduino Leonardoに始まり、各種のボードが販売されているものの、U2は機能不足だから商品化するメリットないよね、と納得しました。
とはいえU2ちっちゃいしピン数もU4より少なくて値上がりしたとはいえまだ秋月で400円だし、もう撤退できない状況があるので、検索をGoogleに変更してみたところ、わりとあっさりとkosakailabさんのブログエントリがヒットしまして、
とはいえU2ちっちゃいしピン数もU4より少なくて値上がりしたとはいえまだ秋月で400円だし、もう撤退できない状況があるので、検索をGoogleに変更してみたところ、わりとあっさりとkosakailabさんのブログエントリがヒットしまして、
ATmega32U2でArduinoモドキを作る - kosakailabMinimus32という商品(?)がかつてあったらしいことを知りました。
こちらMinimus32解析サイトによりますと、www.minimususb.comというドメインがOfficialだということでリンクが貼ってあるんですが、いま見ても日本語で2015年頃にゲーミングマウスがどうとかいう数個のエントリが掲載されたブログが表示されるのみでして、経緯がよくわかりません。他のリンク先もドメインが無効だったりして、情報不足であります。
ただ、kosakailabさんがGitHubリポジトリとbootloader作成の手がかりを示してくださっているので、一通り道具は揃いました。
pbrook/minimus-arduino - GitHub実際のところ、5V電源で16MHzのクロックを使うなら、すでにhexが置いてあるのでコンパイルする必要はないんですが、3.3V動作にする都合でクロックを8MHzに変更する必要があり、Makefileを書き換えてコンパイルする必要があった次第。
データシートの26.3項に、「安全動作圏」を示したグラフがあり、8bitのAVRマイコンでは3.3Vでは10MHz以下のクロックにしなければなりません。Arduinoでは3.3V製品としてSparkFun製Arduino Pro Miniの3.3V版があり、それに合わせて8MHz設定が公式ライブラリに追加されているので、3.3V動作の場合、8MHzのクリスタル一択です。bootloaderコンパイルにはLUFAが必要だよ、と書かれています。Unoが搭載しているUSB-UART変換にいまはATmega8U2が使われていますが、かつてはATmega16U2が使われていたこともあり、それらには、LUFAが活用されているようです。
オフィシャルサイトは「(2013)」と但し書きがついていますが、GitHubリポジトリは今年も更新されているようです。ともかくも、LUFAは、USBつきAVR開発支援軽量ライブラリとのこと。
さてそんじゃあbootloader作るべし、となるのですが、minimusプロジェクトが3年前で止まっているので、ちと工夫が必要でした。
まず、pbrookさんのレポジトリですが、Forkとjoinのグラフをみると、2年前にSurrealityLabsさんが手を加えたのがいまの最新っぽく見えました。
SurrealityLabs/minimus-arduino - GitHubこれを開くといきなり「avr」しか見えなくて不安になりますが大丈夫、全部入ってます。
よって、ここからgit clone。あとLUFAですが、最新のリポジトリからもってきたものはいろいろ構成がかわっているようで、コンパイルが通らず、Makefileに書かれていた111009(2011年10月9日版)を公式サイトからダウンロードしてくるのが簡単でした。
配置ですが、
avr-gcc
などツールチェインをArduino IDEから借りるのが手っ取り早いので、すでにインストールしてあるArduino IDE 1.6.11に組み込んでしまうのが話が早いです。あと、Windowsではmake
をどうするの、とかよくわからなかったのでコンパイルはMacでやりました。実はBash on Ubuntu on Windows 10でがんばってみたんだけど断念。いま思えばLinux用Arduino IDEから拾えばよかったのかも。コンパイルに必要な変更は、Makefileの「
F_CPU = 16000000
」を8000000
に変更するだけ。あと、bootloaderはCaterinaを使っていて、USBのVID/PIDは、Arduino LLCのVIDとLeonardoのPIDが書かれたままになっていますが、目をつぶってそのままに。おかげでlsusb
すると「Arduino SA Leonardo ( CDC ACM, HID)
」と出ますが、まあそういうことであります。pbrookさんのWikiには、Arduino IDEの
hardware/avr
以下を置き換えろみたいな乱暴なことが書かれていますが、そうするとMacの場合、Arduino IDEが上がらなくなってしまいました。で、Windowsのほうではどうだろうと、SurrealityLabsさんの
platform.txt
には1.6.0と書かれているので1.6.0でがっつり置き換えると、まあ起動はしましたが、bootloaderを書こうとすると、「書き込み装置の選択をしろ」的なメッセージが出て先に進みません。AVRISP mkIIを使っているので、それを選択してあるんですが、どうもだめ。そこで再び検索すると、こんなブログエントリがありまして
Arduino IDE on Windows with Minimus32 Profileなんだか、「一式固めといたよ」としてZIPファイルがリンクされていました。ですが、これを展開するとバッチファイルがありまして、Arduino IDE 1.0.5をダウンロードしてそこに置き換えのツールチェインとpbrookさんのリポジトリのZIPを配置する、というような仕立てになっておりました。
それができた状態で、Macで作ったhexファイルをもとのものと置き換えるものの、こちらではbootloaderを書き込もうとするとJavaのランタイムエラーが出てだめでした。Windows 10(1608版)なんですが。
もうこれはavrdudeのコマンドラインでいくしかないかな、と思いつつ、「もしやMacでこれと同じ構成にしたらうまくいくんではないか?」と思ったところ、うまくいきました。
Arduino IDEの設計は全くわかっていないんですが、
hardware
以下にarduino
というフォルダがあるところを、上のバッチファイルで作成した1.0.5版では、minimus
というフォルダを隣に作り、pbrookさんの一式はこちらにまるっと入れるという仕上がりになっていて、既存のファイル、特にboards.txt
なんかは一切書き換えていないのですが、起動したArduino IDEではきちんとminimus
以下のboards.txt
の内容が反映されていたわけです。ということで、Macの1.6.11でも同様に、
hardware/minimus
というフォルダを作り、一式をそこに放り込み、LUFA-111009
も放り込んでMakefile
でavr-gcc
等を呼び出すパスの追記やLUFAのパスを現状に合わせます。それから、macOSの認証を通すために一度無改造のままArduino.app
を起動してからなかみの変更をする必要がありますが、最初の起動時に、ボード設定その他をJSON形式で ~/Library/Arduino15
以下に置くので、それをリセットするために、このフォルダごと消しておきます。そして、とても大事なことなんですが、3.3Vにしたので、
boards.txt
に記述するAVRのフューズビットの設定を変更し、ブラウンアウト(電圧低下)検出 の電圧を3Vから2.7Vにしておかないと不安です。フューズビットは書き込み時にavrdude
のコマンドラインをArduino IDEが生成するときboards.txt
を参照するので、その16進の値を理解して、適切に設定した内容を書いておかなければなりません。ここで、AVR Fuse Calculatorの出番です。ところが検索してもATmega32Uシリーズが入っているものがなかなかありませんが、なんとか見つけました。
Engbedded Atmel AVR® Fuse Calculator - Electronics-Base.comで、「AVR Part Name」はATmega32U2ですからすぐ終わるわけですが、あとが困ります。わかんねえ。データシート全部読むのめんどい。
Atmelのデータシートの作りも不親切で、Fuse Bitについてまとめた項目がないんですよ。機能の説明があって、そこにFuse Bitはこう設定する、という部分的な表がばらばらにあるので、一覧できない。全部嫁ということになる。
まあいいや、ということで、既存の
boards.txt
でATmega32U4が採用されているものと、Minimus32の設定を見比べつつ、上の計算機の値をポチポチしてみると、Minimus32とU4採用Arduinoのfuse bitの設定は同じだということに気づくわけです。Yún, Leonardo, Micro, Esplora, Lilypad USB、どれとも共通です。すると問題になるのはBODの電圧設定のみで、それはextendedの項目であり、5V版である既存設定では3.0V。U2の場合選べるのは最低2.7Vしかないので、そこだけを変更。すると、0xf8が0xf6になるだけだ、という結論が導かれました。ということで、既存の
minimus32
の設定を複写して、minimus32v33
とかクラス名を変更したところで、name=Minimus 32 (3.3V)
とか書いて、bootloader.extended_fuses=0xf6
と書き換えます。あと、build.f_cpu=8000000L
も忘れずに変更しておきます。build.usb_product
にも「3V3
」を追記して、これでおしまい。参考までに、作ってみた部分を掲載しておきます。
追記するのは、############################################################# minimus32v33.name=Minimus 32 (3.3V) minimus32v33.vid.0=0x2341 minimus32v33.pid.0=0x0036 minimus32v33.vid.1=0x2341 minimus32v33.pid.1=0x8036 minimus32v33.upload.tool=avrdude minimus32v33.upload.protocol=avr109 minimus32v33.upload.maximum_size=28672 minimus32v33.upload.speed=57600 minimus32v33.upload.disable_flushing=true minimus32v33.upload.use_1200bps_touch=true minimus32v33.upload.wait_for_upload_port=true minimus32v33.bootloader.tool=avrdude minimus32v33.bootloader.low_fuses=0xff minimus32v33.bootloader.high_fuses=0xd8 minimus32v33.bootloader.extended_fuses=0xf6 minimus32v33.bootloader.file=caterina/Caterina-Minimus.hex minimus32v33.bootloader.unlock_bits=0x3F minimus32v33.bootloader.lock_bits=0x2F minimus32v33.build.mcu=atmega32u2 minimus32v33.build.f_cpu=8000000L minimus32v33.build.vid=0x2341 minimus32v33.build.pid=0x8036 minimus32v33.build.usb_product="Minimus32 3V3" minimus32v33.build.usb_manufacturer="Arduino" minimus32v33.build.board=MINIMUS32 minimus32v33.build.core=minimus minimus32v33.build.variant=minimus32 minimus32v33.build.extra_flags={build.usb_flags}
minimus
フォルダ以下のboards.txt
だけでよいです。arduino
以下には一切触りません。それでArduino IDE 1.6.11を起動して、ボードの選択をすると、ちゃんとArduinoとMinimusでカテゴリが分けられて選択できるようになりました。よくできてる。
ボード選択メニューの下に追加された |
ためしにスケッチを書いて、コンパイルと転送が通るかも試します。といっても、いまは何もないので、
Serial
オブジェクトがUSBに割り当てられているのを使って、IDEのシリアルモニタから入力があったら"Hello"
を印刷する簡単なスケッチを作り、コンパイルと転送してみました。なにやら「Minimusには対応していません」な警告が3つぐらい出ましたが、そのままコンパイルを終えて書き込みまでさくっと完了しました。感動。USBの標準速度が57600bpsになっているので、
Serial.begin(57600);
などと書き、シリアルモニタの設定も57600bpsにして適当な文字を入れ、「送信」ボタンを押すと、"Hello"
が出ました。動いているようです。これで、追加の回路も載せて制御できる見通しが立ちました。よかったよかった。なんですが、ひとつ回路について重大なことを書くのが遅くなりました。このブログエントリは流れ的にソフトウェアの話でいったん完結させるしかなかったので、最後ですが、自作されようとする方のために、また自分の作業記録として、書かなければなりませんので、ここに記します。
Minimus32の解析サイトに回路図がありますが、これをみると、普通のArduinoには見慣れない「HWB」というタクトスイッチがあります。pbrookさんのWikiにも図があって、リセットと隣合わせに並んでいるようです。そして、データシートを見ると、2ページのピン配置図では13番ピンに、「#HWB」なる端子があります(#は負論理)。さらに、他のU4を使ったArduinoでもフューズビット設定で、「Hardware Boot Enable」にチェックを入れています。「ハードウェアブート」はArduinoにおいて重要らしい。
Minimus32の商品(?)では、まじめにそのボタンをつけているんですが、U4を使った他のArduinoにそんなボタンはありません。なんでだろうと思ってデータシートを読むと、「HWBがLのときにRESETがUPするとハードウェアリセットがかかる」とありました。めんどくせえ。それで、手持ちのArduino Nanoの回路図をみたところ、HWBのラインは10kΩの抵抗を通してプルダウンされており(GNDに接続)、わざわざ「USB RESET EN」と書かれていました。HWBをプルダウンしておけば、リセットラインのL→Hの瞬間にリセットがかかるわけで、「これでいいのだ」ということのようです。よって、このピンはプルダウンしておきました。
それから、Minimus32はあえてICSP端子を設けていません。が、最初にbootloaderを書くにはICSPの6端子を用意しておいたほうが便利なわけでして、僕はつけておくことにしました。U2だと15ピンがSCK、16ピンがMOSI、17ピンがMISOと、SPI端子が連続しているので作りやすいと思います。
あと、要注意な点として、Minimusのピン配列は普通のArduinoとはだいぶ違います。pbrookさんのWikiの図必携。
具体的には、
HardwareSerial
(Serial1
)はD2がRx、D3がTxですし、D6, D7はUSBの送受信表示のLEDに使われています。D8はHWBで今回はプルダウンされたまま。さらにU2の制約として、タイマーは0(16bitカウンタ)と1(8bitカウンタ)の2つしかないのでPWMは4つですが、D1, D17がタイマー0、D19とD21がタイマー1という配置。タイマーという点では、標準ライブラリの
Servo()
はタイマー1を使うのでたぶん動くと思いますが、タイマー0はmills()
やdelay()
など時間関係の関数のために保留されていて、analogWrite()
は使えるよう考慮されているものの、Tone()
のために使うことはできず鳴りません。ためしにD1を指定してみたものの、コンパイルは通っても実際には鳴りませんでした。ただ、タイマー1で音を出すライブラリはいくつかあるようなので、
Servo()
に興味がなく、音を出したいという用途にはそれらを使うのだろうと思います。
最初のは正確な音程とコードのシンプルさ追求、2番目はタイマー出力2ピン両方をスピーカーにつなぐ形での音質追求、最後のはタイマー0のプリスケーラを1にして(分周しない)、超音波まで出せて音量調節まで実現するかわりに時間関数は破綻してよしとするなど、標準ライブラリに物足りない人向けのようです。
長くなりましたが、こちらからは以上です。