1주차 LED제어하기

아두위키 : Arduwiki
ArduWiki (토론 | 기여)님의 2024년 12월 8일 (일) 20:20 판

1. 아두이노 디지털 핀

# 아두이노 Digital Pin


아두이노 디지털 입출력 pin은 보드의 digital pin 0 ~ 13을 사용할 수 있습니다. 0, 1번 pin은 컴퓨터와 아두이노가 통신할 때 주로 사용하기 때문에 우리는 2 ~ 13 핀을 사용하여 디지털 입출력을 사용할 수 있습니다.

디지털 입출력은 LOW(0V)와 HIGH(3.3V) 중 하나의 값을 사용할 수 있습니다.

2. 브레드보드

브레드보드의 구조를 살펴봅시다. 브레드보드는 위의 그림처럼 각각 가로, 세로 방향으로 연결되어 있습니다.

아두이노의 GND, 5V pin이 부족한 경우 브레드보드를 이용해 확장하여 사용할 수 있습니다.

3. LED

LED

LED(5mm) 일반적으로 2개의 전극단자로 구성되어 있습니다. 긴 단자가 [+], 짦은 단자가 [-]입니다.

3-1. LED 회로도

LED 회로도

3-2. 변수 선언과 초기화 방법

// 자료형 변수명;
// 자료형 변수명 = 값;
int led1;
int led2 = 9;

[int]은 2 byte 정수(-32,768 ~ 32,767)를 저장할 수 있는 자료형입니다.

[led1] 변수를 선언하였고 [led2] 변수는 선언하고 9라는 값으로 초기화하였습니다.

3-3. 초기 설정 함수 setup()

LED 제어를 위해 setup() 함수에 디지털 입출력 설정 함수를 사용해봅시다.

int led = 9;
void setup() {
    pinMode(led, OUTPUT);
}

pinMode() 함수는 led 핀 번호를 디지털 출력으로 사용하겠다는 의미입니다.

3-4. 반복 함수 loop()

void loop() {
    digitalWrite(led, HIGH);
    delay(1000);
    digitalWrite(led, LOW);
    delay(1000);
}

loop() 함수는 반복 함수입니다. 아두이노가 동작하는 동안 loop() 함수 내의 코드가 계속해서 반복됩니다.

digitalWrite() 함수는 디지털 출력 함수입니다. led 변수에 저장된 9번 digital pin의 상태를 HIGH 또는 LOW로 설정하는 함수입니다.

delay() 함수는 대기 함수입니다. 원하는 시간만큼 대기한 후 다음 코드를 진행할 수 있습니다. 매개변수로는 밀리초(ms) 단위의 시간을 넣습니다. 따라서 delay(1000)은 1초동안 대기할 수 있습니다.

3-5. 전체 코드

int led = 9;
void setup() {
  pinMode(led, OUTPUT);
}
void loop() {
  digitalWrite(led, HIGH);
  delay(1000);
  digitalWrite(led, LOW);
  delay(1000);
}

위의 코드를 실행해보면 1초 간격으로 LED가 켜지고 꺼지는 모습을 볼 수 있습니다.

4. LED 3개 제어하기

위에서 LED 1개를 제어하는 방법을 배웠습니다. 이번에는 LED 3개를 회로에 연결하고 코딩하여 동작시켜 봅시다.

4-1. 회로도

LED 3개 회로도

4-2. LED 3개 제어 코드

int led1 = 11;
int led2 = 12;
int led3 = 13;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

void loop() {
  digitalWrite(led1, HIGH);
  delay(1000);
  digitalWrite(led1, LOW);
  delay(1000);
  digitalWrite(led2, HIGH);
  delay(1000);
  digitalWrite(led2, LOW);
  delay(1000);
  digitalWrite(led3, HIGH);
  delay(1000);
  digitalWrite(led3, LOW);
  delay(1000);
}

이 코드를 실행하게 되면 led1, led2, led3이 차례대로 켜지고 꺼지는 모습을 볼 수 있습니다.

4-3. 반복문 for

앞의 코드를 잘 살펴보면 led1, led2, led3이 켜지고 꺼지는 코드가 반복된다는 것을 알 수 있습니다.

반복문을 배우고 위 코드를 수정하는 연습을 해봅시다!

for(선언  초기화; 조건; 증감부) {
    // code..
}

