[매드정] 아두이노 강좌 - 08.Multi-Function Shield Segment 동작


안녕하세요~ 매드 입니다.

어느세 2015년이 지나가고 새로운 2016년이 왔습니다! ...

나이도 한살 더 먹었... 늙은이가 되어가고 있...
시간이 빠르게 지나가네요...

그래도!! 우리에겐 꿈이 있으니! ㅎㅎ 2015년을 그저 그렇게 보냈다면 새로시작한 2016년은 원하는 것 바라는 것 모두 실행에 옮겨서 한번 사는 인생 즐겁게 보내보아요!! >.<

라고 시작하고 이번 강좌 들어가 보겠습니다~~

지난 시간 말씀드린대로 이번 시간에는 멀티펑션 보드의 마지막 기능인 Segment 기능을 동작 시켜보고 이제 멀티 펑션 보드는 마무리 하는 시간이 되겠네요!~

자 그럼 시작해볼까요?~


8-1. 세그먼트란?

이번 시간에는 세그먼트 라는 것을 동작시켜 볼텐데요. 먼가 겉으로 보기엔 어려워 보이지만 별거 없습니다. 저희 이전시간에 했던 LED를 숫자 모양으로 만들어 놓은 것이 바로 세그먼트 입니다! 그런데 이 LED를 몇개 사용했냐? 7개를 사용해서 숫자 모양을 만들 수 있기 때문에 저희는 7-Segment 라고 부르는 것이죠! (사실은 점이 하나 더 있어서 LED 8개임)

<출처 : 구글 사진>

그림으로 보니까 좀 더 이해가 잘 되시죠?~
이런 세그먼트에 종류가 2종류가 있는데 바로 common-anode type과 common-cathode type 입니다. 이 두종의 차이는 별거 없습니다. 말 그대로 LED의 공통으로 묶여 있는 곳이 VCC냐 GND냐에 따라 이름이 달라지는 것이죠~ 이게 무슨 차이인고하니 저 위의 세그먼트 LED에 불이 들어오게 하려면 0을 입력했을 때 켜지는 것을 common-anode type이라고하고 1을 입력했을 때 켜지는 것을 common-cathode type 이라고 하는 것입니다~

간단하죠~?

나머지는 우리가 생각하는 것과 같습니다. b, c 만 불들어오게하면 1이 되고 a,b,g,e,d가 불들어오게하면 2가 되고 이런 식이죠~ LED가 전부 다 들어오게되면 8이 되는 신기한 일이 일어납니다!

<출처 : 구글 사진>

이런식으로 하다보면 아라비아 숫자인 0~9 뿐만 아니라 A,B,C,D,E,F 까지도 표시할 수 있습니다. 이게 왜 중요하냐하면 우리가 일반적으로 사용하는 숫자는 10진수라고 하는데 컴퓨터에서는 2진수 또는 16진수를 더 많이 사용하기 때문이죠. 이 중 16진수에서 표시하는 숫자가 0~9, A~F 까지 이기 때문입니다~

대략 이해가 되시죠!?

이런 세그먼트도 빨간색 뿐만아니라 여러 색상들이 있고 특수한 모양들도 표시할 수 있는 여러 종류들이 있으니 시간 나시면 구글신께 물어보면서 공부하시면 많은 도움이 되실 겁니다! 우선저희는 아직 초보니까 여기까지만 하고 멀티펑션 쉴드에 적용된 회로를 한번 봐보도록 하죠~


8-2. Multi-function shield Segment 회로

<멀티펑션 보드 세그먼트 회로>

맙소사...

지금까지 중에 가장 복잡한 회로가 나왔습니다. ㅠㅠ 방금전에 설명하는건 별거 아닌 것처럼 설명하더니 왜 이렇게 복잡한 회로가 나온거야 ㅠ? 라고 생각하시는 분들이 있을텐데 이것도 다 이유가 있으니 하나하나 살펴보도록 하죠.

앞서 설명한 세그먼트는 하나의 숫자만 표시할 수 있는데요. 멀티펑션보드는 4개의 숫자를 표시할 수 있도록 되어 있습니다. 한개의 숫자만 표시한다면 8개의 포트만 있으면 세그먼트에 내가 원하는 숫자를 표시할 수 있는데 4개나 된다면 단순 계산으로 4 x 8 = 32개의 포트가 필요하게 되는 것이죠!! >.<

32개를 각각 제어하여 숫자를 표시해주는 것도 상관 없지만 효율적으로 이는 엄청난 낭비임에 틀림 없습니다~ 그래서 VCC와 GND가 연결되었던 부분을 포트로 연결 할 수 있게 만들어두고 숫자가 표시되는 LED 부분을 4개의 세그먼트와 같이 묶어서 사용하게 됩니다. 이게 먼소리냐하면 1이라는 숫자를 표시하고 세그먼트 1번만 전원을 넣어주면 1번 세그먼트에만 1숫자가 표시되는 것이죠~

그럼 다른 세그먼트에도 전원을 넣으면? 전부다 1이 표시되게 됩니다. ㅠ

여기서 가장 중요한 기능이 나오게 되는데 이름하여 '다이나믹 구동'이 되겠습니다.

잠시 다른 설명을 해보겠습니다.

<출처 : 구글 사진>
옛날 옛적에 연필로 휙휙 흔들면서 신기하게 연필이 여러개로 보이거나 휘어 보이는 것처럼 장난 쳐보신적이 있겠죠~? (... 아니시라면 여기서 필자 연식 들킴;)

