Arduinoに14本以上の出力ピンを持つことは可能ですか、私はいくつかのLEDを個別に点灯する必要があるプロジェクトに取り組んでいます。Arduino Unoしか持っていないので、Megaを手に入れたくありません。
Arduinoに14本以上の出力ピンを持つことは可能ですか、私はいくつかのLEDを個別に点灯する必要があるプロジェクトに取り組んでいます。Arduino Unoしか持っていないので、Megaを手に入れたくありません。
回答:
Arduinoで使用可能な出力ピンのセットを拡張する一般的な方法は、74HC595 ICなどのシフトレジスタを使用することです(データシートへのリンク)。
これらのチップを制御するには、3つのピンが必要です。
プログラムでは、次のようにshiftOut()コマンドを使用して、データを一度に1ビットずつシフトレジスタに渡します。
shiftOut(dataPin, clockPin, data);
そのコマンドを使用して、data
変数の8ビットを使用して、595 ICの8つの出力のそれぞれを設定します。
1つの595で、5つのピンを獲得します(ICで8つですが、話をするのに3つ費やします)。より多くの出力を得るために、シリアル出力ピンを次のデータピンに接続することにより、一連の595をデイジーチェーン接続できます。また、すべての595 ICのクロックピンとラッチピンを接続する必要があります。
結果の回路(595を1つ使用)は次のようになります。
上の図は、このcodeproject.com Webページから引用したものです。
ラッチピンは、次のようにデータをシフトアウトしている間、595出力を安定させるために使用されます。
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, data);
digitalWrite(latchPin, HIGH);
Arduinoからより多くのピンを取得するには、2つの方法があります。
最初の方法は、アナログピンをデジタル出力ピンとして使用することです。これは非常に簡単です。必要なのは、A0-A5をピン14,15,16,17,18,19として参照することだけです。たとえば、ピンA0にハイを書き込むには、digitalWrite(14、HIGH)を使用します。
Arduinoからピンを増やすもう1つの方法は、シフトレジスタを使用することです。これを行うには、EZ-Expander Shieldを使用することをお勧めします。EZ -ExpanderShieldを使用すると、EZ-ExpanderライブラリをインポートするときにdigitalWrite([20-35]、HIGH)を使用できます。ただし、このシールドでは、ピンを出力としてのみ使用でき、ピン8、12、および13を使用してシフトレジスタを制御できます。
すばらしいことは、上記の2つの方法の両方を問題なく使用できることです。
A0
- A5
番号14-19を使用するのではなく、直接識別子を。たとえば、digitalWrite(A0, HIGH)
。
digitalWrite(A0)
ますがdigitalWrite(14)
、前者は常に正しい物理(アナログ)ピンにマッピングされるため、より正確です。別のボードでpin 14
は、実際にはそうA0
ではないかもしれません。たとえばpin 14
、MEGAではSerial3でTX
あり、使用しているアナログピンには影響しません。つまり、digitalWrite
アナログピンで使用する場合は、A0
- A5
参照を使用します。
LEDを駆動する場合は、追加の回路なしで64個のLEDを駆動できるMAX7219を使用することもできます(信号を増幅するトランジスタは不要です)。
MAX7219を駆動するには、Arduinoで3つの出力ピンのみが必要です。また、いくつかのArduinoライブラリを見つけることができます。
64個を超えるLEDに電力を供給する必要がある場合は、それらのいくつかをチェーンすることもできます。
複数の7セグメントLEDディスプレイに使用できました。
欠点:高価です(約10ドル)。
Charlieplexingを使用できます。この手法を使用するとn*(n-1)
、nピンからLED を直接駆動できます。したがって、3つのピンを使用すると、6個のLED、4個のピン-12個のLED、5個のピン-20個のLEDなどを駆動できます。
例:
3ピンの6つのLED
PINS LEDS
0 1 2 1 2 3 4 5 6
0 0 0 0 0 0 0 0 0
0 1 Z 1 0 0 0 0 0
1 0 Z 0 1 0 0 0 0
Z 0 1 0 0 1 0 0 0
Z 1 0 0 0 0 1 0 0
0 Z 1 0 0 0 0 1 0
1 Z 0 0 0 0 0 0 1
0 0 1 0 0 1 0 1 0
0 1 0 1 0 0 1 0 0
0 1 1 1 0 0 0 1 0
1 0 0 0 1 0 0 0 1
1 0 1 0 1 1 0 0 0
1 1 0 0 0 0 1 0 1
1 1 1 0 0 0 0 0 0
I 2 Cプロトコル(Wireライブラリ)を使用して、ポートエクスパンダーなどの他のデバイスに接続できます。たとえば、MCP23017。
これらのチップの1つを使用して、LCDボードに接続しました。MCP23017には16個のポートがあり、入力または出力として構成できます。入力として、必要に応じて割り込みを発生させることができます。
16のうち13をLCDに接続する例:
次に、2本のワイヤ(SDA / SCL)と電源とグランドのみを使用してArduinoに接続します。
一部のサードパーティメーカーは、4 x MCP23017を搭載したボードを製造しています。これにより、64の入出力が可能になります。
次のように、74HC4051(8ポート)や74HC4067(16ポート)などのアナログマルチプレクサを使用して、1つのピンを8/16ポートの1つ(ただし、一度に1つだけ)に接続できます。
これらは双方向なので、入力または出力エキスパンダーとして使用できます。
SPIを使用すると、74HC595などのシフトレジスタに高速シリアルデータを送信できます。これらはデイジーチェーン接続できます。この例では、3つのI / Oピン(MOSI / MISO / SCK)と電源とグランドのみで32個のLEDを制御しています。
72個のLEDが74HC595チップによって駆動されていることを商業用LED看板の中に見つけました。
これには、多重化構成で、列を駆動する9個のチップ(9 x 8 = 72個のLED)と行を駆動する1個のチップがありました。
LEDを駆動したいだけであれば、通常はLEDを多重化できます。MAX7219は、7セグメントディスプレイなどのLEDマトリックスを駆動するように設計されているため、それが簡単になります。
または64 LEDマトリックス:
どちらの場合でも、これらは次のようにデイジーチェーン接続できます。
これらの例はすべて、Arduino(MOSI / MISO / SCK)の3つのピンと電源とグランドのみを使用しています。
前述の16ポートポートエクスパンダー(MCP23017)にはSPIバリアント(MCP23S17)もあり、これは実質的に同じことを行います。もう1本のワイヤを使用しますが、より高速になります。
LEDストリップ(NeoPixelなど)には独自のプロトコルがあります。Josh LevineによるYoutubeでの投稿があり、そこで著者はDuemilanoveで1000ピクセル以上を運転しました!
シフトレジスタは他の回答でも言及されており、多くのプロジェクトにとって間違いなく優れた選択肢です。それらは安価で、シンプルで、適度に高速であり、通常はチェーン化して出力を追加できます。ただし、通常は複数のピンを排他的に使用する必要があるという欠点があります(設定方法によっては2〜4)。
もう1つの方法は、16ビットMCP23017やMCP23S17などのより高度なポートエクスパンダーを使用することです。これらはそれぞれI2CとSPIをサポートします。つまり、他のいくつかのデバイス(場合によっては異なるタイプ)を備えたバス上に配置できます。バス上の各デバイスは個別にアドレス指定できます。つまり、すべてのデバイスと通信するには2本または3本のピンしか必要ありません。通常、更新速度は非常に高速であるため、Arduinoプロジェクトで大幅な遅延(つまり、伝送遅延)が発生することはほとんどありません。
低レベルでは、I2CまたはSPIを使用することは、単純なシフトレジスタよりもかなり複雑です。ただし、Arduinoがそれを処理するライブラリコードがあります。たとえば、この質問を参照してください:ArduinoでI2Cデバイスを使用するにはどうすればよいですか?
リカルドの答えに加えて、ウィキペディアがシフトレジスタについて述べていること:
シフトレジスタの最も一般的な使用法の1つは、シリアルインターフェイスとパラレルインターフェイス間の変換です。[...] SIPOレジスタは、一般に使用可能なピンよりも多くの汎用入力/出力ピンが必要な場合、マイクロプロセッサの出力に接続されます。これにより、2つまたは3つのピンのみを使用して複数のバイナリデバイスを制御できますが、パラレルI / Oよりも低速です。
リカルドがリンクした記事では、シフトレジスタの図を見ることができます。
ここで何が起こるかは、8ピンのデータを連続して配置し、各クロックティックごとにシフトレジスタがシフトする(各ラッチから次のラッチにバイナリデータを移動する)ことです。最後のピンに到着します。シフトレジスタには、シフトをオン/オフできる入力があり、データがその位置にシフトされた後もステータスを保持できます。簡単なデモについては、次のアニメーションを参照してください。
ここで、赤色のライトはシリアル入力であり、緑色のライトはこの簡略化されたSIPOシフトレジスタのラッチの状態を示しています。データを場所にシフトした後、シフトをオフにして、ピンを読み取ることができます。この例では、私はシフトアウトしました10101011
。
これらの例から、シフトレジスタがビットを適切な位置にシフトするのを待つ必要があるため、シリアル転送はパラレルよりも遅いことがわかります。ロードするビット数と同じ量のクロックティックを待つ必要があります。これは、ロードに時間がかかるため、無期限にチェーンできない多くの理由の1つです。
すでに記述したように、TXおよびRXを含むすべてのピンをデジタル出力として使用できます。少し前にデモンストレーターでそれを行い、このかなり無意味なプロジェクトのビデオ(20ピンの20個のLED)を記録しました。
ここでPeter R. Bloomfieldが 説明したように、アップロードのためにTXとRXを切断する必要があります。さらに、センサーを読み取って対話性を確保するためにピンが不足しているため、合計電流制限に達していないことを確認する必要があります。Arduinoで直接駆動する場合、5VのLEDに限定されることを忘れないでください。
したがって、一般的なシフトレジスタとリカードが説明した595の使用を強くお勧めします。
少し前に、アップサイクリングアーティストDominik Jais のカワイイミー(リンクのテキストはドイツ語)のはんだ付けとプログラミングの部分に気付いたときに使用しました。
ここでは、8個の11個のLEDのディスプレイを駆動するために、595個だけが使用されました。LEDは12V SMD LEDのストライプから切断されたため、追加の電源と、シフトレジスタの出力ピンに接続されたUDN2803Aダーリントンアレイが必要でした。
他の一般的な方法には、PCF8574(A)8ビットポートエクスパンダーの使用が含まれます。これらは、I2Cバスを介して制御されます。
とにかく、私は595シフトレジスタを最初に試してみます。
ただし、いくつかのRGB LEDを制御する必要がある場合は、より専門的なソリューションを探してください。一部のRGB LEDには、独自のWS2812が付属しています。これらの細かい部分はカスケード接続することができ(1-Wireバス)、チェーン内の位置を介してアドレス指定されます。
すべてがLEDの場合、WS2812B LEDストリップ、またはドライバーチップ自体はどうですか?1つのピンを使用して、事実上無制限の数のLEDを制御できます!
人々はこれらをストリップで使用していますが、スタンドアロンLED(Adafruitではneoピクセルとして知られています)として利用できます。または、単一の色のみを駆動する場合、各WS2811チップは、それぞれ単一のLEDの各RGB出力を使用して3つのLEDを制御できます。
最近作成したプロジェクトでは、Door1を開閉するDoor1、Door2を開閉する、motor1がアクティブ、motor2がアクティブ、電源の5つのLEDを使用するプロジェクトを作成しました。「アクティブ」LEDは、赤がアクティブなモーターからの入力であり、緑がArduino内のアクティブなフラグであるため、二重の目的です。
ポイントは、1ピンとライブラリがインストールされている場合、任意の数のLEDを制御できることです
私は自分自身でこの方法を主張していませんが、WebページMUX-DEMUXでこのきちんとしたトリックを見つけました:CD4051 Parlor Tricks
出力の駆動または入力の読み取りに使用する方法(シフトレジスタ、マルチプレクサ、またはArduinoピン自体の直接的な直接使用)の選択にかかわらず、並列回路ペアの巧妙な使用により出力または入力の数を2倍にすることができます(デュアルを形成するため)入力または出力バンク)、各並列ブランチで反対方向のダイオードを使用し、入力/出力をハイとローに切り替えます。
出力の方法を説明するために(この場合のLEDは、追加のダイオードが必要ないことに注意してください):
この例のLEDのペアを「バンク」と見なし、LED_0を点灯させる場合は、PIN 17をHIGHに、PIN 18をLOWに設定する必要があります。(ピン番号は紛らわしいですが、後者の例と一致しているので、私には必要ありません)。LED_1を点灯するには、PINを逆にするだけです。LEDのダイオードの性質により、電流が反対方向に流れないようにし、もう一方をオフにします。
入力の方法を説明するために(この場合はCdSs、追加のダイオードが必要であることに注意してください):
CdS光センサーでアナログ読み取りを行う場合、これはもう少し複雑になります。まず、流量を制御するために各センサーにダイオードを追加する必要があります。第二に、値を読み取っているので、入力をフローティング状態にしないために、入力をハイまたはローにする必要があります。怠け者なので、内部プルアップ抵抗を使用してそれらを高く引き上げます。CdS_0を読み取るには、PIN 17モードをOUTPUTに設定し、LOWに設定します。これが基盤となります。次に、PIN 18モードをINPUTに設定し、それをHIGHに設定してプルアップ抵抗を有効にします。これで、PIN 18(別名アナログピン4)で読み取りを行うように設定されました。他のセンサーにアクセスするには、モードと出力を切り替えるだけです。
したがって、Arduinoの5ピンを使用して(通常の3つではなく)CD4051 8ポートマルチプレクサーを使用している場合、16の入力または出力、または2つのミックスを取得できます。
同様に、4067 16ポートマルチプレクサーがある場合は、32の入力または出力、または2つの混合を取得できます。
スケッチの例は次のとおりです。
/*
* Example of getting 16 i/o from 5 pins using a CD4051
*
* Based on tutorial and code by david c. and tomek n.* for k3 / malmö högskola
* http://www.arduino.cc/playground/Learning/4051?action=sourceblock&ref=1
*/
int selPin[] = { 14, 15, 16 }; // select pins on 4051 (analog A0, A1, A2)
int commonPin[] = { 17, 18}; // common in/out pins (analog A3, A4)
int led[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW }; // stores eight LED states
int CdSVal[] = { 0, 0, 0, 0 }; // store last CdS readings
int cnt = 0; // main loop counter
int persistDelay = 100; // LED ontime in microseconds
void setup(){
Serial.begin(9600); // serial comms for troubleshooting (always)
for(int pin = 0; pin < 3; pin++){ // setup select pins
pinMode(selPin[pin], OUTPUT);
}
}
void loop(){
flashLEDs();
if (cnt == 0){
for(int x; x < 8; x++){
led[x] = random(2);
}
}
cnt++;
if (cnt > 100) { cnt = 0; }
}
void flashLEDs() {
for(int pin = 0; pin < 2; pin++) { // set common pins low
pinMode(commonPin[pin], OUTPUT);
digitalWrite(commonPin[pin], LOW);
}
for (int bank = 0; bank < 4; bank++) {
for(int pin = 0; pin < 3; pin++) { // parse out select pin bits
int signal = (bank >> pin) & 1; // shift & bitwise compare
digitalWrite(selPin[pin], signal);
}
if (led[bank * 2]){ // first LED
digitalWrite(commonPin[0], HIGH); // turn common on
delayMicroseconds(persistDelay); // leave led lit
digitalWrite(commonPin[0], LOW); // turn common off
}
if (led[bank * 2 + 1]){ // repeat for second LED
digitalWrite(commonPin[1], HIGH);
delayMicroseconds(persistDelay);
digitalWrite(commonPin[1], LOW);
}
}
}
最初の行で述べたように、完全な説明はMUX-DEMUXにあります:CD4051 Parlor Tricks
ためのクラスプロジェクト Iは、7セグメントディスプレイを駆動するためにCD4024二Arduinoのピンを使用します。
このアプローチにはいくつかの注意事項があります。たとえばhigh
、リップルカウンタの最初の出力に値を書き込むにはreset
、クロックピンを2回切り替えるだけで済みます。ただし、high
n個すべてのピンに書き込むには、クロックピン2をn回切り替える必要があり、その間、他のすべてのピンは常にオンとオフに切り替えられます。
アプリケーションがこれらの制限に対処でき、ピンが足りない場合は、別のオプションです。
少しの作業(別のブートローダーのインストール)により、UnoのICSP1およびJP2ヘッダーで、さらに7つのI / Oラインを使用できます。代替ブートローダーはHoodLoader2と呼ばれます。UnoのAtmega328とAtmega16U2の両方にスケッチをインストールできます。複数のプロセッサを扱うことは、この方法を使用する主な問題です。
Unoでは、ICSP1およびJP2ヘッダーはAtmega16U2のピンPB1 ... PB7に接続します。さらに、Atmega16U2には約9個のI / Oピンがあり、回路基板に接続されていません。顕微鏡の下で作業する人は、16U2の合計18個のI / Oピンにワイヤを接続し、他の3つのI / Oピンを通常の接続に接続したままにすることができます。
HoodLoader2はMegaボードでも動作します。