for문은 가장 처음 [선언 및 초기화]가 실행되고 [조건]을 확인합니다. 그 다음 for문 안의 [code]가 실행되고 [증감부]가 수행됩니다. 그 후 [조건] → [code] → [증감부]가 계속해서 반복되다가 [조건]이 거짓이 되면 반복문이 종료됩니다.

for(int i=1; i<=5; i+=1) {
    // code..
}
// i가 1, 2, 3, 4, 5를 반복함.

for(int i=5; i>=1; i-=1) {
    // code..
}
// i가 5, 4, 3, 2, 1를 반복함.

4-4. 코드 수정하기

int led1 = 11;
int led2 = 12;
int led3 = 13;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

void loop() {
  for(int led = 11; led <= 13; led+=1) {
    digitalWrite(led, HIGH);
    delay(1000);
    digitalWrite(led, LOW);
    delay(1000);
  }
}

위의 코드를 확인하면 [led]라는 변수가 반복문에서 선언되었고 11로 초기화되었습니다.

for 문을 해석해보면 led 변수가 11부터 시작해서 1씩 증가하며 13까지 반복되고 14가 되는 순간 종료됩니다.

그러므로 digital pin 11번 LED를 켜고 끄고, 12번 LED를 켜고 끄고, 13번 LED를 켜고 끄는 모습을 확인할 수 있습니다.

4-5. [실습] LED 3개를 차례대로 켜고 모든 LED가 켜진 후 차례대로 끄기

배운 반복문 for을 이용해 코드를 작성하고 실행시켜 봅시다.

만약 어렵다면 먼저 반복문 없이 코드를 작성해보고 수정하는 연습을 해봅시다!

int led1 = 11;
int led2 = 12;
int led3 = 13;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

void loop() {
    // code..
}

4-6. [실습] LED 3개를 동시에 켜고 끄기

배운 반복문 for을 이용해 코드를 작성하고 실행시켜 봅시다.

만약 어렵다면 먼저 반복문 없이 코드를 작성해보고 수정하는 연습을 해봅시다!

int led1 = 11;
int led2 = 12;
int led3 = 13;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

void loop() {
    // code..
}

5. LED 밝기 제어

아두이노의 아날로그 출력 함수에 대해서 알아봅시다.

아날로그 출력은 보드 위에 ~ 표시가 붙은 포트로 digital pin 3, 5, 6, 9, 10, 11 이렇게 총 6개의 포트를 사용할 수 있습니다.

아날로그 출력은 0~5V 값을 출력할 수 있고 analogWrite() 함수를 이용해 0~255의 값을 매개변수로 입력할 수 있습니다.

위에서 LED를 켜고 끄는 작업을 수행해보았습니다.

이제 아두이노 아날로그 출력을 이용해 LED의 밝기를 제어해봅시다.

5-1. 회로도

5-2. LED 밝기 제어 코드

analogWrite() 함수는 pinMode() 함수가 내장되어 있어 setup() 함수에서 따로 선언하지 않아도 됩니다.

int led = 9;

void setup() {

}

void loop() {
  analogWrite(led, 0);
  delay(1000);
  analogWrite(led, 100);
  delay(1000);
  analogWrite(led, 200);
  delay(1000);
  analogWrite(led, 255);
  delay(1000);
}

5-3. [실습] LED가 천천히 켜지고 천천히 꺼지는 동작 만들기

int led = 9;

void setup() {

}

void loop() {
    // code..
}

6. 가변 저항

가변 저항은 센서는 저항 값을 변화시킬 수 있는 소자입니다. 볼륨을 조절하거나 빛의 밝기를 조절하는데 사용될 수 있습니다.

양 끝(왼쪽, 오른쪽)의 핀에 5V, GND를 연결시킬 수 있습니다.

5V 방향으로 센서를 돌리면 저항의 값이 커지고 GND 방향으로 센서를 돌리면 저항의 값이 작아집니다.

이때, 저항의 값은 0~1023 사이의 값이 반환됩니다.

6-1. 회로 구성, 가변 저항 값 출력하기

먼저 회로 그림을 보고 가변 저항을 아두이노에 연결해봅시다.

아래 코드를 실행시켜 가변 저항의 값을 출력해봅시다.

가변 저항은 analog pin A0에 연결합니다.

가변 저항은 analogRead(pin) 함수를 사용합니다. 함수 매개변수로 연결한 pin 번호를 넣어주면 가변 저항의 값을 읽어올 수 있습니다.

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

