google-site-verification: google3bd66dd162ef54c7.html
FC2ブログ

Arduino よもやま話-5 (Arduino as ISP のエラー)

1.まえがき
久しぶりにArduino よもやま話です。ブートローダー入りの ATmega328P の手持ちが少なくなってきたので、新しいチップにブートローダーを書き込んだのですが、そこでちょっとトラブルが発生しました。幸い、問題は解決出来たのですが、その調査過程で結構勉強になったので、その内容について紹介します。

2.書き込み方法
ブートローダーを書き込むには、ハードとソフトの組み合わせでいろいろな方法があります。以前の私の記事では、Arduino UNOで ATmega328Pへブートローダーを書き込むでブレッドボードと optifix を使ったやり方について紹介しました。
そうしょっちゅうやる作業では無いので、その都度ブレッドボードを組んでも良いのですが、まあ面倒です。そういう手間を省くために買っておいたのが、aitendoの極貧ブートローダー書き込み機です。

▼極貧ブートローダー書き込み機
極貧ブートローダライター
書き込みに必要な最小限の回路だけ入っていて、表示用のLEDさえ省略するという貧乏臭い 割り切った仕様になっています。ちなみに195円のキットです。

▼使い方
極貧ブートローダライター取り付け
こんなふうに Arduino UNO の上に差し込んで使います。ピンとしては、10,11,12,13 とGNDと5Vの6ピンが接続されています。

3.ブートローダーを書き込んだらエラー(フェイル)発生
以前もこれを使って書き込んだことがあるのですぐに終わる、と思ってやってみたら様子が変で、何やらエラーが出ています。ちなみに、以前の記事では optifix を使いましたが、現在では Arduino IDE から直接サポートされている、Arduino as ISP を使うのが判り易い、というか正しい方法だと思います。

ということで、純正ツールである Arduino as ISP を使ったのにエラーが出る、というのは困ったものです。ともかく順に作業の経過を追ってみます。

▼Arduino ISP を書き込み
Arduino ISP

まずは書き込みツールとなるUNOに、スケッチ例にある書き込みソフト (ArduinoISP.ino) を書き込みます。

ちなみに optifix は書き込みのための全ての機能とブートローダーのhexファイルまで持っていて、UNO だけあればブートロダーの書き込みが出来ました(とは言っても操作のためにシリアルインターフェイスは必要)。それに対して ArduinoISP はライターの機能だけで、操作や書き込み用のhexファイルの供給は PC 上の avrdude から行なう仕様になっています。

▼書き込み実行(クリックで別窓に少し拡大)
Arduino as ISP でエラー

ツールから、書き込み装置:"Arduino as ISP" を指定して、「ブートローダーを書き込む」を実行すれば、書き込みが行われます。なお、ここでボードを指定すれば、違う種類のCPUにもブートローダーが書けるようです。つまり、ベース(書き込み機)へのスケッチ (ArduinoISP.ino)の書き込みの時と、ブートローダーを書き込む時のボードの指定を変えることになるのだと思いますが、なんだか間違えそうで怖い仕様です。

話を戻します。上の画面をよく見ると、「ブートローダーの書き込みが完了しました」と、うまくいっているような表示が出ていますが、下の情報窓には、***failed: と出ていて、「efuse の設定がおかしいのでチップのデーターシートをよく読みなさい」、などと書かれています。ちなみに、この時使った IDE のバージョンは 1.8.1 ですが、これが後で重要になってきます。

4.エラーの内容
エラーの内容は、IDE の環境設定の、より詳細な情報を表示のオプションで、書き込みにチェックを入れると表示されるようになります。詳しく見ると、「efuse (extended fuse) の書き込みで、x05 を指定しているけど、上位5ビットは1固定なので 0xFD と書くのが正しい。こんなことやっていると将来困るかも知れないよ。」てな内容のエラーが出ています。

これって、avrdude が出しているメッセージですが、そういうコマンドを送っているのは Arduino IDE です。つまり内輪もめのような話で、そういうのを私らエンドユーザーに言われても(見せられても)困っちゃいます。

