公開日:2020/02/15
title.png

9th Season


#9-5 ブレッドボードにArduinoっぽい物

 前回(「#9-4 ATmega328のヒューズ書き込み」)は、購入したATmega328P-PU単体LSIに遊ばれて、ようやく、UNO用のブートローダ書き込みまで終わらせました。今回は、ブレッドボード上にArduinoっぽい物を作り込みます。

 そもそも、Arduino UNOって、ATmega328のI/Oポートを全てピンソケットに引き出して、後はリセットや電源、クロック回路と、USBでインターフェイスするためのUSB⇔UART変換チップ(ATmega16U2等)が載っただけのMCUボードとなっています。
 UNOで開発したアプリケーションは、単体のATmega328チップを購入してくれば、もっと安価で、かつ小さいスペースに押し込むことができます。他のパッケージ(QFP等)品を使うと、もっと小さくできます。

 と、言うことで今回の目標は、「ATmega328P-PUを使って、Arduinoで開発したアプリケーションを実施可能な最小回路を作る」です。
 量産現場では、AVRプログラマみたいなものを使って、プログラムをフラッシュに書き込むのですが、趣味の世界(DIY)では、Arduino IDEから書き込めた方が便利なので、Arduinoとしてプログラムを書き込めるように構成したいと思います。

 本家Arduinoの回路構成調査から始めましょう。

情報調査

 Arduino HPから、「RESOURCES ⇒ PRODUCTS」を選択すると、ArduinoのMCUボード一覧にアクセスできます。この中から、MCUにATmega328を使用している、UNO/Pro Mini/Nanoの各回路図を参照して調査します。
 回路が一番簡単なPro Miniを見て、そこからUNOやNanoの回路で差分を見つけるという方法が、一番わかりやすいでしょう。Pro Miniは、下の方の「Retired」カテゴリに残っているはずです。Pro Miniをクリックして、表示されたページの「DOCUMENTATION」タブに「SCHEMATICS」が見つかりますので、これを開きます。

 Pro Miniはシンプルですね〜。USB⇔UART変換機能を持たないので、ほぼ、ATmega328周りの回路しかありません。今回、電源は、5Vなど所定の電源電圧を外部から供給してもらうことを前提とするので、電源回路については不問とします。
 すると、作り込みが必要な回路は、リセット回路と発振回路くらいですね。それぞれ見て行きましょう。

リセット回路

 Pro Miniのリセット回路は、プルアップ(10kΩ)と、リセットスイッチ、0.1μF(=100nF)を介したDTR接続、だけですね。DTR接続の部分については、後ほどシミュレーションするので、そこで考察します。
 Nanoも、Pro Miniと全く同じ回路構成でした。ただし、プルアップ抵抗が1kΩと小さめです。
 UNOは、1)プルアップ抵抗(10kΩ)と並列にダイオードが入っている、2)DTRが1kΩで接地されている、の2点で差分が見られます。後ほど考察します。

発振回路

 Pro miniの発振回路は、発振子および負荷容量×2個、と、一般的な発振回路の部品が見えます。具体的なパラメータの記載はありませんでした。
 NanoもPro Miniと同じ構成です。
 UNOは、発振子と並列に1MΩ抵抗が追加されています。実はUNOだけ、発振子の型番が記載されています。
 発振回路についても、後ほど考察します。

その他回路

 その他は、Vcc−GND間にパスコン(バイパスコンデンサ、0.1μF)を接続、AREF−GND間にデカップリングコンデンサ(=パスコン……同じ物を指すらしい……、0.1μF)を接続、PB5(SCK、D13)にオンボードLED(LED_BUILTIN)が繋がっています。

回路の詳細検討

 ここから、リセット回路と発振回路の設計にあたって、具体的に検討を進めて行きたいと思います。UNO/Pro Mini/Nanoで、若干の差異が見られたので、回路の動作原理等を調べながら、各々について検討を進めます。

リセット回路

 最大仕様だった、UNOの回路をLTspiceでシミュレーションして動作を確認しておきます。UNOの回路を下図に示します。

ar95_resuno.png

