(第2回)拡張ICについて(その1)

使用しているArduino Pro Mini 328 3.3V 8MHz はピン数が16個と多くありません。たくさんのモーターやセンサーとマイコンと接続するには、ピン数が不足するため拡張させる必要があります。拡張するために、拡張ICを使います。
入力用の拡張ICは74HC165というICを使用します。コントローラーを自作してスイッチを増設するためにも使用できるので、マイコンの3カ所のピンを16個の入力に拡張します。

マイコンの3つのピンで16個の入力にする

マイコンの3つのピンを16個の入力につかえるようにします。

<必要な物>

a.Arduino Pro Mini 328 3.3V 8MHz

b.74HC165

c.抵抗(30kΩ)

d.FTDI USBシリアル変換アダプター Rev.2

e.USBケーブル(micro-B)

f.パソコン

 

1.接続

(74HC-165)

74HC-165は複数個使えるようになっています。まずは、1番をONにすると、入力ピン(3~6・11~14)が固定されます。2番をON-OFFするたびに入力ピンの状態を9番から出力します。74HC165-1はマイコンへ出力しますが、同時に74HC165-2の9番から74HC165-1の10番に入力ピンの状態を送ります。
2番のON-OFFの度にピンの状態が出力されるので、16回ON-OFFすることで、2個のICのピンの状態をマイコン側に保存することができます。

(接続図)

aとbを2個接続します。ちょっと複雑ですが、マイコンの方は、電源以外3ピンを使用しているだけで、入力点(緑色の□)が全部で16個になっています。
入力部分に3.3Vを接続することで、スイッチなどのセンサーとして利用することができるようになります。
cの30kΩの抵抗が16個ついていますが、これは、プルダウンといって、センサーから3.3Vが接続されていない場合、強制的に0Vにする役割があります。

2.プログラムの準備

①以下がサンプルプログラムです。コピーして使います。
プログラムが3個に分かれています。最初の2つは2個のICからデータを読み取るプログラムです。

//----(プログラム)----

//74HC165-1のデータピン状態を8回チェックする
byte ShiftIn(int dataPin, int clockPin, int loadPin)
{
unsigned char x ;
int i ;
x = 0;
digitalWrite(loadPin, LOW) ;// 15番OFF 入力端子(A-H)読み込み
digitalWrite(loadPin, HIGH) ;// 15番ON 入力端子(A-H)ロック
x = x | (digitalRead(dataPin) << 7) ;//H端子の状態を読み込む(最初の1回目)
for (i = 6 ; i >= 0 ; i--) {// G端子~A端子まで繰り返す
digitalWrite(clockPin, HIGH) ;// 17番ON 次の端子の状態にシフト
digitalWrite(clockPin, LOW) ;// (例)H→Gの状態
x = x | (digitalRead(dataPin) << i) ; // 16番でシフトされた内容を受信する
}
return x ;
}
//74HC165-2のデータピン状態を8回チェックする
byte ShiftIn2(int dataPin, int clockPin, int loadPin)//loadPinは実際使わない(15番)
{
unsigned char x ;
int i ;
x = 0;
for (i = 7 ; i >= 0 ; i--) {// H端子~A端子まで繰り返す
digitalWrite(clockPin, HIGH) ;// 17番ON 次の端子の状態にシフト
digitalWrite(clockPin, LOW) ;// (例)H→Gの状態
x = x | (digitalRead(dataPin) << i) ; // 16番でシフトされた内容を受信する
}
return x ;
}

void setup() {
delay(1000);
//シリアル通信の初期化
Serial.begin(9600) ;

// 74HC165のピン情報初期化
pinMode(16, INPUT) ;
pinMode(17, OUTPUT) ;
pinMode(15, OUTPUT) ;
//ICの準備する
digitalWrite(15, HIGH) ;
digitalWrite(17, LOW) ;
}
void loop() {

//入力IO
byte dt ;
byte dt2 ;
String sendPacket;
String sendPacket2;
int StrCount;
int StrCount2;
uint16_t MyInt;
uint16_t MyInt2;
int i;
dt = ShiftIn(16, 17, 15) ;//74HC165-1の状態を確認させる。(上のShiftInプログラム実行)
dt2 = ShiftIn2(16, 17, 15) ;//74HC165-2の状態を確認させる。(上のShiftIn2プログラム実行)
//データを文字にする
sendPacket = String(dt, BIN);
sendPacket2 = String(dt2, BIN);
StrCount=8-sendPacket.length();
for (int i = 0; i < StrCount; i++) {
sendPacket="0"+sendPacket ;
}
StrCount2=8-sendPacket2.length();
for (int i = 0; i < StrCount2; i++) {
sendPacket2="0"+sendPacket2 ;
}
//表示
Serial.print("74HC165-1:") ;//シリアル通信で出力
Serial.print(sendPacket) ; //シリアル通信で出力
Serial.print(" 74HC165-2:") ;//シリアル通信で出力
Serial.println(sendPacket2) ;//シリアル通信で出力

delay(1000);
}

②プログラムを書き込んだら、好きな入力に3.3Vを接続します。書き込みにd・e・fを使いますが、そのままにすることで、マイコンとICが動作します。モーターと違って、電流が少ないため、パソコンからの電力でも十分動作できます。

③パソコンソフトのArduino IDE のメニュー→ツールに「シリアルモニタ」があります。開くと下のような文字が1秒毎に表示されます。ICの11番(A)が一番左の桁で、BCDEFGと続き、6番(H)が一番右の桁になっています。
「01001000」はBとEが3.3Vで、そのほかは0Vという意味です。

74HC165-1:01000000 74HC165-2:01001000
74HC165-1:01000000 74HC165-2:00001000
74HC165-1:01010000 74HC165-2:00011000
74HC165-1:01000100 74HC165-2:00001001
74HC165-1:01000000 74HC165-2:00000000
74HC165-1:01000000 74HC165-2:01001000

実験の様子

3.3Vにしたところがマイコンから出力されましたか?これで16個のボタンやセンサーを接続することができるようになります。最初のころは、入力側にスイッチを付けて、コントローラー にしていました。モーターに直結できないような小さいスイッチも使えますが、小さいスイッチは、汗ですぐ壊れてしまいます。(汗がスイッチに入り込んで、接触不良になる) 大きいスイッチは接触不良にはならないのですが、操作がしにくいという欠点がありました。
センサーはいままでもほとんど使ったことがないので、16個も必要ないかもしれません・・・。

-------------