산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

직접 만든 A4 크기 7세그먼트 디스플레이로 아두이노 빙고 머신 만들기

부품 및 소모품

부품 수량 비고
펙 보드 (Peg Board) 3 7세그먼트 디스플레이 2개용, 스코어보드 1개용
플라스틱 도마 (회색) 1 스코어보드용
디지털 LED 스트립 5m WS2811 (5050 LED) 1 다수 벤더 판매
DC5V WS2812B 300LED (60LED/m, 5050 RGB) 1 다수 벤더 판매
오디오 케이블 1 스코어보드와 7세그먼트 디스플레이 간 연결용
투명 플라스틱 도마 2 7세그먼트 디스플레이 전면 패널용
유연 플라스틱 도마 (회색) 1 스코어보드 커버용
아두이노 우노 (Arduino UNO) 1
저항 220옴 2
커패시터 100µF 2
대형 푸시버튼 스위치 (모멘터리) 1
소형 푸시버튼 (일반) 1
리니어 레귤레이터 (7805) 1

필요 도구

프로젝트 소개

ACTION 매장에서 저렴한 디지털 LED 스트립(12V 어댑터 및 IR 리모컨 컨트롤러 포함)을 발견하고 아두이노 우노로 제어해보기로 했습니다. 이 스트립은 3개 5050 LED와 WS2811 드라이버 1개로 구성된 세그먼트 타입이었습니다.

이를 이용해 A4 크기의 7세그먼트 디스플레이를 만들기로 했습니다. 7개 세그먼트 + 소수점(DP) = 8개 세그먼트가 필요하며, 아두이노 출력 핀 1개와 12V 어댑터로 제어 가능합니다.

단일 7세그먼트 디스플레이로는 뭘 할 수 있을까 고민하다, 2개를 만들어 빙고 머신을 만들기로 했습니다. 버튼을 누르면 1~75 사이의 랜덤 숫자가 두 디스플레이에 표시됩니다.

1단계: 7세그먼트 디스플레이 제작

레이저 커터나 3D 프린터를 쓰면 더 간단하지만, 직접 만드는 재미로 기존 재료로 제작했습니다. 액션 매장의 펙 보드를 하우징으로 사용하고, 이케아의 투명 도마로 전면 패널을 만들었습니다. 템플릿으로 검은 프라이머 층을 잘라 세그먼트 모양을 냈습니다.

LED 스트립 16개 세그먼트(각 3 LED)를 납땜으로 연결(+12V, GND, DO, DI)하고, 저렴한 오디오 케이블(3선: 12V, GND, Data in)로 아두이노와 연결(220옴 저항 경유)했습니다.

2단계: 스코어보드 제작

생성된 랜덤 숫자를 기록하고, 새 숫자 생성을 위한 버튼, 빙고 완료를 위한 '빙고 버튼'을 갖춘 스코어보드를 만들었습니다. 같은 펙 보드 하우징에 회색 도마로 커버를 만들고, 내부에는 WS2812B LED 스트립(75개 숫자 표시용 5개 섹션 + 'BINGO' 백라이트용 3x8 섹션)을 배치했습니다.

3단계: 소프트웨어 제작

초기 실험은 브레드보드에서 진행했습니다. 큰 모멘터리 푸시버튼을 GND와 디지털 핀 2에 연결해 새 숫자 생성을 트리거합니다. 짧은 '라이트 쇼 1' 후 두 7세그먼트 디스플레이에 숫자가 나타납니다.

7세그먼트 숫자 매핑 테이블과 플로우차트(ClickCharts 사용)로 코드 구조를 잡았습니다. 생성된 숫자는 SCORE[76] 배열(0 또는 1)에 저장되며, 중복 시 자동으로 다시 생성합니다. 스코어보드에는 생성된 숫자가 점등되고, 7세그먼트에도 동시 표시됩니다.

'빙고 버튼'을 누르면 '빙고 라이트 쇼' 후 라운드 종료, SCORE 배열 초기화 후 새 라운드 시작. 전원 토글로도 리셋 가능.

4단계: 전자 회로

12V 2A 충전기로 전체 전원 공급. 아두이노 전원 잭을 수정해 파워 스위치 추가. 7805 레귤레이터로 5V 생성해 스코어보드용 99개 LED(WS2812B) 구동(히트싱크 권장). 프리칭 다이어그램 참조.

두 7세그먼트 디스플레이(12V 구동)와 스코어보드 LED(5V 구동) 모두 아두이노 핀 6 하나로 제어됩니다.

