Arduino UnoPWMピンの競合
タンクの2つのモーターを制御するためにL298Nチップに基づいて このモーターシールド を作成しました。 1つのモーターにはピン5と6を使用し、もう1つのモーターにはピン10と11を使用します。
IRリモートでタンクを制御するために TSOP 4838 を追加しようとしているときに、ピン10/11のモーターを逆方向に動かすと全速でしか機能しないことに気づきました-つまり、HIGH(255 )ピン11の値。この値を下回ると、ピン11には何も出力されません(これらのピンで測定された電圧は0 Vです)。
リモートの場合、私は このライブラリ を使用します。 [〜#〜] ir [〜#〜] レシーバーはピン2に接続されています(ただし、ピンは関係ありません)。問題はライブラリコード自体です。 IRリスニングを有効にする行irrecv.enableIRIn();
が問題の原因です。内部ArduinoタイマーとシールドによってPWMに使用されるピンの競合があることを学びました。
これは逆にモーターに電力を供給するコードです:
_#include <IRremote.h>
// IR receiver configuration
const int irPin = 2;
IRrecv irrecv(irPin);
// Motors configuration
const int mLeftPin1 = 10;
const int mLeftPin2 = 11;
const int mRightPin1 = 5;
const int mRightPin2 = 6;
void setup()
{
// Start IR
irrecv.enableIRIn();
// Setup motors
pinMode(mLeftPin1, OUTPUT);
pinMode(mLeftPin2, OUTPUT);
pinMode(mRightPin1, OUTPUT);
pinMode(mRightPin2, OUTPUT);
// Move left motor in reverse, slower speed
analogWrite(mLeftPin2, 100); // This works only with 255 instead of 100
digitalWrite(mLeftPin1, LOW);
}
_
さて、 ここ のタイマーが使用するピンは Arduino Uno であることがわかりました:
- ピン5および6:Timer0によって制御されます
- ピン9および10:Timer1によって制御されます
- ピン11および3:Timer2によって制御
だから私の質問は:
インストラクタブルのシールドがPWMにピン10と11を使用するのはなぜですか?それらは2つの異なるタイマーに対応します。なぜ9と10ではないのですか?
IRをモーターシールドと一緒に使用するには、使用するIRライブラリをどのタイマーで構成する必要がありますか?
答えが2の場合、_
IRremoteInt.h
_の行のコメントを外す必要があります。私はUnoが68行目でelse
分岐を取ると思いますが、timer1とtimer2しかありません。なぜtimer0が宇野に使えなかったのかしら。
最後の選択肢として、痕跡の切断と再はんだ付けを残したいのですが、別の可能性は、シールドが使用するピンを変更することですが、どれですか?これは、タイマーをデフォルト以外のピンでPWMに構成することとも組み合わせられると思いますが、タイマー/割り込みについては何も知りません。ArduinoとCに関する知識は限られています。
問題を解決するだけでなく、学びたいので、長い質問をしましたので、質問以上に気軽に説明してください。
解決策を探しているときに、 [〜#〜] pwm [〜#〜] またはタイマーを使用するときに留意する必要がある他の競合も見つけました:
- Timer0は8ビットタイマーで、最大値255を保持できます。
delay()
およびmillis()
、それでそれをいじると結果があります - Timer1は16ビットタイマーで、最大65535(符号なし16ビット整数)を保持できます。 Arduinoサーボライブラリはこのタイマーを使用します
- Timer2は、Arduino
tone()
関数で使用される8ビットタイマーです
そしてもちろん、IRremoteライブラリは_TIMER_RESET
_を使用するため、使用するタイマーによっては、関連するピンと競合する可能性があります。
- すべてのハードウェアが最良の方法で設計されているわけではありません。 10と11を使用すると、2つのタイマーが必要になるため、実際に無駄になります。
2/3。理想的には、Timer0ではないタイマーを使用します。タイマー/割り込みの詳細は次のとおりです。
Arduinoチップ(328P)には3つのタイマーがあります。各タイマーは複数の用途に使用できますが、タイマーごとに有効にできるタイマー割り込みは1つだけであることに注意してください。
Timer0を例にとってみましょう。 delay()メソッドとdelay_us()メソッドに適切な遅延を生成するために割り込みます。これは、ピン5および6のPWM出力にも使用されます。これは、PWM出力がタイマー割り込みを使用せず、別個の出力比較モジュールを使用するために発生する可能性があります。
ここで特に問題を見ると、should正常に動作します。timer2を使用するPWM出力がある場合でも、PWMはtimer2で割り込みを受け取らないため、IRライブラリはその割り込みを自由に使用できます。ただし、IRライブラリコードを調べると、次のコードが表示されます。
ISR(TIMER_INTR_NAME)
{
TIMER_RESET;
中断するたびに、タイマーのカウントがリセットされるようです。これが、PWM出力が正しく機能していない理由である可能性があります。出力比較モジュールは特定のティックカウントを待機しており、それに達することはありません。
なぜ255で機能するのかについて、analogWriteコードを見てみましょう:
void analogWrite(uint8_t pin, int val)
{
// We need to make sure the PWM output is enabled for those pins
// that support it, as we turn it off when digitally reading or
// writing with them. Also, make sure the pin is in output mode
// for consistenty with Wiring, which doesn't require a pinMode
// call for the analog output pins.
pinMode(pin, OUTPUT);
if (val == 0)
{
digitalWrite(pin, LOW);
}
else if (val == 255)
{
digitalWrite(pin, HIGH);
}
したがって、255を書き込むことにより、analogWriteコードはPWMと出力の比較全体を無視し、ピンをHighに書き込むだけです。
最後に、あなたの問題を解決するために、私は個人的に11番ピンと3番ピン(timer2)を使用しない方法をとります。はい、少し再配線する必要がありますが、そうすれば、IRライブラリが使用できるようにtimer2を解放できます。
または、IRライブラリを調べて、カウントをリセットせずに機能させることもできます。
使用するボードに注意してください。ArduinoUnoを使用する場合、責任のあるコードは次のようになります。// Arduino Duemilanove、Diecimila、LilyPad、Mini、Fioなどelse // define IR_USE_TIMER1 // tx = pin 9 define IR_USE_TIMER2 // tx =ピン3endif
ビルド済みの L298 V2 モーターシールドでも同じ問題が発生しました。
ピンはシールドに次のようにマークされています。
モーター1:ピン3および5モーター2:ピン6および9
私は3ではなくPIN10を使用し、小さな回避策を使用しています。SHIELDにPIN10からPIN3へのワイヤを配置します。私のプロジェクトは、SAMSUNG TVリモコンでロボットを制御することでした。