티스토리 뷰

공부공부/아두이노

GPS이용

필님님 2018. 2. 19. 16:33

GPS모듈

아두이노를 더 다양하게 활용하기위해선 아두이노에 연결할 모듈이나 쉴드가 필요할 수도 있을 것입니다.

다양한 모듈중 GPS모듈 활용에대해 해본것을 쓸려고합니다.

 

 

이것이 GPS모듈로써 u-blox 의 6m 제품입니다.

모듈밑의 구멍 4개는 아두이노와 연결할 곳을 나타내는 부분으로 순서대로 GND, TXD, RXD, VCC를 나타내고 있습니다.

 

 

 

아두이노와 연결

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <SoftwareSerial.h>
SoftwareSerial GPS(2,3);
 
void setup() {
 GPS.begin(9600);
 Serial.begin(9600);
}
 
void loop() {
 if(Serial.available()){
  GPS.write(Serial.read());
 }
 if(GPS.avilable()){
  Serial.write(GPS.read());
 }
}
 
 
cs

이것이 GPS모듈을 사용하는 가장 간단한?? 방법입니다.

SoftwareSerial 은 디지털핀 2개를 사용하여 Serial통신을 할때 사용하는 함수입니다.

SoftwareSerial함수를 사용하기위해서는

#include <SoftwareSerial.h> 이라는 헤더파일을 넣어주어야지 사용할수 있습니다.

GPS(2,3)에서 GPS는 GPS모듈을 사용하므로 알기쉽게 이름을 정한것이고(2,3)은 각각 RX,TX로 사용할 핀을 나타낸 것입니다. RX는 received라서 데이터 수신하는선이고, TX는 transfer로 데이터 송신하는 선으로 알고 있습니다.

RX,TX선은 10번11번도 안정적이라서 많이 사용합니다. 이때 주의할것은 0,1번은 사용하면 안된다는 것입니다.

0,1번은 SoftwareSerial이 아닌 Hardware Serial로 이미 정해져있기때문에 그것을 제외한 핀을 사용해야 합니다.

 

 u-blox 의 6m 제품도 UARTBaud rate 가 9600이므로

GPS.begin(9600);으로 사용한다.

(Serial 통신을 하기위한 방법중하나가 UART통신입니다)

 

이제 loop로 들어가서

안의 코드는 PC에서받은 데이터는

 

 

이코드를 실행하면 단점이있는데 위치값이 NMEA값으로 나오게 됩니다.

NMEA데이터는 http://www.gpsinformation.org/dale/nmea.htm

에 자세히 나와있는데 GPS모듈이 주는 정보가 위도 경도뿐만아니라 상당히 많은것을 알수있습니다. 보통 필요한 정보는 $GPGGA 라인에 들어있는데 이것은 시간 ㅡ위도,경도 , 고도, 위성수 등을 알려줍니다.\

여기서 Parsing이라해서 원하는 정보만 골라서 위도경도등을 나타낼수도 있지만

이미 그러한 것들을 해놓은 라이브러리인

"TinyGPS++""!!를 사용하면 편리하게 원하는정보만 추출할수 있습니다.

NMEA값또한 인터넷에서 치면 지도의 위치로 바로 나타낼수도 있습니다!!ㅎㅎ

 

TinyGPS++라이브러리는 github에서 다운받으실수 있습니다.

https://github.com/mikalhart/TinyGPSPlus/blob/master/src/TinyGPS%2B%2B.h 

요것을 푸는 장소가 중요한데 이때 맨처음 아두이노를 설치한 장소가 중요합니다

다운받을때 위치를 아두이노가 설치된 폴더의libraries에 설치해야지 아두이노 IDE가 읽어들여서 사용할수 있습니다.

 

다른 라이브러리들도 이곳에 다운받으시면 됩니다!ㅎㅎ

잘 설치 되었는지는 아두이노 IDE를 켜셔서 파일-> 예제 -> 가장 밑에보시면 TinyGPSPlus 예제가 있으면 잘 설치된 것입니다.

이 라이브러리를 사용하시려면 코드 가장위쪽 헤더파일에

#Include <TinyGPS++.h>를 써주시면 됩니다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
SoftwareSerial serial_connection(2,3); //RX=pin 2, TX=pin 3
TinyGPSPlus gps;
 