사람의 눈은 신기하게도 잔상이라는 것이 남는데 약 45Hz 이상이 되면(1초에 45번 변화하면) 잔상이 사람눈에 진짜 처럼!! 보이는 현상이 나타나게 됩니다!!!!!

정말 옛날 사람들은 이런 인간의 문제점을 이용해서 이것저것 만들게 되는데 그것이 현재 우리가 항상 움직이는 영상을 보고 있는 영화, TV, 프로젝터 등등 이 되겠죠. 신기하죠~?

다시 돌아와서~

세그먼트도 동일 합니다. 처음에는 1번 세그먼트만 ON 시켜서 1을 표시하고 두번째는 2번 세그먼트만 ON 시켜서 2를 표시하고 세먼째는 3번 세그먼트만 ON 시켜서 3을 표시하고 네번째는 4번 세그먼트만 4를 표시한 후 이를 빠르게 반복시키면 마치 사람눈에는 세그먼트 4개가 동시에 동작하는 것처럼 보이게 되는 것이죠.

ㅠㅠ 그런데 멀티펑션 보드에는 한가지가 더 사용 되었습니다. 이렇게 해도 숫자 8개 포트 + 세그먼트 4개 = 12개의 포트가 필요한 것이죠 ㅠ

이를 해결 한 것이 '74hc595' 입니다!!

참 .. 인간은 필요한거 잘 만드는 것 같습니다.

74hc595 가 무엇이냐하면 '8 bit serial-in parallel-out shift register' 입니다.

말 그대로 직렬로 들어간 데이터를 병렬러 출력해주는 것이죠!!

<멀티펑션 보드 세그먼트 회로>

다시한번 세그먼트 회로를 보면 이것저것 복잡한것 처럼 보이지만 74hc595와 아두이노가 연결된 핀을 봐보죠.

SDI은 아두이노 8번핀
SFTCLK은 아두이노 7번핀
LCHCLK은 아두이노 4번핀

로 연결되어 있네요!~ 연결된 회로를 통해서 직렬로 데이터 12개를 쭉~ 넣어주면 이를 통해 병렬로 출력되어 아두이노 3개핀으로 세그먼트 4개를 동시에 동작시킨다는 것 입니다.

이해가 좀 되시나요?~

' 아~ 어렵다 ㅠ '

라고 생각하신다면 다 필요 없습니다. 이미 이것들도 구글 신께 멀티펑션보드 소스코드라고 검색하면 이미 잘하시는 분들이 만들어 놓은 소스코드들이 있습니다!! 그걸 그냥 쓰면 됩니다~

어렵다고 생각하면 한없이 어려워지고 쉽다고 생각하면 언제가는 풀리리니 '유레카' !!

이제 실습을 해보도록 하죠~

멀티펑션 보드 마지막 시간이기도 하고 난이도가 좀 있는 내용을 설명하려다보니 조금 길어지지만!

마지막이니까~
화이팅 해봅시다!


8-3. 펌웨어 코드

/* Define shift register pins used for seven segment display */
#define LATCH_DIO 4
#define CLK_DIO 7
#define DATA_DIO 8

#define Pot1 0

/* Segment byte maps for numbers 0 to 9 */
const byte SEGMENT_MAP[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90};
/* Byte maps to select digit 1 to 4 */
const byte SEGMENT_SELECT[] = {0xF1,0xF2,0xF4,0xF8};

void setup ()
{
Serial.begin(9600);
/* Set DIO pins to outputs */
pinMode(LATCH_DIO,OUTPUT);
pinMode(CLK_DIO,OUTPUT);
pinMode(DATA_DIO,OUTPUT);
}

/* Main program */
void loop()
{
int PotValue;
PotValue = analogRead(Pot1);
Serial.print(“Potentiometer: “);
Serial.println(PotValue);
/* Update the display with the current counter value */
WriteNumberToSegment(0 , PotValue / 1000);
WriteNumberToSegment(1 , (PotValue / 100) % 10);
WriteNumberToSegment(2 , (PotValue / 10) % 10);
WriteNumberToSegment(3 , PotValue % 10);
}

/* Write a decimal number between 0 and 9 to one of the 4 digits of the display */
void WriteNumberToSegment(byte Segment, byte Value)
{
digitalWrite(LATCH_DIO,LOW);
shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_MAP[Value]);
shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_SELECT[Segment] );
digitalWrite(LATCH_DIO,HIGH);
}

위 코드는 구글신께 물어본 후 그대~로 퍼왔습니다.

실습은 언제나처럼 영상으로 대체할께요~

그럼 다음 시간에 봐용~~!



댓글 쓰기

2 댓글

  1. 안녕하세요. 유투브 잘보고있습니다. 한가지 질문이 있는데요, 'WriteNumberToSegment' was not declared in this scope 업로드중에 이러한 오류 메시지가 뜨는데 뭐가 잘못 된걸까요?

    답글삭제
    답글
    1. void WriteNumberToSegment(byte Segment, byte Value) 함수가 인식이 안되어서 그렇습니다.

      void WriteNumberToSegment(byte Segment, byte Value); 이렇게해서 define 밑에 함수선언으로 넣어주시거나 함수를 다 잘라내기해서 setup() 보다 위에 붙여 넣으신 후 컴파일 하시면 될 겁니다`~ ^^

      삭제