질문과 답변

2월 주제 - 예제1 [온도가 측정되는 컵받침] - 과정 3 - 스위치 & LED
2022. 3. 3 (목) 16:21 E4DSLAB 조회 67 좋아요 1 스크랩 0 댓글 3

안녕하세요~!

저도 그렇지만, 다들 일하는 시간 외에 콘테스트 참여하시느라 힘드시죠?
끝까지 힘을 내봅시다.

전 편에 아두이노 나노와 7세그먼트 디스플레이까지 연결해봤는데,
오늘은 LED와 스위치를 추가해보겠습니다.

초보자분들을 생각해서 너무 상세한 설명을 했었는데,
아무래도 다들 아두이노 정도는 다루시는 거 같아서 아주 초보적인 설명은 생략하겠습니다 ^^

LED모듈의 핀은 왼편부터 1.GND, 2.VCC, 3.nc, 4.Signal 순입니다.(3번은 사용안함)
스위치는 핀번호 배열은 같지만 커넥터가 거꾸로여서 왼편부터 시그널, nc, VCC, GND 순서입니다.

VCC와 GND는 아두이노의 27번과 29번에 연결하고,
LED모듈의 4번을 아두이노의 7번(DIO4)에.
스위치 모듈의 4번을 아두이노의 8번(DIO5)에 연결했습니다.

연결은 테스트를 위해 브래드보드에 꽂은 상태로 해보고, 프로그래밍을 끝낸 후에
만능기판에 납땜을 할 생각입니다.

[아두이노 IDE]

기존 코드에 LED와 스위치가 연결된 아두이노 I/O핀을 정의해줍니다.

// Module connection pins (Digital Pins)
#define CLK 2  //아두이노 나노 Pin5(D2)
#define DIO 3  //아두이노 나노 Pin6(D3)

const int pinLED = 4;      //아두이노 Pin7(D4)
const int pinButton = 5; //아두이노 Pin8(D5)

그리고, 
스위치와 LED테스트 코드를 스위치를 누르면 LED가 켜지고, 디스플레이에도 ‘on’ 표시를 하고
스위치를 떼면 LED가 꺼지고, 디스플레이에는 ‘oFF’ 표시가 되도록 해볼 생각입니다.

그래서, ‘on’과 ‘oFF’를 세그먼트에 표시할 데이터 테이블을 만들어 봤습니다.
그래픽 디스플레이가 아니어서 최대한 비슷한 모양으로 on/oFF를 만들어 보겠습니다.

const uint8_t SEG_ON[] = {
  0,  0,                                                   // 앞 두자리는 깜깜 
  SEG_C | SEG_D | SEG_E | SEG_G,     // o
  SEG_C | SEG_E | SEG_G                     // n
};

const uint8_t SEG_OFF[] = {
  0,                                                         // 앞 한자리는 깜깜
  SEG_C | SEG_D | SEG_E | SEG_G,     // o
  SEG_A | SEG_E | SEG_F | SEG_G,     // F
  SEG_A | SEG_E | SEG_F | SEG_G      // F
};

이정도면 그럴듯해 보이겠네요

이제. 아두이노의 I/O핀 설정을 해줍니다.

void setup()
{
    pinMode(pinLED, OUTPUT);     //LED 연결된 핀을 출력모드로
    pinMode(pinButton, INPUT);    //스위치가 연결된 핀을 입력모드로
}

**스위치를 읽어봅니다.

digitalRead라는 함수를 사용하면 스위치를 읽을 수 있습니다.
읽은 값는 스위치가 눌려진 상태면 HIGH, 뗀 상태면 LOW 입니다.

digitalWrite라는 함수를 사용해 pinLED포트에 HIGH를 출력하면 LED가 켜집니다.
반대로 pinLED포트에 LOW를 출력하면 LED가 꺼집니다.

if(digitalRead(pinButton))         // 스위치가 눌린 상태면
{
    digitalWrite(pinLED, HIGH); // LED를 켭니다
    delay(50);                              // 50ms 지연을 줍니다 (스위치 접점 노이즈를 무시)
}
else                                             // 스위치가 눌린 상태가 아니면
{
    digitalWrite(pinLED, LOW);  // LED를 끕니다.
    delay(50); // 50ms지연.
}

네~ 잘됩니다.

이제, LED On/Off됨과 동시에 디스플레이에도 on/off를 표시해 보겠습니다.

 while (1) {                                      // 테스트 무한 반복
    if(digitalRead(pinButton))          // 스위치가 눌린 상태면
    {
        digitalWrite(pinLED, HIGH);       // LED를 켭니다 
        display.setSegments(SEG_ON); // on 메시지 표시
        delay(50);                                   // 50ms 지연을 줍니다(스위치 접점 노이즈를 무시)       
    }
    else                                                 // 스위치가 눌린 상태가 아니면  
    {
      digitalWrite(pinLED, LOW);        // LED를 끕니다.
      display.setSegments(SEG_OFF); // off 메시지 표시
      delay(50);                                    // 50ms지연.
    }      
  }