void setup() {
  Serial.begin(9600);
  serial_connection.begin(9600);
  Serial.println("GPS Start");
}
 
void loop() {
 while(serial_connection.available())
 {
  gps.encode(serial_connection.read());
 }
 if(gps.location.isUpdated())
 {
  Serial.println("Satellite Count:");
  Serial.println(gps.satellites.value());
  Serial.println("Latitude:");
  Serial.println(gps.location.lat(),6);
  Serial.println("Longitude:");
  Serial.println(gps.location.lng(),6);
  Serial.println("Speed MPH:");
  Serial.println(gps.speed.mph());
  Serial.println("Altitiude Feet:");
  Serial.println(gps.altitude.feet());
  Serial.println("");
 }
}
 
cs

RX,TX선을 아두이노 2,3번에 연결한후 VCC는 5V, GND를 아두이노의 GND에 연결한 후에 업로드를 시켜준후 시리얼모니터를 클릭하면

위성수, 위도, 경도, 속도, 고도 등이 나오게 됩니다. 이것은 tinyGPSPlus라는 라이브러리를 사용하였기때문에 보기좋고 또 사용하기쉽게 나오는 것입니다.

 

아, 측정시에는 창가나 밖에서 해줘야지 신호가 잘 잡힙니다. 실내에서하면 또는 주변에 건물이 많은곳에서 작동하면 잘 안잡혀요ㅠㅠ

 

 

 

 

 

 

Google Map을이용하면?

휴휴 이것을 구글의 위도경도 서비스를이용해 지도로 바로 보고싶다면 컴퓨터에 데이터를 전송해주어야 합니다.

저는 VisualStudio를 이용하여 이 작업을 해보려고 합니다.

처음에 visualstudio를 클릭하여 파일 -> 새로만들기 -> 프로젝트에 들어가서

 

Windows Forms 앱을 열어줍니다.

 

그다음 위쪽의 바에 프로젝트(P) -> NuGet패키지관리로 들어갑니다.

그러면 찾아보기에서 GMap을 찾아서 다운받아주시면 됩니다

 

 

 

 

 

프로젝트를 만들면 가장 먼저나오는 cs디자인에서 디자인한 모습입니다.

옆부분의 도구상자를 이용하면 코드를 직접짜는것보다 훨신간편하게 만들수 있는것같습니다.

왼쪽부분에서 구글맵의 화면이 나오도록 만들어 보았습니다.

처음에 아두이노 IDE에서 포트이름을 맞추었듯이 여기서도 포트이름을 맞춰주어야합니다.

Start 버튼을 누르면 아두이노에서 받아온 gps 데이터가 Load into Map밑의 텍스트파일에 차례대로 올라오고 그 중에 위도 경도가 위쪽의 Latitude와 Longitude에 적히고 그때의 시간도 적히도록 해보았습니다.

그리고 Load Into Map을 누르면 그때의 위도와 경도를 파악해 옆에 부분에 구글맵이 켜지도록 해보았습니다.

Stop버튼을 누르면 지금까지 받은 데이터를 text파일로 저장하는것도 해보았습니다.

 

 

아래는 전체코드입니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
using GMap.NET.MapProviders;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using System.IO.Ports;
 
 
namespace GPS3
{
    public partial class Form1 : Form
    {
        private SerialPort myport;
        private DateTime datetime;
        private string in_data;
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void start_btn_Click(object sender, EventArgs e)

  //start버튼을 클릭했을때 일어나는 일들 입니다.

        {
            myport = new SerialPort();
            myport.BaudRate = 9600;
            myport.PortName = port_name_tb.Text;
            myport.Parity = Parity.None;
            myport.DataBits = 8;
            myport.StopBits = StopBits.One;
            myport.DataReceived += new SerialDataReceivedEventHandler(Myport_DataReceived);

            //요기까지는 기본적으로 통일된 부분이라 사용하시면 됩니다. 

            this.Invoke(new EventHandler(displaydata_event));
            try
            {
                myport.Open();
                myport.ReadLine();
               data_tb.Text = "";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error"); //포트가 열리지 않았을때 경고문입니다
            }
        }
 
 
        private void Myport_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            in_data = myport.ReadLine();
            Invoke(new EventHandler(displaydata_event));
        }
 