あと、このエラーはかなり気になる話だと思うのですが、世の中で特に話題になっている風ではありません。

5.対策
ここまでの話で使っていた IDE のバージョンは1.8.1 だったのですが、ひょっとして最新の IDE を使うと解決するかも知れません。と考えて最新版の1.8.9を入れてみると、このエラーは出なくなりました。
他のバージョンでは判りませんが、どうもバージョン 1.8.1 で発生する問題だったようです。どうりで誰も話題にしていない訳です。

6.原因調査
IDE のバージョンを最新版にすればこの問題は解決できることが判ったのですが、どうも釈然としません。ということで、もう少し原因を探ってみます。ヒューズの設定については boards.txt で定義されているので、UNO の項目(uno.name=Arduino/Genuino Uno) の内容を調べたのが次の結果です。

IDE1.8.1 では、
uno.bootloader.low_fuses=0xFF
uno.bootloader.high_fuses=0xDE
uno.bootloader.extended_fuses=0x05
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.bootloader.file=optiboot/optiboot_atmega328.hex

extended_fuses の値が 0x05 になっています。上位5ビットは未定義なのでそこをゼロとみなせば、これでもおかしくはありませんが、実際に読み出した値とは違ってきます。まあともかく、ブートローダーの書き込みの時のヒューズの設定値をここから読み出しているのは、間違いなさそうです。

IDE 1.8.9 では、
uno.bootloader.low_fuses=0xFF
uno.bootloader.high_fuses=0xDE
uno.bootloader.extended_fuses=0xFD
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.bootloader.file=optiboot/optiboot_atmega328.hex

extended_fuses の値は正しく 0xFD になっています。これが IDE 1.8.9 を使うとエラーが出ない理由と考えて良さそうです。

ちなみに、Arduino IDE 1.6.5 では、
uno.bootloader.tool=avrdude
uno.bootloader.low_fuses=0xFF
uno.bootloader.high_fuses=0xDE
uno.bootloader.extended_fuses=0x05
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.bootloader.file=optiboot/optiboot_atmega328.hex

となっていて、このころから extended_fuse の定義は 0x05 だったようです。これでも問題が出なかったのは、avrdude の仕様が変わったためでしょうか。

7.avrdude のコマンド
AVR のライタープログラムである avrdude は名前はよく聞くのですが、そのコマンドが複雑すぎてあまり触りたくない、と思っていました。ただ、今回の調査で書き込みのログをいろいろ見たので、少し親近感が沸いてきました。
ブートローダー書き込み時の avrdude のコマンドはたった2行だけだったので、以下に書き出してみました。なお、1行のコマンドがとても長いので、オプションごとに改行を入れています。

▼最初のコマンド(主にヒューズの設定)
C:\Program Files (x86)\arduino-1.8.9\hardware\tools\avr/bin/avrdude
-CC:\Program Files (x86)\arduino-1.8.9\hardware\tools\avr/etc/avrdude.conf
-v
-patmega328p
-carduino
-PCOM4
-b19200
-e
-Ulock:w:0x3F:m
-Uefuse:w:0xFD:m
-Uhfuse:w:0xDE:m
-Ulfuse:w:0xFF:m

▼次のコマンド(主にブートローダーの書き込み)
C:\Program Files (x86)\arduino-1.8.9\hardware\tools\avr/bin/avrdude
-CC:\Program Files (x86)\arduino-1.8.9\hardware\tools\avr/etc/avrdude.conf
-v
-patmega328p
-carduino
-PCOM4
-b19200
-Uflash:w:C:\Program Files (x86)\arduino-1.8.9\hardware\arduino\avr/bootloaders/optiboot/optiboot_atmega328.hex:i
-Ulock:w:0x0F:m

上のコマンドを avrdude のオプションと見比べれば、良い勉強になりそうです。

8.最後に
たまたまエラーが出ていることに気付いたので調べてみたのですが、IDE1.8.1 でブートローダーの書き込みエラーが発生する原因が判って良かったです。なお、エラーメッセージは出ますが、ブートローダーは正常に書き込まれているし、ヒューズも正しく書き込まれていたので実害はありませんでした。また、最新版は1.8.9なので1.8.1を使っている人は僅かでしょう。

