이번에는 여러 입력값을 받아서 적은 출력값을 내도록 하는 (74164나 595와는 반대의) 실험을 해보겠습니다. 스마트 어항 제어기 하나로 3개의 어항을 모니터링 하려니 INPUT 핀이 매우 모자르기에 집에 있는 74151, 74138, 4053B 를 갖고 INPUT Multiplexing 실험을 해보도록 하겠습니다.
Input / Output 이 모두 되어 Multiplexing / Demultiplexing 이 되고, Analog IN/OUT 이 된다고 하니 한번 모두 해보도록 하겠습니다.
CD4053B
CD4053B 는 " triple 2-Channel multiplexer having three separate digital control inputs, A, B, and C, and an inhibit input." 이라고 되어있다. 즉 2채널의 INPUT/OUTPUT 을 3개 갖고있고, 이를 A,B,C 를 통해서 선택할 수 있는거다.
4015B 는 가장 많이 쓰는녀석인데, 8 채널의 INPUT 중 1개를 A,B,C 로 선택해서 입출력할 수 있고, 8개의 채널을 1개의 핀으로 읽거나 쓸 수 있어, 총 4개의 핀만 있으면 8개를 읽거나 쓸 수 있는겝니다.
4052B 는 4채널 씩 X 와 Y 로 나누어 A,B 로 입출력할 수 있고, 2개의 핀 + 2개의 핀(A,B) 총 4개 핀으로 입출력이 가능한겁니다.
4053B 는 위에서 얘기했듯이 3개의 핀으로 입출력이 오고 3개의 핀(A,B,C)으로 선택을 하니까 총 6개의 핀으로 6개의 입출력을 하게됩니다. 이걸 쓰느니 그냥 6개 입력이나 출력을 그냥 해버리면 되니 아두이노에서는 그닥 쓸모가 없어보입니다. 그래서인지 예제도 거의 안나옵니다. 4051B 만 예제가 나오지요..ㅠㅠ
위 마지막 4053B 를 갖고 실험해보기로 한다.
빨간색 박스가 각각 a,b,c 이고, a, b, c 에는 각각 x 와 y 의 2개의 채널이 있다. 스위치 처럼 되어있으며, ax, ay 의 IN/OUT 은 14번 핀으로 OUT/IN 되고, bx, by 의 IN/OUT 은 15번 핀 으로 OUT/IN 된다. cx, cy 도 마찬가지이다.
INH는 HIGH 인 경우 칩의 동작을 멈추게 합니다.
VEE 와 VSS 는 모두 GND 로 연결합니다.
VDD 는 5V 에 연결해주면 되고, A, B, C 는 Arduino 로 연결합니다.
허용전류는 10mA 이므로 입력이나 출력전류를 잘 계산하도록 합니다.
위 그림은 4053B 의 기능도인데, 이를 보면, A,B,C 시그널에 의해 각 x,y 중 하나를 선택해서 IN/OUT 을 OUT/IN 으로 연결해주는것을 알 수 있습니다.
푸시 스위치 입력받기 (디지털 입력)
푸시 스위치를 입력받아 보겠습니다. 그런데 푸시스위치를 이런 방식으로 읽어들이는것은 바람직하지 않겠네요. 동시에 푸시스위치를 여러 개 누를게 아니라면 좋지 않습니다.
왜냐하면, 예를 들어 100ms 씩 채널의 INPUT 을 READ 한다고 가정할 때 10개의 버튼 입력값을 읽어들일 때 제일 마지막 버튼이 눌렸지 체크하는데 까지 걸리는 시간은 1초가 됩니다. 물론 4053B 는 3개 채널 그룹으로 병렬로 READ 할 수 있으니 이것보다는 짧겠네요. 하지만, 여전히 바람직하지는 않겠어요.
이보다는 405X 시리즈는 INPUT 시그널을 스위칭 해가면서 READ 할 때 사용하거나 출력할 때 사용하는게 더 낫겠다는 생각입니다.
그래도 아래와 같이 한번 해봅니다.
센서 입력받기 (아날로그 입력)
더많은 입력받기 (Shift Register 응용)
2043B 의 INH 를 활용하면 더 많은 204XB 들을 연결하여 더 많은 입력을 받아 SELECT 할 수 있습니다. 이제 그 진가가 발휘되는거죠.
74595 (UTC U75HC595AL) / 8-BIT SERIAL-IN SHIFT REGISTER WITH LATCHED 3-STATE PARALLEL OUTPUTS, PROVIDING SERIAL OUTPUT
무슨 Datasheet 에 Description 이 이리도 긴지 모르겠습니다. 하지만 뭐하는 놈인지는 잘 알 수 있네요. 시리얼 IN 을 받아서 8Bit 패러랠로 넘기는 Shift Register 이고, Latch 가 있고, 3-State 패러랠 아웃풋(? 이게 뭔지는 하면서 알아봐야 겠네요), Serial Output 까지 제공하는 녀석입니다.
위 처럼 생긴 녀석입니다. 다리가 8*2 = 16개가 달렸습니다. 164는 같은 8Bit Shift Register 이지만 14개가 달려있지요.
74164와 가장 다른점은 OUTPUT ENABLE, LATCH CLOCK, SQH 입니다. LATCH 와 SQH 는 Latch, Serial 출력 일 것으로 짐작 되지만, Output Enable 핀은 무엇인지 모르겠네요. 하면서 찾아봐야 하겠습니다.
위 테이블을 보면, Operation 에 적혀있는 동작을 하기 위해서는 각 제어 핀들이 어떻게 시그널을 주어야 하는지 보여주고 있습니다. OUTPUT ENABLE 핀은 High Impedance State 라는 동작을 하기 위해 쓰이는군요. 그런데 이것도 모르겠습니다. 그래서 또 하다보면 나오겠다 생각됩니다.
1개의 595로 LED 켜기
가장 기본적인 단계입니다. 1개의 595로 불 켜는 예제를 해보겠습니다.
위 처럼 연결합니다. 이때 1uF 짜리 캐패시터는 Latch 시그널을 줄 때 클럭이 깨끗하지 못한 경우 깜빡임이 있을 수 있으므로 연결합니다.
위 회로도에서, Q7" 는 SQH 이고, MR 은 Clear (Reset), OE 가 Output Enable 핀 입니다. (회로도 그리기가 귀챦아서 퍼다 쓰다보니..^^)
위 코드의 for Loop 에서 처음 shitOut 을 하면, shiftOut() 내에서 1비트 씩 8번을 shift 합니다. 그리고 그 다음 shitOut() 은 또 8비트를 shift 하는데, 이때 부터는 데이터가 SQH 로 넘어가기 때문에 두 번째 Shift Register 에 출력이 됩니다.
좀더 명확히 이해하는데에는 아래 코드가 도움이 되겠습니다.
#define PIN_DATA 3
#define PIN_LATCH 4
#define PIN_CLOCK 5
void setup() {
pinMode(PIN_DATA,OUTPUT);
pinMode(PIN_LATCH,OUTPUT);
pinMode(PIN_CLOCK,OUTPUT);
digitalWrite(PIN_CLOCK,LOW);
shiftOut(PIN_DATA, PIN_CLOCK, LSBFIRST, 0);
shiftOut(PIN_DATA, PIN_CLOCK, LSBFIRST, 0);
}
void loop() {
for (int i = 0 ; i < 256 ; i++) {
digitalWrite(PIN_LATCH, LOW);
digitalWrite(PIN_DATA, !(i%4)); //4회 OFF ,1회 ON
digitalWrite(PIN_CLOCK, HIGH);
digitalWrite(PIN_CLOCK, LOW);
digitalWrite(PIN_LATCH, HIGH);
delay(500);
}
}
위 코드를 실행하면, LED 가 4개는 빈칸, 1개는 켜짐 상태로 계속 Shift 를 합니다.
SQH(Q7") 는 계속 Serial 로 자신이 Shift 될 때 마다 넘어가는(Overflow) 데이터를 출력해 줍니다.
동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
OUTPUT ENABLE 핀
Output Enable 은 구글링을 해보니, Shift Register 의 전체 출력을 보이게 하거나 안보이게 하는 역할을 한답니다. 그래서, 이 핀을 아두이노와 같은 PWM 출력이 되는 MCU 와 결합하면 LCD 등에서 밝기를 조절하는 역할을 합니다.
실제 analogWrite() 를 통해서 PWM 출력을 해보니 밝기 조절이 되네요. 출력을 높게 줄수록 밝기는 어두워집니다. GND 일때가 ON 이고 HIGH 주면 OFF 입니다.
결론
Shift Register 와 Latch 를 잘 활용하면 깜빡임이나 스크롤 현상 없는 출력을 만들어 낼 수 있고, Serial Output 을 사용하여 무한대에 가까운 (전력이 허용하는 한) 출력을 뽑아낼 수 있겠습니다. 거기에 OUT ENABLE 을 더하여 밝기 조절을 하면, LED 를 통한 다양한 표현이나 LCD 의 제어가 더욱 용이해지겠습니다.
물론 LCD 에 드라이버가 내장된것들이 많지만 이러한 원리를 알아가는 과정이 참 재미있네요.
74164 (Renesas SN74HC164N) / 8-BIT PARALLEL-OUT SERIAL SHIFT REGISTERS
10여년 전 AVR 한다고 책 사놓고 함께 사두었던 IC 들이 몇가지 있어서 부품들을 하나씩 테스트 해보기로 합니다. 그중 첫 번째, Shift Register 입니다.
용도
아두이노로 제어할 모듈들도 많은데 거기에 LCD 까지 붙여놓고 나면 GPIO 핀이 모자른 경우가 있습니다. 그래서 이런 부분을 충족 시킬 수 있는게 Shift Register 라고 들었기에, 정말로 이게 가능한지 함 해보도록 하겠습니다.
이름
SN
이건 뭐 회사에서 앞에 붙이는 이름이겠지요. SN 은 RENESAS 회사에서 주로 붙이는 것 같습니다.
74
74XX 시리즈 패밀리라는 얘기이지요. 예전 부터 TTL (Transistor - Transistor Logic)으로 불리우던 로직 IC 들에 붙는 이름입니다. 74 시리즈는 밑의 URL 가보시면 엄첨 많습니다. 전에 아는 분 책상에 TTL IC Spec 책자가 엄청 두꺼운게 놓여있었던걸 본게 기억나네요. 74 시리즈는 비교적 저전력으로 작동됩니다.
Highspeed CMOS 의 약자입니다. MOSFET 이 발명되고 나서 N / P 타입 MOSFET을 함께 구성하여 만든 회로가 CMOS 인걸로 알고있습니다. 이전의 Transistor 방식에 비해 훨씬 전력소모가 작지만 더 큰 전압을 제어할 수 있는걸로 알고있습니다. 요새는 그래서 대부분 HC 방식으로 나옵니다. LS 방식 (Lowpower Shotky)도 있지만 TTL 방식 대비 속도는 빨라도 전력 소모가 커서 요새는 HC 이네요.
속도도 TTL 만큼 나오고 (Highspeed) 전력 소모가 더욱 적으니 좋은놈이죠. 그리고 HCT 방식이 있는데요, 이건 HC 에 TTL 호환성을 가지는 녀석입니다. 그래서 TTL IC 들을 그대로 교체할 수 있고 함께 회로에 섞여있어도 잘 동작한답니다.
164
이건 뭐 다 아시다 시피 모델 번호죠. 164 는 8-bit parallel-out serial shift register with asynchronous clear 라고 되어있네요. 즉, 8Bit Shift Register 입니다.
8Bit
Shift Register 는 Flip-Flop 회로로 만들어집니다. 이 회로 1개는 1비트를 Holding 할 수 있습니다. 즉, HIGH 또는 LOW 상태를 저장할 수 있고, 이런걸 "메모리"라고 부르죠. 이게 8개 즉, 8Bit = 1Byte 있다는 이야기입니다. 1Byte 의 데이터를 저장할 수 있다는 이야기 이죠. 물론 전원이 계속 들어와 있는 상태여야 합니다.
Serial In / Parallel Out
아두이노가 데이터를 Serial 하게 보내고 이걸 8Bit 로 Parallel 하게 나누어서 출력할 수 있다는 이야기 입니다. 이 74164 의 경우는 2 개의 Input 을 받아서 8개의 Output 을 만들어 냅니다. 그래서 아두이노에서는 선 2개만 있으면 됩니다.
Non-Latched
이 164는 Latch 가 있다는 말이 없다. 그러면 없는것이다. 이게 단점이 될 수 있는데, 가령, 00000001 을 표현하려고 하면, 처음에 Data 를 HIGH 를 주면, 1번 QA 가 우선 켜지고, 다음 Clock 이 주어지면 1 을 하나 Shift 하므로, 01 이 되고, 이런식으로 7번 Clock 을 주면 스크롤 되는것 같이 모든 Output 에 HIGH 가 한번씩 매우 짧게 간 후에야 00000001 이 됩니다.
Latch 가 있는 IC 는 Data 를 준다고 바로 출력되는게 아니고 별도의 메모리가 있어서 일단 저장 되었다가 Switch 를 Flip 시키면 출력이 됩니다. 그러나 1개의 추가적인 선과 프로그램이 더 필요하게 됩니다.
LED 를 통해 이녀석을 실험 해 볼텐데, 이렇게 스크롤 되는게 매우 빠르게 보일것입니다.
PIN ARRANGE
핀은 저렇게 되어있습니다. 총 14개 핀 이고, 4개의 INPUT 핀(A,B,CLR,CLK)과 8개의 OUTPUT PIN (QA~QH), VCC와 GND 가 있습니다.
PIN 1,2 는 Serial Input 을 받기 위한 PIN 입니다. 두 핀은 AND Gate 로 되어 있어서, 1 이 입력되게 하려면 둘 다 HIGH 이어야 합니다. 둘 다 0 이면 0이 되는겁니다. 그런데 우리는 아두이노로 제어를 할 것이고 프로그램으로 충분히 HIGH / LOW 를 만들어낼 수 있기 때문에 AND Gate 는 필요 없습니다. 그래서 VCC 로 A 핀을 묶어 주도록 하겠습니다.
74164 의 3,4,5,6 번 PIN 은 첫 4 bit 가 되고, 10,11,12,13 은 그 다음 4비트가 됩니다.
CLR(-) 의 경우, LOW 를 주면 Register 를 모두 Clear 합니다. 나중에 쓰려면 쓰고, 우선은 High 로 주어서 유지합니다.
LED 켜기
일단 164를 아래와 같이 연결해봅니다.
74HC164N 의 Output Current 는 SPEC 에 Continuous Output Current 는 +-25mA 로 나와있습니다. LED 8개를 밝게 켜주기에는 무리가 있죠. TR 이 8개가 있어야 하겠네요. 하지만 일단 켜봅니다. LED 2V 전압 강하 예상하고, 20mA 는 8놈에게 나누어 줍니다. 개당 3mA 도 못먹겠네요. 저항이라도 좀 따로 달면 좋겠지만 일단 해봅니다.
연결할게 별로 없으니 심플하고 좋습니다. 의외로 밝기도 괜챦습니다. 잠시 동작하는 동영상을 보시지요.
동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
위 동영상은 순차적으로 HIGH 를 SHIFT 한 예제 입니다. 소스코드는 다음과 같습니다.
다음은 왼쪽과 오른쪽을 깜빡여 봤고, Arduino 의 ShiftOut 함수를 활용해봤습니다.
동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
소스코드는 다음과 같습니다.
결론
잠깐 동안이었지만 글을 쓰면서 진행 하니 그래도 시간이 꽤 걸리는군요.
Shift Register 는 이렇게 채널을 확장하는데에는 필수적인 존재인듯 합니다. 하지만 이 74164 의 경우는 Latch 가 없어서, 처음에는 shiftOut 함수에 0xF0 을 주건 0x0F 를 주건 계속 불이 켜져있는 것처럼 보여서(Delay도 안주고 했더니 더했네요..^^) 참 난감했습니다. 빠른속도로 Shift 하는 잔상이 생겨서(스크롤 현상) 동작하지 않는것으로 느낀정도였습니다.
앞으로 특수한 목적이나 Pin 이 너무 모자른 경우가 아니면 Latch 가 있는 Register (74594~599) 를 사용하는게 낫겠다는 생각입니다.
CMD : 0x22 - 창문 닫기 강제 / S2 눌려도 무시하고 계속 모터 진행. !주의! DAT : 0x0000 (보드설정사용), 0x0001 ~ 0x00FF (강제속도)
CMD : 0x13 - 모터 멈춤(급정거)
CMD : 0x14 - 모터 OFF
<RESPONSE - OK> CMD : 0x00 DAT : "OK"
<RESPONSE - ERROR> CMD : 0xF1 - 오류 DAT : 오류 코드 0x0001 - 데이터 오류 (CRC 불일치 / 재전송 요청) 0x0101 - 모터 오류
샘플 데이터 : 5354111100FF0000FFFF4554
위 프로토콜로 PC 와 통신 테스트를 합니다. 프로토콜 테스트는 ARDUINO NANO 를 활용해서 해봤습니다. 쬐그맣고 빵판에 그냥 심어놓고 하면 되기땜에 배선 시간이 줄어서 테스트할때는 이놈으로 합니다. UNO 와 PWM 출력핀 번호도 같아서 Schematic 도 그대로 사용하면 됩니다.
동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
PC에서 속도를 조절해보고, 정/역회전 및 정지를 해봤습니다.
데이터가 깨지거나 맞지 않는 경우를 생각해서 STX/ETX가 안맞으면 패킷을 DISCARD 하도록 하였고 테스트 해보니 잘 동작합니다.
Debug 메시지를 출력중인데, Serial 을 잡고 출력하다보니 나중에 설치하여 동작할때(릴리즈)는 문제가 되겠다 싶어서, debug 출력 제어핀(D12)을 두었습니다.
아두이노 내부의 PULLUP 을 사용해서, 평소 HIGH (릴리즈모드), GND 로 묶을 때 LOW 로 가서 디버그 모드로 돕니다. 이때는 출력을 안하고(나중에 RESPONSE 만 줘야겠죠) 그냥 넘깁니다.
동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
이제 모터 굴리고 UART 로 제어도 되었으니 남은건 CRC16으로 패킷체크 하는것과(뭐 이것까지 필요할까 합니다마는.. ) RESPONSE 주는것, 그리고 제일 큰일인 땜질용 빵판에 옮기는것이 남았습니다. (아.. 요걸 해야하나..)
그리고, DC모터를 제어하면서 문제점이 하나 보입니다. 바로 "정지" 기능인데요, 일반적인 서보모터는 지정 각도에서 딱 멈춰있는 반면, 이노무 "서보형 DC모터"는 그딴 기능이 없네요. 그냥 회전만 하는거라, L293에 브레이크를 먹여도 OFF 한것과 차이가 없이 휙휙 돌아갑니다.
나중에 설치하게 되면 문을 닫았을때는 크게 문제없겠지만, 당기고 있는(열기)때에는 어느정도 힘으로 끈을 붙들고(?)있게 해야겠네요.^^
MOTOR 는 일반 DC 모터를 다는 경우는 저렇게 보호를 해줘야 하고, 서보나 조금 신경 써서 캐패시터를 달아준 모터는 안달아줘도 된다.
L293B 는 총 4개의 OUTPUT 으로 이루어져 있는데,
위와 같은 PIN Assign 으로 구성되어 있고, Uni-Direction (한방향) 은 4개의 DC 모터를, Bi-Direction (양방향)은 2개의 DC 모터를 구동할 수 있다.
양방향구동이 필요한 경우, 좌/우 채널 별로 DC 모터의 +/- 를 3,6번 핀에 연결하고 아두이노의 Signal 을 2,7 번 핀에 연결하면 된다.
ENABLE1 / 2 에 Digital 회로 쪽(아두이노)의 5V 를 연결해주면 되고, Vs 라고 되어있는 부분은 Motor 용 외부 전력을 입력해주면 된다. L293B 의 최대 출력 전압은 37V 이고, 최대 출력 피크 전류는 2A이므로 이걸 잘 고려해서 모터를 물려주어야 한다.