Arduinoに14個を超える出力ピンを使用する方法はありますか?


52

Arduinoに14本以上の出力ピンを持つことは可能ですか、私はいくつかのLEDを個別に点灯する必要があるプロジェクトに取り組んでいます。Arduino Unoしか持っていないので、Megaを手に入れたくありません。


拡張性の精神で、I2CはArduinoのオプションでもありますか?
クリスO 14

@ChrisO I2Cとはどういう意味ですか?私が理解していることから、シフトレジスタはI2Cと見なされるからです。
JVarhol

ああ、それから私の質問に答えさせてください;-)ここに、このバス標準に関するウィキペディア記事があります。また、I2CのWire libからのサポートを見つけたので、I2CチェーンをUnoに接続できます。
クリスO 14

@JVarholそうではありません。I2C、別名TWIは2線式インターフェースですが、SPIは3線式インターフェースと見なすことができます。
クラウスディエターワルシャチャ14

1
@JVarholは、プロジェクトのソリューションをすでに選択していますか?はいの場合、質問を編集し、ソリューションに一致する(または最も近い)回答を受け入れると便利です。
jfpoilpret

回答:


50

Arduinoで使用可能な出力ピンのセットを拡張する一般的な方法は、74HC595 ICなどのシフトレジスタを使用することです(データシートへのリンク)。

これらのチップを制御するには、3つのピンが必要です。

  1. 時計
  2. ラッチ
  3. データ

プログラムでは、次のようにshiftOut()コマンドを使用して、データを一度に1ビットずつシフトレジスタに渡します。

shiftOut(dataPin, clockPin, data); 

そのコマンドを使用して、data変数の8ビットを使用して、595 ICの8つの出力のそれぞれを設定します。

1つの595で、5つのピンを獲得します(ICで8つですが、話をするのに3つ費やします)。より多くの出力を得るために、シリアル出力ピンを次のデータピンに接続することにより、一連の595をデイジーチェーン接続できます。また、すべての595 ICのクロックピンとラッチピンを接続する必要があります。

結果の回路(595を1つ使用)は次のようになります。

595シフトレジスタを使用する回路

上の図は、このcodeproject.com Webページから引用したものです。

ラッチピンは、次のようにデータをシフトアウトしている間、595出力を安定させるために使用されます。

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, data); 
digitalWrite(latchPin, HIGH);

1
Thx、シフトレジスタの動作を含めるのを忘れていました。計画していたが、コンプから離れなければならなかったし、戻ってきたとき、それは私の心を滑らせていた。:)
JVarhol 14

問題ありません。だからこそ私たちはコミュニティです。私たちはお互いの答えを補完します。ただし、特にEZ-Expanderシールドに関して、いくつかの優れたヒントを回答に追加したことは素晴らしいことです。これにより、PCBを簡単に作成できない場合でも、使用可能なポートの数を増やすことができます。
リカルド14

2
また、プログラミングが簡単になります。データをシフトインしてクロックをパルスし、ラッチをアクティブにする必要はありません。シールドについてはかなり前から知っていましたが、初心者には最適だと思います。最も良いのは、コードがオープンソースであるため、実際にシールドを使用していないが独自のボードを持っている場合、またはブレッドボードを使用している場合でもコードを使用できることです。
JVarhol

1
これらを(理論的に)無期限にインラインでリンクできることを忘れないでください。したがって、2つの8ビットレジスタが1つの16ビットになる可能性があります。
スコットM. 14

ありがとう!ここに、リンクがダウンした場合の驚くべきコードプロジェクトの説明へのアーカイブリンクがありますarchive.fo/1uvPE
akhmed

27

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つの方法の両方を問題なく使用できることです。


3
Arduinoのリファレンスによると、あなたが実際に使用することができますA0- A5番号14-19を使用するのではなく、直接識別子を。たとえば、digitalWrite(A0, HIGH)
ピーターブルームフィールド

3
@ PeterR.Bloomfieldどちらも正しいですが、読みやすくするためにA0〜A5をお勧めします。LEDが点滅することは大したことではありませんが、大規模なプロジェクトでは少しの習慣が増えます。
匿名のペンギン14

2
実際、どちらもUNOと互換性のあるボードで作業を行いdigitalWrite(A0)ますがdigitalWrite(14)、前者は常に正しい物理(アナログ)ピンにマッピングされるため、より正確です。別のボードでpin 14は、実際にはそうA0ではないかもしれません。たとえばpin 14、MEGAではSerial3でTXあり、使用しているアナログピンには影響しません。つまり、digitalWriteアナログピンで使用する場合は、A0- A5参照を使用します。
マディバッド14年

18

