IT개발및프로그래밍/아두이노

아두이노 5 : PWM을 이용한 LED 제어 및 버튼 활용하기

devgodmj 2024. 10. 28. 19:20

1. PWM을 이용한 아날로그 출력의 이해

PWM(Pulse Width Modulation)은 디지털 신호로 아날로그 출력을 흉내 내기 위한 기법입니다. 아두이노는 디지털 핀에서 0과 1의 두 가지 상태만 출력할 수 있기 때문에, 평균 전압을 제어하는 방식으로 아날로그 출력을 시뮬레이션합니다.

  • 듀티 사이클(Duty Cycle): PWM에서 단위 시간 동안 높은 전압(HIGH) 신호가 유지되는 비율입니다. 듀티 사이클이 높을수록 평균 전압이 증가하여 LED의 밝기가 밝아지거나 모터의 속도가 빨라지는 효과를 얻을 수 있습니다.
  • 사용 가능한 핀: 아두이노의 3, 5, 6, 9, 10, 11번 핀에는 틸트(~) 표시가 있으며, 이를 통해 PWM을 지원하는 핀임을 알 수 있습니다.
  • PWM을 적용하는 방법: 
analogWrite(9, 128);  // 9번 핀에서 50% 듀티 사이클로 신호 출력, 약 2.5V에 해당

2. LED(Light Emitting Diode, 발광 다이오드)

LED는 전류가 흐르면 빛을 발하는 반도체 소자입니다. 기본적으로 LED는 전류가 한 방향으로 흐를 때 빛을 내는 다이오드로, 전구처럼 빛을 내지만 더 효율적이고 내구성이 높습니다. 다양한 색상의 빛을 낼 수 있어 조명, 디스플레이, 표시등 등 다양한 용도로 활용됩니다.

 

LED의 특징

  • 전류가 흐르면 빛이 나는 액추에이터: LED(Light Emitting Diode)는 전류가 흐를 때 빛을 발하는 장치로, 주로 시각적 신호를 제공합니다.
  • 다양한 색상: LED는 빨강, 파랑, 노랑, 녹색, 주황 등 다양한 색을 낼 수 있습니다. 프로젝트의 목적에 맞춰 원하는 색상의 LED를 선택할 수 있습니다.
  • LED 렌즈: 윗부분이 둥근 모자처럼 생긴 부분을 렌즈라고 부릅니다. 이 부분을 통해 빛이 확산되며, LED의 시각적 효과를 나타냅니다.
  • 5mm 렌즈: 아두이노와 함께 사용하는 LED는 주로 렌즈의 지름이 5mm인 것을 많이 사용합니다. 이 크기는 일반적으로 아두이노 프로젝트에서 사용하기에 적합하며, 다양한 색상과 밝기로 제공됩니다.
  • 극성(Polarity): LED는 플러스(+)와 마이너스(-)로 나뉘는 극성을 가지고 있습니다. 전류는 플러스에서 마이너스로 흐르기 때문에, 방향에 맞게 연결해야 LED가 정상 작동합니다.
  • 연결 주의사항: 플러스와 마이너스를 잘못 연결하면 LED가 손상될 수 있습니다. 따라서 연결 시 극성을 확인하는 것이 중요합니다.
  • 다리 길이:
    • 긴 쪽: 플러스(양극)
    • 짧은 쪽: 마이너스(음극)

LED 전류와 저항

  • 과전류 방지: LED는 과전류에 연결되면 손상될 수 있기 때문에, 적절한 전류가 흐르도록 조정해야 합니다.
  • 전류와 밝기 관계: 전류가 너무 적으면 LED의 빛이 약해지고, 너무 많으면 LED가 탈 수 있습니다.
  • 저항 사용: LED의 전류를 조절하기 위해 저항을 LED의 앞이나 뒤에 연결합니다.
  • 필요 전류와 전압: 일반적으로 5mm LED약 15mA의 전류2V의 강하전압을 필요로 합니다.
  • 저항 계산:
    • 옴의 법칙을 이용하여 필요한 저항 값을 계산할 수 있습니다: 전압=전류×저항

암페어(A)

  • 암페어(A)란 전류의 단위로, 전기가 흐르는 양을 나타냅니다.
  • 아두이노와 같은 전자 부품에서는 작은 전류를 많이 사용하기 때문에, 일반적으로 밀리암페어(mA) 단위를 주로 사용합니다.
  • 1 mA는 0.001 A이며, 전류가 많을수록 더 많은 전기가 흐르게 됩니다.

