1. 4 Digit 7 Segment 1개

 

배선

Arduino 74HC595 4 digit 7 segment
  1 (Q1) 7 (B segment)
  2 (Q2) 4 (C segment)
  3 (Q3) 2 (D segment)
  4 (Q4) 1 (E segment)
  5 (Q5) 10 (F segment)
  6 (Q6) 5 (G segment)
  7 (Q7) 3 (DP segment)
GND 8 (GND)  
  9 (Q7')  
VCC 10 (MR)  
D10 11 (SH_CP)  
D11 12 (ST_CP)  
GND 13 (OE)  
D9 14 (DS)  
  15 (Q0) 11 (A segment)
VCC 16 (VCC)  
D2   12 (D1)
D5   9 (D2)
D6   8 (D3)
D13   6 (D4)

아두이노와 4 Digit 7 Segment 사이에 74HC595를 넣고 연결한다.
 
소스

//a,b,c,d,e,f,g 상태값
byte segValue[10] = {
  0b11111100, //0
  0b01100000, //1
  0b11011010, //2
  0b11110010, //3
  0b01100110, //4
  0b10110110, //5
  0b10111110, //6
  0b11100000, //7
  0b11111110, //8
  0b11110110, //9
};

byte digitPin[4] = { 2, 5, 6, 13 }; //segment 위치 핀
int dataPin = 9; //DS Pin
int clockPin = 10; //SH_CP Pin
int latchPin = 11; //ST_CP Pin

unsigned long readTime = 0; //현재시간
int d1 = 0; //1의 자리
int d2 = 0; //10의 자리
int d3 = 0; //100의 자리
int d4 = 0; //1000의 자리

void setup()
{
    for (int j = 0; j < 4; j++)
    {
      pinMode(digitPin[j], OUTPUT);
      digitalWrite(digitPin[j], HIGH);
    }
    pinMode(dataPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(latchPin, OUTPUT);
}

void loop()
{
    readTime = millis() / 1000;
    d1 = readTime % 10; //1의 자리
    d2 = (readTime / 10) % 10; //10의 자리
    d3 = (readTime / 100) % 10; //100의 자리
    d4 = (readTime / 1000) % 10; //1000의 자리

    segOutput(3, d1, 0); //1의 자리
    if (readTime >= 10) segOutput(2, d2, 0); //10의 자리  
    if (readTime >= 100) segOutput(1, d3, 0); //100의 자리  
    if (readTime >= 1000) segOutput(0, d4, 0); //1000의 자리  
}
//LED 초기화
void segClear()
{
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, 0);
    digitalWrite(latchPin, HIGH);    
}
//LED 출력
void segOutput(int d, int Number, int dp)
{
    segClear();
    digitalWrite(digitPin[d], LOW);
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, segValue[Number]);
    digitalWrite(latchPin, HIGH);    
    delayMicroseconds(1000);
    digitalWrite(digitPin[d], HIGH);
}

 
프로그램을 실행하면 0부터 시작하여 1초에 1씩 증가한다.


복잡도가 증가하여, 디버깅하는데 시간이 많이 걸렸다.
 
shiftOut 함수 참고
https://www.arduino.cc/reference/ko/language/functions/advanced-io/shiftout/

 

shiftOut() - 아두이노 참조

설명 한번에 한 비트씩의 바이트를 옮긴다. 최고(가장 왼쪽) 또는 최저(가장 오른쪽) 비트부터 시작한다. 각 비트에, 클락 핀은 하이로 풀 되고, 다음 비트는 데이터 라인에서 읽히고, 클락 핀은

www.arduino.cc

 
74HC595 참고
https://bbangpower-blog.blogspot.com/2021/03/74hc595.html

 

[아두이노] 74HC595 시프트 레지스터 연동

PLC, Factory Automation

bbangpower-blog.blogspot.com

 

2. 4 Digit 7 Segment 2개

 

배선

