[Arduino] 자료형, byte와 int의 차이
아두이노에서 자료형은 변수의 크기, 메모리 사용량, 저장할 수 있는 값의 범위를 결정한다. 기본적으로 C/C++기반이기때문에 C언어의 자료형과 유사하다.
1. boolean
크기: 1바이트 (8비트)
값의 범위: true 또는 false
boolean ledState = true; // true = 1, false = 0
2. char
크기: 1바이트 (8비트)
값의 범위: -128 ~ 127 (부호 있는 값) 또는 0 ~ 255 (부호 없는 값으로 사용 시)
용도: 문자 저장.
char myChar = 'A'; // 문자 'A' 저장
3. byte
크기: 1바이트 (8비트)
값의 범위:
- 0 ~ 255 (부호 없는 정수)
- 음수를 표현할 수 없음
사용 예시:
작은 정수, 이진 데이터를 다룰 때 유용 (예: 센서 데이터, 비트 연산).
byte myByte = 200; // 0에서 255 사이의 값 저장 가능 Serial.println(myByte); // 출력: 200
4. int
크기: 2바이트 (16비트, 일반적으로 AVR 기반 아두이노에서)
값의 범위:
- -32,768 ~ 32,767 (부호 있는 정수)
사용 예시:
큰 정수나 음수까지 표현해야 할 때 사용.
int myInt = -1000; // -32,768에서 32,767 사이의 값 저장 가능 Serial.println(myInt); // 출력: -1000
5. unsigned int
크기: 2바이트 (16비트)
값의 범위: 0 ~ 65,535 (부호 없음)
unsigned int counter = 50000;
6. long
크기: 4바이트 (32비트)
값의 범위: -2,147,483,648 ~ 2,147,483,647 (부호 있음)
long distance = 123456789;
7. unsigned long
크기: 4바이트 (32비트)
값의 범위: 0 ~ 4,294,967,295 (부호 없음)
unsigned long milliseconds = 3000000000;
8. float
크기: 4바이트 (32비트)
값의 범위: 약 -3.4E+38 ~ 3.4E+38 (소수점 포함)
용도: 부동소수점(실수) 계산.
float voltage = 5.23;
9. double
크기: 4바이트 (32비트, 대부분 아두이노 보드에서 float와 동일)
값의 범위: float와 동일.
double pi = 3.14159;
헷갈렸던 byte, int 데이터 유형에 대해 좀더 비교해보자. 이 둘은 유사하지만 표현할 수 있는 값의 범위가 다르다.
byte와 int의 차이
특성 | byte |
int |
---|---|---|
크기 | 1바이트 (8비트) | 2바이트 (16비트) |
값의 범위 | 0 ~ 255 |
-32,768 ~ 32,767 |
부호 유무 | 부호 없음 | 부호 있음 |
메모리 사용 | 적음 | 많음 |
용도 | 작은 정수, 이진 데이터 | 큰 정수, 음수 포함 데이터 |
예제 값 | byte x = 200; |
int y = -1000; |
- 메모리가 제한된 아두이노 환경에서는 크기가 작은 byte를 사용하는 것이 더 효율적! (값이 넘치지 않는다면)
- 하지만 큰 값이 필요하거나 음수까지 다뤄야 한다면 int를 사용
// Cooling Fan Practice
// 1. 초록색 버튼 : 최대 속도의 50%로 Fan 회전. (제어량과 회전 속도는 비례한다고 가정)
// 2. 노란색 버튼 : 최대 속도로 Fan 회전.
// 3. 빨간색 버튼 : Fan 회전 정지.
// 4. 검정색 버튼 : Fan 목의 회전을 멈추고 정면(90도, 나를 바라보는 방향)을 바라본다.
// 5. 파란색 버튼 : Fan 목이 30~150도 사이에서 연속적으로 회전한다.(30도, 150도 도달 시 Fan 목 회전 방향 전환)
// 제약 : Servo 의 position 설정 시 servoRotate.read()의 return값을 변수 copy 없이즉시 전달인자로 활용해야 한다.
#include <Servo.h>
#define PIN_MOTOR_CTRL_0 3
#define PIN_MOTOR_CTRL_1 11
#define PIN_SWITCH_GREEN 8
#define PIN_SWITCH_YELLOW 7
#define PIN_SWITCH_RED 6
#define PIN_SWITCH_BLACK 5
#define PIN_SWITCH_BLUE 4
#define PIN_SERVO_CTRL 13
int prevSwitchGreen = HIGH;
int prevSwitchYellow = HIGH;
int prevSwitchRed = HIGH;
int prevSwitchBlack = HIGH;
int prevSwitchBlue = HIGH;
int motorValMax = 255;
byte motorCtrlValue0;
byte servoPosition = 90;
int rotateFlag = 0;
Servo servoRotate;
void setup() {
servoRotate.attach(PIN_SERVO_CTRL);
servoRotate.write(servoPosition);
pinMode(PIN_SWITCH_GREEN, INPUT);
pinMode(PIN_SWITCH_YELLOW, INPUT);
pinMode(PIN_SWITCH_RED, INPUT);
pinMode(PIN_SWITCH_BLACK, INPUT);
pinMode(PIN_SWITCH_BLUE, INPUT);
pinMode(PIN_MOTOR_CTRL_0, OUTPUT);
pinMode(PIN_MOTOR_CTRL_1, OUTPUT);
pinMode(PIN_SERVO_CTRL, OUTPUT);
analogWrite(PIN_MOTOR_CTRL_0, 0);
analogWrite(PIN_MOTOR_CTRL_1, 0);
Serial.begin(115200);
}
void loop() {
// Fan Control
int currentSwitchGreen = digitalRead(PIN_SWITCH_GREEN);
int currentSwitchYellow = digitalRead(PIN_SWITCH_YELLOW);
int currentSwitchRed = digitalRead(PIN_SWITCH_RED);
if ((prevSwitchGreen == LOW) && (currentSwitchGreen == HIGH)) {
// 1. 초록색 버튼 : 최대 속도의 50%로 Fan 회전. (제어량과 회전 속도는 비례한다고 가정)
analogWrite(PIN_MOTOR_CTRL_0, motorValMax/2);
Serial.println(motorValMax/2);
}
if ((prevSwitchYellow == LOW) && (currentSwitchYellow == HIGH)) {
// 2. 노란색 버튼 : 최대 속도로 Fan 회전.
analogWrite(PIN_MOTOR_CTRL_0, motorValMax);
Serial.println(motorValMax);
}
if ((prevSwitchRed == LOW) && (currentSwitchRed == HIGH)) {
// 3. 빨간색 버튼 : Fan 회전 정지.
motorCtrlValue0 = 0;
analogWrite(PIN_MOTOR_CTRL_0, motorCtrlValue0);
Serial.println(motorCtrlValue0);
}
prevSwitchGreen = currentSwitchGreen;
prevSwitchYellow = currentSwitchYellow;
prevSwitchRed = currentSwitchRed;
// Rotate Control
int currentSwitchBlack = digitalRead(PIN_SWITCH_BLACK);
int currentSwitchBlue = digitalRead(PIN_SWITCH_BLUE);
if ((prevSwitchBlack == LOW) && (currentSwitchBlack == HIGH)) {
// 4. 검정색 버튼 : Fan 목의 회전을 멈추고 정면(90도, 나를 바라보는 방향)을 바라본다.
rotateFlag = 0;
servoPosition = 90;
servoRotate.write(servoPosition);
Serial.println(servoPosition);
}
if ((prevSwitchBlue == LOW) && (currentSwitchBlue == HIGH)) {
// 5. 파란색 버튼 : Fan 목이 30~150도 사이에서 연속적으로 회전한다.(30도, 150도 도달 시 Fan 목 회전 방향 전환)
rotateFlag = 1;
}
if((servoRotate.read() < 30) || (servoRotate.read() > 150)){
rotateFlag = rotateFlag * (-1);
}
if(rotateFlag != 0){
servoRotate.write(servoRotate.read() + rotateFlag);
Serial.println(servoRotate.read() + rotateFlag);
}
prevSwitchBlack = currentSwitchBlack;
prevSwitchBlue = currentSwitchBlue;
delay(100);
}
위의 코드에서 rotateFlag의 자료형을 byte로 썼을 때 문제가 발생했다. byte는 8비트 정수 자료형으로 0~255의 부호 없는 정수를 나타내므로 음수 값을 표현할 수 있다.
rotateFlag = rotateFlag * (-1);
위의 코드에서 rotateFlag가 -1로 설정되는 경우가 있는데, byte는 음수를 표현하지 못하므로 255로 변환되면서 문제가 발생했다.(8비트 2의 보수 표현에서 -1 = 255)
따라서 적절한 자료형을 정의하는 것의 중요성을 깨달음 !