LEDを駆動する場合は、追加の回路なしで64個のLEDを駆動できるMAX7219を使用することもできます(信号を増幅するトランジスタは不要です)。

MAX7219を駆動するには、Arduinoで3つの出力ピンのみが必要です。また、いくつかのArduinoライブラリを見つけることができます。

64個を超えるLEDに電力を供給する必要がある場合は、それらのいくつかをチェーンすることもできます。

複数の7セグメントLEDディスプレイに使用できました。

欠点:高価です(約10ドル)。


MAX7219については忘れてしまいました、投稿してくれてありがとう!
JVarhol

384個のLED ... さらに、USB推論用の2つのピン。どのような迷惑な小物を(十分な電源で)作成できるか疑問に思います。
匿名のペンギン14

17

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

ここに画像の説明を入力してください

ここでより良いチュートリアルを見ることができます


注意すべきことの1つは、この手法では、より多くのledを制御できることですが、必ずしも同時に制御できるわけではありません。
kontur

1
@konturはい、そうです。しかし、ビジョンの持続性の観点からは、それらがそうであると考えることができます。質問にはそのような詳細はありません。
ダニエルグリロ

Charlieplexingは、シフトレジスタを使用せずにLEDを多重化する唯一の方法ではありません。
linhartr22

1
@ linhartr22それが唯一の方法だとは決して言わなかった。Charlieplexingは、この問題の一般的な解決策です。そして、私の答えは7番目でした。そのため、他の可能性が以前に示されていました。
ダニエルグリロ

@DanielGrillo私はより具体的で、LEDキューブで通常使用される列と行の多重化を、シフトレジスタなしで、Charlieplexingの制限なしで実行できる方法を説明する必要がありました。4x4行の列マトリックスは、8個のI / Oラインで16個のLEDを個別に制御できます。4x4x4キューブは、12個のI / Oラインで64個のLEDを個別に制御できます(デジタルラインとしてアナログA0-A5を使用することでUnoでも可能)。
linhartr22

13

I 2 C(ワイヤー)

I 2 Cプロトコル(Wireライブラリ)を使用して、ポートエクスパンダーなどの他のデバイスに接続できます。たとえば、MCP23017。

これらのチップの1つを使用して、LCDボードに接続しました。MCP23017には16個のポートがあり、入力または出力として構成できます。入力として、必要に応じて割り込みを発生させることができます。

16のうち13をLCDに接続する例:

LCDスクリーンに接続されたMCP23017

次に、2本のワイヤ(SDA / SCL)と電源とグランドのみを使用してArduinoに接続します。

Arduinoに接続されたMCP23017


一部のサードパーティメーカーは、4 x MCP23017を搭載したボードを製造しています。これにより、64の入出力が可能になります。

ムカデ板


マルチプレクサー

次のように、74HC4051(8ポート)や74HC4067(16ポート)などのアナログマルチプレクサを使用して、1つのピンを8/16ポートの1つ(ただし、一度に1つだけ)に接続できます。

74HC4051マルチプレクサー

これらは双方向なので、入力または出力エキスパンダーとして使用できます。


SPIと74HC595

SPIを使用すると、74HC595などのシフトレジスタに高速シリアルデータを送信できます。これらはデイジーチェーン接続できます。この例では、3つのI / Oピン(MOSI / MISO / SCK)と電源とグランドのみで32個のLEDを制御しています。

32個のLEDを駆動する74HC595


72個のLEDが74HC595チップによって駆動されていることを商業用LED看板の中に見つけました。

スクロールLEDサイン

これには、多重化構成で、列を駆動する9個のチップ(9 x 8 = 72個のLED)と行を駆動する1個のチップがありました。


MAX7219を使用したSPI

LEDを駆動したいだけであれば、通常はLEDを多重化できます。MAX7219は、7セグメントディスプレイなどのLEDマトリックスを駆動するように設計されているため、それが簡単になります。

7セグメントディスプレイ付きMAX7219

または64 LEDマトリックス:

64 LEDマトリックス付きMAX7219

どちらの場合でも、これらは次のようにデイジーチェーン接続できます。

MAX7219デイジーチェーン

これらの例はすべて、Arduino(MOSI / MISO / SCK)の3つのピンと電源とグランドのみを使用しています。


MCP23S17を使用したSPI

前述の16ポートポートエクスパンダー(MCP23017)にはSPIバリアント(MCP23S17)もあり、これは実質的に同じことを行います。もう1本のワイヤを使用しますが、より高速になります。


その他のプロトコル

LEDストリップ(NeoPixelなど)には独自のプロトコルがあります。Josh LevineよるYoutubeでの投稿があり、そこで著者はDuemilanoveで1000ピクセル以上を運転しました!


参照資料


12