코드


/* Bingo Machine with Arduino Uno and 2 A4 sized 7-Segment Displays
   Developed by Pierre Pennings (November 2018) - GPL3+ license */
#include <Adafruit_NeoPixel.h>

const int NewnumberButton = 2;
const int BingoButton = 4;
const int LedPin = 6;

int Newnumber = 1, Bingo = 1;
int SCORE[76];
int count = 0;
long randNumber;
int NUMBER = 0, NW_NUMBER = 0, TENSNUMBER = 0, UNITNUMBER = 0;

#define NUM_LEDS 99
// 0-15: 두 7세그먼트 디스플레이 (각 8세그먼트, 7과 15는 DP)
// 16-99: 스코어보드 (24개 BINGO 백라이트 + 75개 숫자)
#define BRIGHTNESS 250

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LedPin, NEO_GRB + NEO_KHZ800);

// 숫자-세그먼트 매핑 배열 [세그먼트][숫자]
byte SEGMENTarray[8][10] = {
  {1,0,1,1,0,1,1,1,1,1}, // 세그먼트 0/8
  {1,1,1,1,1,0,0,1,1,1}, // 세그먼트 1/9
  {1,1,0,1,1,1,1,1,1,1}, // 세그먼트 2/10
  {1,0,1,1,0,1,1,0,1,1}, // 세그먼트 3/11
  {1,0,1,0,0,0,1,0,1,0}, // 세그먼트 4/12
  {1,0,0,0,1,1,1,0,1,1}, // 세그먼트 5/13
  {0,0,1,1,1,1,1,0,1,1}, // 세그먼트 6/14
  {0,0,0,0,0,0,0,0,0,0}  // 세그먼트 7/15 (DP)
};

byte color_scheme[] = { 50,100,200,100,150,250,150,200,50,200,250,100,250,50,150,0,100,200,50,150,250,100,200,0,150,250,50,200,0,100,250,50,200,0,100,250,50,150,0,250,0,0 };

void setup() {
  Serial.begin(9600);
  pinMode(LedPin, OUTPUT);
  pinMode(NewnumberButton, INPUT_PULLUP);
  pinMode(BingoButton, INPUT_PULLUP);
  strip.setBrightness(BRIGHTNESS);
  strip.begin();
  strip.show(); // 모두 끄기
  
  // 시작 시 스코어보드에 파란색 'BINGO' 표시
  for (int t = 16; t < 24; t++) {
    strip.setPixelColor(t, 0, 0, 250);
    strip.show();
  }
  
  for (count = 0; count < 76; count++) SCORE[count] = 0;
}

void loop() {
  Newnumber = digitalRead(NewnumberButton);
  if (Newnumber == LOW) {
    randomSeed(millis());
    do {
      GENERATENEWNUMBER(75);
    } while (NW_NUMBER == SCORE[NW_NUMBER] * NW_NUMBER);
    
    SCORE[NW_NUMBER] = 1;
    NUMBER = NW_NUMBER;
    TENSNUMBER = NUMBER / 10;
    UNITNUMBER = NW_NUMBER - (10 * TENSNUMBER);
    
    CLEARDISPLAY();
    LIGHTSHOW1(4, 100);
    CLEARDISPLAY();
    DISPLAYNUMBER(TENSNUMBER, UNITNUMBER);
    DISPLAYSCORE();
  } else {
    Bingo = digitalRead(BingoButton);
    if (Bingo == LOW) delay(3000); // 디바운스
    if (Bingo == LOW) {
      BINGOLIGHTSHOW();
      for (count = 0; count < 76; count++) SCORE[count] = 0;
    }
  }
}

// 라이트 쇼 1: DP 깜빡임 + 레인보우 색상
void LIGHTSHOW1(int duration, uint8_t wait) {
  for (int t = 16; t < 24; t++) { strip.setPixelColor(t, 0, 0, 0); strip.show(); }
  for (int k = 0; k < duration; k++) {
    strip.setPixelColor(7, 200, 200, 200); strip.show(); delay(wait);
    strip.setPixelColor(7, 0, 0, 0);
    strip.setPixelColor(15, 200, 200, 200); strip.show(); delay(wait);
    strip.setPixelColor(15, 0, 0, 0);
  }
  int redVal, blueVal, greenVal;
  for (int k = 1; k < 45; k += 3) {
    redVal = color_scheme[k];
    blueVal = color_scheme[k+1];
    greenVal = color_scheme[k+2];
    for (int p = 0; p < 7; p++) {
      int i = p; int j = 8 + p;
      strip.setPixelColor(i, strip.Color(redVal, blueVal, greenVal));
      strip.setPixelColor(j, strip.Color(greenVal, redVal, blueVal));
      strip.show(); delay(30);
    }
  }
  for (int q = 0; q < 7; q++) {
    strip.setPixelColor(q, 0, 0, 0);
    strip.setPixelColor(8+q, 0, 0, 0);
    strip.show();
  }
}