実は実際のヒューズの書き込み内容を確認するために、AVRISP mk2 を使ったのですが、そっちはそっちでトラブルが出て、対策のためにAtmel Studio 7をインストールするはめになりました。

うちでは古い Arduino のバージョンをいくつか保存しています。というのは、昔 Arduino のサポート組織が一旦分裂し、その後元に戻るというゴタゴタがありましたが、その前後で互換性の問題が出ると嫌なので、分裂前のバージョンである 1.6.5 を消さないで保存していました。実は今回の問題を発見した時に、1.8.1 はゴタゴタの後に出来た物なので、その影響で作る時にミスったのではないか、などと邪推してしまいました。
なお、古いバージョンのArduino IDE はこちらから入手出来るので、自分で持っていなくてもよかったみたいです。

今回始めて Arduino IDE 1.8.9 を使ってみたのですが、スケッチの名の最初の文字に数字が使えるようになっていて良い感じです。当たり前ですが、バージョンアップはちゃんと見ておけ、と言う話ですね。

【追記】
全く同じ症状と、それに対する対策方法が、しなぷすさんの、Arduino IDE 1.6.10でブートローダの書き込みに失敗する場合の対処法という記事に書かれていました。エラーが出るようになったのは、Arduino IDE で使う avrdude のバージョンが上がって、ヒューズビットのチェックを厳密に行うようになったためだそうです。ちなみにシナプスさんの記事の作成時点では、エラーは Arduino 1.6.10 から 1.8.0 の範囲で発生していたと書かれています。Arduino 1.8.9 では直っているので、この間のどこかのタイミングで修正されたものと思われます。

Atmel Studio 7 にバージョンアップ

Arduino で使っている CPU の ATmega328P にブートローダーを書き込んだら、ヒューズの設定についてのワーニングが出ました。書き込み自体はうまく行っているようですが、なんだか気持ち悪いです。そんなことで、Atmel Studio からAVR ISP mk2 を使ってヒューズの内容を見ようとしたら、Toolのメニューの中にAVRISP mk2 が出なくなっていて確認が出来ません。

たぶんUSBのドライバ周りを windows が勝手にいじったためにこうなったのだと思います。あれこれ修正を試みたもののダメです。使っていたのはAtmel Studio 6 ですが、最新版は既に 7 になっているので、古いバージョンで対策しても作業が無駄になる可能性があります。

ということで、Atmel Studio のバージョンを 6 から 7 に上げることにしました。

▼Atmel Studio 6
AtmelStudio6
これをバージョンアップします。

バージョン7 をそのまま上書きインストールすればたぶん大丈夫な気はしましたが、上に書いたように動作がおかしくなっているところがあるので、まずは古いバージョンのアンイストールを Windows から行いました。Atmel 関連のプログラムがいろいろ入っていたので、それらも全部アンインストールしました。

Atmel Studio 7 のインストール方法についてはいろいろな方が記事を書かれているので詳細は省略しますが、私が遭遇したトラブルに絞って解説します。

▼Atmel Studio インストール開始
ATMEL STUDIO7 インストール
as-installer-7.0.1931-web.exe というファイルをダウンロードして実行する方法でインストールしました。

最初は順調だったのですが、

▼エラー発生
ATMEL STUDIO7 インストールエラー
インストール中に上記の画面になってこの先に進めません。インストーラーかWindows Update が既に走っているので終わるまで待て、と言っていますがここで止まったままで先に進みません。

ネットを調べると既知の問題のようで、対応方法が書かれていました。インストーラーにオプションを付けて起動する事で、この問題は回避出来るようです。

具体的には、

▼インストールファイルのあるフォルダに行って、
エラー対策
そのフォルダからDOS窓を開くために、ツールバーにCMDと入力して、リターン。

