코드 검색

레슨 17/31: 아두이노에서 지연을 중단하는 방법 및 조도 의존 저항 LDR | Robojax

레슨 17/31: 아두이노에서 지연을 중단하는 방법 및 조도 의존 저항 LDR | Robojax

이 가이드에서는 두 가지 필수적인 Arduino 개념인 인터럽트와 광의존 저항기(LDR)에 대해 알아보겠습니다. 코드에서 지연을 중단하여 Arduino가 버튼 누름에 즉시 반응하도록 하는 방법을 배우고, 밤에 자동으로 부저나 조명을 켤 수 있는 빛 감지 회로를 구축해 보겠습니다. 이 프로젝트는 기본적인 LED 깜빡임 스케치를 넘어 반응형 실제 자동화 프로젝트를 만들고자 하는 모든 사람에게 적합합니다. 이러한 기술을 활용하여 복도의 스마트 야간등, 문이 열릴 때 울리는 간단한 보안 경보기, 해질녘에 작동하는 태양광 정원등, 또는 해가 지면 자동으로 닫히는 자동 커튼을 만들 수 있습니다. 이 강의는 SunFounder 3-in-1 Arduino 키트를 기반으로 하지만, 개념은 모든 표준 Arduino 보드에 적용됩니다.

LDR_12708_orig
LDR Illustration and symbol

하드웨어 및 부품

이 프로젝트를 따라 하려면 다음 부품이 필요합니다. 표준 Arduino Uno 또는 Nano가 이 빌드에 적합합니다.

  • Arduino Uno 또는 Nano
  • 광의존 저항기(LDR), 예: Kweeds KM601
  • 10k 옴 저항기
  • 푸시 버튼
  • 부저
  • 브레드보드 및 점퍼 와이어

Arduino 인터럽트 이해하기

표준 Arduino 스케치에서 loop() 함수는 연속적으로 실행되며 작업을 줄 단위로 처리합니다. delay()를 사용하면 Arduino는 해당 시간 동안 다른 작업을 중단합니다. 다른 작업이 실행되는 동안 버튼 누름과 같은 중요한 이벤트에 응답해야 하는 경우 이는 문제가 됩니다. 예를 들어 LED를 깜빡이기 위해 1초 지연이 있으면 버튼 누름이 최대 1초 동안 등록되지 않아 반응이 없는 것처럼 느껴질 수 있습니다(비디오 08:13 참조).

Arduino 인터럽트는 이 문제를 해결합니다. 인터럽트는 특정 핀이 메인 프로그램을 "중단"하고, 현재 수행 중인 작업을 일시 중지하며, 인터럽트 서비스 루틴(ISR)이라는 특수 함수를 실행할 수 있게 하는 하드웨어 기능입니다. 이를 통해 Arduino는 다른 작업이 무엇이든 관계없이 우선순위가 높은 이벤트에 즉시 응답할 수 있습니다. 모든 핀이 인터럽트를 지원하는 것은 아니라는 점을 기억하는 것이 중요합니다. Arduino Uno 및 Nano에서는 핀 2와 3만 이 목적으로 사용할 수 있습니다(비디오 02:37 참조). Mega와 같은 다른 보드에는 더 많은 옵션이 있지만, 이 프로젝트에서는 핀 2를 사용하겠습니다.

인터럽트는 핀의 다양한 상태 변화에 의해 트리거될 수 있습니다: LOW, CHANGE, RISING, FALLING. CHANGE 모드는 핀 상태가 HIGH에서 LOW로 또는 LOW에서 HIGH로 변경될 때마다 인터럽트를 트리거하며, 이는 버튼 누름 토글에 적합합니다.

배선 가이드

buzzer_push_button_schematic
lcd1602_I2C_wiring_sunfounder

이 강의에서는 두 개의 회로를 구축할 것입니다. 첫 번째는 버튼과 부저로 인터럽트를 시연하고, 두 번째는 LDR을 사용하여 빛의 양을 감지합니다. 인터럽트 회로부터 시작하겠습니다.

회로 1: 인터럽트 데모용 버튼 및 부저

이 회로는 간단합니다. 버튼은 인터럽트 핀인 핀 2에 연결됩니다. 10k 옴 풀다운 저항은 버튼을 누르지 않았을 때 핀이 LOW를 읽고, 눌렀을 때 HIGH를 읽도록 보장합니다. 부저는 핀 8에 연결됩니다.

