비트연산자를 활용한 LED제어

star-planet·2024년 8월 30일
0
post-thumbnail

국비과정을 진행하며 스마트시티라는 주제로 프로젝트를 진행하게 되었다.

프로젝트의 일환으로 시프트 레지스터에 연결된 LED 4개를 GUI로 제어할 수 있도록 구현해야 했으며, 동시에 여러 개의 LED가 켜져 있을 수 있어야 했다.

발생한 문제

초기 구현에서는 GUI를 통해 LED 하나를 켜고 다른 LED를 켜려고 하면, 이전에 켜져 있던 LED가 꺼지고 새 LED만 켜지는 상황이 발생했다.
이는 각 LED의 상태가 개별적으로 관리되지 않아서 생긴 문제였다.

구현 과정

우선 초기 LED 상태는 OFF로 설정한다.

byte currentLedStatus = B11110000;

각 LED를 ON/OFF하기 위한 상태를 미리 정의한다.

byte LED_ON[] = {
  B11111000,
  B11110100,
  B11110010,
  B11110001
};

byte LED_OFF[] = {
  B11110111,
  B11111011,
  B11111101,
  B11111110
};

현재 LED ON/OFF 상태변수를 선언한다.

bool light[] = {
  false,
  false,
  false,
  false
};

setup 함수에서는 LED초기 상태를 업데이트해주고,

void setup() 
{
  Serial.begin(9600);
  updateShiftRegister(currentLedStatus);
}

loop 함수에서는 GUI의 입력에 따라 각 LED의 상태를 업데이트하는 로직을 구현한다.

void loop() 
{
  if (Serial.available() > 0) {
    char receivedChar = Serial.read();  // Read from GUI data
    if (receivedChar == '1') {
      if (light[0] == false)
      {
        updateShiftRegister(currentLedStatus | LED_ON[0]); // LED1 On
        currentLedStatus = currentLedStatus | LED_ON[0];
        light[0] = true;
      }
      else
      {
        updateShiftRegister(currentLedStatus & LED_OFF[0]); // LED1 Off
        currentLedStatus = currentLedStatus & LED_OFF[0];
        light[0] = false;
      }
    }
    else if (receivedChar == '2') {
      if (light[1] == false)
      {
        updateShiftRegister(currentLedStatus | LED_ON[1]); // LED2 On
        currentLedStatus = currentLedStatus | LED_ON[1];
        light[1] = true;
      }
      else
      {
        updateShiftRegister(currentLedStatus & LED_OFF[1]); // LED2 Off
        currentLedStatus = currentLedStatus & LED_OFF[1];
        light[1] = false;
      }
    }
    else if (receivedChar == '3') {
      if (light[2] == false)
      {
        updateShiftRegister(currentLedStatus | LED_ON[2]); // LED3 On
        currentLedStatus = currentLedStatus | LED_ON[2];
        light[2] = true;
      }
      else
      {
        updateShiftRegister(currentLedStatus & LED_OFF[2]); // LED3 Off
        currentLedStatus = currentLedStatus & LED_OFF[2];
        light[2] = false;
      }
    }
    else if (receivedChar == '4') {
      if (light[3] == false)
      {
        updateShiftRegister(currentLedStatus | LED_ON[3]); // LED4 On
        currentLedStatus = currentLedStatus | LED_ON[3];
        light[3] = true;
      }
      else
      {
        updateShiftRegister(currentLedStatus & LED_OFF[3]); // LED4 Off
        currentLedStatus = currentLedStatus & LED_OFF[3];
        light[3] = false;
      }
    }
  }
}

동작 방식

LED를 ON하려면 currentLedStatusLED_ON[index]을 OR 연산을 해준다.
이 때, OR 연산은 한쪽만 1이어도 결괏값이 1이 되는 특징을 활용해 LED가 켜지도록 한다.

currentLedStatus = b11110001 // 4번 LED ON
LED_ON[0]        = b11111000
currnetLEDStatus = currnetLEDStatus | LED_ON[0]

---

currentLedStatus = b11111001 // OR 연산 후 1, 4번 LED ON

마찬가지로, LED를 OFF하려면 currentLedStatusLED_OFF[index]를 AND 연산한다.
AND 연산은 한쪽이 0이면 결괏값이 0이 되는 특징을 활용해 LED가 꺼지도록 한다.

currentLedStatus = b11111001 // 1, 4번 LED ON
LED_OFF[0]       = b11110111
currnetLEDStatus = currnetLEDStatus & LED_OFF[0]

---

currentLedStatus = b11110001 // AND 연산 후 4번 LED ON

필자는 이러한 방법으로 LED가 여러 개가 켜져 있거나 꺼져있게끔 만들었다.

0개의 댓글

관련 채용 정보