Arduino, 초음파 센서

이도현·2023년 8월 10일
0

아두이노 학습

목록 보기
29/34
post-custom-banner

1. 초음파 센서

  • 초음파를 이용하여 벽이나 사물의 거리를 측정하는 센서

2. 초음파 센서 동작 원리

  • Trig에 HIGH 전압 인가시 초음파 발사
  • Echo에서 초음파 수신(처음에는 LOW)
  • 시간 차이를 측정하여 거리 계산

3. 초음파 센서 거리 측정

#include <MiniCom.h>

MiniCom com;
int echoPin = 5;
int triggerPin = 6;

void check() {
	// trigger 핀으로 10us의 펄스를 발생
	digitalWrite(triggerPin, HIGH);
	delayMicroseconds(10);
	digitalWrite(triggerPin, LOW);

	// echo 핀 입력으로부터 거리르 cm 단위로 계산
	int distance = pulseIn(echoPin, HIGH) / 58;
	com.print(1, "Dist.(cm)=", distance);
}

void setup() {
	com.init();
	com.setInterval(1000, check);
	com.print(0, "[[Distance]]");
	pinMode(echoPin, INPUT);
	pinMode(triggerPin, OUTPUT);
}

void loop() {
	com.run();
}

4. Ultra class

//Ultra.h
#pragma once

#include <Arduino.h>

class Ultra{
protected:
	int echo;
	int trig;

public:
	Ultra(int echo, int trig);
	int getDistance();
};
//Ultra.cpp
#include "Ultra.h"

Ultra::Ultra(int echo, int trig) : echo(echo), trig(trig){
	pinMode(echo, INPUT);
	pinMode(trig, OUTPUT);
}

int Ultra::getDistance(){
	digitalWrite(trig, HIGH);
	delayMicroseconds(10);
	digitalWrite(trig,LOW);

	// echo 핀 입력으로 부터 거리를 cm 단위로 계산
	// y = 0.034*x/2 = 0.017 *x cm --> 실수 연산
	int distance = pulseIn(echo, HIGH) / 58;
	return distance;
}
//app.ino
#include <MiniCom.h>
#include <Ultra.h>

MiniCom com;
Ultra ultra(5, 6);

void check(){
	int distance = ultra.getDistance();
	com.print(1,"Dist.(cm)=", distance);
}

void setup(){
	com.init();
	com.setInterval(1000, check);
	com.print(0, "[[Distance]]");
}

void loop(){
	com.run();
}

5. Buzzer.cpp 자동차 후방 감지기 만들기

// Buzzer.h
#pragma once
#include <Arduino.h>
class Buzzer {
protected:
	int pin; // 핀번호
	int state; // 소리 출력 상태
	int on_time; // 소리를 내야하는 시간 간격
	int off_time; // 꺼져야 할 시간 간격
	unsigned long old_time; // 이전 상태 변화 시간
	bool bstop;

public:
	Buzzer(int pin);
	void beep();
	void stop() { 
		bstop = true; 
		digitalWrite(pin, LOW);
	}
	void setOffTime(int off_time);
	void run();
};
#include "Buzzer.h"

Buzzer::Buzzer(int pin): pin(pin){
	state = LOW;
	off_time = 0;
	on_time = 100; // 100ms
	pinMode(pin, OUTPUT);
	bstop = true;
}

void Buzzer::beep(){
	digitalWrite(pin,HIGH);
	delay(50);
	digitalWrite(pin, LOW);
}

void Buzzer::setOffTime(int off_time){
	this -> off_time = off_time;
	bstop = false;
}

void Buzzer::run() {
	unsigned long cur, diff;
	if(bstop) return;

	cur = millis(); // 현재 시간
	diff = cur - old_time; // 이전 상태변화 시간에서의 시간차

	if(state) { // 소리를 출력하고 있는 상태
		if(diff > on_time) { // 소리 출력 시간이 끝났음
			digitalWrite(pin, LOW); // 소리 끄기
			state = LOW; // 꺼짐 상태
			old_time = cur; // 상태 변이 시간 갱신
		}
	} else { // 소리가 껴져 있는 상태
			if(diff > off_time ) { // 소리 꺼진 시간이 끝났음
				digitalWrite(pin, HIGH); // 소리 켜기
				state = HIGH; // 켜짐 상태
				old_time = cur; // 상태 변이 시간 갱신
			}
	}
}
//app.ino
#include <MiniCom.h>
#include <Ultra.h>
#include <Buzzer.h>

MiniCom com;
Ultra ultra(5, 6);
Buzzer buzzer(7);

void check() {
	int distance = ultra.getDistance();
	com.print(1, "Dist.(cm)=", distance);

	if(distance < 50 && distance >= 30) { 
	buzzer.setOffTime(1000);
	} else if(distance < 30 && distance >= 20) { 
	buzzer.setOffTime(500);
	} else if(distance < 20 && distance >= 10) { 
	buzzer.setOffTime(200);
	} else if(distance < 10) { 
	buzzer.setOffTime(100);
	} else {
	buzzer.stop();
	}
}
void setup() {
	com.init();
	com.setInterval(100, check);
	com.print(0, "[[Distance]]");
	buzzer.stop();
}

void loop() {
	com.run();
	buzzer.run();
}

6. 물체 감지기

// utlra.h 수정
#pragma once

#include <Arduino.h>

typedef void (*ultra_callback_t)(); 
class Ultra {
protected:
	int echo;
	int trig;
	int threshold; // 기준 거리
	ultra_callback_t on_f; // 기준 거리 내로 진입한 경우 호출 할 함수
	ultra_callback_t off_f; // 기준 거리를 벗어난 경우 호출 할 함수
	int state; // 벗어난 경우 false, 진입한 경우 true

public:
	Ultra(int echo, int trig);
	int getDistance();
	void setThreshold(int t, ultra_callback_t on_f, ultra_callback_t off_f);
	int run();
};
//ultra.cpp 수정
#include "Ultra.h"

Ultra::Ultra(int echo, int trig) : echo(echo), trig(trig) {
	pinMode(echo, INPUT);
	pinMode(trig, OUTPUT);
	on_f = NULL;
	off_f = NULL;
	state = false;
}

:

void Ultra::setThreshold(int t, ultra_callback_t on_f, ultra_callback_t off_f) 
{
threshold = t;
this->on_f = on_f;
this->off_f = off_f;
}

int Ultra::run() {
	int distance = getDistance();
	if(!state && distance <= threshold) { // 기준 거리내로 진입한 경우
		state = true;
		if(on_f != NULL) {
			on_f();
		}
	// 기준 거리를 벗어난 경우
	} else if(state && (distance == 0 || distance > (threshold+2))){
		state = false;
		if(off_f != NULL) {
			off_f();
		}
	} 

	if(distance == 0 || distance > threshold ) {
	return 0;
	}

	return distance;
}
//app.in
#include <MiniCom.h>
#include <Ultra.h>

MiniCom com;
Ultra ultra(5, 6);

void notice_in() {
com.print(1, "NOTICE IN");
}

void notice_out() {
com.print(1, "NOTICE OUT"); 
}

void setup() {
	com.init();
	com.print(0, "[[Distance]]");
	ultra.setThreshold(40, notice_in, notice_out);
}

void loop() {
	com.run();
	ultra.run();
}
profile
좋은 지식 나누어요
post-custom-banner

0개의 댓글