인터럽트 데모를 위해 구성 요소를 다음과 같이 연결합니다:

  • 푸시 버튼: 한쪽 다리를 5V에, 다른 쪽 다리를 디지털 핀 2에 연결합니다. 핀 2에서 GND로 10k 옴 저항을 연결합니다.
  • 부저: 음극 리드를 GND에, 양극 리드를 디지털 핀 8에 연결합니다.

회로 2: 빛 감지용 LDR 및 부저

LDR 회로에서는 전압 분배기 구성을 사용합니다. LDR의 저항은 빛에 따라 변하며, 이는 아날로그 핀의 전압을 변경합니다. 어두울 때 LDR은 높은 저항(약 10k 옴)을 가지며, 밝을 때 저항은 크게 감소합니다(비디오 16:25 참조). 이 저항 변화가 우리가 측정하는 것입니다.

Arduino는 저항이 아닌 전압만 읽을 수 있으므로 전압 분배기가 필요합니다. LDR을 고정 10k 옴 저항과 직렬로 배치하면 두 저항 사이의 지점 전압이 LDR의 저항에 비례하여 변경됩니다. 이 전압은 Arduino의 아날로그-디지털 변환기(ADC)에 의해 읽힙니다.

LDR 데모를 위해 구성 요소를 다음과 같이 연결합니다:

  • LDR: 한쪽 다리를 5V에, 다른 쪽 다리를 아날로그 핀 A0에 연결합니다.
  • 10k 옴 저항: A0에 연결된 LDR 다리에서 GND로 연결합니다. 이렇게 하면 전압 분배기가 생성됩니다.
  • 부저: 음극 리드를 GND에, 양극 리드를 디지털 핀 8에 연결합니다.

참고: 정확한 핀 할당은 코드에 정의되어 있으며 설정에 맞게 변경할 수 있습니다.

코드 설명

프로젝트 동작을 제어하는 제공된 코드의 사용자 구성 가능 부분에 초점을 맞추겠습니다. 전체 프로그램은 기사 아래에서 다운로드할 수 있습니다.

코드는 쉽게 수정할 수 있도록 설계되었습니다. 스케치 상단에서 조정할 수 있는 주요 변수를 찾을 수 있습니다.

const byte buzzerPin = 8;
const byte interruptPin = 2;
volatile byte state = LOW;
int count=0;

여기서 buzzerPin은 8번 핀으로 설정되며, 이곳에 부저를 연결합니다. interruptPin은 2번 핀으로 설정되며, 버튼 누름을 감지할 핀입니다. state 변수는 부저의 현재 상태(HIGH 또는 LOW)를 저장하는 volatile 바이트입니다. 이 변수는 인터럽트 서비스 루틴(ISR) 내부에서 수정되므로 volatile로 표시되며, 이 키워드는 Arduino가 항상 최신 값을 읽도록 보장합니다. count 변수는 메인 루프에서 증가하는 간단한 카운터로, 인터럽트가 활성화된 동안 루프가 계속 실행되고 있음을 보여줍니다.

setup() 함수에서 부저 핀은 OUTPUT으로 설정되고, 인터럽트 핀은 INPUT으로 설정됩니다. 핵심 줄은 attachInterrupt()로, 여기서 인터럽트를 구성합니다. 이 함수는 Arduino에 어떤 핀을 감시할지, 인터럽트가 발생했을 때 어떤 함수를 호출할지, 그리고 어떤 트리거 조건을 사용할지 알려줍니다.

attachInterrupt(digitalPinToInterrupt(interruptPin), noisy, CHANGE);

이 줄은 지정된 핀에 인터럽트를 연결합니다. digitalPinToInterrupt() 함수는 핀 번호를 올바른 인터럽트 번호로 변환합니다. noisy는 인터럽트가 트리거될 때 호출될 함수의 이름입니다. 마지막으로 CHANGE는 모드로, 핀의 상태 변화가 있을 때마다 인터럽트를 트리거합니다. 필요에 따라 이를 RISING, FALLING 또는 LOW로 변경할 수 있습니다.

