IVS/Arduino

[Arduino] 자료형, byte와 int의 차이

코곰_ 2025. 1. 15. 12:09

아두이노에서 자료형은 변수의 크기, 메모리 사용량, 저장할 수 있는 값의 범위를 결정한다. 기본적으로 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)
따라서 적절한 자료형을 정의하는 것의 중요성을 깨달음 !