강하전압

  • 강하전압(Voltage Drop): 전자 부품에 전류가 흐르면서 전압이 내려가는 현상입니다. 각 부품이 필요로 하는 전압만큼 에너지를 사용하며, 그만큼의 전압이 감소합니다.
  • 예시: 아두이노 보드에서 5V 전원을 공급할 때, 강하전압이 2V인 LED를 연결하면 LED에서 2V가 소모되고, 나머지 3V가 회로에 남게 됩니다.
  • 강하전압 개념을 통해 LED와 같은 부품에 맞는 전압을 공급하고, 회로를 안전하게 구성할 수 있습니다.

옴의 법칙을 활용한 LED 회로 저항 값 계산

  • 옴의 법칙 활용:
    • LED 회로에서 아두이노의 전압(5V) 중 LED가 사용하는 전압(2V)을 제외한 3V가 저항에 걸립니다.
    • LED 에서 필요한 전류는 15mA(0.015A)이므로, 저항 값 R은 다음과 같이 계산됩니다.



  • 저항 선택:
    • 계산 결과 200Ω 저항이 필요합니다.
    • 안정적인 사용을 위해 계산된 값보다 약간 더 큰 저항을 사용하는 것도 좋은 방법입니다.

이렇게 200Ω 저항을 연결하면 LED가 안전하게 동작하면서 아두이노의 전원을 효율적으로 사용할 수 있습니다.

 


2. LED 깜빡이기

LED 깜빡이기는 아두이노에서 가장 기본적인 프로젝트 중 하나입니다. 이를 위해 pinMode와 digitalWrite 함수를 사용하여 LED를 제어합니다.

  • 준비물: LED, 220Ω 저항, 점퍼 와이어, 브레드보드, 아두이노 보드
  • 연결: 아두이노의 13번 핀에 LED의 긴 다리를 연결하고, 짧은 다리는 저항을 통해 아두이노의 그라운드(GND)에 연결합니다.

void setup() {
  pinMode(13, OUTPUT);  // 13번 핀을 출력 모드로 설정
}

void loop() {
  digitalWrite(13, HIGH); // LED 켜기
  delay(1000);            // 1초 대기
  digitalWrite(13, LOW);  // LED 끄기
  delay(1000);            // 1초 대기
}

 

pimMode()
- 디지털 핀의 모드를 출력 또는 입력으로 설정하는 함수
- 구조: pinMode(핀 번호, 모드)
- 핀 번호: 모드를 설정하고자 하는 핀 번호
- 모드: 출력인 경우 OUTPUT, 입력인 경우 INPUT을 입력
- 반환 값: 없음
pinMode(13, OUTPUT); // 13번 핀을 출력 모드로 설정
pinMode(13, INPUT); //13번 핀을 입력 모드로 설정

digitalWrite()
- 디지털 핀의 전압을 HIGH 또는 LOW로 설정하는 함수. digitalWrite 하수를 사용하려는 핀은 꼭 pinMode 함수를 이용해 출력 모드로 설정해야 함.
- 구조: digitalWrite(핀 번호, 전압)
- 핀 번호: 전압을 설정하고자 하는 핀 번호
- 전압: HIGH인 경우 HIGH, LOW인 경우 LOW를 입력
- 반환 값: 없음 
digitalWrite(13, HIGH); // 13번 핀의 전압을 HIGH로 설정
digitalWrite(13, LOW); // 13번 핀의 전압을 LOW로 설정

delay()
- 아두이노 보드를 일정 시간 멈추는 함수
- 구조: delay(멈출 시간)
- 멈출 시간: 단위는 밀리초로 1밀리초는 0.001초를 뜻함
- 반환 값: 없음
delay(1000); //아두이노 보드를 1초 멈춤

 


3. LED 밝기 조절하기

LED의 밝기 조절은 PWM 신호를 이용해 구현됩니다. analogWrite 함수를 통해 0에서 255 사이의 값을 입력하여 LED의 밝기를 조절할 수 있습니다.

  • 준비물: LED, 220Ω 저항, 점퍼 와이어, 아두이노 보드
  • 연결: 9번 핀에 LED를 연결하고 저항을 통해 GND에 연결합니다.

void setup() {
  pinMode(9, OUTPUT); // 9번 핀을 출력 모드로 설정
}