noisy() 함수는 ISR입니다. 이는 부저의 상태를 반전시키는 간단한 토글 함수입니다. 버튼을 누르면 인터럽트가 이 함수를 트리거하고, state 변수를 반전시켜 부저 핀에 씁니다. 이를 통해 메인 루프가 카운팅과 지연으로 바쁘더라도 버튼을 누를 때마다 부저를 켜고 끌 수 있습니다.

프로젝트의 동작을 낮 대신 밤에 부저를 활성화하도록 변경하려면 메인 루프의 조건부 로직을 수정하여 HIGH 및 LOW 상태에 대한 digitalWrite() 명령을 교체하면 됩니다.

실시간 프로젝트 및 데모

데모에서는 두 가지 주요 실험을 볼 수 있습니다. 첫째, 인터럽트 코드 없이 인터럽트 회로가 실행되는 모습으로, 루프의 지연으로 인해 버튼 반응이 느려집니다. 이는 인터럽트가 해결하는 문제를 강조합니다.

그런 다음 인터럽트 코드가 로드된 상태에서 시리얼 모니터는 카운터가 매초 증가하는 것을 보여줍니다. 버튼을 누르면 메인 루프의 지연과 관계없이 부저가 즉시 켜지거나 꺼집니다. 이는 인터럽트가 대기 시간을 우회하고 즉시 작업을 실행함을 증명합니다(비디오 14:07 참조).

LDR 부분에서는 시리얼 모니터가 원시 아날로그 값을 출력합니다. 밝은 빛에서는 값이 높고(약 960), 센서를 가리면 값이 크게 떨어지는(약 400 이하) 것을 볼 수 있습니다. 이는 LDR의 저항이 빛의 강도에 따라 어떻게 변하는지 보여줍니다. 코드는 임계값을 사용하여 "낮" 또는 "밤"을 판단하고 그에 따라 부저를 제어합니다. 센서를 가려 밤을 시뮬레이션하면 부저를 트리거할 수 있고, 빛에 노출하면 끌 수 있습니다.

챕터

  • [00:00] Arduino 인터럽트 및 LDR 소개
  • [01:43] Arduino 코드에서 지연의 문제
  • [03:37] 인터럽트 핀 및 모드 이해
  • [04:20] 버튼 및 부저 회로 배선
  • [06:22] 지연 데모 코드 설명
  • [07:48] 지연 문제 데모
  • [09:26] 인터럽트 구현 및 코딩
  • [11:50] 인터럽트 함수 작동 방식
  • [14:26] 광의존 저항기(LDR) 소개
  • [15:44] 멀티미터로 LDR 저항 측정
  • [17:22] LDR 및 부저 회로 배선
  • [19:55] LDR 값 읽기 코드
  • [20:49] LDR 값 변화 데모
  • [22:08] 낮 및 밤 임계값 설정
  • [23:40] LDR로 부저 제어 코드
  • [25:21] 자동 야간 조명 데모

이미지

An LDR
An LDR
LDR Illustration and symbol
LDR Illustration and symbol
lcd1602_I2C_wiring_sunfounder
lcd1602_I2C_wiring_sunfounder
buzzer_push_button_schematic
buzzer_push_button_schematic
buzzer_push_button_wiring
buzzer_push_button_wiring
ldr
ldr
LDR_12708_orig
LDR_12708_orig
913-Lesson 17/31: interrupt a delay in Arduino and Light Dependent Resistor LDR
언어: C++
/*
Lesson 20/31: interrupt a delay in Arduino and Light Dependent Resistor LDR
Get this code and watch video Download and resource page https://robojax.com/RJT600
YouTube video https://www.youtube.com/watch?v=N_L11m1v_yk
 
  
 * This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.* 
 * This code has been download from Robojax.com
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
const byte buzzerPin = 8;
const byte interruptPin = 2;
volatile byte state = LOW;
int count=0;

void setup() {
  pinMode(buzzerPin, OUTPUT);
  pinMode(interruptPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin), noisy, CHANGE);
  Serial.begin(9600);
  digitalWrite(buzzerPin, state);
}

void loop() {
  count++;
  Serial.println(count);
  delay(1000);
}

void noisy() {
  state = !state;
  digitalWrite(buzzerPin, state);
}

자원 및 참고자료

파일📁

아두이노 라이브러리 (zip)