※ 결론보다 문제점 설명이 더 길기에 미리 쓰는 해결방법 : 풀 다운 저항
아두이노의 디지털 핀 확장을 위해 많은 분들께서 74HC595나 74HC165 IC 등을 주로 사용하곤 합니다.
제 경우에는 업무상 필요에 의해 디지털 입력확장 보드를 제작할 필요가 있었는데, 회사에 4051 아날로그 MUX가 많더군요.
이 아날로그 MUX를 디지털 MUX로 사용할 수 있는지 알아봤는데 딱히 이렇게 쓰면 된다 하는 글을 못찾겠더군요.
제 검색 실력이 형편없었을 수도 있고, 그냥 74HC595/165를 쓰는게 효율적이기에 제가 찾는 글이 없었을 수도 있지요.
허나, 업무상 한정적인 자원으로 급하게 진행해야 하는 제 경우엔 또 새로운 IC를 적용해서 테스트를 하고 PCB를 설계할
시간적 여유가 없었기에 결국 4051 아날로그 MUX를 디지털 MUX로 사용하게 되었습니다.
4051 IC는 기본적으로 아날로그 멀티플렉서이며, 9~11번 핀의 A, B, C 컨트롤을 High/Low로 변경하며, 이를 이진법으로 0번에서 7번까지의 채널I/O핀을 제어해 COM I/O핀으로 데이터를 읽던가 보내던가 할 수 있습니다.
다음 그림은 4051 IC를 사용하는 간단한 예제입니다.
# 아두이노 핀 맵핑
- 22 : Ctrl A ( IC 11번핀 )
- 24 : Ctrl B ( IC 10번핀 )
- 26 : Ctrl C ( IC 9번핀 )
- A0 : 0ch I/O ( IC 13번핀 )
- A1 : 1ch I/O ( IC 14번핀 )
- A2 : 2ch I/O ( IC 15번핀 )
- A3 : 3ch I/O ( IC 12번핀 )
- A4 : 4ch I/O ( IC 1번핀 )
- A5 : 5ch I/O ( IC 5번핀 )
- A6 : 6ch I/O ( IC 2번핀 )
- A7 : 7ch I/O ( IC 4번핀 )
- A15 : COM I/O ( IC 3번핀)
위와 같이 회로를 구성하면, 0~7Ch I/O(아두이노 A0~A7핀)중 하나에 analogWrite() 함수로 값을 쓰고, Ctrl A~C(아두이노 22, 24, 26핀)을 사용하여 특정 채널에 써진 값을 COM_I/O(아두이노 A15핀)로 읽어올 수 있고, 반대로 COM_I/O핀에 analogWrite() 함수로 값을 쓰고 Ctrl A~C를 제어하여 특정 채널 I/O에 값을 보낼 수도 있습니다.
예를 들어 A3에 200의 값을 쓰고, Ctrl A(22)에 Low, Ctrl B(24)에 High, Ctrl C(26)에 High를 주면 COM_I/O핀에 200의 값이 전달됩니다. int value = analogRead(A3); 한 후 시리얼 모니터에 찍어보면 200이란 값이 나오겠지요.
여기서 analogRead 대신 digitalRead를 사용하면 High가 나올까요 Low가 나올까요.
결과는 '장담 못한다.' 입니다. 저는 루즈하게 analogRead/Write의 값 범위가 0~1023 이니까 적당히 512를 기준으로 낮으면 Low, 높으면 High가 나오겠지하고 생각했으나, 그렇지 않았습니다.
아날로그 값과 디지털 값을 다 읽어보았으나 어쩔땐 700~800이 나와도 Low일 때가 있고, 어쩔땐 50~100이 나와도 High일 때가 있더군요. 너무 안일했습니다.
제가 제작한 회로의 경우, 4051의 각 채널I/O 핀에 스위치를 통해 5v 전압이 걸리면 High로 인식하여 COM_IO로 HIGH를 가져와야 했으나, 5v 전압을 걸어도 High가 제대로 걸리지 않고, 인접한 다른핀의 5v 인가에도 영향을 받아 High-Low가 지멋대로 바뀌더군요.
이런 저런 시도끝에 4051의 0~7ch 핀에 각 10K옴 풀다운 저항을 걸어주니 값을 정확히 High/Low로 받을 수 있었습니다.
제 회로는 (하나의 4051 IC의 각 채널 I/O를 8개의 또다른 4051 IC의 COM_I/O로 연결) x 2 하여 최종적으로는 A0, A1 두개의 아두이노 핀과 컨트롤신호핀 6개, 총 8개의 아두이노 핀을 사용하여 128개의 디지털 인풋을 입력받을 수 있도록 확장했습니다.
이 경우 스위치와 연결되어 5v를 직접 받는 16개의 4051에는 풀 다운 저항을 달아줄 필요가 없으며, 8개의 4051 IC가 모이는 허브 역할을 하는 4051 IC의 각 채널 I/O에만 풀 다운 저항을 사용하면 인풋을 High/Low 디지털로 읽을 수 있습니다.
이하는 제가 사용한 PCB 설계도 입니다.
무료 설계툴인 Fritzing에서는 2레이어 PCB까지밖에 설계할 수가 없기에 점프 와이어를 꽤 많이 날려야 하지만, 일단 동작은 확실하게 검증하였습니다.
Ctrl A,B,C는 허브 역할을 하는 4051의 채널을 제어하며, Ctrl 1,2,3은 5v가 인가되는 말단 4051을 제어합니다.
Slot 0,1을 아두이노 A0, A1에 연결하여 디지털 High/Low를 가져오도록 되어있습니다.
이하는 위 PCB로 디지털 입력을 확장한 소스코드입니다.
#define DigitIn_enable 0x01 // DigitIn_DATA_PIN[0][DigitIn_nSlot]에 각 Slot에서 들어온 값 넣음. |
원래 소스코드에는 192개 LED 개별 밝기조절/점등 부분과 TCP/IP 서버 생성하여 클라이언트에 변화감지 시 메세지 날리는 부분도 함께 있었으나, 포스팅의 깔끔함을 위해 편집을 가하였습니다. 편집 과정에서 불필요한 부분이 남아있을 수 있다는 점 미리 양해를 구합니다.
아마도 저처럼 사용하실 분이 계시긴 할런지 의문이긴 한데, 혹시나 4051 아날로그 MUX를 보유중인데, 디지털 MUX가 따로 더 필요하다 하시는 분이 계시다면 풀 다운 저항을 이용하여 디지털 MUX로 유용할 수 있다는 정보를 공유하고 싶었습니다 ㅎㅎ
그럼 오늘의 포스팅은 여기까지!! 휘리릭 뿅~