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가 왼쪽으로 이동한다.
'IOT > 아두이노' 카테고리의 다른 글
[아두이노] 4 Digit 7 Segment (1) | 2023.12.29 |
---|---|
[아두이노] PWM 전송 (0) | 2023.11.14 |
아두이노 부트로더 굽기 MiniCore (Arduino IDE 2.2.1) (0) | 2023.10.20 |
아두이노 부트로더 굽기 (Arduino IDE 2.2.1) (1) | 2023.10.17 |
아두이노 개발환경 설치 (Arduino IDE 2.2.1) (0) | 2023.10.13 |