void loop() {
  int val = analogRead(A0);
  Serial.println(val);
  delay(200);
}

6-2. [실습] 가변저항을 이용해 LED 밝기 제어하기

가변 저항의 값을 읽어와 LED 밝기를 제어해봅시다.

가변 저항을 GND 방향으로 돌릴수록 LED 밝기가 점점 어두워지고, 5V 방향으로 돌릴수록 LED가 밝아지는 코드를 작성해봅시다.

위에서 배운 코드를 사용해 보세요!


★★★ 생각해보기!

LED는 출력 값으로 0~255까지의 값을 사용합니다.

그런데 가변 저항의 값은 0~1023까지의 값을 반환하죠!

그럼 LED에 가변 저항의 값을 그냥 넣게되면 알맞은 값을 출력할 수 없습니다.

읽어온 가변 저항의 값을 변환해서 LED 출력 값에 알맞게 넣어봅시다.

나누기 연산자를 이용해보세요!


아두이노에서 나누기 연산자는 [ / ] 입니다.

int a = 10;
int b = 3;
int result = a / b;
// result에는 3이 저장된다.

int a = 20;
int b = 5;
int result = a / b;
// result에는 4가 저장된다.

int a = 100;
int b = 7;
int result = a / b;
// result에는 14가 저장된다.

// "int" 는 정수를 저장하는 자료형이므로 소수점이 저장되지 않습니다!!


int LED = pin number;

void setup() {
  
}

void loop() {
  int val = analogRead(A0);
  // code..
  delay(200);
}

7. 초음파센서

초음파를 사용하여 거리를 측정하는 센서 입니다.

환경에 따라 사용 가능 범위에 오차가 발생합니다.

[초음파 발생 -> 초음파 반사 -> 되돌아온 초음파 감지] 순서로 거리 값을 측정합니다.

7-1. 작동 방식

1. trig로 초음파를 발생시킨다.

2. 초음파 발생 종료 직후 echo에 HIGH 상태를 유지시킨다.

3. 발생시킨 초음파가 되돌아와서 감지될 경우 echo를 LOW로 변경한다.

4. pulseIn(echoPin, HIGH); 을 사용하여 초음파가 갔다가 돌아오는 시간을 얻어낸다.

5. 이후 식에 대입하여 거리를 측정한다.

7-2. 거리 측정 방법

초음파 속도 340m/s
초음파 왕복 시간 x
물체와의 거리 y

7-2. 회로 구성

GND GND
VCC 5V
Trig D3
Echo D4

7-3. 거리 측정하여 출력하기

초음파 센서로 앞의 장애물과의 거리를 측정하여 시리얼 모니터로 출력합니다.

시리얼 모니터란 아두이노에서 보내주는 데이터를 아두이노 IDE에 포함되어 있는 창을 이용해 출력해 확인해볼 수 있는 것을 말합니다.

아두이노에 연결된 센서를 이용해 측정된 값을 출력해서 확인해볼 수 있습니다.


//영상넣기

int trigPin = 3;
int echoPin = 4;

int time;

void setup()
{
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    
    Serial.begin(9600);
}

void loop()
{
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    time = pulseIn(echoPin, HIGH);

    int distance_cm = time * 17 / 1000;

    Serial.print("거리(cm) = ");
    Serial.println(distance_cm);
      
    delay(100);
}

시리얼 모니터를 사용하기 위해서는 setup() 함수에 Serial.begin() 함수를 이용해 보드 레이트 기본값을 설정하고 시리얼 모니터를 사용하겠다고 코드를 작성합니다.

Serial.print() 함수는 괄호 안의 문자를 출력하는 함수이며 Serial.println() 함수는 괄호 안의 문자를 출력하고 마지막에 줄바꿈을 해주는 함수입니다.

7-4. 비교, 논리 연산자와 조건문 if

비교 연산자(<, <=, >, >=, ==, !=)는 두 개의 값을 비교하는 연산자입니다. 아두이노에서 결과는 참(1) 또는 거짓(0)으로 나타납니다.

< 왼쪽 값이 오른쪽 값보다 작다. A < B
<= 왼쪽 값이 오른쪽 값보다 작거나 같다. A <= B
> 왼쪽 값이 오른쪽 값보다 크다. A > B
>= 왼쪽 값이 오른쪽 값보다 크거나 같다. A >= B
== 왼쪽 값과 오른쪽 값이 동일하다. A == B
!= 왼쪽 값과 오른쪽 값이 동일하지 않다. A!=B