※Pro MiniとNanoでは、接地抵抗R2、クランプダイオードD1が省略されています。ダイオードは手持ちの1N4007を使う予定なので、UNOの回路図とは異なる型番を使用しています。

 まずは、いきなりシミュレーションしてみます。

ar95_res1.png

 DTR端子(下段、緑線)を適切にトグルしてみたところ、RESET端子(上図ではRES、中段青線)には、DTRの立ち下がりエッジで一瞬0Vに落ちた後、CR回路(対象はC5とR1)に充電され、Vcc(=5V)まで上昇する波形が得られました。逆に、DTRの立ち上がりエッジで、ぴょこっと、6.1V程度まで上昇する波形になっています。

 さて、DTR(Data Terminal Ready)ですが、非同期シリアル通信において、通信端末(Data Terminal)の準備ができた(Ready)時に、アサートされる信号です。一般的に負論理なので、アサート=LOWレベルとなります。
 Arduinoでこの信号がどう使われているか?と言うと、ホストPCからプログラム(スケッチ)の書き込み指示が来た時にDTRがアサートされるので、そのタイミングでATmega328にリセットをかけて、ブートローダを呼び出すために使っています。
 従って、Arduino IDEからのプログラム書き込みに対応するためには、DTRによるリセット回路が必須となります。

 DTRは、Arduino IDEの書き込み中ずっとアサートされ続けているので、立ち下がりエッジでリセットする必要があります。0.1μFのコンデンサC5は、この立ち下がりエッジを検出するために入っているみたいです。シミュレーション波形の上段、赤線で示したのは、RESET(RES)端子の入力レベル(Vil=0.1×Vcc,Vih=0.9×Vcc)で二値化した波形です。Vil⇔Vih間の電圧は、条件によって0と読めるか1と読めるか不明なので、この電圧の間は2.5V(中間値)になっています。
 ATmega328は、赤線が0Vに落ちたところでリセットがかかります。髭のように細いですが、拡大してみたところ、RESET端子に確実にLOWレベルが入力される時間は約100μsでした。ATmega328データシートによると、RESET端子の最小パルス幅は2.5μsなので、100μsのLOW幅があれば確実にリセットがかかります。

 もう一点注意しておきたいのは、DTR立ち上がりエッジにおいて、RESET端子に約6.1Vの電圧がかかっていることです。
 通常のI/Oポートだと、入力電圧<Vcc+0.5V(ABS.MAX)が規定されているので、Vcc=5Vの時、6.1Vがかかってしまうと絶対最大定格違反となり、LSI(ATmega328)が破壊される可能性があります。
 しかし、RESET端子のみ、入力電圧<13.0V(ABS.MAX)が規定されており、6.1V程度なら、何ら問題ありません。元々RESET端子は、パラレルプログラミングモードで使用する時に、メモリ書き込み用の高電圧電源(12V)を供給するための端子となっているため、耐圧が高くなっているようです。

 UNOとPro Mini/Nanoとの差分は、接地抵抗R2と、クランプダイオードD1の2点でした。
 接地抵抗R2に関しては、DTRが切り離された時に、DTRノードの電位を確実にGNDレベルに落とすためのものと、考えることができます。R2は、有った方が良いけど、無ければ無いで、「動作に支障をきたす可能性は低い」との判断なのでしょう。個人的には接地しておくべきだと思いますが……。

※というか、ここ、接地じゃなくてプルアップではダメだったのだろうか??

 クランプダイオードD1については、D1を削除してシミュレーションして見れば一目瞭然です(下図)。

ar95_res2.png

 この(↑)通り。ダイオードが無いと、DTR立ち上がりエッジでRESET端子が10V(=2×Vcc)まで跳ね上がります。「RESET端子の耐圧が13V(ABS.MAX)なので問題ない」という判断なのでしょうが、何か、気持ち悪いですよね?

※10V(=2×Vcc)まで跳ね上がるメカニズムは、「#6-1 オペアンプ、の、前に香辛料」で試したチャージポンプ(ダブラ)と同じです。

 以上の考察より、部品点数は多くなりますが、UNOの回路を採用したいと考えます。

発振回路

 一般的な発振回路は、以下図の様になります。

