ArduinoでAdafruitのGPSを使ってみる2


このエントリーをはてなブックマークに追加

前回

ArduinoでAdafruitのGPSを使ってみる | ぬわーーーーーーー!!!

今回は、好きなコマンドを送ってみる & ボタンを押した時にコマンドが送られるようにやってみる


例えば、AdafruitのGPS LibraryのAdafruit_GPS.h を見てみると

1
2
3
4
5
6
7
8
9
10
11
...
// turn on only the second sentence (GPRMC)
#define PMTK_SET_NMEA_OUTPUT_RMCONLY "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
// turn on GPRMC and GGA
#define PMTK_SET_NMEA_OUTPUT_RMCGGA "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
// turn on ALL THE DATA
#define PMTK_SET_NMEA_OUTPUT_ALLDATA "$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
// turn off output
#define PMTK_SET_NMEA_OUTPUT_OFF "$PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
...

となっている

それぞれチェックサムを確認してみたらちゃんとあってたのでこれでいけそう

チェックサムの確認は前回の記事参照


これを元に、GPSデータで欲しいものだけを取得するコマンドを考えてみる

たとえば、NMEAを変更するコマンドは、コマンドの仕様書12ページ目を見てみると

  • PMTK314: パケットタイプ
  • そのあと続く 0 または 1 の並び 19個は, それぞれ順番に
    • 0 NMEA_SEN_GLL, // GPGLL interval - Geographic Position - Latitude longitude
    • 1 NMEA_SEN_RMC, // GPRMC interval - Recommended Minimum Specific GNSS Sentence
    • 2 NMEA_SEN_VTG, // GPVTG interval - Course over Ground and Ground Speed
    • 3 NMEA_SEN_GGA, // GPGGA interval - GPS Fix Data
    • 4 NMEA_SEN_GSA, // GPGSA interval - GNSS DOPS and Active Satellites
    • 5 NMEA_SEN_GSV, // GPGSV interval - GNSS Satellites in View
    • 6 //Reserved
    • 7 //Reserved
    • 13 //Reserved
    • 14 //Reserved
    • 15 //Reserved
    • 16 //Reserved
    • 17 //Reserved
    • 18 NMEA_SEN_MCHN, // PMTKCHN interval – GPS channel status
  • という意味で、1だとそのデータが出てくるような仕様らしい
    • ちなみに設定できる数字は 0 ~ 5 まであって
      • 0: Disabled or not supported sentence
      • 1: Output once every one position fix
      • 2: Output once every two position fixes
      • 3: Output once every three position fixes
      • 4: Output once every four position fixes
      • 5: Output once every five position fixes

となっている

試しに、NMEA_SEN_GLLだけ出てくるコマンドを考えると下記のようになる


1
$PMTK314,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29


コードにしてArduinoでやってみると、ちゃんとGLLデータだけが出力される結果となる

(コードは下記)

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
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // (RX, TX)
Adafruit_GPS GPS(&mySerial);
String NMEA1; // Variable for first NMEA sentence
String NMEA2; // Variable for second NMEA sentence
char c; // to read characters coming from the GPS
void setup() {
pinMode(7, INPUT);
Serial.begin(115200); // turn on serial monitor
while(!Serial) {
;
}
Serial.println("Ready");
GPS.begin(9600); // turn on GPS at 9600 baud
GPS.sendCommand("$PMTK314,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29");
delay(1000);
}
void loop() {
readGPS();
}
void readGPS() {
while(!GPS.newNMEAreceived()) { // loop until you have a goo NMEA sentence
c=GPS.read();
}
GPS.parse(GPS.lastNMEA()); //parse that last good NMEA sentence
NMEA1=GPS.lastNMEA();
while(!GPS.newNMEAreceived()) { // loop until you have a goo NMEA sentence
c=GPS.read();
}
GPS.parse(GPS.lastNMEA()); //parse that last good NMEA sentence
NMEA2=GPS.lastNMEA();
Serial.println(NMEA1);
Serial.println(NMEA2);
}


ボタン(タクトスイッチ)を押したら設定が変わるようにとかやってみる

ボタン(タクトスイッチ)を押したらトリガーがかかってwriteとかreadとかできるようなシステム考えてみよう

まずは下記を参照に、タクトスイッチでLEDを制御させてみた

10.タクトスイッチの入力を判定するdigitalRead | | 大好きArduino

digital 7 pin を入力(INPUT)にして、Arduino UNO 基板上のLED(13 pin ) を点けたり消したりしてみた

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define LED_PIN 13
void setup() {
pinMode(7, INPUT);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
int status;
status = digitalRead(7); // スイッチの状態を読む
if(status == HIGH){
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
delay(2000);
}

できた!

ということはボタンを押したらsendCommandが送られるようになればよいので

図は下記


下記コードでやってみた

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
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // (RX, TX)
Adafruit_GPS GPS(&mySerial);
String NMEA1; // Variable for first NMEA sentence
String NMEA2; // Variable for second NMEA sentence
char c; // to read characters coming from the GPS
void setup() {
pinMode(7, INPUT);
Serial.begin(115200); // turn on serial monitor
while(!Serial) {
;
}
Serial.println("Ready");
GPS.begin(9600); // turn on GPS at 9600 baud
// cold start for reset
// GPS.sendCommand("$PMTK104*37");
GPS.sendCommand("$PMTK314,1,1,1,1,1,5,0,0,0,0,0,0,0,0,0,0,0,0,0*2c");
delay(1000);
}
void loop() {
readGPS();
int status;
status = digitalRead(7);
if(status == LOW) {
sendGPSCommand();
}
}
void readGPS() {
while(!GPS.newNMEAreceived()) { // loop until you have a goo NMEA sentence
c=GPS.read();
}
GPS.parse(GPS.lastNMEA()); //parse that last good NMEA sentence
NMEA1=GPS.lastNMEA();
while(!GPS.newNMEAreceived()) { // loop until you have a goo NMEA sentence
c=GPS.read();
}
GPS.parse(GPS.lastNMEA()); //parse that last good NMEA sentence
NMEA2=GPS.lastNMEA();
Serial.println(NMEA1);
Serial.println(NMEA2);
}
void sendGPSCommand() {
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
Serial.println("change NMEA OUTPUT");
delay(1000);
}


これで、ボタンを押した時にRMCデータだけ出力されるようにできた


ちなみに

  • コマンドを送ると、$PMTK001,314,3*36みたいなACKが返ってくる
  • ACKの仕様は仕様書(pdf)の5ページに載ってて、たとえばSET_NMEA_OUTPUTコマンド(PMTK314コマンド)を送ると
    • $PMTK001,314,3*36
    • が返ってくる、これは
      • PMTK001: ACKコマンドのコマンド番号が001
      • 314: 送ったコマンド番号、この場合PMTK314コマンド(SET_NMEA_OUTPUT)を送ったので314
      • 3: Flag
        • 3は、コマンドは正常に送られて受け付けられましたよ、って意味っぽい
        • ここは 0 ~ 3 までを取りうる、他のやつの意味は
          • 0だと 無効なコマンドですよ
          • 1だと そのコマンドはサポートされていませんよ
          • 2だと 有効なコマンドですが失敗しました
        • みたい
        • 例えば GPS.sendCommand("$PMTK314,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*20"); というコマンドを送ってみたところ(NMEAでGLLデータだけ出力してってモードにするとして、数字に範囲外の8を設定してみたやつ)
          • $PMTK001,314,3*36 のACKが返ってきた
          • これは、 unsupportedなコマンドになるらしい

今回は以上


このエントリーをはてなブックマークに追加