아두이노에서 가장 흔하게 사용하는 출력 장치는 7세그먼트 LED를 이용한 디스플레이입니다. LED를 사용하는 방법과 핀을 확장하기 위한 MUX (multiplexer)의 한 종류인 74HC595 사용법을 알아봅시다.
다이오드(diode)는 한 방향으로만 전류를 흐르게 하는 반도체 소자입니다.그중에서 전류를 흘리면 빛을 발하는 다이오드를 LED (발광 다이오드, Light Editting Diode)라고 합니다.
다이오드는 극성이 있습니다.다리가 긴 쪽이 + 방향이며 아노드라고 하고,그 반대쪽이 캐소드입니다.
LED를 7개 모아서 글자를 구성하는 부품이 ‘7세그먼트 튜브’입니다.실용적으로는 소숫점을 포함하여 8개의 LED로 숫자 하나를 표현합니다.숫자 하나를 표시하기 위하여 8개의 핀이 필요합니다.
7세그먼트 튜브는 공통 단자를 아노드(+) 또는 캐소드(-)로 만듭니다. 공통 단자와 반대 극성의 전압이 걸리는 세그먼트 낱개가 켜지게 됩니다. 시중에 판매되는 제품에는 공통 아노드가 더 많습니다.
만약 4자리 숫자를 표현하려면 몇개의 핀이 필요할까요? 아두이노 우노의 핀이 20개인데 튜브에 40개의 핀을 사용할 수는 없는 노릇입니다.
여러 자리를 표시하는 경우는 자리 번호를 공통 아노드나 공통 개소드로 하고,자리수를 번갈아 가면서 표시하는 ‘다이나믹 표시’ 기법을 사용합니다.위와 같이 4자리를 표시할 때도 12개의 핀만 있으면 됩니다.
이 경우 특정 시점에는 하나의 숫자만 켜지게 되는데 아주 빠르게 반복되므로 마치 동시에 켜져 있는 듯 보입니다. 빠르게 반복되게 프로그램 로직을 구성해야 합니다. 이런 상황에서는 타이머 인터럽트를 이용하면 편합니다.
74HC595 소자에는 데이터를 받아들이는데 사용되는 핀이 3개 있고,받아들인 데이터를 동시에 출력하는 핀이 8개 있습니다. 이 소자에는 8비트의 레지스터가 있는데 각 비트의 값에 따라 해당 핀에 5V(1)나 0V(0)가 출력됩니다. LATCH핀에 0V를 걸면 레지스터에 값을 보낼 수 있습니다. CLK핀이 0V에서 5V로 바뀔 때 DATA핀에 5V가 걸리면 비트 1, 0V가 걸리면 비트 0이 전송됩니다. shiftOut() 함수는 8비트를 레지스터에 보내는데 사용합니다. 소자는 여러 개를 직렬로 연결할 수도 있습니다.이론적으로는 여러 개의 74HC595를 단 3개의 핀으로 제어할 수가 있습니다.
다음은 각 세그멘트별 값을 나타낸 표입니다. 특정 숫자를 표현할 때는 각 세그멘트를 |(OR)로 연결해서 만든 값을 사용할 수도 있고, 미리 완성된 값을 지정할 수도 있습니다.
세그먼트 | 이진수 | 10진수 |
---|---|---|
SEG_A | B0000 0001 | 1 |
SEG_B | B0000 0010 | 2 |
SEG_C | B0000 0100 | 4 |
SEG_D | B0000 1000 | 8 |
SEG_E | B0001 0000 | 16 |
SEG_F | B0010 0000 | 32 |
SEG_G | B0100 0000 | 64 |
SEG_DP | B1000 0000 | 128 |
숫자 '2' | B0101 1011 | 91 |
SEG_A | SEG_B | SEG_D | SEG_E | SEG_G | 1+ 2+ 8+ 16+ 64= 91 |
다음은 공통 아노드 4 자리 튜브를 두 개의 74HC595로 제어하는 예입니다. LATCH,CLK,DATA핀은 각각 4,7,8번 핀에 연결되어 있습니다. 첫 번째 자리에 숫자 ‘2’를 표시하는 경우를 도식화한 것입니다.
배선를 살펴보면 두 소자의 LATCH와 CLK핀은 아두이노와 연결되어 있습니다. 자릿수 소자의 DATA핀은 아두이노와 연결되어 있고 세그먼트 소자의 DATA핀은 자릿수 소자의 핀에 연결되어 있습니다. 두 개의 74HC595는 순차적으로 연결되어 있어서 shiftOut()을 한 번 수행하면 자릿수 레지스터에 8비트가 옮겨지고,두 번째 shiftOut()를 수행하면 새롭게 8비트가 자릿수 레지스터에 들어가면서 기존에 있던 8비트는 세그먼트 레지스터로 밀려서 옮겨갑니다.
공통 아노드 튜브의 경우 세그먼트 낱개에 연결되는 핀이 LOW가 되어야 ON 상태가 됩니다. 그림의 ‘2’를 표시하는 패턴은 사람이 이해하기 쉽게 핀이 HIGH가 되어야 ON 상태가 되도록 표시되어 있으므로 shiftOut()하기 전에 ~기호를 이용해서 반전시킵니다.
위 경우를 나타낸 스케치 일부입니다.
1 2 3 4 5 6 7 8 |
const byte latchPin = 4; const byte clkPin = 7; const byte dataPin = 8; // digitalWrite(latchPin,LOW); shiftOut(dataPin, clkPin, MSBFIRST, ~B010111011); shiftOut(dataPin, clkPin, MSBFIRST, B00000001); digitalWrite(latchPin,HIGH); |
비트연산자 | 의미 | 설명 |
---|---|---|
& | 비트 AND | 둘다 1 일때 1 |
| | 비트 OR | 둘중 하나만 1이면 1 |
^ | 비트 XOR | 둘중 하나만 1이면 1 둘다 1이면 0 |
~ | 비트 반전 | 0 -> 1 1 -> 0 |
<< | 왼쪽으로 비트 이동 | 자릿수 만큼 이동 넘치면 없어짐 |
<< | 오른쪽으로 비트 이동 | 자릿수 만큼 이동 넘치면 없어짐 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
// 74HC595에 사용되는 핀 #define LATCH_PIN 4 #define CLK_PIN 7 #define DATA_PIN 8 // 숫자(0~9)표현하는 비트 패턴 //const byte num[] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111}; const byte num[] = { B00111111, // 0 B00000110, // 1 B01011011, // 2 B01001111, // 3 B01100110, // 4 B01101101, // 5 B01111101, // 6 B00000111, // 7 B01111111, // 8 B01101111 // 9 }; const byte segA = B00000001; const byte segB = B00000010; const byte segC = B00000100; const byte segD = B00001000; const byte segE = B00010000; const byte segF = B00100000; const byte segG = B01000000; const byte segDP= B10000000; const byte segBlank = B00000000; // 자릿수(1~4)를 표현하는 비트 값 const byte segmentDigit[] = {0x01,0x02,0x04,0x08}; void setup () { pinMode(LATCH_PIN,OUTPUT); pinMode(CLK_PIN,OUTPUT); pinMode(DATA_PIN,OUTPUT); } void loop() { // 25.7c 표시 writePattern(0 , num[2]); writePattern(1 , num[5] | segDP); // 소숫점 표시 writePattern(2 , num[7]); writePattern(3 , segD | segE| segG); // c } void writePattern(byte digit, byte pattern) { // LATCH핀이 LOW가 되면 74HC595의 레지스터에 비트를 받아들일 준비가 됩니다. digitalWrite(LATCH_PIN,LOW); // 공통 아노드 튜브의 경우 segment 낱개에 연결되는 핀이 LOW가 되어야 ON 상태가 됩니다. // 위 num[]은 사람이 이해하기 쉽게 핀이 HIGH가 되어야 ON 상태가 되도록 표시되어 있으므로 // shiftOut()하기 전에 ~기호를 이용해서 반전시킵니다. shiftOut(DATA_PIN, CLK_PIN, MSBFIRST, ~pattern); shiftOut(DATA_PIN, CLK_PIN, MSBFIRST, segmentDigit[digit] ); digitalWrite(LATCH_PIN,HIGH); // LATCH핀이 HIGH가 되면 74HC595의 레지스터에 있는 비트 값에 따라 해당 핀에 5V(1)나 0V(0)를 동시에 출력합니다. } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// 74HC595에 사용되는 핀 #define LATCH_PIN 4 #define CLK_PIN 7 #define DATA_PIN 8 // 주기적으로 튜브에 update하기 위하여 Timer1을 이용합니다. #include <TimerOne.h> // 7세그먼트용 기초 클래스입니다. #include <SanguruSegmentBasic.h> SanguruSegmentBasic seg(LATCH_PIN,CLK_PIN,DATA_PIN); void setup () { // 250 microSec 마다 수행합니다. Timer1.initialize(250); // 7세그먼트 update용 ISR(Interrupt Service Rountine)을 지정합니다. Timer1.attachInterrupt(segUpdate); seg.setBrightness(5); // 밝기 단계 1~7, 높을수록 밝다. //seg.setDigitOrderHigh(); // common digit 배선이 역순일 때 사용 //seg.setCommonCathode(); // common cathode 일 때 사용 } void loop() { // 25.7c 표시 seg.writePattern(0 , seg.num[2]); seg.writePattern(1 , seg.num[5] | seg.DP); // 소숫점 표시 seg.writePattern(2 , seg.num[7]); seg.writePattern(3 , seg.D | seg.E | seg.G); // c } void segUpdate() { seg.update(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#ifndef SANGURU_SEGMENT_BASIC_H_ #define SANGURU_SEGMENT_BASIC_H_ #include "Arduino.h" class SanguruSegmentBasic { public: // constructor 에는 void 조차도 없다. SanguruSegmentBasic(byte inLatchPin, byte inClkPin, byte inDataPin); void writePattern(byte digit, byte pattern); void write(int number); void write(float number, byte decimalPlaces); // ISR에 이 메쏘드를 넣어야 한다. void update(); // common digit 배선이 역순으로 되어 있을 때 사용 void setDigitOrderHigh(); // common cathode 일 때 사용 void setCommonCathode(); // 밝기를 1~7단계로 표시. 높을 수록 밝다. 기초값 5 void setBrightness(byte bright); //const bytenum[] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111}; const byte num[10] = { B00111111, // 0 B00000110, // 1 B01011011, // 2 B01001111, // 3 B01100110, // 4 B01101101, // 5 B01111101, // 6 B00000111, // 7 B01111111, // 8 B01101111 // 9 }; const byte A = B00000001; const byte B = B00000010; const byte C = B00000100; const byte D = B00001000; const byte E = B00010000; const byte F = B00100000; const byte G = B01000000; const byte DP= B10000000; const byte Blank = B00000000; volatile byte buffer[4]; private: byte latchPin,clkPin,dataPin; byte digitOrderLowOrHigh = LOW; byte bright = 5; bool commonAnode = true; const byte digit[4] = {0x01,0x02,0x04,0x08}; // ISR에서 수정되거나 사용되는 변수는 volatile을 지정해야 값이 안전하게 전달된다. volatile byte digitLoop = 0; volatile int eachDigitLoop[4]; }; //↑ class 뒤에는 ;가 있어야 한다. #endif |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
#include "SanguruSegmentBasic.h" #include "Arduino.h" // constructor 앞에는 void 조차도 없다. SanguruSegmentBasic::SanguruSegmentBasic(byte inLatchPin, byte inClkPin, byte inDataPin) { latchPin = inLatchPin; clkPin = inClkPin; dataPin = inDataPin; pinMode(latchPin,OUTPUT); pinMode(clkPin,OUTPUT); pinMode(dataPin,OUTPUT); } void SanguruSegmentBasic::writePattern(byte digit, byte pattern) { buffer[digit] = pattern; } void SanguruSegmentBasic::write(int number) { write((float)number,0); } void SanguruSegmentBasic::write(float number, byte decimalPlaces) { int expo[4] = {1,10,100,1000}; byte buffer[4] = {0,0,0,0}; bool sign = false; if (decimalPlaces > 3 || decimalPlaces < 0) return; int val = number * expo[decimalPlaces]; if (val > 9999 || val < -999) { writePattern(3,121); // 121=E return; } if (val < 0 ) { val = 0 - val; sign = true; } int i; for (i = 3; i >= 0 && val != 0; val /= 10, i--) { buffer[i] = num[val % 10]; } if (sign == true) { buffer[i] = 64; // minus(-) } if (decimalPlaces > 0) { buffer[3-decimalPlaces] += 128; // decimal point } for (int i = 0; i <= 3; i++) { writePattern(i,buffer[i]); } } void SanguruSegmentBasic::update() { // 한 자릿수씩 번갈이 가면서 표시한다. digitLoop++; if (digitLoop > 3) digitLoop = 0; // common digit의 배선 순서가 역순인 경우 대비 byte newDigitLoop; if (digitOrderLowOrHigh == LOW) newDigitLoop = digitLoop; else newDigitLoop = 3 - digitLoop; // 공통 아노드 튜브의 경우 segment 낱개에 연결되는 핀이 LOW가 되어야 ON 상태가 된다. // 위 num[]은 사람이 이해하기 쉽게 핀이 HIGH가 되어야 ON 상태가 되도록 표시되어 있으므로 // shiftOut()하기 전에 buffer[]를 ~기호를 이용해서 반전시킨다. byte newDigit,newBuffer; if (commonAnode == true) { newBuffer = ~buffer[newDigitLoop]; newDigit = digit[digitLoop]; } else { newBuffer = buffer[newDigitLoop]; newDigit = ~digit[digitLoop]; } // 밝기를 1~7 단계로 조절 eachDigitLoop[digitLoop]++; if ( (bright == 1 && (eachDigitLoop[digitLoop] % 20 !=0)) || (bright == 2 && (eachDigitLoop[digitLoop] % 13 !=0)) || (bright == 3 && (eachDigitLoop[digitLoop] % 10 !=0)) || (bright == 4 && (eachDigitLoop[digitLoop] % 6 !=0)) || (bright == 5 && (eachDigitLoop[digitLoop] % 3 !=0)) || (bright == 6 && (eachDigitLoop[digitLoop] % 2 !=0)) ) { newBuffer = B00000000; newDigit = B00000000; } // LATCH핀이 LOW가 되면 74HC595의 레지스터에 비트를 받아들일 준비가 된다. digitalWrite(latchPin,LOW); shiftOut(dataPin, clkPin, MSBFIRST, newBuffer); shiftOut(dataPin, clkPin, MSBFIRST, newDigit ); digitalWrite(latchPin,HIGH); // LATCH핀이 HIGH가 되면 74HC595의 레지스터에 있는 비트 값에 따라 해당 핀에 5V(1)나 0V(0)를 동시에 출력한다. } void SanguruSegmentBasic::setDigitOrderHigh() { digitOrderLowOrHigh = HIGH; } void SanguruSegmentBasic::setCommonCathode() { commonAnode = false; } void SanguruSegmentBasic::setBrightness(byte inBright) { if (inBright > 7) inBright = 7; else if (inBright < 1) inBright = 1; bright = inBright; } |
위 클래스를 확장하여 정수를 표현하는 write() 함수를 (교육 목적으로) 만들어 보았습니다.
(실제로는 SanguruSegmentBasic.h에는 write()메쏘드가 포함되어 있으므로 별도로 함수를 만들 필요는 없습니다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// 사용할 때 write(&seg,-234); write(&seg,25.8,1); // void write(SanguruSegmentBasic *seg,int number) { write(seg,(float)number,0); } void write(SanguruSegmentBasic *seg,float number, byte decimalPlaces) { int expo[4] = {1,10,100,1000}; byte buffer[4] = {0,0,0,0}; bool sign = false; if (decimalPlaces > 3 || decimalPlaces < 0) return; int val = number * expo[decimalPlaces]; if (val > 9999 || val < -999) { seg->writePattern(3,121); // 121=E return; } if (val < 0 ) { val = 0 - val; sign = true; } int i; for (i = 3; i >= 0 && val != 0; val /= 10, i--) { buffer[i] = seg->num[val % 10]; } if (sign == true) { buffer[i] = 64; // minus(-) } if (decimalPlaces > 0) { buffer[3-decimalPlaces] += 128; // decimal point } for (int i = 0; i <= 3; i++) { seg->writePattern(i,buffer[i]); } } |
다음은 두 개의 74HC595 소자를 사용하는 4 자리 LED 튜브를 제어할 수 있는 SanguruSegment.h의 사용 예입니다.
시리얼로 입력된 명령어에 따라 다양한 방식으로 표시할 수 있습니다. 소스를 보면 그 사용 예를 익힐 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
// SanguruSegment.h 사용시 필요 #include <TimerOne.h> // SanguruSegment.h 클라스 #include <SanguruSegment.h> SanguruSegment segment; // 74HC595 핀 설정 #define LATCH_PIN 4 // RCLK_PIN #define CLK_PIN 7 // SCLK_PIN #define DATA_PIN 8 // QB_PIN,DIO_PIN void setup () { // 값을 250에서 1000 사이의 값을 사용하면 된다. int microSec = 250; Timer1.initialize(microSec); // 반복적으로 update할 때 사용할 ISR을 정의한다. // ISR안에는 segment.update()가 있어야 한다. Timer1.attachInterrupt(segment_update); // 글자가 역순으로 나타나면 LOW와 HIGH를 서로 바꾸면 된다. // LOW: LOW to HIGH, HIGH: HIGH to LOW byte digitOrder = LOW; segment.init(LATCH_PIN,CLK_PIN,DATA_PIN,digitOrder,microSec); Serial.begin(9600); Serial.println("Started..." ); printHelp(); // 초기치로 '1234'를 표시해 둔다. segment.write(1234); } void loop() { // Serial로 입력된 'key value'에 따라 다양하게 표현한다. if (Serial.available()) { readAndDisplay(); } } // ISR void segment_update(){ segment.update(); } // 클라스 SanguruSegment.h의 사용 예를 알 수 있다. void readAndDisplay() { char c = Serial.read(); // 정수 표시 if ( c == 'i' ) { int i = Serial.parseInt(); Serial.print("i "); Serial.println(i); segment.write(i); } // 앞에 0을 채운 정수 else if ( c == 'I' ) { int i = Serial.parseInt(); Serial.print("I "); Serial.println(i); segment.write(i,'0'); } // 소숫점 표시 else if ( c == 'f' ) { float f = Serial.parseFloat(); Serial.print("f "); Serial.println(f,1); segment.write(f,1); } // 앞에 0을 채운 소숫점 표시 else if ( c == 'F' ) { float f = Serial.parseFloat(); Serial.print("F "); Serial.println(f,1); segment.write(f,1,'0'); } // 윈도우 시작설정. 초기값은 0 else if ( c == 'w' ) { int val = Serial.parseInt(); segment.setWindow(val,segment.windowLen); Serial.print("windowFrom "); Serial.println( segment.windowFrom); } // 윈도우 길이 설절, 초기값은 4 else if ( c == 'l' ) { int val = Serial.parseInt(); segment.setWindow(segment.windowFrom,val); Serial.print("windowLen "); Serial.println( segment.windowLen); } // 첫 자리에 패턴값을 표시한다. else if ( c == 'a' ) { segment.patternBuffer[0] = Serial.parseInt(); Serial.print("a --> patternBuffer[0] "); Serial.println( segment.patternBuffer[0]); } // 둘째 자리에 패턴값을 표시한다. else if ( c == 'b' ) { segment.patternBuffer[1] = Serial.parseInt(); Serial.print("b --> patternBuffer[1] "); Serial.println( segment.patternBuffer[1]); } // 세째 자리에 패턴값을 표시한다. else if ( c == 'c' ) { segment.patternBuffer[2] = Serial.parseInt(); Serial.print("c --> patternBuffer[2] "); Serial.println(segment.patternBuffer[2]); } // 네째 자리에 패턴값을 표시한다. else if ( c == 'd' ) { segment.patternBuffer[3] = Serial.parseInt(); Serial.print("d --> patternBuffer[3] "); Serial.println( segment.patternBuffer[3]); } // Timer1 주기를 microSec 단위로 다시 지정한다. else if ( c == 'y' ) { unsigned long titmer1InitVal = Serial.parseInt(); Serial.print("y --> timer1InitVal "); Serial.println( titmer1InitVal); Timer1.initialize(titmer1InitVal); } // 문자 스트링를 출력한다. 문자 끝에는 #로 표시한다. else if ( c == 'q' ) { char buf[20]= {0}; Serial.readBytesUntil('#',buf,19); Serial.print("q --> ["); Serial.print(buf); Serial.println("]"); String strBuf = String(buf); strBuf.trim(); Serial.print("q(~#String) --> ["); Serial.print(strBuf); Serial.println("]"); segment.write(buf); } // 설정된 윈도우를 깜빡거린다. else if ( c == 'k' ) { int val = Serial.parseInt(); Serial.print("k(blink) --> ["); Serial.print(val); Serial.println("]"); segment.blink(val); } // 콜론을 on(1) off(0)한다. else if ( c == 'n' ) { int val = Serial.parseInt(); Serial.print("n(colon) --> ["); Serial.print(val); Serial.println("]"); segment.colon(val); } // 윗쪽 점을 on(1) off(0)한다. else if ( c == 'u' ) { int val = Serial.parseInt(); Serial.print("u(upperDot) --> ["); Serial.print(val); Serial.println("]"); segment.upperDot(val); } // 콜론 깜빡거림을 on(1) off(0)한다. else if ( c == 'o' ) { int val = Serial.parseInt(); Serial.print("o(blinkColon) --> ["); Serial.print(val); Serial.println("]"); segment.blinkColon(val); } // 윗쪽 점 깜빡거림을 on(1) off(0)한다. else if ( c == 'p' ) { int val = Serial.parseInt(); Serial.print("p(blinkUpperDot) --> ["); Serial.print(val); Serial.println("]"); segment.blinkUpperDot(val); } // 소숫점 깜빡거림을 on(1) off(0)한다. else if ( c == 'z' ) { int val = Serial.parseInt(); Serial.print("z(blinkDot) --> ["); Serial.print(val); Serial.println("]"); segment.blinkDot(val); } // 모든 표시를 지운다. else if ( c == 'x' ) { int val = Serial.parseInt(); Serial.print("x(clear) --> ["); Serial.print(val); Serial.println("]"); segment.clear(); } // 표시 순서를 바꾼다. 0: LOW to HIGH, 1:HIGH to LOW else if ( c == 'r' ) { int val = Serial.parseInt(); Serial.print("r(digitOrder) --> ["); Serial.print(val); Serial.println("]"); segment.setDigitOrder(val); } // 왼쪽에 붙여서 표시한다. 숫자인 경우 기초값은 오른쪽 붙임이다. else if ( c == 'j' ) { int val = Serial.parseInt(); Serial.print("j(leftJustify) --> ["); Serial.print(val); Serial.println("]"); segment.setLeftJustify(); } // 오른쪽에 붙여서 표시한다. 숫자인 경우 기초값은 오른쪽 붙임이다. else if ( c == 'J' ) { int val = Serial.parseInt(); Serial.print("J(rightJustify) --> ["); Serial.print(val); Serial.println("]"); segment.setRightJustify(); } // 밝기를 1~7단계로 표시한다. 기초값은 5이다. 큰 숫자가 밝게 표시된다. // 글자가 깜빡거려 보이면 Timer1.initialize() 값을 낮추면된다.(250 정도) else if ( c == 't' ) { int val = Serial.parseInt(); Serial.print("t(bright) --> ["); Serial.print(val); Serial.println("]"); segment.setBrightness(val); } // help 표시 else if ( c == 'h' ) { printHelp(); } } void printHelp(){ Serial.println("commands"); Serial.println("h display help"); Serial.println("x clear"); Serial.println("i integer with leading blank"); Serial.println("I integer with leading zero"); Serial.println("f float with leading blank"); Serial.println("F float with leading zero"); Serial.println("w set window from"); Serial.println("l set window len"); Serial.println("a set patternBuffer[0]"); Serial.println("b set patternBuffer[1]"); Serial.println("c set patternBuffer[2]"); Serial.println("d set patternBuffer[3]"); Serial.println("y Timer1 interval in microSec"); Serial.println("q readBytesUntil #"); Serial.println("n colon 1/0"); Serial.println("u upperDot 1/0"); Serial.println("k blink 1/0"); Serial.println("z blinkDot 1/0"); Serial.println("o blinkColon 1/0"); Serial.println("p blinkUpperDot 1/0"); Serial.println("r digitOreder 0/1"); Serial.println("j leftJustify"); Serial.println("J rightJustify"); Serial.println("t bright(1~7"); } |
댓글 남기기