ar95_osc.png

 この内、Pro Mini/Nanoの回路図に存在するのは、XTAL,CL1,CL2の3点です。UNOの回路には、加えてRfが接続されていると考えることができます。

 通常、帰還抵抗は、安定して発振させるために必要なので、LSI内部に組み込まれていることが多いです。Pro Mini/Nanoの回路にRfが外付けされていないことから考えて、少なくとも、ATmega328の内部にOSC,INV,Rfの3点が内蔵されているものと考えられます。Rdも組み込まれている可能性はありますが、通常は0Ωでしょう。

※ATmega328のデータシートには、内蔵発振回路のポンチ絵ですら記載が無いので、詳細は不明であり、想像するしかありません。

 よって、UNOの回路に記載のあった1MΩ抵抗は、内蔵されたRfと並列に入っていることになるので、帰還抵抗が合成抵抗値(=1MΩ//Rf)になるように調整していることになります。

 量産現場では、発振回路はとてもシビアで、部品やLSIの製造ばらつき、温度特性、電源電圧など、全条件で安定して発振させるのは、とても大変です。通常は、LSIメーカないし発振子メーカに評価を依頼して、適切な発振子の型番と外部回路のパラメータを教えてもらって、量産します。
 UNOの回路も、使用した発振子とATmega328P-PUとの組み合わせで、1MΩを追加する様に助言があったのでしょう。今回使う水晶発振子は、UNOの回路図とは異なるものですし、恐らく、趣味の世界(DIY)で使うだけなら、そんなにナーバスにならずとも発振するはずですので、帰還抵抗は追加せず、Pro Mini/Nanoの回路構成を採用します。

※さらに言及すると、同じチップ(ダイ)を使ったATmega328であっても、パッケージが異なると、発振回路の最適なパラメータが変わる可能性があります。UNOはATmega328P-PU(28DIP)に対して、Pro MiniはATmega328P-AU(32TQFP)、Nanoは手持ちがないのでわからないけど、多分、ATmega328P-MU(32MLF)と、みんな違うパッケージです……(1^へ^;)。

 負荷容量CL1,CL2は、ATmega328データシートに、「12〜22pF」と記載がありました。これも、本来は、発振子メーカ等に依頼して最適値をアドバイスしてもらうものですが、そもそも、手持ちに22pFのセラミックコンデンサしか無い(一択)ので、これを使います。

回路を設計する

 前節の検討を受けて完成した回路図が下図となります。

ar95_schem1.png

 前回「#9-4 ATmega328のヒューズ書き込み」、購入した真っ新なATmega328P-PUにUNOのブートローダを書き込んであるので、上の回路を構築した後、USB⇔UART変換モジュール(FTDI等)を使って、RXI,TXO,DTRを介してPCと接続すると、Arduino IDEから「UNOターゲット」で書き込み/デバッグを実行することが可能となります。

実装する

 「Arduinoっぽい物」の「最小構成」を謳うので、170穴ミニブレッドボードに構築したいと思います。普段は、何も考えず行き当たりばったりでブレッドボードに回路を構築するのですが、170穴(17行)しかないミニブレッドボードへ28ピン(14行占有)LSIを挿したら、さすがにパンパンなので、まずは、PowerPointを使ってフロアプランを作成しておきます(下図)。

ar95_floor.png

 さすがに、リセットスイッチ(タクトスイッチ)を実装するスペースは確保できませんでした。前節に示した回路図で、リセットスイッチに当たるSW1を除いて、残りの部品は全て配置してあります。

 フロアプランに従って実装した結果がこちら(↓)です。

ar95_328duino_1.jpg

 ディスクリート部品が多いので、ゴチャッとした印象ですね。
 今後、自作装置として実験に使うこともあろうかと思いますので、本HP(Arduino DIY)では、上図の装置を「328duino」と称します。

※328duino:ほぼほぼ、ATmega328そのもの、なので命名。ちなみに、読み進んでいただくとわかりますが、こっちは「第一形態」です。

動作検証

 328duino(←呼称、早速使ってみる……)は、アプリケーションとしてはUNOと同等ですが、USBなど、Arduino IDEとのインターフェイスが無いので、プログラム(スケッチ)を書き込む際には、USB⇔UART変換モジュールが必要となります。ここでは、手持ちのFTDI(下図)を使います。

ar41_ftdi.jpg

 では、328duinoにプログラム(スケッチ)を書き込んでみましょう。以下の様に結線してUSBでPCと接続します。

FTDI 接続 328duino
VCC(5V) Vcc
GND GND
RX TXO
TX RXI
DTR DTR

※FTDIの電圧ジャンパは5V側にしておきます。

 以下、実験手順です。

 エラー無くコンパイル&書き込みが終了すれば成功です。PB5_SCK_D13にLED_BUILTINを接続しておくと、およそ1秒間隔でLEDが点いたり消えたりするはずです。

 以下、実験中の様子です。

ar95_expr1.jpg

 筆者の環境では、無事、動作しました。動かなかった場合には、回路が間違っていないか、よく確認して下さい。

※万一、「発振しない」なんて悲劇に遭遇すると、専門外の筆者にはノーアイディアですm(1__)m。既にRd=0Ωなので、負荷容量CL1,CL2を変えて見るとか、UNOみたいにフィードバック抵抗を追加してみるとか??

 アプリケーション(システム)のデバッグ中は、頻繁にプログラムを修正して、その都度書き込みが発生するので、上図の様に、FTDIは繋ぎっぱなしになります。デバッグ中は、FTDIから電源(5V)をもらった方が便利です。デバッグが終了するとFTDIは不要なので、別途、5V電源を外部から供給する必要があります。

更に部品点数を減らす

 前節の動作確認で、以上終了、めでたしめでたし♪、なのですが、ここから更に、極限まで部品点数を減らしてみたいと思います。

リセット回路

 リセット回路は、NanoやPro Miniの回路を採用すると、部品点数を削減可能でしたね。
 でも、そんなものではないんです。実は、ATmega328データシートによると、RESET端子にはプルアップ抵抗が内蔵されています。本文中には、リセット回路のブロック図内に表記があり、電気的特性の中に「Rrst(Reset Pull-up Resistor)=30〜60[kΩ]」の規定が存在します。
 念のため実物で確認したところ、ちゃんとプルアップされていました。

※RESET端子に10kΩ程度の抵抗だけを繋いで接地した状態で、ATmega328P-PUに電源(5V)を投入しました。Logiscopeを起動したArduino UNOから、RESET端子の電位を測定(【ina】コマンド)したところ、約0.86Vが読めました。この電圧は、プルアップ抵抗Rrstと接地抵抗10kΩの抵抗分圧値と見ることができるので、5V×10kΩ/(Rrst+10kΩ)=0.86Vより、Rrst≒48kΩとなり、バッチリ定格範囲内でした。

 つまり、外付けのプルアップ抵抗は削除可能です。
 Arduino IDEからプログラム(スケッチ)を書き込む時だけ、コンデンサを介してDTRを接続すれば良く、フィールドでプログラムの書き込みが必要なければ、RESET端子の処理はプルアップのみで良いので、内蔵プルアップを期待して「N.C.で良い」、というのが結論です。
 なんと、RESET回路が丸ごと要らなくなってしまいました。

 ただし、本当に外部のプルアップ抵抗を削除してしまったところ、書き込み時の挙動が怪しいです。DTRでうまくリセットがかかっていない様な挙動が見られました。原因は、プルアップ抵抗(Rrst≒48kΩ、実測値)が大きすぎるためでした。
 リセット回路では、エッジ検出に使っているC5とプルアップ抵抗(Rrst)の間でCR回路を構成しており、時定数C5×Rrstが大きすぎることで、1)DTRの立ち下がりエッジでRESETのLOWレベルが十分に下がり切らないこと、2)RESET端子がHIGHに戻るまでの時間が伸びること、等によって、うまくリセットがかからなかった様です。
 解決策は、時定数がC5×Rrst=0.1μF×10kΩ程度となるように、C5=0.1μF×10kΩ/Rrst≒20nFとするか、外付けに10kΩ程度のプルアップ抵抗を追加するかのいずれかです。手持ちに20nFのコンデンサがありませんので、書き込みする時だけは、外部にプルアップ抵抗10kΩを追加することにしました。
 次節で示す完成版回路図でご確認ください。