シフトレジスタは他の回答でも言及されており、多くのプロジェクトにとって間違いなく優れた選択肢です。それらは安価で、シンプルで、適度に高速であり、通常はチェーン化して出力を追加できます。ただし、通常は複数のピンを排他的に使用する必要があるという欠点があります(設定方法によっては2〜4)。

もう1つの方法は、16ビットMCP23017やMCP23S17などのより高度なポートエクスパンダーを使用することです。これらはそれぞれI2CとSPIをサポートします。つまり、他のいくつかのデバイス(場合によっては異なるタイプ)を備えたバス上に配置できます。バス上の各デバイスは個別にアドレス指定できます。つまり、すべてのデバイスと通信するには2本または3本のピンしか必要ありません。通常、更新速度は非常に高速であるため、Arduinoプロジェクトで大幅な遅延(つまり、伝送遅延)が発生することはほとんどありません。

低レベルでは、I2CまたはSPIを使用することは、単純なシフトレジスタよりもかなり複雑です。ただし、Arduinoがそれを処理するライブラリコードがあります。たとえば、この質問を参照してください:ArduinoでI2Cデバイスを使用するにはどうすればよいですか?


うわー、私はそれらについて知りませんでした、thx、それらを見てください!
JVarhol

I2Cを使用してLEDを制御できますか?
プロQ

1
@ProQ I2Cを使用して標準LEDを直接制御することはできません。ただし、I2Cドライバーが組み込まれた一部のLED製品を入手することは可能です。これは通常、ストリップやマトリックスなど、LEDがたくさんある製品用です。
ピーターブルームフィールド

8

リカルドの答えに加えて、ウィキペディアがシフトレジスタについて述べていること

シフトレジスタの最も一般的な使用法の1つは、シリアルインターフェイスとパラレルインターフェイス間の変換です。[...] SIPOレジスタは、一般に使用可能なピンよりも多くの汎用入力/出力ピンが必要な場合、マイクロプロセッサの出力に接続されます。これにより、2つまたは3つのピンのみを使用して複数のバイナリデバイスを制御できますが、パラレルI / Oよりも低速です。

リカルドがリンクした記事では、シフトレジスタの図を見ることができます。

シフトレジスター図

ここで何が起こるかは、8ピンのデータを連続して配置し、各クロックティックごとにシフトレジスタがシフトする(各ラッチから次のラッチにバイナリデータを移動する)ことです。最後のピンに到着します。シフトレジスタには、シフトをオン/オフできる入力があり、データがその位置にシフトされた後もステータスを保持できます。簡単なデモについては、次のアニメーションを参照してください。

シフトレジスタアニメーション

ここで、赤色のライトはシリアル入力であり、緑色のライトはこの簡略化されたSIPOシフトレジスタのラッチの状態を示しています。データを場所にシフトした後、シフトをオフにして、ピンを読み取ることができます。この例では、私はシフトアウトしました10101011

これらの例から、シフトレジスタがビットを適切な位置にシフトするのを待つ必要があるため、シリアル転送はパラレルよりも遅いことがわかります。ロードするビット数と同じ量のクロックティックを待つ必要があります。これは、ロードに時間がかかるため、無期限にチェーンできない多くの理由の1つです。


1
追加情報と、きれいにアニメーション化されたGIFとその教訓的な効果のために+1!GIFはどこで見つけましたか?またはあなたはそれを作りましたか?
リカルド

1
@Ricardo Digital Worksを使用して回路を作成し、画面を印刷し、編集し、GIFアニメーターを作成しました。
totymedli 14

6

すでに記述したように、TXおよびRXを含むすべてのピンをデジタル出力として使用できます。少し前にデモンストレーターでそれを行い、このかなり無意味なプロジェクトのビデオ(20ピンの20個のLED)を記録しました。

ここPeter R. Bloomfieldが 説明したように、アップロードのためにTXとRXを切断する必要があります。さらに、センサーを読み取って対話性を確保するためにピンが不足しているため、合計電流制限に達していないことを確認する必要があります。Arduinoで直接駆動する場合、5VのLEDに限定されることを忘れないでください。

したがって、一般的なシフトレジスタとリカードが説明した595の使用を強くお勧めします。

  • 彼らは安いです!
  • それらをカスケードするのはかなり簡単です。
  • ハードウェアSPIを使用すると、多くの速度が得られます。

少し前に、アップサイクリングアーティストDominik Jais のカワイイミー(リンクのテキストはドイツ語)のはんだ付けとプログラミングの部分に気付いたときに使用しました。

ここでは、8個の11個のLEDのディスプレイを駆動するために、595個だけが使用されました。LEDは12V SMD LEDのストライプから切断されたため、追加の電源と、シフトレジスタの出力ピンに接続されたUDN2803Aダーリントンアレイが必要でした。

