
こんにちは、愛するhabravchane!
この記事では、Arduinoボード上のRESET脚を自分のニーズに合わせて安全に使用する方法について説明します。
実際、この問題の解決策を探して、 Arduino Pro Miniに基づいて、開発中のシステムに足が欠けていることに動機付けられました(Habrで実装をどのように完了するかを説明したいと思います)。
そのため、タスクは明確であり、要件は次のとおりです。
- Arduinsの通常の方法でスケッチをロードする機能
- プログラムでRESETフットをデジタルI / Oピンとして使用する機能
重要:この記事には、不正確な使用によりArduinが動作不能な状態に陥る可能性があるチームがあります。
この問題に関するグーグルは、新規参入者を混乱させます-彼らはこれが不可能であることを至る所に書いているようですが、例えば、ここ[1]のように、この制限を回避する方法があることはめったに言及されません。
そのため、目的の結果を得るには、ブートローダーコードを変更し、Arduinoでフラッシュして、ヒューズを変更する必要があります。 この順序で! これは非常に重要です! 準備はいいですか
最初のステップ
次に、ブートローダーから始めます。 ネットワーク上には、さまざまな機能を備えたArduins用の多くのブートローダーがあります。 最小のoptibootを取りました[2] 。 メインプログラムコード用にさらに1.5キロバイトを解放するだけでなく、 Watchdogを使用できるようにします[3] 。 サイトからソース( アーカイブ )を含む最新バージョンをダウンロードし、フォルダー「\ optiboot-9e0c0b9db6fe \ optiboot \ bootloaders \ optiboot」を解凍して、フォルダー「pathToArduino \ hardware \ arduino \ avr \ bootloaders \」にコピーします 。 Arduino IDEバージョン1.5.8を使用しています。 バージョンArduino IDE 1.0.5を使用している場合は、 ブートローダーフォルダーを自分で見つけてください。
テキストエディタまたは既存のプログラミング環境( Atmel Studio 6.2を使用)でファイル「pathToArduino \ hardware \ arduino \ avr \ bootloaders \ optiboot \ optiboot.c」を開きます。 以下の行をコメント化する必要があります。
ch = MCUSR; MCUSR = 0; if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF))) appStart(ch);
その後、次のコードを挿入します。
//ch = MCUSR; //MCUSR = 0; //if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF))) //appStart(ch); #define PIN_BOOT PCINT14 DDRC &= ~_BV(PIN_BOOT); PORTC |= _BV(PIN_BOOT); _delay_us(4); if(_BV(PIN_BOOT)&PINC) { PORTC &= ~_BV(PIN_BOOT); appStart(MCUSR); }
また、プログラムのヘッダーで#includeを見つけ、すべてのインクルードの後に、以下を挿入します。
#include <util/delay.h>
ブートローダーでのすべてのアクションの正確性を検証するには、ファームウェアコード内のレッグへのポインターを置き換えてテストファームウェアを作成するのが最善です。 そうだとすると( PCINT10はレッグA2 ):
#define PIN_BOOT PCINT10
その後、テストファームウェアで、ヒューズに影響を与えることなく、すべてが正しく行われていることを確認できます。
ここで何が起こっているのかを説明します。 ソフトリセットと低電力リセットの後に発生するメインプログラムへの移行を削除しました。 PCINT14は、 PORTCレジスタのRESETフットのアドレスです 。 DDRCレジスタへの直接アクセスを使用して、このピンにpinMode INPUTを設定し、内部抵抗( PORTCレジスタ、いわゆるpinMode INPUT_PULLUP )を通じて5ボルトを印加しました。 十分な数の電子機器が抵抗器を流れるまでしばらく待ってから、 PINCレジスターを介して脚の信号を見ました。 足に信号がない場合は、接地されているため、メインプログラムのフラッシュに進みます。 それ以外の場合、レッグをデフォルトのINPUTモードに変換し、メインプログラムを実行します。
次に、すべてをコンパイルする必要があります。 omake.batファイルは 、 make.exeへのパスに置き換える必要があります。 私の場合( Arduino IDEバージョン1.5.8 )は".. \ .. \ .. \ sam \ system \ CMSIS \ Examples \ cmsis_example \ gcc_atmel \ make.exe"です。 さらにオプションを追加したので、コンパイルの開始行は次のようになります。
..\..\..\sam\system\CMSIS\Examples\cmsis_example\gcc_atmel\make.exe OS=windows ENV=arduino LED_DATA_FLASH=1 BAUD_RATE=57600 %*
まず、 cleanパラメーターを指定してomake.exeを実行し、次にatmega328パラメーターを指定して、答えを注意深く読みます。 エラー「error:」がそこに記載されていない場合、 optiboot_atmega328.hexファームウェアがフォルダーに表示されます。 いいね!
第二段階
ブートローダーのフラッシュを開始しましょう。 この場合、 Arduino IDEでフラッシュ機能を使用することは最適なオプションではありません。これは、Arduinoの動作不能につながる可能性が高いです。 ブートローダーファームウェアの場合、 avrdude.exeを使用します 。 このコンソールプログラムは、フォルダー"pathToArduino \ hardware \ tools \ avr \ bin \"にあります。 ここで使用されているパラメータについてお読みください[4] 。 ファームウェアのあるフォルダーで使用するには、次の内容のflash.batコマンドスクリプトを 1つ作成します。
..\..\..\..\tools\avr\bin\avrdude.exe -C "..\..\..\..\tools\avr\etc\avrdude.conf" -c stk500v1 -p m328p -b 19200 -P COM5 %*
2番目はflash_boot.batです。
flash.bat -e -U flash:w:optiboot_atmega328.hex:i
ファイルパスを置き換えます。 COMポート。SPIプログラマーまたはArduinaが使用するものを指定します。これはプログラマーを置き換えます。 PL2303HXA COM プログラマーを介して別のPro Miniを使用しました。 ArduinoISPの標準スケッチをダウンロードし、 STK500 v1プロトコルを使用したSPIプログラマーの操作をエミュレートします。 この記事では、接続図の例を示しています[5] 。
すべてが接続された後、flash.batを実行して、プログラム可能なArduinaとの接続を確認できます。これは、マイクロコントローラーの署名とその他の情報を表示します。 これで、2番目のflash_boot.batスクリプトを実行できます。 彼が「フラッシュの非常に多くのバイトが検証された」と言ったら、すべては問題ありません、ブートローダーは適切です。
このステップでは、テストファームウェアの動作を確認できます。たとえば、標準の点滅をロードし、Arduinaの起動中にテストレッグ(この場合はA2 )を接地します。 内蔵LEDがランダムに点滅するはずです-このウォッチドッグは、ブートローダーがシリアルポートからコマンドを読み取ってメインプログラムを上書きしようと試みた段階で、マイクロコントローラーを再起動します。
第三段階
最後に、最も重要な段階はヒューズの取り付けです。 それらを使用する前に、たとえばここ[6]でそれらについて読む必要があります。
間違ったヒューズは、 「Atmega fusebit doctor」 [7]の助けを借りて治療できることに注意してください。