※折角削減したプルアップ抵抗を復活させるというのは間抜けな話でした……(1x_x)。お手元に20nF程度のコンデンサをお持ちの方は、そちらで試してみてください。

発振回路

 さすがに、発振回路は削減できない、と、思ってますか?ATmega328には、内蔵RC発振器(8MHz)があるので、こいつを使うと、外部に発振回路が必要なくなります。
 この場合、動作周波数が8MHzになることで、16MHzを前提としたUNOのブートローダでは通信速度が合わず、書き込みできなくなってしまうため、別なブートローダを書き込みます。Pro Miniには、3.3V,8MHzで動作するバリエーション(機体)が存在するので、この、Pro Mini(@3.3V,8MHz)用のブートローダを書き込むと、Arduino IDEから書き込みできるようになります。

 ブートローダの書き込み手順は、繰り返しになるので、「#9-4 ATmega328のヒューズ書き込み」を参照してください。

※上のリンク先を参照して、書き込むブートローダの選択肢を「Pro or Pro Mini (@3.3V,8MHz)」に読み替えてください。

 ブートローダを書き込んだ直後の状態では、ヒューズが「8〜16[MHz]低電力水晶発振モード」に設定されていますので、ヒューズ値を書き換えます。
 前回の記事で、単体LSI ATmega328P-PUの設定ビットを確認した回路と手順で、以下の様に実行します。

  実験サンプル:【 】内は、シリアルモニタからの送信データ
  【dmpb】
  OK+ fuse: 0xfd 0xda 0xff
  OK+ lock: 0xcf
  OK+ cali: 0x9c
  OK: sign: 0x1e 0x95 0x0f 0x00

 Pro Miniのブートローダは、UNOより少しサイズが大きいので、ブート領域のサイズ(ヒューズH=0xda、UNOでは0xde)が異なっていますが、Pro Miniとしては正常です。