▼コマンドを入力
エラー対策
as-installer-7.0.1931-web.exe/SystemValidationErrorAsWarning と入力します。要はシステム バリデーションにエラーがあっても気にしないで(ワーニング扱いにして)インストールを行うように指定しているのだと思います。

▼インストールが進む
インストール継続

▼Atmel Studio 7 のロゴ
ATMEL STUDIO7ロゴ
めでたくシステムのロゴが出るようになって、

▼Atmel Studio 7 起動成功
ATMEL STUDIO7
今回インストールしたのはAtmel Studio 7 (Version: 7.0.1931) です。

▼Tool の Device Programinng からAVRISP mk2を選択
tool programing
ヒューズの確認が出来るようになりました。

◆まとめ
これで AVRISP mk2 が使えるようになって、めでたしめでたしです。Atmel Studio の本体の方も使ってみたいのですが、Arduino IDE があれば特に困らないので、とりあえずこのまま塩漬けかと。

それにしても windows が余計なことをやってくれるおかげで、世界中でどれだけの工数が無駄使いされているのやら。

これで ATmega328 のヒューズが読めるようになったので、次の記事ではブートローダーの書き込みで発生したエラーについて書いてみたいと思います。

3.3VのI2Cを5VのArduinoに接続する場合の注意事項

 このところ0.96インチOLEDでいろいろ遊んでいますがそろそろネタ切れです。そんなことで、このデバイスを使う時のコツみたいなものをまとめてみようと思っていました。

 内容としては、「画面を部分消去するより、全画面消去した方がずっと速い」だとか、「display.display()コマンドで画面が更新されるので、チマチマと書き換えても舞台裏は見えない」、はたまた「Adafluitのロゴを表示するために、フラッシュメモリを無駄使いしていてけしからん」なんてことを思っていました。

 ところがI2Cバスの使い方でもっと重要な話が出てきました。ということで今回の記事ではそのあたりに絞って書きたいと思います。

◆0.96インチOLED
0.96インチOLED
 インターフェイスにSSD1306を使ったOLEDです。

 このデバイスはインターフェイス基板付きで売られていて、基板には3.3VのLDOシリーズレギュレーターが入っているので電源電圧は5Vから3.3Vまで使えます。また、I2Cバスは基板内の3.3Vに4.7kΩでプルアップされています。
 詳しくはこちらの解説記事参照

 この記事を書いた時は、「そうか、5Vでも3.3Vでも使えて便利じゃん!」と思いました。でも最近気付いたのですが、3.3Vでも5Vでも良いのは電源電圧だけで、I2Cの信号レベルは3.3V固定なので、5VのArduinoに接続する時にはレベル変換が必要になります。

 I2Cで3.3V/5Vレベルが混在している時には2N7000を使ったレベルコンバーターを入れていたのに、とんだ勘違いをしたもんです。

 ただ、このOLEDを使った他の方の製作記事を見るとI2Cのレベル変換なんて余計な回路は入っていないようです。3.3Vロジックの信号を5V側で受ける時に問題が起きそうですが、VIHは0.6Vcc以上あれば良いので、5VのArduinoなら3V以上あれば大丈夫なはず。ということは、3.3Vあればいけるんじゃないの?という考え方が成立しそうです。(注:後記しますが、ArduinoというかATmega328PのWireインターフェイスのVIHは0.7Vcc以上必要です)

▼Arduinoで使う場合
OLEDをArduinoに接続(I2C)
 もう一つ考慮すべき点として、wireライブラリを使った時にArduino(ATmega328P)側に自動的に入るプルアップ抵抗があります。上の回路図のRarduinoの35kΩです(ATmega328Pのデーターシートによるとプルアップ抵抗は20-50kΩとなっているのでその中間の35kΩと表現しています)。
 この抵抗で5Vへ引っ張ると、D3がONになりますが、信号がLOWになるとD3はOFFになるので、D3の逆回復時間の影響で波形に段が付きそうでちょっと心配になります。保護ダイオードの特性なんてどこにも書いて無い、というか何の保証もないので、ONになることを前提にして使うのは気持ち悪いです。

 そんなことを考えていました。でもよく考えてみたら、

