정보나눔

오픈소스하드웨어 프로젝트에 대한 다양한 정보를 나누는 공간입니다.

블루투스 안드로이드 통신 관련 질문입니다. (2)
김학현 | 2016-02-03

http://kocoafab.cc/fboard/484 의 두 번째 질문입니다.

 

 

int trigPin = 12;
int echoPin = 13;
int safeZone = 30;
#define PIN_RX 2
#define PIN_TX 3

#include
SoftwareSerial btSerial(PIN_RX, PIN_TX);

char val;
void setup()
{
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  Serial.begin(9600);
  btSerial.begin(9600);
  Serial.println("HC-SR04. distance measure start!");
  btSerial.println("HC-SR04. distance measure start!");
  Serial.println();
}

void loop()
{
  float duration, distance;
  digitalWrite(trigPin, LOW);
  digitalWrite(echoPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = ((float)(340 * duration) / 10000) / 2;
 
if( btSerial.available() )
{
  val = btSerial.read();
 
  if(val == '3') //SONAR
{    
  btSerial.println("Auto Sonar Start!");
 
       if (distance < 30)  // 만약 30cm 안에 장애물이 감지되면,
       {
        Serial.print(val);
          Serial.println("right"); // 오른쪽으로 회전합니다.
       }
      
       else  // 아닐경우,
       {
        Serial.print(val);
          Serial.println("forward"); // 계속 전진합니다.     
       }
       delay(500);
}
}
}

while문 밖에다가 써봤는데 그것이 안되서 아예 처음부터 코딩을 하여서.

이런식으로 작성하고 시리얼 통신으로 테스트 해봤는데

3을 입력받고 계속 초음파 센서를 통한 거리재기가 계속 나오지 않고

3을 입력 받을때만 작동합니다.. 어떻게 하면 좋죠

 

 

HC-SR04. distance measure start!

3forward
3forward
3forward
3right

프로필사진

원기옥 2016-02-03 08:52:51

위의 소스코드에서는 '3'번을 입력해야, 그 시점에서 단한번 해당 블럭이 실행됩니다. 
 
의도하시는 것 같이, 3을 한번 입력하면, 무한 반복되면서 거리를 계속 체크하는 로직이 아닙니다. 
 
계속 수행을 하게하려면, 조건을 없애거나, 3을 입력 받았을때, 특정 boolean 변수를 true|false 값으로 변경하고 이 변수를 기반으로 동작 여부를 결정하면 됩니다. 

 

 

distance = ((float)(340 * duration) / 10000) / 2;
 
// 만약 30cm 안에 장애물이 감지되면,오른쪽으로 회전합니다.
if (distance < 30) {
    Serial.print(val);
    Serial.println("right"); 

// 아니라면, 계속 전진합니다.  
} else {
    Serial.print(val);
    Serial.println("forward");    
}
delay(500);  

 

즉, 위와 같이 작성을 하면, 무한 반복이 되겠죠. 그리고 특정 값으로, 가령 3으로 해당 블럭의 실행여부를 결정하고자 한다면, 아래와 같이 하면 됩니다.

 

boolean running = false;

void loop() {

if (btSerial.available()) {
	val = btSerial.read();
 
	if(val == '3') {
		running = true;
	}
	
	...    
	
	distance = ((float)(340 * duration) / 10000) / 2;
	
 	...
 
 	if (running) {
		// 만약 30cm 안에 장애물이 감지되면,오른쪽으로 회전합니다.
		if (distance < 30) {
  		  	Serial.print(val);
 		   	Serial.println("right"); 

		// 아니라면, 계속 전진합니다.  
		} else {
 		   	Serial.print(val);
 		   	Serial.println("forward");    
		}
		delay(500);  
	}
}

 

 

프로필사진

수박쨈 2016-02-03 10:21:23

아래 글에서 제가 밑에서 말한 코드는 while()문 밖으로 if문 val == '3'의 조건을 가진 조건문만 빼는 거였는데

그 조건문위에도 또 if(btSerial.available()) { }을 달아놓으셨네요.

아래 글 댓글에서 달았지만 btSerial.available()이라는 조건을 달아놓으셨으면 3이라는 데이터가 전송될때만 조건문이 실행됩니다.

그냥 while문 밖으로 아래 코드만 빼놓으시면 됩니다.

 

  if(val == '3') //충돌방지
{    
  btSerial.println("Auto Sonar Start!");
 
       if (distance < 30)  // 만약 30cm 안에 장애물이 감지되면,
       {
          turn_right(); // 오른쪽으로 회전합니다.
       }
      
       else  // 아닐경우,
       {
          forward(); // 계속 전진합니다.     
       }
}

프로필사진

김학현 2016-02-03 11:28:19

ㄴ원기옥 님

아아.. 위 코드는 아주 잘됩니다..

하지만 밑에 코드는 계속 똑같은 문제점이 발생 되네요,, ㅠㅠㅠ

게다가 3말고 다른 문자를 입력해도 알고리즘이 돌아갑니다.

또한 초음파 센서에서 계속 소리가 납니다. 첫 번째 코드에서 소리가 날떄는 delay(500)간격으로 소리가 나는데

두 번쨰 코드는 3을 입력 하지도 않았는데 소리가 꾸준히 나고 3을 입력하면 그때서야 잠깐 끊기고 다시 소리가 계속 납니다.

int trigPin = 6;
int echoPin = 7;
int safeZone = 30;
#define PIN_RX 2
#define PIN_TX 3

#include <SoftwareSerial.h>
SoftwareSerial btSerial(PIN_RX, PIN_TX);

char val;
boolean running = false;
void setup()
{
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  Serial.begin(9600);
  btSerial.begin(9600);
  Serial.println("HC-SR04. distance measure start!");
  btSerial.println("HC-SR04. distance measure start!");
  Serial.println();
}


void loop()
{
  float duration, distance;
  digitalWrite(trigPin, LOW);
  digitalWrite(echoPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = ((float)(340 * duration) / 10000) / 2;
 
  if (btSerial.available()) {
  val = btSerial.read();
 
  if(val == '3') {
    running = true;
   
  }
 
 
  if (running) {
    // 만약 30cm 안에 장애물이 감지되면,오른쪽으로 회전합니다.
    if (distance < 30) {
        Serial.print(val);
        Serial.println("right");

    // 아니라면, 계속 전진합니다. 
    } else {
        Serial.print(val);
        Serial.println("forward");   
    }
    delay(500); 

}
  }
}

 코드도 이해했고 그에따라 똑같이 코딩 했는데 문제가 해결 안되니 정말 미쳐버리겠네요.

HC-SR04. distance measure start!

3forward
2right
5forward
5forward
5forward
6forward
0right
�right
꿧orward
땏orward
�forward
�forward
땏orward
�forward
꿧orward
땏orward
�forward
꿧orward
땏orward
zforward
zforward
zforward
zforward
aforward
aforward

프로필사진

김학현 2016-02-03 11:28:30

ㄴ수박쨈 님

아... 제가 깜빡하고 마지막 수정을 안하고 복사 붙이기 했나봅니다.

btSerial.available() 조건을 빼고 업로드 해봤는데도 안됐었습니다.ㅠㅠㅠㅠㅠㅠㅠ

while( !btSerial.available() );
   while( btSerial.available() )
 {
      val = btSerial.read();
      Serial.print(val);
    
      if(val == '4') //left
      {

       btSerial.println("left");
        left();
      }
      else if(val == '6') //right
      {
        btSerial.println("right");
        right();
      }
      else if(val == '8') //forward
      {
        btSerial.println("forward");
        forward();
      }
      else if(val == '2') //backward
      {
        btSerial.println("backward");
        backward();
      }
      else if(val == '0') //stop
      {

       btSerial.println("stop");  
       stop();
      }
      else if(val == '1') //temperature
      {
      
        temperature();
      }
 }


   if(val == '3') //충돌방지
{   
   btSerial.println("Auto Sonar Start!");
 
        if (distance < 30)  // 만약 30cm 안에 장애물이 감지되면,
        {
           turn_right(); // 오른쪽으로 회전합니다.
        }
      
        else  // 아닐경우,
        {
           forward(); // 계속 전진합니다.    
        }
 }

이 코드 또한 3을 입력 받을 때 만 작동 합니다.. 으악!

프로필사진

원기옥 2016-02-03 13:32:49

네, 그러네요. btSerial 부분을 따로 빼어주는게 맞습니다. 

 

boolean running = false;

void loop() {

	if (btSerial.available()) {
		val = btSerial.read();
 
		if(val == '3') {
			running = true;
		}
		...
	}
	...    
	
	distance = ((float)(340 * duration) / 10000) / 2;
	
 	...
 
	if (running) {
		// 만약 30cm 안에 장애물이 감지되면,오른쪽으로 회전합니다.
		if (distance < 30) {
  		  	Serial.print(val);
 		   	Serial.println("right"); 

		// 아니라면, 계속 전진합니다.  
		} else {
 		   	Serial.print(val);
 		   	Serial.println("forward");    
		}
		delay(500);  
	}
}

요렇게 응용하시면 될 거 같아요.

프로필사진

김학현 2016-02-03 23:32:53

댓글 감사드립니다.. 많이 배워 갑니다..

허나 문제가 해결 되진 않네요.. 안드로이드 블루투스 통신으로 인한 충돌방지 기능 제어 프로젝트는 그만 둬야 겠습니다..

프로필사진

DontForget 2016-02-04 08:45:28

여기서 그만 두시면 아니됩니다. ^^;; 다른 프로젝트를 하시더라도 같은 어려움에 마주치실 거에요. 

 

일단 간단한 C프로그래밍 관련 책이나 온라인 강좌나 글을 읽어보시고 언어에 대한 이해를 하시는 것이 무엇보다 먼저 필요합니다. 

 

뭐든 전체 분량의 1/3정도 되는 기본 문법을 이해하시면 위의 문제는 쉽게 해결하실 것 같습니다. 

 

그리고 사용하는 함수나 명령어에 대하여 그냥 가져다 쓰지지 마시고 관련 문서나 설명을 꼭 찾아 읽어보시는 것이 중요합니다. 

 

화이팅^^

이전글   |    블루투스 안드로이드 통신 관련 질문입니다. ... 2016-02-01
다음글   |    지니어스 키트처럼 아두이노 BLE 와 파는 키트는 없나요? ... 2016-02-05