※Pro Miniのブートサイズは、1,024×16ビット=2Kバイトと、ちょっと大きめ(ちなみにUNOは256×16ビット=512バイト)。ブートでこんなに食うなんて、もったいないな……。

  【wrfl,e2】
  OK? to write 0xE2 to fuse.l? send 'y' or 'n' > Yes, go
    【y】 …… 確認して、OKの場合。
  OK: write fuse.l=0xe2

 ヒューズLビットに内蔵RC発振器(8MHz)をシステムクロックとして使用する設定値を書き込みました。前回は予想外に、ブートローダの書き込みとヒューズビットの設定をArduinoISP.inoが実行してくれたため、せっかく作ったプログラム(ser_prog.ino)の活躍するチャンスが無かったのですが、ようやく、ヒューズの書き込みで活用することができましたv(1^−^)v。

完成した第二形態

 さて、最終的な回路図がどうなったか?と言うと、以下図です。

ar95_schem2.png

 もう、ほんと何も無いです。パスコンと電源の結線だけ……。

※こう言っては何ですが、パスコンなんて回路上不要な部品であって、無ければ無いでそこそこ動きはするので、ほぼ、ATmega328P-PU単体で動作させられてしまうんですね。やっぱり、愛い奴です💘

 170穴ミニブレッドボードに実装してみても、以下図の通り。あまりにスカスカなので、電源(Vcc,GND)配線をプラグインターミナル(青いブロック)に引き出してみました。

ar95_328duino_2.jpg

※前節の回路とは構成が違っているので、前節の回路を特に「328duino(第一形態)」、本節の回路を「328duino(第二形態)」と区別することにします。

プログラム(スケッチ)書き込み

 さっきと同様に、Blinkを書き込んでみましょう。Pro Mini(@3.3V,8MHz)のブートローダを書き込んだ時点で、前節で書き込んだBlinkは消されてしまっているので、再書き込みが必要です。プログラムを書き込む時だけ、FTDIのDTR出力を、コンデンサC5+追加プルアップ抵抗R1を介してRESET端子に接続します。
 FTDIとの接続は前節と同じです。fcpu=8MHzであれば、Vcc≧2.7Vで十分動作可能(w/10%マージン)なので、FTDIの電圧ジャンパ:3.3V側して使用することも可能です。ただし、FTDIの3.3V電源は50mA(MAX)程度しか電流を流せないので、電流供給能力には注意して下さい。
 書き込みが終了したら、C5,R1は取り外してしまってOKです。