無はんだブレッドボード上のAtmega fusebitドクター
Fusion Calculator [8]とデータシート[9]を使用して、 flash_fuse.batコマンドスクリプトを作成し、 問題のあるチップに正しいヒューズをインストールします。
flash.bat -u -U lfuse:w:0xFF:m -U hfuse:w:0x56:m -U efuse:w:0x05:m
hfuseの番号5は、対応するレッグのRESET機能を無効にします。 残りのヒューズは、お客様の裁量で決定します(データシートで確認します!)。 この瞬間が来た、あなたはまだ標準のArduinに
第4ステップ
多くの困難を克服したので、正しいブートローダーをコンパイルし、それをマイクロコントローラーにフラッシュし、正しいヒューズを取り付けました。 Arduino IDEがボードと通信できるように、 「pathToArduino \ hardware \ arduino \ avr \ board.txt」ファイルの何かを修正する必要があります。
ファイルの最後に設定を追加します( Arduino IDE 1.0.5の場合は少し異なります):
############################################################## pro328o16.name=[Optiboot] Arduino Pro Mini (5V, 16MHz) w/ ATmega328p pro328o16.upload.tool=avrdude pro328o16.upload.protocol=arduino pro328o16.upload.maximum_size=32256 pro328o16.upload.speed=57600 pro328o16.bootloader.tool=avrdude pro328o16.bootloader.low_fuses=0xff pro328o16.bootloader.high_fuses=0x56 pro328o16.bootloader.extended_fuses=0x04 pro328o16.bootloader.file=optiboot/optiboot_atmega328.hex pro328o16.bootloader.unlock_bits=0x3F pro328o16.bootloader.lock_bits=0x0F pro328o16.build.mcu=atmega328p pro328o16.build.f_cpu=16000000L pro328o16.build.board=AVR_PRO pro328o16.build.core=arduino:arduino pro328o16.build.variant=arduino:eightanaloginputs
ボードの名前[Optiboot] Arduino Pro Mini(5V、16MHz)w / ATmega328pは、リストの最後にある[ツール/ボード ]メニューに表示されます。
制限事項
覚えているように、ArduinoボードのRESETボタンはRESET脚を地面に閉じます[10] 。 それを使用して、マイクロコントローラーをメインプログラムの点滅モードにします。 5ボルトの出力モードでこの足を使用することはお勧めしません。 「電力」負荷を制御する必要がある場合は、大地を脚に持ち込み、2番目の負荷供給ラインに5ボルトをかける方が良いでしょう。 脚を入力モードにすると、電源が切れます。 これにより、短絡の可能性を回避できます。 他のモードは問題なく使用できます。
2番目の発言はサードパーティのライブラリに関するものです。足をパラメーターとして渡すと、どのモードで機能するかわかりません。 何もする必要はありません。 それは、私たち自身が書いた非常に単純なロジックでのみ脚を使用することです。 また、プログラムの初期化の開始時に一時停止することをお勧めします。これにより、LEDによって、ボタンが突然機能しない場合はすぐにリセットボタンを放したほうがよいことが明確になります。
3番目のコメントは、脚の標準的な番号付けに関するものです。 はい、 リセット脚には番号がありません! 制御されるマイクロコントローラレジスタのみがあります。 この問題は、 「pathToArduino \ hardware \ arduino \ avr \ variant \ standard \ pins_arduino.h」ファイルをいくつか編集することで簡単に解決できます。
static const uint8_t RST = 20; const uint8_t PROGMEM digital_pin_to_port_PGM[] = { … PC, /* 20 */ }; const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { … _BV(6), /* 20, port C */ }; const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { … NOT_ON_TIMER, /* 20 - port C */ };
その後、 analogRead()を除くすべての標準関数は、他の場合と同様に、番号20 ( RST )のRESETレッグで動作します。 また、追加のアナログレッグA6およびA7がある場合でも、それらは原則に従って別々に動作します。 これを自分で確認するには、次のスケッチを作成します。
void setup() { Serial.begin(9600); pinMode(RST, INPUT_PULLUP); // RST HIGH INPUT } void loop() { Serial.println(digitalRead(RST)); // RST 1, Serial.println(analogRead(A6)); // A6 "" , delay(500); }
おわりに
私の記事が、Arduinoでのプロジェクトの困難な状況から抜け出す唯一の方法ではないことを願っています。 しかし、彼女が誰かをさらに深く掘り下げて興味深い解決策を見つけるように促してくれたら、とてもうれしいです。
Arduino IDE 1.5.8の影響を受けるすべてのファイルを含むアーカイブは、リンク[11]からダウンロードできます。 ディレクトリ構造が保存されました。
コメントはPMまたはコメントで受け付けます。