정보나눔

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

아두이노 초음파모듈+GPS모듈+TTS모듈
박상우 | 2017-08-18

안녕하세요 아두이노에 위 3가지 모듈 + 진동모듈을 이용해서 작품을 만들고있는데요

 

택트 스위치를 가지고 

스위치1은 On/off 형식으로 켜지면 초음파 모듈이 작동, 거리를 재서 장애물을 감지하면 TTS 모듈을 통해 "Detected" 라는 구문이 음성출력되고 진동이 울립니다.

 

스위치2는 눌렀을때만 on 되는 형식으로 해서 Gps 모듈로부터 위도/경도값을 받고, 그 값을 TTS 모듈을 통해 음성출력 하도록 했습니다.

 

각각 GPS 와 초음파 를 따로 돌리면 잘 작동하는데

 

두개를 합치게되면 스위치 1,2의 HIHG,LOW 가 reset 할떄마다 서로 바뀌고

또 초음파모듈의 거리가 잘 측정될떄도있고 안될때도 있습니다.

 

GPS 모듈이 계속해서 데이터를 수신받아서 이런거 같기도한데

정확한 원인을 모르겠습니다

case1 은 초음파센서부분이고

case2 는 tinygps 라이브러리를 이용한 gps 코딩부분입니다.

코딩도 많이 미숙해서 도움이필요해서 미숙한 글 남겨봅니다.

 

 

 

//스위치를 100ms 이상 누름으로 on-off가 바뀌고, 스위치가 on이면
//초음파센서가 작동 되어 25cm 안에 물체가 감지되면 진동이 울리는 코드
#include <SoftwareSerial.h>
#include <TinyGPS.h>

#define rxPin   9     // Serial input (connects to Emic 2's SOUT pin)
#define txPin   8     // Serial output (connects to Emic 2's SIN pin)
#define RXPIN 11       //Gps Rx
#define TXPIN 10       //Gps Tx   

#define SP 7          //Speaker
#define Trig  4       //초음파
#define Echo  5       //초음파
#define MotorPin  6   //진동
#define SW   2       //초음파 센서 On/Off 스위치
#define SW2  3       //Gps On/Off 스위치

SoftwareSerial emicSerial =  SoftwareSerial(rxPin, txPin);
TinyGPS gps;
SoftwareSerial uart_gps(RXPIN, TXPIN);

void pinlnit()
{
  pinMode(SP,OUTPUT);
  digitalWrite(SP,LOW);
}

long microsecondsToInches(long microseconds)
{
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;
}

int state = LOW;              //초음파 스위치 초기 상태
int state2= LOW;              //GPS 스위치 초기 상태
int reading;                  // 초음파 상태를 저장할 변수
int previous = LOW;           // SW 이전 상태
long time = 0;                // 스위치가 ON/OFF 토글된 마지막 시간
long debounce = 100;          // Debounce 타임 설정
                                              
float latitude, longitude;    //위도,경도 변수

void setup() {
  /*초음파,진동 Setup*/
  pinMode(Trig, OUTPUT);        //초음파 출력
  pinMode(Echo, INPUT);         //초음파 입력
  pinMode(MotorPin, OUTPUT);    //진동 출력
  pinMode(SW, INPUT_PULLUP);    //스위치 입력
 
  /*Emic2 Setup*/
  Serial.begin(9600);          //시리얼통신 시작
 
  pinMode(rxPin, INPUT);        //Emic2 입력 (스피커)
  pinMode(txPin, OUTPUT);       //Emic2 출력 (스피커)
  
  emicSerial.begin(9600);
  emicSerial.print('\n');             // Send a CR in case the system is already up
  while (emicSerial.read() != ':');   // When the Emic 2 has initialized and is ready, it will send a single ':' character, so wait here until we receive it
  delay(10);                          // Short delay
  emicSerial.flush();                 // Flush the receive buffer
  pinlnit();                          //스피커 Setup
  
  /*GPS*/
  uart_gps.begin(9600);
  Serial.println("");
  Serial.println("GPS Shield QuickStart Example Sketch v12");
  Serial.println("       ...waiting for lock...           ");
  Serial.println(""); 
}

void loop() {
  //초음파 제어문
  
  long duration, cm;
      
  reading = digitalRead(SW);  // SW 상태 읽음
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
  if (state == HIGH)    // LED 가 HIGH 면 LOW 로 바꿔준다.
      state = LOW;
  else                  // LED 가 LOW 면 HIGH 로 바꿔준다.
      state = HIGH;
 
    time = millis();
  }
  previous = reading;
  state2 = digitalRead(SW2);  // SW2 상태 읽음

 int i = 0;
 if(state==HIGH){i=1;}
 if(state2==LOW){i=2;}
 
  switch(i){
    case 1: {
            digitalWrite(Trig, HIGH);
            delayMicroseconds(10);
            digitalWrite(Trig, LOW); 
            duration = pulseIn(Echo,HIGH);                // Echo pin: HIGH->Low 간격을 측정
            cm = microsecondsToCentimeters(duration);     // 거리(cm)로 변환
            if (cm < 25) { 
              digitalWrite(MotorPin, HIGH);
              emicSerial.print('S');
              emicSerial.print("Detected");
              emicSerial.print('\n');
              delay(500);
              digitalWrite(MotorPin, LOW);         
            }
            else  {      
              digitalWrite(MotorPin, LOW);
              delay(500);
            }         
            Serial.print(cm);
            Serial.print("cm");
            Serial.println();   
            delay(1000); // 1초 대기 후 다시 측정
            i = 0;
    }
    case 2: {
      if(uart_gps.available())     // RX핀에 데이터가 오고 스위치가 눌린 상태이면
            {
            int c = uart_gps.read();    // load the data into a variable...
            if(gps.encode(c))      // if there is a new valid sentence...
              {
              gps.f_get_position(&latitude,&longitude);
              Serial.print("Position: ");
              Serial.print("lat: ");Serial.print(latitude,5);Serial.print(" ");
              Serial.print("lon: ");Serial.println(longitude,5);   
              digitalWrite(SP,HIGH);
              emicSerial.print('S');
              emicSerial.print("latitude.");
              emicSerial.print(latitude);
              emicSerial.print(",longitude");
              emicSerial.print(longitude);
              emicSerial.print('\n');
              digitalWrite(SP,LOW);
              delay(2000);        // then grab the data.
              }   
            }
            i = 0;           
   }
  }
}

이전글   |    아두이노 블루투스 ㅡ 안드로이드폰 연동 2017-08-16
다음글   |    프로젝트보고 하려고 하는데 어떻게 하는지를 모르겠어요ㅜㅜ... 2017-08-18