他の一般的な方法には、PCF8574(A)8ビットポートエクスパンダーの使用が含まれます。これらは、I2Cバスを介して制御されます。

とにかく、私は595シフトレジスタを最初に試してみます。

ただし、いくつかのRGB LEDを制御する必要がある場合は、より専門的なソリューションを探してください。一部のRGB LEDには、独自のWS2812が付属しています。これらの細かい部分はカスケード接続することができ(1-Wireバス)、チェーン内の位置を介してアドレス指定されます。


3

すべてがLEDの場合、WS2812B LEDストリップ、またはドライバーチップ自体はどうですか?1つのピンを使用して、事実上無制限の数のLEDを制御できます!

人々はこれらをストリップで使用していますが、スタンドアロンLED(Adafruitではneoピクセルとして知られています)として利用できます。または、単一の色のみを駆動する場合、各WS2811チップは、それぞれ単一のLEDの各RGB出力を使用して3つのLEDを制御できます。

最近作成したプロジェクトでは、Door1を開閉するDoor1、Door2を開閉する、motor1がアクティブ、motor2がアクティブ、電源の5つのLEDを使用するプロジェクトを作成しました。「アクティブ」LEDは、赤がアクティブなモーターからの入力であり、緑がArduino内のアクティブなフラグであるため、二重の目的です。

ポイントは、1ピンとライブラリがインストールされている場合、任意の数のLEDを制御できることです


2

私は自分自身でこの方法を主張していませんが、WebページMUX-DEMUXでこのきちんとしたトリックを見つけました:CD4051 Parlor Tricks

出力の駆動または入力の読み取りに使用する方法(シフトレジスタ、マルチプレクサ、またはArduinoピン自体の直接的な直接使用)の選択にかかわらず、並列回路ペアの巧妙な使用により出力または入力の数を2倍にすることができます(デュアルを形成するため)入力または出力バンク)、各並列ブランチで反対方向のダイオードを使用し、入力/出力をハイとローに切り替えます。

出力の方法を説明するために(この場合のLEDは、追加のダイオードが必要ないことに注意してください):

LEDバンク

この例のLEDのペアを「バンク」と見なし、LED_0を点灯させる場合は、PIN 17をHIGHに、PIN 18をLOWに設定する必要があります。(ピン番号は紛らわしいですが、後者の例と一致しているので、私には必要ありません)。LED_1を点灯するには、PINを逆にするだけです。LEDのダイオードの性質により、電流が反対方向に流れないようにし、もう一方をオフにします。

入力の方法を説明するために(この場合はCdSs、追加のダイオードが必要であることに注意してください):

CdS銀行

CdS光センサーでアナログ読み取りを行う場合、これはもう少し複雑になります。まず、流量を制御するために各センサーにダイオードを追加する必要があります。第二に、値を読み取っているので、入力をフローティング状態にしないために、入力をハイまたはローにする必要があります。怠け者なので、内部プルアップ抵抗を使用してそれらを高く引き上げます。CdS_0を読み取るには、PIN 17モードをOUTPUTに設定し、LOWに設定します。これが基盤となります。次に、PIN 18モードをINPUTに設定し、それをHIGHに設定してプルアップ抵抗を有効にします。これで、PIN 18(別名アナログピン4)で読み取りを行うように設定されました。他のセンサーにアクセスするには、モードと出力を切り替えるだけです。

したがって、Arduinoの5ピンを使用して(通常の3つではなく)CD4051 8ポートマルチプレクサーを使用している場合、16の入力または出力、または2つのミックスを取得できます。

CD4051を使用した16の出力/入力

同様に、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


1

ためのクラスプロジェクト Iは、7セグメントディスプレイを駆動するためにCD4024二Arduinoのピンを使用します。

このアプローチにはいくつかの注意事項があります。たとえばhigh、リップルカウンタの最初の出力に値を書き込むにはreset、クロックピンを2回切り替えるだけで済みます。ただし、highn個すべてのピンに書き込むには、クロックピン2をn回切り替える必要があり、その間、他のすべてのピンは常にオンとオフに切り替えられます。

アプリケーションがこれらの制限に対処でき、ピンが足りない場合は、別のオプションです。

ボーナス回答:ここには多重化入力の例がたくさんありますが、その多くは多重化出力にも当てはまります。


7ステージカウンターを使用して7セグメントディスプレイを駆動することは、あなた自身が示した理由から、次善のアプローチと思われます。
jfpoilpret

1

少しの作業(別のブートローダーのインストール)により、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ボードでも動作します。


0

ここにはたくさんの良い答えがありますが、時間をかけた場合、メガを買う方が安くなるでしょう。

私の3 / 2-d価値。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.