// 빙고 라이트 쇼
void BINGOLIGHTSHOW() {
  for (int l = 0; l < 10; l++) {
    for (int k = 24; k < 39; k++) {
      strip.setPixelColor(k, 200,200,200);
      strip.setPixelColor(k+15, 200,200,200);
      strip.setPixelColor(k+30, 200,200,200);
      strip.setPixelColor(k+45, 200,200,200);
      strip.setPixelColor(k+60, 200,200,200);
      strip.show(); delay(5);
      strip.setPixelColor(k, 0,0,0);
      strip.setPixelColor(k+15, 0,0,0);
      strip.setPixelColor(k+30, 0,0,0);
      strip.setPixelColor(k+45, 0,0,0);
      strip.setPixelColor(k+60, 0,0,0);
      strip.show();
    }
    for (int t = 0; t < 24; t++) { strip.setPixelColor(t, 0,250,250); strip.show(); }
    delay(50);
    for (int t = 0; t < 24; t++) { strip.setPixelColor(t, 0,0,0); strip.show(); }
  }
}

// 새 숫자 생성
void GENERATENEWNUMBER(int range) {
  randNumber = random(1, range + 1);
  NW_NUMBER = int(randNumber);
}

// 7세그먼트 디스플레이에 숫자 표시 (빨간색)
void DISPLAYNUMBER(int TENS, int UNIT) {
  for (int t = 16; t < 24; t++) { strip.setPixelColor(t, 200, 0, 0); strip.show(); }
  for (int s = 0; s < 8; s++) {
    int t = SEGMENTarray[s][TENS];
    int u = SEGMENTarray[s][UNIT];
    int i = s; int j = 8 + s;
    strip.setPixelColor(i, u*250, 0, 0);
    if (TENS != 0) strip.setPixelColor(j, t*250, 0, 0);
    else strip.setPixelColor(j, 0, 0, 0);
    strip.show();
  }
}

// 스코어보드에 숫자 표시 (기존: 녹색, 새 숫자: 빨간색)
void DISPLAYSCORE() {
  for (int t = 16; t < 24; t++) { strip.setPixelColor(t, 200, 0, 0); strip.show(); }
  for (int s = 24; s < 100; s++) {
    int u = SCORE[s-23];
    strip.setPixelColor(s, 0, u*200, 0);
    strip.show();
  }
  strip.setPixelColor(23+NUMBER, 200, 0, 0); // 새 숫자 빨간색
  strip.show();
}

// 7세그먼트 디스플레이 지우기
void CLEARDISPLAY() {
  for (int q = 0; q < 7; q++) {
    strip.setPixelColor(q, 0, 0, 0);
    strip.setPixelColor(8+q, 0, 0, 0);
    strip.show();
  }
  for (int t = 16; t < 24; t++) { strip.setPixelColor(t, 0, 0, 0); strip.show(); }
}

커스텀 파트 및 인클로저

회로도

제조공정

  1. 집에서 직접 만드는 DIY 숙제 작성 머신 (펜 플로터)
  2. 아두이노로 만드는 레트로 누미트론 클락: 심플하고 신뢰성 높으며 에너지 효율적
  3. 아두이노와 노키아 5110 LCD로 만드는 DIY 전압계 - 단계별 가이드
  4. 아두이노 나노와 로터리 인코더로 만드는 정밀 측정 바퀴
  5. Sharp GP2Y1010AU0F 센서로 정밀 공기질 모니터 만들기
  6. 아두이노 나노와 WS2812 LED 스트립으로 만드는 1차원 퐁(Pong) 게임
  7. 아두이노 나노 R3로 완전한 기능의 CNC 머신 만들기
  8. 아두이노 프로 마이크로로 구현한 HID UPS: 더미 전원장치를 USB 호환 스마트 UPS로 업그레이드
  9. 아두이노로 만드는 휴대용 RFID 도어락 - 단계별 완벽 가이드
  10. 아두이노 나노 기반 블루투스 스마트 커피 메이커 - 온도 모니터링 및 자동 추출