void loop() {
  for (int i = 0; i <= 255; i++) {    // LED 밝기 증가
    analogWrite(9, i);
    delay(10);
  }
  for (int i = 255; i >= 0; i--) {    // LED 밝기 감소
    analogWrite(9, i);
    delay(10);
  }
}
analogWrite()
- 아날로그 출력 핀의 전압을 설정하는 함수. 전압을 0V~5V 사이에 원하는 값으로 설정할 수 있음.
단, 꼭 틸트(~) 표시가 있는 핀을 사용해야 함.
- 구조: analogWrite(핀 번호, 전압)
- 핀 번호: 전압을 설정하고자 하는 핀 번호
- 전압: 0~255. 0V는 0, 5V는 255를 입력
analogWrite(9, 0); //9번 핀의 전압을 0V로 설정
analogWrite(9, 127); //9번 핀의 전압을 약 2.5V로 설정
analogWrite(9, 255); //9번 핀의 전압을 5V로 설정

4. 버튼 사용하기

버튼을 통해 디지털 신호를 입력받아 LED를 제어할 수 있습니다. 버튼을 누르지 않았을 때는 전류가 흐르지 않지만, 누르면 전류가 흐르며 디지털 신호로 전달됩니다.


택트 스위치 

  • 평소에는 전류가 흐르지 않다가 눌리면 전류가 흐르도록 하는 전자부품
  • 누르지 않았을 때는 4개의 다리가 서로 연결이 안되어 있음
  • 가운데 있는 부분을 누르면 4개의 다리가 모두 연결됨
  • 버튼을 이용해 디지털 신호 입력을 제어할 수 있음

 


  • 준비물: LED, 10kΩ 저항, 220Ω 저항, 버튼, 점퍼 와이어, 아두이노 보드
  • 연결: 버튼을 통해 신호를 입력받아 LED가 켜지도록 설정합니다.

void setup() {
  pinMode(8, INPUT);     // 버튼 핀을 입력 모드로 설정
  pinMode(13, OUTPUT);   // LED 핀을 출력 모드로 설정
}

void loop() {
  int buttonState = digitalRead(8);  // 버튼 상태 읽기

  if (buttonState == HIGH) {         // 버튼이 눌렸을 때
    digitalWrite(13, HIGH);          // LED 켜기
  } else {
    digitalWrite(13, LOW);           // LED 끄기
  }
}
digitalRead()
- 아날로그 입력 핀의 전압 상태를 읽는 함수. digitalRead 함수를 사용하려는 핀은 꼭 pinMode 함수를 입력 모드로 설정
- 구조: digitalRead(핀 번호)
- 핀 번호: 전압의 상태를 읽고자 하는 핀 번호
- 전압 상태: 전압이 LOW이면 LOW, HIGH이면 HIGH를 반환

5. 시리얼 통신 활용하기

시리얼 통신을 통해 아두이노의 상태나 센서 값을 모니터링할 수 있습니다. Serial.print와 Serial.println 함수를 통해 값을 출력할 수 있으며, 실수형 변수의 소수점 자릿수도 조정 가능합니다.

  • Serial : 아두이노가 사용하는 통신 프로토콜
  • 0번, 1번 핀은 시리얼 통신에 사용되므로 다른 용도의 사용을 지양 하는 것이 좋습니다.
  • 시리얼 통신을 통한 데이터 출력
    • Serial.begin(9600): 시리얼 통신을 정의하면서, 데이터 전송 속도 설정. 보통 9600보드(baud, 비트/초) 속도로 통신
    • Serial.println(data): 시리얼 통신 창으로 출력(줄바꿈 문자 포함)
      ex) Serial.println("Hello, world!")
float light = 1.23456;

void setup() {
  Serial.begin(9600);                // 시리얼 통신 시작
}

void loop() {
  Serial.print("Light: ");
  Serial.println(light, 2);           // 소수점 둘째 자리까지 표시
  delay(1000);                        // 1초 대기
}


//출력 결과
//Light: 1.23

 

  • 시리얼 통신을 통한 데이터 입력
    • Serial.available(): 버퍼에 저장된 데이터의 길이를 반환(바이트 단위)
    • Serial.read(): 버퍼에 있는 데이터 중 맨 앞의 1바이트를 읽는다.
    • Serial.readString(): 버퍼에 있는 모든 데이터를 문자열로 읽는다.

Serial.read() 예제

char content;
void setup(){
	Serial.begin(9600);
}
void loop(){
	if(Serial.available()){
    	content = Serial.read();
        Serial.print(content);
    }
}

//출력 예시
//h

 

Serial.readString() 예제

String content;
void setup(){
	Serial.begin(9600);
}
void loop(){
	if(Serial.available()){
    	content = Serial.readString();
        Serial.print(content);
    }
}

//출력 예시
//hello