        private void displaydata_event(object sender, EventArgs e)
        {
            datetime = DateTime.Now;
            string time = datetime.Hour + ":" + datetime.Minute + ":" + datetime.Second ;
            data_tb.AppendText(time + "\t" + in_data + "\n");
            textBox1.Text = time ;
            //요기는 나중에 필요할수도 있을것 같아서 현재시간을 적는 부분입니다.
           string str = in_data;
            if (in_data == null) {
                txtLat.Text = "0";
                txtLong.Text = "0";
            }
            else {
                 if (txtLong.Text == null)
                    {
                        txtLat.Text = "0";
                        txtLong.Text = "0"; //처음에 데이터가 오지않았을때 임의로 0으로 넣었습니다...
                    }
                 else
                    {
                    string[] result = str.Split(new char[] { ',' });
                    txtLat.Text = System.Convert.ToString(result[0].Trim());
                    txtLong.Text = System.Convert.ToString(result[1].Trim());
                    System.Threading.Thread.Sleep(200);
                    }
                }
        }
 
 
        private void btnLoadIntoMap_Click(object sender, EventArgs e)
        {
            map.DragButton = MouseButtons.Left;
            map.MapProvider = GMapProviders.GoogleMap;
            double lat = Convert.ToDouble(txtLat.Text);
            double Longt = Convert.ToDouble(txtLong.Text);
            map.Position = new GMap.NET.PointLatLng(lat, Longt);
            map.MinZoom = 1//Minimum Zoom Level
            map.MaxZoom = 100//Maximum Zoom Level
            map.Zoom = 10//Current Zoom Level 구글맵에 줌기능을 한번 사용해보았습니다.
        }
  
         private void stop_btn_Click(object sender, EventArgs e)
        {
            try
            {
                string pathfile = @"C:\Users\Desktop\data";
                string filename = "GPS_data.txt";//위치 데이터 저장위치와 파일이름입니다.
                System.IO.File.WriteAllText(pathfile + filename, data_tb.Text);
                MessageBox.Show("Data has been saved to " + pathfile, "Save File");
            }
            catch (Exception ex3)
            {
                MessageBox.Show(ex3.Message, "Error");
            }
        }
 }
cs

 

아두이노에 시리얼 데이터를 비주얼스튜디오에서 이용하기위해선 포트를 통해서 데이터가 이동하는데 이때에는

using System.IO.Ports;이것을 사용해주어야 합니다.

그리고 포트를 열고 데이터를 받는것을 나타내는 부분도 거의 동일하게 작성해주시면 됩니다.

 

 myport = new SerialPort();

myport.BaudRate = 9600;
myport.PortName = port_name_tb.Text;
myport.Parity = Parity.None;
myport.DataBits = 8;
myport.StopBits = StopBits.One;
myport.DataReceived += new SerialDataReceivedEventHandler(Myport_DataReceived);

 

 

아두이노를 업로드할때에는 위도 경도 정보만 있으면 되어서

위의 코드를 사용하지 않코 다시 더 간단하게 만들어서 사용하였습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
SoftwareSerial serial_connection(2,3); //RX=pin 2, TX=pin 3
TinyGPSPlus gps;
 
void setup() {
  Serial.begin(9600);
  serial_connection.begin(9600);
  Serial.println("GPS Start");
}
 
void loop() {
 while(serial_connection.available())
 {
  gps.encode(serial_connection.read());
 }
 if(gps.location.isUpdated())
 {
  Serial.print(gps.location.lat(),6);
  Serial.print(",");
  Serial.println(gps.location.lng(),6);
 }
}
 
cs

 

아두이노를 컴퓨터에 연결하여 IDE를 이용해 업로드 시켜놓읕상태에서

비주얼스튜디오를 이용해 데이터를 받으면 현재위치를 구글을 이용하여 볼 수있게됩니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'공부공부 > 아두이노' 카테고리의 다른 글

[운영체제] 프로세스  (0) 2019.12.19
LED연결  (0) 2018.02.19
아두이노 첫 설명& IDE  (0) 2018.02.13
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함