1つの割り込みを使用する10個のボタン
コンポーネントと消耗品
> ![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 21 | |||
![]() |
| × | 10 |
アプリとオンラインサービス
> ![]() |
|
このプロジェクトについて
はじめに
割り込みは便利です。これらは、コードを単純化する場合があるだけでなく、正確なタイミングや、Arduinoをスリープモードから復帰させるためにも使用できます。
たとえば、バッテリーで動作するリモートコントローラーなどのユーザーインターフェイスがあるとします。電力を節約するために、Arduino(またはスタンドアロンATmega)をパワーダウンモードにすることをお勧めします。 Arduinoがパワーダウンモードに入ると、外部割り込みによってのみウェイクアップできます。 Arduino Unoで使用されているATmega328Pチップには、2つの外部ピン割り込みしかありません。 ( INT0
および INT1
ピン2と3)ユーザーインターフェイスには3つ以上のボタンがある可能性が高いため、これは問題です。
解決するための標準的な方法
これは、すべてのボタンを通常どおりに接続することですが、ダイオードを使用してそれらを割り込みピンに接続することもできます。ただし、これにより回路が大幅に複雑になります。
<図>
ATmega328Pには、標準の外部割り込みに加えて、ピン変更割り込みもあります。それらに対処するためのライブラリがあり、それらはこの問題の優れた解決策です。
ただし、プログラミングコンテスト中に、追加の電気部品を使用せずに標準の外部割り込みを使用してこれを行う方法を見つけました。
回路 <図>



ボタンがいくつかあります。ブレッドボードにぴったり合う10個を使用しました。 (これ以上はありません。)ピンごとに1つのボタンを使用できます。つまり、Unoでは最大20、Megaでは最大70になります。 (実際に70個のボタンが必要な場合は、多重化を使用することをお勧めします。そのためにMega全体は必要ありません。)
各ボタンの片側は任意のピンに接続されています。 (私の場合は4-13)すべてのボタンの反対側は、1つの割り込み対応ピンに一緒に接続されています。 (私の場合は2)
<図>
コード
コードは以下に添付されています。この例を機能させるには、ボードにアップロードしてください。シリアルモニターを開きます。ボタンを押すと、その番号が表示されます。ご覧のとおり、ループ関数はまったく使用されていません。
<図>
どのように機能しますか?
明らかに、割り込みがあります。私の場合、ピン2に接続されています。 FALLING
として構成されています。 。
ダイオードの使用を避けるために、Arduinoはその場で回路を再配線します。 2つの可能な構成があります:コモンモード および個別モード 。
コモンモード
ほとんどの場合、回路はコモンモードになります。割り込みピンは INPUT_PULLUP
として構成されます 残りは OUTPUT
になります および LOW
。

void configureCommon(){pinMode(commonPin、INPUT_PULLUP); for(int i =0; i
コモンモードでは、いずれかのボタンを押すと、割り込みピンが引き下げられ、割り込みが発生します。それが発生すると、割り込みサービスルーチンがピンを個別モードに再構成します。
個別モード
割り込みがトリガーされると、すぐに個別モードに切り替わります。
個別モードは、共通モードの反対です。割り込みピンは OUTPUT
になります および LOW
残りは INPUT_PULLUP
になります 。

void configureDistinct(){pinMode(commonPin、OUTPUT); digitalWrite(commonPin、LOW); for(int i =0; i
個別モードでは、実際に押されたボタンに対応するピンのみがプルダウンされます。すべてのピンを簡単に調べて、どのピンが割り込みをトリガーしたかを見つけることができます。
それが完了すると、Arduinoはコモンモードに戻って別の割り込みを待つことができます。または、アプリケーションによっては、通常どおりに個別モードを維持してユーザー入力を処理し、Arduinoがスリープ状態になる前にコモンモードに戻すことができます。
より複雑な例
もう少し複雑なことを試してみましょう。サーボを取り付けて、各ボタンを異なる角度にマッピングします。 (1 =0°、2 =20°... 10 =120°)Arduinoにもいくつかのバッテリーで電力を供給します。
<図>


この例では、電力を節約するために、非アクティブ状態が5秒間続いた後、Arduinoをパワーダウンモードにします。スリープモードに関するいくつかのチュートリアルをオンラインで見つけることができます。それに加えて、トランジスタを介してサーボに電力を供給し、使用していないときにサーボをシャットダウンします。
この例のコードも以下に添付されています。
コード
- シリアルロガー
- スリープモードのサーボ
シリアルロガー Arduino
const int commonPin =2; const int buttonPins [] ={4,5,6,7,8,9,10,11,12,13}; unsigned long lastFire =0; void setup(){configureCommon( ); //割り込みのピンを設定しますattachInterrupt(digitalPinToInterrupt(commonPin)、pressInterrupt、FALLING); Serial.begin(9600);} void loop(){//空!} void pressInterrupt(){// ISR if(millis()-lastFire <200){//デバウンスreturn; } lastFire =millis(); configureDistinct(); //個々のボタンをテストするためのピンを設定します(int i =0; iスリープモードのサーボ Arduino
#include#include #include const int commonPin =2; const int buttonPins [] ={4,5,6,7,8 、9,10,11,12,13}; const intservoEnablePin =A1; const intservoPin =A0;サーボサーボ; unsignedlong lastFire =0; int status =0; void setup(){pinMode(commonPin、INPUT_PULLUP); configureCommon(); attachInterrupt(digitalPinToInterrupt(commonPin)、pressInterrupt、FALLING); Servo.attach(servoPin); pinMode(servoEnablePin、OUTPUT);} void loop(){if(millis()-lastFire> 5000){digitalWrite(servoEnablePin、LOW); set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable();スリープモード(); } delay(10);} void pressInterrupt(){sleep_disable(); power_all_enable(); if(millis()-lastFire <200){return; } lastFire =millis(); configureDistinct(); for(int i =0; i
回路図


製造プロセス