논리 연산자(&&, ||, !)은 참과 거짓을 연산하기 위해 사용됩니다.

and
참 && 참 1
참 && 거짓 0
거짓 && 참 0
거짓 && 거짓 0
or
참 || 참 1
참 || 거짓 1
거짓 || 참 1
거짓 || 거짓 0
not
!참 0
!거짓 1

조건문 if는 조건이 "참"인 경우 작성한 코드가 수행되고 "거짓"인 경우 수행되지 않습니다.

if(조건) {
    // code..
}

7-5. [실습] 거리를 측정하여 LED 제어하기

초음파 센서를 이용해 앞의 장애물과의 거리를 측정합니다. 장애물과의 거리가 15cm 이하라면 LED를 켜고 아니라면 LED를 끄는 코드를 작성하세요.

//영상넣기

7-6. [실습] 거리를 측정하여 3개의 LED 제어하기

초음파 센서를 이용해 앞의 장애물과의 거리를 측정합니다. 아래 표를 보고 LED를 제어하세요. ※ 논리연산자 &&를 사용해보세요!

거리 LED
3cm 이상 7cm 이하 LED 3개 켜기
8cm 이상 12cm 이하 LED 2개 켜기
13cm 이상 16cm 이하 LED 1개 켜기
17cm 이상 모든 LED 끄기


8. 실습 코드 참고하기

4-5. [실습] LED 3개를 차례대로 켜고 모든 LED가 켜진 후 차례대로 끄기(반복문 미사용)

int led1 = 11;
int led2 = 12;
int led3 = 13;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

void loop() {
    digitalWrite(led1, HIGH);
    delay(1000);
    digitalWrite(led2, HIGH);
    delay(1000);
    digitalWrite(led3, HIGH);
    delay(1000);
    digitalWrite(led1, LOW);
    delay(1000);
    digitalWrite(led2, LOW);
    delay(1000);
    digitalWrite(led3, LOW);
    delay(1000);
}

4-5. [실습] LED 3개를 차례대로 켜고 모든 LED가 켜진 후 차례대로 끄기(반복문 사용)

int led1 = 11;
int led2 = 12;
int led3 = 13;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

void loop() {
  for(int led=11; led<=13; led+=1) {
    digitalWrite(led, HIGH);
    delay(1000);
  }
  for(int led=11; led<=13; led+=1) {
    digitalWrite(led, LOW);
    delay(1000);
  }
}

4-6. [실습] LED 3개를 동시에 켜고 끄기(반복문 미사용)

int led1 = 11;
int led2 = 12;
int led3 = 13;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

void loop() {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    delay(1000);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    delay(1000);
}

4-6. [실습] LED 3개를 동시에 켜고 끄기(반복문 사용)

int led1 = 11;
int led2 = 12;
int led3 = 13;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

void loop() {
  for(int led=11; led<=13; led+=1) {
    digitalWrite(led, HIGH);
  }
  delay(1000);
  for(int led=11; led<=13; led+=1) {
    digitalWrite(led, LOW);
  }
  delay(1000);
}

5-3. [실습] LED가 천천히 켜지고 천천히 꺼지는 동작 만들기

int led = 9;

void setup() {

}

void loop() {
  for(int i=0; i<=255; i+=5) {
    analogWrite(led, i);
    delay(50);
  }
  for(int i=255; i>=0; i-=5) {
    analogWrite(led, i);
    delay(50);
  }
}

6-2. [실습] 가변저항을 이용해 LED 밝기 제어하기

int LED = pin number;

void setup() {
  
}

void loop() {
  int val = analogRead(A0);
  analogWrite(LED, val/4);
  delay(200);
}

7-5. [실습] 거리를 측정하여 LED 제어하기

int trigPin = 3;
int echoPin = 4;

int led = 2;

int time;

void setup()
{
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    pinMode(led, OUTPUT);
    
    Serial.begin(9600);
}

void loop()
{
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    time = pulseIn(echoPin, HIGH);

    int distance_cm = time * 17 / 1000;

    // distance_cm을 3 이상 15 이하로 설정한 이유는
    // 음수가 나오는 경우를 거르기 위한 코드입니다!
    if(distance_cm>=3 && distance_cm<=15) {
      digitalWrite(led, HIGH);
    }
    else {
      digitalWrite(led, LOW);
    }
    delay(100);
}