※尚、C5とR1は、繋ぎっぱなしでも悪さはしないはずです(Pro Miniと同じ回路構成になるだけ)。「最小構成」と言う事で、取り外すような記述になっていますが、普段使うときは、繋ぎっぱなしでOKです。

 書き込みが成功したら、約1秒間隔でLED_BUILTINが点滅するはずです。回路図には記載してませんが、点滅を確認したい場合には、PB5_SCK_D13端子にLED_BUILTINを接続しておいてください。



 最小回路でLチカしている様子です。アプリケーションのLED_BUILTIN(LED+電流制限抵抗)は別として、ATmega328P-PU+0.1μFコンデンサ×2個+電源結線のみで動作していることに注目してください。
 本ページの解説を読まないで動画だけ見たら、「ただのLチカじゃん」って思うでしょうが、発振回路も見当たらず、ほぼハダカのATmega328P-PU単体でLチカしていると気が付けば、「ん?」ってなるはずです。

ar95_expr2.jpg

 動画では、手元にあった単三型電池ボックス(×4本タイプ)を使って給電しました。注意!使用したのはeneloop(1.2V)×4本=4.8Vです。アルカリ乾電池(1.5V)×4本=6Vだと、絶対最大定格違反です(LSIが破壊する恐れあり)。

 8MHzで動作させるだけなら、動作電圧的には乾電池4本も必要ありません(下図)。

ar5a_fmax.png

 ATmega328のVcc−動作周波数特性は上図の様になっているので、動作周波数を落として低電圧で動作させたい場合、fcpu=8MHzなら2.4Vがオンスペック(マージン0%)なので、eneloop(1.2V)×2本で駆動できます。ただし、ヒューズEでBOD(低電圧検出機能)を有効にしている場合、UNO/Pro Miniの設定ではBODLEVEL=2.7V(TYP、2.5V(MIN)〜2.9V(MAX))なので、2.4Vだと、BODレベル以下となってリセットがかかってしまいます(つまり、動作しない)。

※「#9-4 ATmega328のヒューズ書き込み」のプログラム(ser_prog.ino)を使えば、ヒューズに所望の値を書き込むことができるので、BODLEVELをもう一段低い値(1.8V(TYP))に設定すれば、動作させることができると思われます(ただし、当方では未確認)。

 マージン10%以上確保したい場合にはVcc≧2.7Vが必要なので、eneloopなら×3本(1.2V×3=3.6V)または、アルカリ乾電池×2本(1.5V×2=3V)が必要となります。

※他のマイコンやモジュールなどと連携する時には、3.3V/5Vなどに統一しない限り、一々L/Sの挿入が必要になります。

 また、低電圧で動作させたいモチベーションが無い場合、8MHzだろうが10MHzだろうが、5Vを供給しておけば、AD変換器のリファレンス電圧もUNOと同じ5Vのまま使用できますし、I/Oの出力レベルも5Vにできるので、UNO等とのインターフェイスも取りやすくなります。

今回のお買い物

 今回のお買い物は、以下の通りです。

 電池BOXからの給電用に使ったプラグイン端子(下図)だけは、ずいぶん昔に買っておいたものです。

ar95_plugin.jpg

 USBケーブルをばらして電源線(5VとGND)を引き出した時、ブレッドボードにコンタクトするため等に、ちょいちょい使っていました。写真に見えている2本脚がブレッドボードに挿さるので、普通の撚線をブレッドボードに導入するのに最適です。
 その他の部品は、前回のATmega328P-PUと一緒に購入しました。


 今回のチャレンジが示すものは、「Arduinoで作ったアプリケーションは、ATmega328を購入してボードに実装すれば、簡単に組み込めますよ」ってことです。量産する人たちにも嬉しいことだろうし、DIY民にとっても、ブレッドボードや万能基板上に簡単に組み込めるって言うのは、ハッピィなことです💯。……無駄な周辺回路とか、カッチリ作り込まないと動かないようなシビアなチップとか、要らないの……。ホレてまうやろ〜。


btn_arduino.png

btn_prev.png btn_next.png

home