▼プルアップの等価回路
テブナン終端の等価回路
 プルアップ抵抗の部分だけを取り出して、テブナン終端を等価回路に描き直すとこのようになります。3.5Vに4.14kΩで引っ張っていることになり、3.3V電源に入っているダイオードは0.2Vだけ正にバイアスされるだけです。これくらいなら飽和していないので、逆回復時間とかは全く考えないで良いはずです。

 なるほど、これなら大丈夫そうです。それにArduino側で5Vにプルアップしておけば、I2Cバスの電圧が僅かに上昇するのでマージンが少し増えることが期待できます。

 理論的な話は分かったので、実際の波形を見てみます。

▼Arduino側プルアップ無し(OLED側のプルアップだけ)
OLEDのプルアップだけ
 上がSDA,下がSCLで、SCLの負スロープでトリガしています。なお、プルアップ無しにするには、I2Cの(OLEDの)初期化が終わった後で、pinMode(SCL,INPUT); pinMode(SDA,INPUT); と入れています。

▼Arduino側プルアップ有り(ArduinoとOLEDの両方でプルアップ)
Arduino側のプルアップあり
 なるほど、少しレベルが上がっています。それに立ち上がり速度も少し速くなっています。

 少しでもレベルが上がれば5V側のVIHのマージンが増えるので、Arduino側のプルアップは入れたままにした方が良いということです。というか、余計なことはしない方が良かったです。

◆マージンの確認
 とりあえず大丈夫な感じではありますが、3.3/5Vのレベル変換回路を省略するとギリギリのマージンで動かすことになります。そんな訳で、もしやるなら、配線は最短にして、ノイズの飛び込みを減らすために、GNDに近付けて配線すべきでしょう。

 ノイズマージンを見るのに、SDAピンに触ったりしてハングアップしないか見るのが手っ取り早いです。DSO-SHELLのように入力の静電容量が大きなオシロ(約90pFもあります)を接続すると、しばらくするとハングアップしたりするので、これでもマージンの確認が出来ます。まあ、プロならESDテストとかやる、というか最初からこんな無茶はしないのでしょう。

◆データーシート上のVIH
 また見たくなると思うので、ATmega328PのデーターシートのVIHの項を転載しておきます。

▼一般IOピン (32.2.DC特性)
IOピンのVIH
 0.6Vccとなっています。

▼wireピン (32.7. 2線直列インターフェイス特性)
WireピンのVIH
 0.7Vccとなっています。内部で引きずっているものが多いので、マージンを大きくしておく必要があるのでしょうか?

◆まとめ
 OLEDのI2Cインターフェイスの回路についてはなんだかもやもやしていたのですが、纏めてみてすっきりしました。結論をもう一度書くと、5VのArduinoに3.3VのI2Cインタフェースのデバイスを接続する場合、3.3V側をプルアップするだけで直結しても大丈夫だと思います。

 ATmega328Pのデーターシートを読むと、一般ピンのVIHは0.6Vcc、つまり5Vで使うなら3Vですが、wireのピンでは、0.7Vcc必要。つまりHighレベルには3.5V必要となっています。ArduinoとOLEDの両側でプルアップすることで、3.5Vにプルアップしていることになり、ギリギリでOKと考えることが出来ます。但しマージンはゼロです。でも、スペック自体がマージンを持っているので、アマチュアがやるなら大丈夫だと思います。

 I2Cバスではありませんが、CMOSの3.5V/5V間のインターフェイスについて、ケプストラム社のwebの、5V系・3.3V系信号レベル変換という記事に同じような話の解説がありました。こういう情報はほんとうに貴重です。

 あと記事中でダイオードの飽和を嫌っていますが、私の世代は飽和型と非飽和型ロジックの性能差について刷り込まれているので、条件反射的に反応しちゃいます。TTLからショットキーTTL、はたまたECLやらCMLなんてのがあったのは、70年から80年代だったか、(遠い目、、)
カレンダー
03 | 2019/04 | 05
- 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 - - - -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード