BASIC4MCU | 질문게시판 | 아두이노 응답이 너무 느립니다.
페이지 정보
작성자 헤헿 작성일2020-10-06 11:50 조회16,576회 댓글7건첨부파일
본문
아두이노 메가를 사용해서 만들고 있습니다
시리얼 모니터에서 입력을 1 2 3을 넣는다고 하면 1이 출력되고 한참 뒤에 2 또 한참뒤에 3 이 출력되고 있습니다.
이게 함수들 중간 중간에 사용한 delay때문인지 아니면 코딩 중 문제가 발생한건지 궁금합니다.
#include <Servo.h>
int red1 = 2; // 차량 신호등 핀 설정
int red2 = 4; // 보행자 신호등 핀 설정
int green1 = 7; // 차량 신호등 핀 설정
int green2 = 8; // 보행자 신호등 핀 설정
int yellow = 9; // 신호등 핀 설정
int music=10; // 부저 핀 설정
int Sigpin = 11 ; // start 함수 입력 핀 설정
int trigPin = 12; // 동작감지 아웃풋 핀 설정
int echoPin = 13; // 동작감지 인풋 핀 설정
int warning=14; // led 동작 핀 설정
void setup ()
{
pinMode(Sigpin , INPUT); //속도 측정 핀
pinMode(red1,OUTPUT); // 차량 신호등 핀
pinMode(red2,OUTPUT); // 보행자 신호등 핀
pinMode(green1,OUTPUT); // 차량 신호등 핀
pinMode(green2,OUTPUT); // 보행자 신호등 핀
pinMode(yellow,OUTPUT); // 신호등 핀
pinMode(trigPin, OUTPUT); // 동작감지 아웃풋
pinMode(echoPin, INPUT); // 동작감지 인풋
pinMode(warning,OUTPUT); // 부저,led 핀
Serial.begin ( 9600 );
}
void loop()
{
char num; // 컴퓨터로 입력 숫자, 신호등 제어
int a; // 속도측정 함수
int b; // 신호등 함수
double distance; // 센서 함수
a = start();
num = Serial.read();
b = traffic(num);
distance = sensor();
Serial.println(b); // 신호등 동작 확인
if(a!=0)
{
melody();
digitalWrite(warning,HIGH);
delay(3000);
digitalWrite(warning,LOW);
}
if(distance!=30)
{
Serial.println("스크린도어 동작 중지");
}
}
int start () //속도 측정 함수
{
int v, vmax, trg; //속도, 최대 속도, 출력
unsigned long T; // 주기
double f; // 주파수
vmax = 0 ;
while (digitalRead (Sigpin));
while ( ! digitalRead (Sigpin));
T =pulseIn (Sigpin , HIGH) + pulseIn (Sigpin , LOW); // 주기 측정
f = 1 / ( double ) T; // 주파수 측정
v = int ((f * 1e6 ) /44.0 ); // 속도 측정
vmax = max (v, vmax); // 속도의 Max값 측정
if ( vmax >10)
trg = 1;
else
trg = 0;
delay(500);
return trg;
}
int traffic(char a) //신호등 함수
{
int output = 0;
switch(a)
{
case '1': //차량 빨강, 보행자 파랑
traffic_sig1();
traffic_sig5();
output = 1;
break;
case '2': //차량 빨강, 보행자 빨강
traffic_sig1();
traffic_sig4();
output = 2;
break;
case '3': // 차량 노랑, 보행자 빨강
traffic_sig2();
traffic_sig4();
output = 3;
break;
case '4': // 차량 파랑, 보행자 빨강
traffic_sig3();
traffic_sig4();
output = 4;
break;
default:
break;
}
return output;
}
double sensor() // 동작감지 함수
{
long duration;
double distance;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration*0.034/2; //Cm
delay(500);
return distance;
}
void melody() // 차량 경고 부저 소리 함수
{
tone(14,500,3000);
}
// 신호등 색 결정 함수들
void traffic_sig1()
{
digitalWrite(red1, HIGH);
digitalWrite(yellow,LOW);
digitalWrite(green1,LOW);
}
void traffic_sig2()
{
digitalWrite(red1, LOW);
digitalWrite(yellow,HIGH);
digitalWrite(green1,LOW);
}
void traffic_sig3()
{
digitalWrite(red1, LOW);
digitalWrite(yellow,LOW);
digitalWrite(green1,HIGH);
}
void traffic_sig4()
{
digitalWrite(red2,HIGH);
digitalWrite(green2,LOW);
}
void traffic_sig5()
{
digitalWrite(red2,LOW);
digitalWrite(green2,HIGH);
}
댓글 7
조회수 16,576헤헿님의 댓글
헤헿 작성일
start 함수 실행시에만 문제가 생기는데 start함수에서 trm-121a를 사용해 속도 측정을 하고 있습니다. 이 과정에서 데이터 처리량이 너무 많아서 그런건지 궁금합니다.
그리고 코드 변경중 delay대신 millis()함수를 사용하는걸로 고쳤습니다. 하지만 3초를 설정했다 가정하면 3초 뒤 동작을 시작해서 딜레이 없이 계속 동작되고 있습니다. 이부분도 알려주시면 감사하겠습니다
#include <Servo.h>
int red1 = 2; // 차량 신호등 핀 설정
int red2 = 4; // 보행자 신호등 핀 설정
int green1 = 7; // 차량 신호등 핀 설정
int green2 = 8; // 보행자 신호등 핀 설정
int yellow = 9; // 신호등 핀 설정
int music=10; // 부저 핀 설정
int Sigpin = 11 ; // start 함수 입력 핀 설정
int trigPin = 12; // 동작감지 아웃풋 핀 설정
int echoPin = 13; // 동작감지 인풋 핀 설정
int warning=14; // led 동작 핀 설정
void setup ()
{
pinMode(Sigpin , INPUT); //속도 측정 핀
pinMode(red1,OUTPUT); // 차량 신호등 핀
pinMode(red2,OUTPUT); // 보행자 신호등 핀
pinMode(green1,OUTPUT); // 차량 신호등 핀
pinMode(green2,OUTPUT); // 보행자 신호등 핀
pinMode(yellow,OUTPUT); // 신호등 핀
pinMode(trigPin, OUTPUT); // 동작감지 아웃풋
pinMode(echoPin, INPUT); // 동작감지 인풋
pinMode(warning,OUTPUT); // 부저,led 핀
Serial.begin (9600);
}
void loop()
{
int a; // 속도측정 함수
int b; // 신호등 함수
double distance; // 센서 함수
double ct = millis(); // 현제시간
double pt = 0; // 과거시간
int cnt;
distance = sensor();
if(Serial.available())
{
char num;
num = Serial.read();
b = traffic(num);
Serial.println(b);
}
if(distance!=30)
{
if(ct - pt > 3000)
{
pt = ct;
Serial.println("스크린도어 동작 중지");
}
}
}
int start () //속도 측정 함수
{
int v, vmax, trg; //속도, 최대 속도, 출력
unsigned long T; // 주기
double f; // 주파수
vmax = 0 ;
while (digitalRead (Sigpin));
while ( ! digitalRead (Sigpin));
T =pulseIn (Sigpin , HIGH) + pulseIn (Sigpin , LOW); // 주기 측정
f = 1 / ( double ) T; // 주파수 측정
v = int ((f * 1e6 ) /44.0 ); // 속도 측정
vmax = max (v, vmax); // 속도의 Max값 측정
if ( vmax >10)
trg = 1;
else
trg = 0;
return trg;
}
int traffic(char a) //신호등 함수
{
int output;
switch(a)
{
case '1': //차량 빨강, 보행자 파랑
traffic_sig1();
traffic_sig5();
output = 1;
break;
case '2': //차량 빨강, 보행자 빨강
traffic_sig1();
traffic_sig4();
output = 2;
break;
case '3': // 차량 노랑, 보행자 빨강
traffic_sig2();
traffic_sig4();
output = 3;
break;
case '4': // 차량 파랑, 보행자 빨강
traffic_sig3();
traffic_sig4();
output = 4;
break;
default:
break;
}
return output;
}
double sensor() // 동작감지 함수
{
long duration;
double distance;
double pt = 0;
double ct = millis();
if(ct - pt > 1000)
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration*0.034/2; //Cm
pt = ct;
}
return distance;
}
void melody() // 차량 경고 부저 소리 함수
{
tone(14,500,3000);
}
// 신호등 색 결정 함수들
void traffic_sig1()
{
digitalWrite(red1, HIGH);
digitalWrite(yellow,LOW);
digitalWrite(green1,LOW);
}
void traffic_sig2()
{
digitalWrite(red1, LOW);
digitalWrite(yellow,HIGH);
digitalWrite(green1,LOW);
}
void traffic_sig3()
{
digitalWrite(red1, LOW);
digitalWrite(yellow,LOW);
digitalWrite(green1,HIGH);
}
void traffic_sig4()
{
digitalWrite(red2,HIGH);
digitalWrite(green2,LOW);
}
void traffic_sig5()
{
digitalWrite(red2,LOW);
digitalWrite(green2,HIGH);
}
master님의 댓글
master 작성일
//
#include <Servo.h>
//
int red1=2; // 차량 신호등 핀 설정
int red2=4; // 보행자 신호등 핀 설정
int green1=7; // 차량 신호등 핀 설정
int green2=8; // 보행자 신호등 핀 설정
int yellow=9; // 신호등 핀 설정
int music=10; // 부저 핀 설정
int Sigpin=11; // start 함수 입력 핀 설정
int trigPin=12; // 동작감지 아웃풋 핀 설정
int echoPin=13; // 동작감지 인풋 핀 설정
int warning=14; // led 동작 핀 설정
//
void setup(){
pinMode(Sigpin,INPUT); //속도 측정 핀
pinMode(red1,OUTPUT); // 차량 신호등 핀
pinMode(red2,OUTPUT); // 보행자 신호등 핀
pinMode(green1,OUTPUT); // 차량 신호등 핀
pinMode(green2,OUTPUT); // 보행자 신호등 핀
pinMode(yellow,OUTPUT); // 신호등 핀
pinMode(trigPin,OUTPUT); // 동작감지 아웃풋
pinMode(echoPin,INPUT); // 동작감지 인풋
pinMode(warning,OUTPUT); // 부저,led 핀
Serial.begin(9600);
}
//
void loop(){
char num; // 컴퓨터로 입력 숫자, 신호등 제어
int a; // 속도측정 함수
int b; // 신호등 함수
double distance; // 센서 함수
a=start();
num=Serial.read();
b=traffic(num);
distance=sensor();
Serial.println(b); // 신호등 동작 확인
if(a!=0){
melody();
digitalWrite(warning,HIGH); delay(3000); digitalWrite(warning,LOW);
}
if(distance!=30){
Serial.println("스크린도어 동작 중지");
}
}
//
int start (){ //속도 측정 함수
int v, vmax, trg; // 속도, 최대 속도, 출력
unsigned long T; // 주기
double f; // 주파수
vmax=0;
while( digitalRead(Sigpin));
while(!digitalRead(Sigpin));
T=pulseIn (Sigpin,HIGH)+pulseIn(Sigpin,LOW); // 주기 측정
f=1/(double)T; // 주파수 측정
v=int((f*1e6)/44.0); // 속도 측정
vmax=max(v,vmax); // 속도의 Max값 측정
if(vmax>10)trg=1; else trg=0;
delay(500);
return trg;
}
//
int traffic(char a){ //신호등 함수
int output=0;
switch(a){
case '1': traffic_sig1(); traffic_sig5(); output=1; break; //차량 빨강, 보행자 파랑
case '2': traffic_sig1(); traffic_sig4(); output=2; break; //차량 빨강, 보행자 빨강
case '3': traffic_sig2(); traffic_sig4(); output=3; break; // 차량 노랑, 보행자 빨강
case '4': traffic_sig3(); traffic_sig4(); output=4; break; // 차량 파랑, 보행자 빨강
}
return output;
}
//
double sensor(){ // 동작감지 함수
long duration;
double distance;
digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW);
duration=pulseIn(echoPin, HIGH); distance=duration*0.034/2; //Cm
delay(500);
return distance;
}
//
void melody(){ tone(14,500,3000); } // 차량 경고 부저 소리 함수
// 신호등 색 결정 함수들
void traffic_sig1(){ digitalWrite(red1, HIGH); digitalWrite(yellow,LOW); digitalWrite(green1,LOW); }
void traffic_sig2(){ digitalWrite(red1, LOW); digitalWrite(yellow,HIGH); digitalWrite(green1,LOW); }
void traffic_sig3(){ digitalWrite(red1, LOW); digitalWrite(yellow,LOW); digitalWrite(green1,HIGH); }
void traffic_sig4(){ digitalWrite(red2,HIGH); digitalWrite(green2,LOW); }
void traffic_sig5(){ digitalWrite(red2,LOW); digitalWrite(green2,HIGH); }
//---------------------------------------------------
while( digitalRead(Sigpin));
while(!digitalRead(Sigpin));
만약 신호가 없다면 무한대기 합니다.
이 센서를 사용하는 한 빠른 동작은 기대하기 어렵습니다.
delay(500);
딜레이 500ms도 두어군데 보이고
delay(3000);
tone(14,500,3000);
3초 딜레이도 두어군데 보입니다.
헤헿님의 댓글
헤헿 작성일
그럼 혹시 start함수를
int start (){ //속도 측정 함수
int v, vmax, trg; // 속도, 최대 속도, 출력
unsigned long T; // 주기
double f; // 주파수
double last=0;
if(millis()-last>500){
last=millis();
if( digitalRead(Sigpin)){
vmax=0;
while( digitalRead(Sigpin));
while(!digitalRead(Sigpin));
T=pulseIn (Sigpin,HIGH)+pulseIn(Sigpin,LOW); // 주기 측정
f=1/(double)T; // 주파수 측정
v=int((f*1e6)/44.0); // 속도 측정
vmax=max(v,vmax); // 속도의 Max값 측정
if(vmax>10)trg=1; else trg=0;
}
else trg = 0;
}
return trg;
}
이런식으로 조건을 달아주거나 인터럽트를 사용해서 해결은 불가능한가요?
그리고
#include <Servo.h>
//
int red1=2; // 차량 신호등 핀 설정
int red2=4; // 보행자 신호등 핀 설정
int green1=7; // 차량 신호등 핀 설정
int green2=8; // 보행자 신호등 핀 설정
int yellow=9; // 신호등 핀 설정
int music=10; // 부저 핀 설정
int Sigpin=11; // start 함수 입력 핀 설정
int trigPin=12; // 동작감지 아웃풋 핀 설정
int echoPin=13; // 동작감지 인풋 핀 설정
int warning=14; // 경고등 동작 핀 설정
double time_screen=0; // 스크린도어 시간
double time_alart=0; // 경고 시간
double time_start=0; // 스타트 시간
double time_sensor=0; // 센서 시간
//
void setup(){
pinMode(Sigpin,INPUT); //속도 측정 핀
pinMode(red1,OUTPUT); // 차량 신호등 핀
pinMode(red2,OUTPUT); // 보행자 신호등 핀
pinMode(green1,OUTPUT); // 차량 신호등 핀
pinMode(green2,OUTPUT); // 보행자 신호등 핀
pinMode(yellow,OUTPUT); // 신호등 핀
pinMode(trigPin,OUTPUT); // 동작감지 아웃풋
pinMode(echoPin,INPUT); // 동작감지 인풋
pinMode(warning,OUTPUT); // 부저,led 핀
Serial.begin(9600);
}
//
void loop(){
char num; // 컴퓨터로 입력 숫자, 신호등 제어
int a; // 속도측정 함수
int b; // 신호등 함수
double distance; // 센서 함수
/*a=start(); */
distance=sensor();
if(Serial.available()){
num=Serial.read();
b=traffic(num);
Serial.println(b); // 신호등 동작 확인
}
/*if(a!=0){ */
alart();
/*} */
if(distance!=30){
if(millis()-time_screen>1000){
time_screen=millis();
Serial.println("스크린도어 동작 중지"); // 센서 확인용
}
}
}
//
int start (){ //속도 측정 함수
int v, vmax, trg; // 속도, 최대 속도, 출력
unsigned long T; // 주기
double f; // 주파수
if(millis()-time_start>500){
time_start=millis();
if(digitalRead(Sigpin)){
vmax=0;
while(digitalRead(Sigpin));
while(!digitalRead(Sigpin));
T=pulseIn(Sigpin,HIGH)+pulseIn(Sigpin,LOW); // 주기 측정
f=1/(double)T; // 주파수 측정
v=int((f*1e6)/44.0); // 속도 측정
vmax=max(v,vmax); // 속도의 Max값 측정
if(vmax>10)trg=1; else trg=0;
}
else trg = 0;
}
return trg;
}
//
int traffic(char a){ //신호등 함수
int output;
switch(a){
case '1': traffic_sig1(); traffic_sig5(); output=1; break; //차량 빨강, 보행자 파랑
case '2': traffic_sig1(); traffic_sig4(); output=2; break; //차량 빨강, 보행자 빨강
case '3': traffic_sig2(); traffic_sig4(); output=3; break; // 차량 노랑, 보행자 빨강
case '4': traffic_sig3(); traffic_sig4(); output=4; break; // 차량 파랑, 보행자 빨강
}
return output;
}
//
double sensor(){ // 동작감지 함수
long duration;
double distance;
if(millis()-time_sensor>500){
time_sensor=millis();
digitalWrite(trigPin, LOW); delayMicroseconds(2);
digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW);
duration=pulseIn(echoPin, HIGH); distance=duration*0.034/2; //Cm
}
return distance;
}
//
void alart(){ //차량 경고등,경고음 함수
tone(warning,500);
digitalWrite(warning,HIGH);
if(millis()-time_alart>3000){
time_alart=millis();
Serial.println("멜로디,경고등"); // 멜로디,경고등 확인용
digitalWrite(warning,LOW);
noTone(warning);
}
}
// 신호등 색 결정 함수들
void traffic_sig1(){ digitalWrite(red1, HIGH); digitalWrite(yellow,LOW); digitalWrite(green1,LOW); }
void traffic_sig2(){ digitalWrite(red1, LOW); digitalWrite(yellow,HIGH); digitalWrite(green1,LOW); }
void traffic_sig3(){ digitalWrite(red1, LOW); digitalWrite(yellow,LOW); digitalWrite(green1,HIGH); }
void traffic_sig4(){ digitalWrite(red2,HIGH); digitalWrite(green2,LOW); }
void traffic_sig5(){ digitalWrite(red2,LOW); digitalWrite(green2,HIGH); }
여기서 시리얼모니터에 값을 입력하면 2번 출력되는데 뭐가 문제인지 알려주실 수 있나요?
master님의 댓글
master
주기를 측정하는 것은 일반 컴파일러를 공부하는 사람에게는 간단하지만
아두이노 사용자에게는 쉬운 일이 아닙니다.
시리얼모니터에 어떤 출력이 2번 된다는 것일까요?
헤헿님의 댓글
헤헿
Serial.read로 받은 값을 이해 traffic()에서 b로 값을 넣어 출력하려 하고 있습니다
제가 생각한 코딩은 1을 넣으면 1이 출력되어야 하는데
지금 1을 넣으면 1\n1이 출력되고있습니다
if(Serial.available()){
num=Serial.read();
b=traffic(num);
Serial.println(b); // 신호등 동작 확인
}
이 구문이 2번 동작하거나 enter키까지 입력으로 받는거 같은데 해결 방법이 있을까요?
그리고 혹시 저 속도 측정센서만 따로 한 아두이노에 연결해서
아두이노 2개를 사용하면 응답문제가 개선 가능할까요?
master님의 댓글
master
시리얼모니터 창 우측하단에 보면 보레이트 옆에 라인피드 관련 설정이 있습니다
헤헿님의 댓글
헤헿
어느정도 해결이 되가는거 같습니다.
답변해 주셔서 감사합니다.