본문 바로가기
Arduino&RasberryPi/Arduino Uno

20. Arduino - 4 자리 / 1자리 세그먼트 동시에 작동시키기

by Rosmary 2019. 12. 10.
728x90
반응형

필자는 지금까지 포스팅했던 4자리 세그먼트와 1자리 세그먼트, 이 두 세그먼트 LED를 하나의 Arduino 보드에서 동시에 작동을 시켜보고 싶었다. 그러나, 각각의 LED가 Arduino와 연결될 수 있는 단자의 수가 12개, 10개였기 때문에, Arduino 보드 하나에 모든 핀을 연결하는 것은 불가능했다. 따라서, 필자는 4자리 세그먼트와 1자리 세그먼트의 각 세그먼트를 하나의 공통 회로로 이어질 수 있도록 회로를 만들었다. 즉, 4자리 세그먼트에서 a 세그먼트 점등에 관여하는 단자는 1자리 세그먼트의 a 세그먼트 점등에 관여하는 단자와 브레드보드의 같은 회로에 연결하고, 이 회로의 끝과 Arduino Pin 하나를 이어줌으로써, 2 LED를 동시에 작동시킬 수 있도록 만드는 것이다. 아래의 사진처럼.

 

 

이전 포스팅에서 분석했던 byte 기반 변수를 토대로, 모든 세그먼트에 동시 점등이 진행되는 것을 확인하기 위한 코드를 작성하고 Arduino에 밀어넣어 보았다. 다행히, 예상한대로, 모든 세그먼트에서 불이 점등 되는 것을 확인할 수 있었다.

 

 

다음으로, 각각의 자릿수들이 독립적으로 숫자를 출력할 수 있는지 확인하는 작업을 진행했다. 첫 자리수가 순차적으로 0부터 9까지 출력되고 나면, 다음 자릿수가 0부터 9까지 출력되도록 하는 코드를 작성한 뒤, 해당 코드의 동작에 이상이 없는지 확인해보았다. 다행히 결과로 출력되는 내용들은 숫자 출력 코드 및 자릿수 지정 코드에도 문제가 없음을 증명해보인다.

 

<코드>

int source_pin[5] = {2, 3, 4, 5, 6};  
int segment[7] = {7, 8, 9, 10, 11, 12, 13};
byte reference[10] = {0XFC, 0X60, 0XDA, 0XF2, 0X66, 0XB6 , 0XBE, 0XE0, 0XFE, 0XF6};

 

//** 1번 핀의 경우, Arduino에서 전송 용도로 사용되는 핀이다. Arduino는 항상 전기적인 신호를 전송하기 때문에, 코드에서 1번 핀으로 전기 전송을 진행하지 말 것을 명시한다해도, 해당 핀과 연결된 세그먼트에는 항상 불이 들어오는 듯 하다. 따라서 세그먼트와 연결하는 핀에서 1번은 제외시켰다.

//**  dp 단자의 경우, Arduino에 연결할 수 있는 핀이 남아나지 않아 부득이하게 GND로 연결하였다. 따라서, dp 세그먼트는 전기 신호가 존재하는 한, 항상 점등될 수 밖에 없다

void setup()
{
  for(int i=2; i<14; i++)
  {
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);
  }
}

void loop()
{
  for(int pos=1;pos<6;pos++)
  {
    for(int num=0; num<10; num++)
    {
     signal(pos, num);
     delay(100);
    }
  }
}

void signal(int pst, int number)
{
  setup();
  digitalWrite(source_pin[pst-1], HIGH);
  for(int arr=1; arr<8; arr++)
  {
    byte seg= (reference[number] & (0X01 << arr)) >> arr;
    if(seg==1)  digitalWrite(segment[7-arr], LOW);
    else digitalWrite(segment[7-arr], HIGH);
  }
}

 

 

 

마지막으로, 4 자리 세그먼트를 시계의 시/분으로 표시하고, 1자리 세그먼트를 PM/AM으로 작동하도록 코드를 작성해보았다만....

 

 

==================================================================

int count = 0;
boolean AMPM = true;
int source_pin[5] = {2, 3, 4, 5, 6};
int segment[7] = {7, 8, 9, 10, 11, 12, 13};
byte reference[12] = {0XFC, 0X60, 0XDA, 0XF2, 0X66, 0XB6 , 0XBE, 0XE0, 0XFE, 0XF6, 0XEF, 0XCF};

void setup() 

  for(int i=2; i<14; i++) 
  { 
    pinMode(i, OUTPUT); 
    digitalWrite(i, LOW); 
  } 


void loop() 

  for(count ; count < 2400; count++)
  { 
    if(count % 100 == 60) 
    {
      count = count +40; 
    }

    if(count == 1200)  
    {
      count = 0;
      AMPM = !AMPM;
    }
    calc(count, AMPM);
    delay(5);   
  }
}

void signal(int pst, int number) 

  setup();
  digitalWrite(source_pin[pst-1], HIGH); 
  for(int arr=1; arr<8; arr++) 
  { 
    byte seg= (reference[number] & (0X01 << arr)) >> arr; 
    if(seg==1)  digitalWrite(segment[7-arr], LOW); 
    else digitalWrite(segment[7-arr], HIGH); 
  }
}

void calc (int number, boolean AMPM)
{
  signal(1, number / 1000);
  delay(1);
  signal(2, (number % 1000) / 100);
  delay(1);
  signal(3, (number % 100) / 10);
  delay(1);
  signal(4, number %10);
  delay(1);
if(AMPM==true) signal(5, 10);
  else  signal(5, 11);
  delayMicroseconds(1);
}

==================================================================

 

<좌 - delay(1)일 때, 우 - delay(50)일 때 >

 

 

빨간색으로 표시된 delay() 함수 내 인자 값이 높아질수록, 네 자리 세그먼트의 출력이 약해지는 현상이 나타난다...

 

4자리 / 1자리 세그먼트가 각 세그먼트마다 회로를 공유한 상태에서는 필자가 고안한 시계를 구현하기가 불가능했다. 왜냐하면, 1자리 세그먼트의 초를 표시하기 위해, 모든 pin의 digitalWrite 값을 0으로 만들어 줄 필요가 있었는데, 1자리와 4자리 세그먼트의 회로가 독립적으로 작동하지 않다보니, 시와 분도 동시에, 그리고 지속적으로 숫자를 점등시키지 못하고 곧바로 꺼져버리는 문제가 발생했다(궁금하신 분들은, 저 delay() 함수 인자값을 천천히 증가시켜보시기 바란다. 인자값이 증가할수록 세그먼트 밝기도 감소한다). 현재의 코드를 크게 변화시키지 않고, 그리고 회로를 공유하면서도 이 문제를 해결할 수 있는 방법을 찾기 위해 열심히 머리를 굴렸지만... 이러한 코드를 만들기 위해서는 setup() 함수 내의 초기화 코드를 조금 더 세밀하게 동작할 수 있도록 작성해주어야 한다는 결론에 다다랐다. 

 

하지만, 필자는 아직 기본적인 Arduino의 동작에 대해 파악하려는 목적으로 포스팅을 진행하고 있는 것이기 때문에, 심화가 필요한 내용은 추후에 따로 진행하려고 한다. 아직도 살펴봐야 할 부품들도 많이 남아있고 말이다.

 

FIN.

반응형

댓글