Arduino 첫 번째 74HC595 두 번째 74HC595 두 번째 4 digit 7 segment
    1 (Q1) 7 (B segment)
    2 (Q2) 4 (C segment)
    3 (Q3) 2 (D segment)
    4 (Q4) 1 (E segment)
    5 (Q5) 10 (F segment)
    6 (Q6) 5 (G segment)
    7 (Q7) 3 (DP segment)
GND   8 (GND)  
    9 (Q7')  
VCC   10 (MR)  
D10   11 (SH_CP)  
D11   12 (ST_CP)  
GND   13 (OE)  
  9 (Q7') 14 (DS)  
    15 (Q0) 11 (A segment)
VCC   16 (VCC)  
D2     12 (D1)
D5     9 (D2)
D6     8 (D3)
D13     6 (D4)

첫 번째 4 Digit 7 Segment와 첫 번째 74HC595는 1. 배선과 동일하다.
첫 번째 74HC595의 9 (Q7')에서 두 번째 74HC595와 연결하는 점이 다르다.
아두이노와 두 번째 4 Digit 7 Segment 사이에 두 번째 74HC595를 넣고 연결한다.
 
소스

//a,b,c,d,e,f,g 상태값
byte segValue[11] = {
  0b11111100, //0
  0b01100000, //1
  0b11011010, //2
  0b11110010, //3
  0b01100110, //4
  0b10110110, //5
  0b10111110, //6
  0b11100000, //7
  0b11111110, //8
  0b11110110, //9
  0b00000000, //10
};

byte digitPin[4] = { 2, 5, 6, 13 }; //segment 위치 핀
int dataPin = 9; //DS Pin
int clockPin = 10; //SH_CP Pin
int latchPin = 11; //ST_CP Pin

/*
data[0] : 첫 번째 7 Segment 출력값
data[1] : 두 번째 7 Segment 출력값
*/
unsigned long data[2] = { 0, 0 };
/*
d[0][0] : 첫 번째 7 Segment 1 자리 숫자
d[0][1] : 첫 번째 7 Segment 10 자리 숫자
d[0][2] : 첫 번째 7 Segment 100 자리 숫자
d[0][3] : 첫 번째 7 Segment 1000 자리 숫자
d[1][0] : 두 번째 7 Segment 1 자리 숫자
d[1][1] : 두 번째 7 Segment 10 자리 숫자
d[1][2] : 두 번째 7 Segment 100 자리 숫자
d[1][3] : 두 번째 7 Segment 1000 자리 숫자
*/
int d[2][4] = {{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }}; 

void setup()
{
    for (int j = 0; j < 4; j++)
    {
      pinMode(digitPin[j], OUTPUT);
      digitalWrite(digitPin[j], HIGH);
    }
    pinMode(dataPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(latchPin, OUTPUT);
}

void loop()
{
    data[0] = millis() / 1000;
    setNumber(data[0], d[0]);
    data[1] = data[0] + 123;  //두 번째 7 Segment 출력값은 첫 번째 7 Segment 출력값에 123을 더한 값이다.
    setNumber(data[1], d[1]);

    segOutput(3, d[0][0], d[1][0], 0); //1의 자리
    segOutput(2, d[0][1], d[1][1], 0); //10의 자리  
    segOutput(1, d[0][2], d[1][2], 0); //100의 자리  
    segOutput(0, d[0][3], d[1][3], 0); //1000의 자리  
}

void setNumber(long number, int* dArray)
{
      dArray[0] = number % 10; //1의 자리
    if (number >= 10)
      dArray[1] = (number / 10) % 10; //10의 자리
    else
      dArray[1] = 10;
    if (number >= 100)
      dArray[2] = (number / 100) % 10; //100의 자리
    else
      dArray[2] = 10;
    if (number >= 1000)
      dArray[3] = (number / 1000) % 10; //1000의 자리
    else
      dArray[3] = 10;
}

//LED 초기화
void segClear()
{
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, 0);
    shiftOut(dataPin, clockPin, LSBFIRST, 0);
    digitalWrite(latchPin, HIGH);    
}
//LED 출력
void segOutput(int d, int Number1, int Number2, int dp)
{
    segClear();
    digitalWrite(digitPin[d], LOW);
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, segValue[Number1]);
    shiftOut(dataPin, clockPin, LSBFIRST, segValue[Number2]);
    digitalWrite(latchPin, HIGH);    
    delayMicroseconds(1000);
    digitalWrite(digitPin[d], HIGH);
}

 
오른쪽에 첫 번째 숫자가 왼쪽에 두 번째 숫자가 출력된다.
값을 쉬프트 하므로 두 번째 7 Segment에 첫 번째 숫자가 출력되고, 첫 번째 7 Segment에 두 번째 숫자가 출력된다.
두 번째 숫자가 첫 번째 숫자보다 123이 크다.

 

3. 4 Digit 7 Segment 2개, LED 9개, 버튼 2개

 

배선

Arduino 두 번째 74HC595 세 번째 74HC595 Led Button
    1 (Q1) 2 + 330 Ohm  
    2 (Q2) 3  + 330 Ohm  
    3 (Q3) 4  + 330 Ohm  
    4 (Q4) 5  + 330 Ohm  
    5 (Q5) 6  + 330 Ohm  
    6 (Q6) 7  + 330 Ohm  
    7 (Q7) 8  + 330 Ohm  
GND   8 (GND)    
    9 (Q7')    
VCC   10 (MR)    
D10   11 (SH_CP)    
D11   12 (ST_CP)    
GND   13 (OE)    
  9 (Q7') 14 (DS)    
    15 (Q0) 1  + 330 Ohm  
VCC   16 (VCC)    
D12     0  + 330 Ohm  
D7       1 + 10K Ohm
D8       2  + 10K Ohm

두 번째 74HC595의 9 (Q7')에서 세 번째 74HC595와 연결한다.
아두이노와 LED 8개 사이에 세 번째 74HC595를 넣고 연결한다.
LED 0은 아두이노와 연결한다.
버튼 두개를 아두이노와 연결한다.
 
소스

//a,b,c,d,e,f,g 상태값
byte segValue[11] = {
  0b11111100, //0
  0b01100000, //1
  0b11011010, //2
  0b11110010, //3
  0b01100110, //4
  0b10110110, //5
  0b10111110, //6
  0b11100000, //7
  0b11111110, //8
  0b11110110, //9
  0b00000000, //10
};

byte bitValue[9] = {
  0b00000001, //0
  0b00000010, //1
  0b00000100, //2
  0b00001000, //3
  0b00010000, //4
  0b00100000, //5
  0b01000000, //6
  0b10000000, //7
  0b00000000, //8
};
int bitIndex = 0;
bool isButton1Pressed = false;
bool isButton2Pressed = false;

byte digitPin[4] = { 2, 5, 6, 13 }; //segment 위치 핀
int dataPin = 9; //DS Pin
int clockPin = 10; //SH_CP Pin
int latchPin = 11; //ST_CP Pin

int bitPin = 12;
int button1Pin = 7;
int button2Pin = 8;

int mode = 0;

/*
data[0] : mode 0 = 1초에 1씩 자동 증가
data[1] : mode 1 = B버튼을 눌러 1 증가
data[2] : mode 2 = B버튼을 눌러 1 감소
mode 3 = bit LED 1 이동
*/
unsigned long data[3] = { 0, 0, 9999 };
/*
d[0][0] : 첫 번째 7 Segment 1 자리 숫자
d[0][1] : 첫 번째 7 Segment 10 자리 숫자
d[0][2] : 첫 번째 7 Segment 100 자리 숫자
d[0][3] : 첫 번째 7 Segment 1000 자리 숫자
d[1][0] : 두 번째 7 Segment 1 자리 숫자
d[1][1] : 두 번째 7 Segment 10 자리 숫자
d[1][2] : 두 번째 7 Segment 100 자리 숫자
d[1][3] : 두 번째 7 Segment 1000 자리 숫자
*/
int d[2][4] = {{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }}; 

void setup()
{
    for (int j = 0; j < 4; j++)
    {
      pinMode(digitPin[j], OUTPUT);
      digitalWrite(digitPin[j], HIGH);
    }
    pinMode(dataPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(latchPin, OUTPUT);

    pinMode(bitPin, OUTPUT);
    pinMode(button1Pin, INPUT);
    pinMode(button2Pin, INPUT);
}

void loop()
{
    data[0] = millis() / 1000;

    if(digitalRead(button1Pin) == HIGH)
    {
      if(isButton1Pressed == false)
      {
        isButton1Pressed = true;
        if(mode == 3) 
          mode = 0;
        else
          mode++;
      }
    }
    else
    {
      if(isButton1Pressed == true)
      {
        isButton1Pressed = false;
      }
    }

    if(digitalRead(button2Pin) == HIGH)
    {
      if(isButton2Pressed == false)
      {
        isButton2Pressed = true;
        switch(mode)
        {
          case 1:
            data[1]++;
            break;
          case 2:
            data[2]--;
            break;
          case 3:
            if(bitIndex == 8) 
              bitIndex = 0;
            else
              bitIndex++;
            break;
        }
      }
    }
    else
    {
      if(isButton2Pressed == true)
      {
        isButton2Pressed = false;
      }
    }

    switch(mode) {
      case 0:
        setNumber(data[0], d[0]);
        break;
      case 1:
        setNumber(data[1], d[0]);
        break;
      case 2:
        setNumber(data[2], d[0]);
        break;
      case 3:
        setNumber(-1, d[0]);
        break;
    }
    setNumber(mode, d[1]); //두 번째 7 Segment 출력값은 mode 값이다.

    segOutput(3, bitValue[bitIndex], d[0][0], d[1][0], 0); //1의 자리
    segOutput(2, bitValue[bitIndex], d[0][1], d[1][1], 0); //10의 자리  
    segOutput(1, bitValue[bitIndex], d[0][2], d[1][2], 0); //100의 자리  
    segOutput(0, bitValue[bitIndex], d[0][3], d[1][3], 0); //1000의 자리

    if(bitIndex == 8) 
    {
      digitalWrite(bitPin, HIGH);
    } 
    else 
    {
      digitalWrite(bitPin, LOW);
    }
}

void setNumber(long number, int* dArray)
{
    if (number >= 0)
      dArray[0] = number % 10; //1의 자리
    else
      dArray[0] = 10;
    if (number >= 10)
      dArray[1] = (number / 10) % 10; //10의 자리
    else
      dArray[1] = 10;
    if (number >= 100)
      dArray[2] = (number / 100) % 10; //100의 자리
    else
      dArray[2] = 10;
    if (number >= 1000)
      dArray[3] = (number / 1000) % 10; //1000의 자리
    else
      dArray[3] = 10;
}

//LED 초기화
void segClear()
{
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, 0);
    shiftOut(dataPin, clockPin, LSBFIRST, 0);
    shiftOut(dataPin, clockPin, LSBFIRST, 0);
    digitalWrite(latchPin, HIGH);    
}
//LED 출력
void segOutput(int d, byte bitValue, int Number1, int Number2, int dp)
{
    segClear();
    digitalWrite(digitPin[d], LOW);
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, bitValue);
    shiftOut(dataPin, clockPin, LSBFIRST, segValue[Number1]);
    shiftOut(dataPin, clockPin, LSBFIRST, segValue[Number2]);
    digitalWrite(latchPin, HIGH);    
    delayMicroseconds(1000);
    digitalWrite(digitPin[d], HIGH);
}

버튼 1을 누르면 모드가 변경된다. 왼쪽(두 번째) 7 Segment에 모드가 표시된다.

모드 0~2 값은 오른쪽(첫 번째) 7 Segment에 표시된다.

모드 0은 0부터 1초에 1씩 자동 증가한다.

모드 1은 0부터 시작하여 두 번째 버튼을 누르면 값이 증가한다.

모드 2는 9999부터 시작하여 두 번째 버튼을 누르면 값이 감소한다.


모드 3은 두 번째 버튼을 누르면 LED가 왼쪽으로 이동한다.

+ Recent posts