2011年2月2日水曜日

DuemilanoveのAuto reset機能を無効にする

Auto resetの問題

Arduinoでシリアル通信のテストをしていたが、PC側の特定のソフトからだとArduinoと通信できない現象に悩まされた。

ArduinoのSerialライブラリは、hand shakeやparity等の指定もDTR/RTS等の操作も無いシンプルなものだ。デフォルトのライブラリが単純すぎるのかと思い、代替のSoftwareSerialNewSoftSerialを使ってみたが全く結果は変わらなかった。またシリアル変換chipの相性などを疑ってみたが、これもよく分からなかった。そもそも有名なFTDIのchipに大きな問題が在る訳なかろうに。

Portmonで調べた結果、動作するソフトと動作しないソフトとでは通信パラメータ(IOCTL)が一部異なっていたが、結果から言うとDTRの制御に問題があることが分かった。

Diecimila以降のArduinoでは、DTR線を特殊な用途(=auto reset)に使っているのだ。

つまり、DuemilanoveではFT232RからのDTR線が、0.1uFのコンデンサを介してATmegaのRESET端子(pin1)に繋がっており、DTRをgroundに落とすことで、コンデンサの放充電によりpin1へのreset pulseを作り出し、auto resetがかかる仕組みになっているのだという。なお、回路図ではRTS線もR2を介してRESETに繋がっている様に見えるが、NMは"not mounted"の略で、ここは繋がっていない。DiecimilaではRTS/DTRともにNMの表記があるが、R2には何も実装されず(NM)、R3には0.1uFのコンデンサが実装されている、と本家に記載がある。
Note that R2 is not mounted and that R3 has been replaced by a 100 nano-farad capacitor.
Arduinoとうまく通信できないソフトでは、DTR線を独自に制御してしているために、どうやら通信中にArduinoにリセットをかけてしまうらしかった。

基板に変更を加えずにAuto resetを無効にする

この問題は有名らしく、対策はすぐに見つかった。Hardwareに変更を加えても良いが、簡便なのは以下の方法。本家のAutomatic resetの解説に小さく書かれている。
You may also be able to disable the auto-reset by connecting a 110 ohm resistor from 5V to the reset line.(RESET端子と5Vの間に、110Ωの抵抗を追加する。)
Playgroundにも解説があって、こちらでは120Ωが推奨されている。実際120Ωの抵抗は見つけにくいから、合成抵抗で110~124Ωにせよと。ピンソケットに刺せるので楽チンだ。
なおRESETと+5Vの間にはまた別に10kの抵抗があるので、これと並列合成で109~122Ω位の値になる。ATmegaのpinあたりの最大電流は40mAだが、109Ωだと5/109*1000=46mA位流れる計算になる。少し流れすぎな気もするが、DTRがgroundに落ちた時にresetがかからなくするためにはこれくらいの電流が必要なんだろう。

この方法を試したところ、無事問題のソフトからも通信できるようになった。

なお、この対策法はSerial変換がFT232Rだけの場合に有効らしく、同様のDTR結線があるUNOでは残念ながら動作しないようだ。(本家には出来ると書いてあり、auto resetは確かに無効に出来るのだが、通信ができない。)

また、auto resetを無効にすると、Playgroundに書いてあるように、programの自動uploadが出来なくなる。手動resetが必要。手順は、
  1. reset buttonを押したままにする。
  2. 基板上のTX/RX LEDから目をそらさずに、
  3. Arduino IDEのUploadボタンをclick。
  4. RX(?) LEDが光ったらすぐにreset buttonから手を離す。
とのことだが、4.で先に光るのはTX LEDの方だ。
また1.を省略し、TX LEDが光ってからすぐにreset buttonを押す方法でもuploadできた。慣れればそれほど面倒ではない。

0 件のコメント:

コメントを投稿