멋지네요. ㅎㅎ

동작 영상입니다.

 

테스트 코드를 올려드립니다.

#include 
#include   // 7SEG 디스플레이 라이브러리 Include

// Module connection pins (Digital Pins)
#define CLK 2  //아두이노 나노 Pin5(D2)
#define DIO 3  //아두이노 나노 Pin6(D3)

const int pinLED = 4;
const int pinButton = 5;

// The amount of time (in milliseconds) between tests
#define TEST_DELAY 500  //0.5초 지연

const uint8_t SEG_DONE[] = {
	SEG_B | SEG_C | SEG_D | SEG_E | SEG_G,           // d
	SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,   // O
	SEG_C | SEG_E | SEG_G,                           // n
	SEG_A | SEG_D | SEG_E | SEG_F | SEG_G            // E
	};

const uint8_t SEG_ON[] = {
    0,  0,                                            // 앞 두자리는 깜깜 
	SEG_C | SEG_D | SEG_E | SEG_G,                    // o
	SEG_C | SEG_E | SEG_G                             // n
	};

const uint8_t SEG_OFF[] = {
    0,                                                // 앞 한자리는 깜깜
	SEG_C | SEG_D | SEG_E | SEG_G,                    // o
	SEG_A | SEG_E | SEG_F | SEG_G,                    // F
	SEG_A | SEG_E | SEG_F | SEG_G                     // F
	};

TM1637Display display(CLK, DIO);

void setup()
{
  pinMode(pinLED, OUTPUT);       //LED 연결된 핀을 출력모드로
  pinMode(pinButton, INPUT);     //스위치가 연결된 핀을 입력모드로
}
    
void loop() {
  int k;
  uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };   	// 모든 세그먼트 켜기 값으로
  uint8_t blank[] = { 0x00, 0x00, 0x00, 0x00 };     // 모든 세그먼트 끄기 값으로
  display.setBrightness(0x0f);                   	// 밝기를 최대로

  // All segments on					        
  display.setSegments(data);            // 모두 켠 후에
  delay(TEST_DELAY);                    // 0.6초 대기
  display.setSegments(blank);           // 모두 끄기
  delay(TEST_DELAY);                    // 0.6초 대기

  while (1) {                           // 테스트 무한 반복
    if(digitalRead(pinButton))          // 스위치가 눌린 상태면
    {
      digitalWrite(pinLED, HIGH);       // LED를 켭니다 
      display.setSegments(SEG_ON);
      delay(50);                        // 50ms 지연을 줍니다. (스위치 접점 노이즈를 무시)                             
    }            
    else                                // 스위치가 눌린 상태가 아니면  
    {
      digitalWrite(pinLED, LOW);        // LED를 끕니다.
      display.setSegments(SEG_OFF);
      delay(50);                        // 50ms지연.
    }      
  }
}

재밌네요 ^^
내일 이어서 대망의 온도센서를 연결해 올려드리겠습니다. 
서둘러야 컵받침을 만들겠군요 ㅠㅠ

wansoo 2022.03.04 11:56 답글  |  신고
잘 읽었습니다. display.setSegments() 함수에다 켜야할 LED 배열 값을 넣어 주면 되나 보네요~ 4자리 7-Segments가 기본 모듈이 되나요? 5자리, 6자리 모듈도 있나요? ^^; 만약 5자리, 6자리 모듈이라도 display를 동일하게 사용 가능할지 궁금합니다. 아직은 아두이노 이론 공부만하고 제대로 가지고 놀아보진 못한 상태인데... 아두이노를 다양하게 활용할 방법들도 찾아 보고 있는 중입니다.
E4DSLAB 2022.03.04 14:54 신고
댓글
읽어주셔서 감사합니다~^^
TM1637 드라이브칩은 최대 6개의 8세그먼트(소숫점포함) 드라이브와 키스위치어레이 스캔 기능도 제공하는 칩이에요.
아두이노 키트용으로 판매되는 것들 중에 6자리 제품도 있습니다. 라이브러리는 같은 라이브러리를 사용합니다.
대부분 6자리 정도 되면 LCD모듈을 사용하게 되는 거 같아요. 라이브러리 상세 설명을 클릭 하셔서 개발자의 github도 재미삼아 한번 둘러 보세요 ^^
E4DSLAB 2022.03.04 14:56 신고
댓글
TM1637Display 라이브러리는 세그먼트 디스플레이를 위한 4가지 함수를 제공합니다.
*setSegments 는 abcdefg 각 세그먼트를 직접 제어할 수 있고,
*showNumberDec 은 십진숫자를 표시하고,
*showNumberDecEx 는 소숫점을 포함한 십진숫자 표시,
*setBrightness 는 밝기 조절에 사용합니다.
공지글 두번째의 소스코드에 사용예가 포함돼있습니다.

로그인 후
참가 상태를 확인할 수 있습니다.