ソロでたのしむ
ソロでたのしむ

ソロでたのしむ

Arduinoを使った自作GPS方位計を車に装着したことを、別の記事で紹介しました。

solocamptouring.hatenablog.com

今回は、その制作内容を紹介します。スケッチ(プログラム)も記事の最後に載せておきます。

  • 使用するモジュールなど
    • Arduino
    • LCDモニター
    • GPSセンサーモジュール
  • 回路図
  • GPSモジュールがやっていること
  • TinyGPS++を使ったサンプルスケッチ 

 

使用するモジュールなど Arduino

Arduino本体、いろいろ種類がありますが私はunoとnanoをよく使います。

どちらも同じ使い勝手です。このGPSモニターにはnanoの互換機を使っています。

LCDモニター

 

写真で上のLCDが、横16x縦2文字を表示するもの(1602)、下のLCDが、横20x縦4文字(2004)です。

配線はどちらも同じなので、表示させる文字数に応じて使い分けます。

今回は、1602を使って、

  • 時刻
  • 高度
  • 速度
  • 方位

を表示します。

GPSセンサーモジュール

今回のメイン部品は、人工衛星から様々な情報をいただけるGPSセンサーです。アンテナ一体や別体などいろいろなものがありますが、どれも使い方はほぼ同じです。今回は、約1,000円で入手したアンテナ別体のものを使いました。

回路図

回路図はFritzingで作成しています。

写この記事で使っている16x2LCDモジュールは、I2C通信を使えば、少ない電線でArduinoと接続することができます。

今回は、あえてパラレル通信で、多くの電線を使って接続しています。LCDのピンについて、簡単に紹介します。

  • D0~D7;実際にデータを送受信する。今回の通信レベルならD4~D7の4本だけでも可能
  • RS;レジスターセレクト。Arduinoに接続
  • R/W;送受信の切り替え。今回は一方通行なので、グランドに接続
  • E;データ取り込みの信号。Arduinoに接続
  • VO;コントラスト調整。10KΩの可変抵抗に接続
  • VDD;+(5V)電源
  • VSS;グランド
  • A;バックライト(LED)電源。220Ωの抵抗を使用
  • K;バックライト(LED)のグランド

 

GPSユニットは、回路図と実際に使っているものが違いますが、接続は一緒です。

最初、RXとTX(データの送受信)が、GPSユニットとArduino側で逆転させないといけないことに気づかずに接続してしまい、作動しない理由がわからずに悩みました。

開封後の初回使用時は、緯度経度を特定してデータを送信し始めるまで時間がかかります。私は15分くらいかかりました。

気長に待っていると、GPSユニットのLEDが点滅して、各種情報がArduinoに送られてきます。

次回の電源投入時からは、前回の位置情報を記憶しているので、すぐに自位置特定して起動します。

GPSモジュールがやっていること

GPSモジュールは、NMEAフォーマットという数列で、多くの情報を送ってきます。 

モジュール自体が計算してアウトプットする情報が多いですが、こんな小さなモジュールなのに賢くて感心します。

その多くの情報の中から、私が使いたい情報は、

  • 緯度経度
  • 速度
  • 高度
  • 協定世界時(UTC)
  • 進行方位

の5種類です。

 

TinyGPS++を使ったサンプルスケッチ 

GPSモジュール用のライブラリは、tinygpsplusから入手します。

ベテランが作るともっと短く完結なスケッチにできる筈ですが、初心者なので”if---else”を多用して、動けば良し!というスケッチになっています。

#include <TinyGPS++.h> #include <SoftwareSerial.h> #include <LiquidCrystal.h> LiquidCrystal lcd( 12, 11, 5, 4, 3, 2 ); byte smiley[8] = { B00100, B01110, B11111, B00000, B00100, B01110, B11111, }; byte sat1[8] = { B00110, B01110, B01110, B01111, B01110, B01110, B01100, }; byte sat2[8] = { B01110, B00100, B01110, B11111, B01110, B00100, B11111, }; byte sat3[8] = { B01100, B01110, B01110, B11110, B01110, B01110, B00110, }; TinyGPSPlus gps; SoftwareSerial gpsSerial(6, 7); const int serialTime = 200; void setup() { lcd.createChar(1, smiley); lcd.createChar(2, sat1); lcd.createChar(3, sat2); lcd.createChar(4, sat3); lcd.begin(16,2); lcd.clear(); gpsSerial.begin(9600); lcd.setCursor(0,0); lcd.print(" CAPTURING "); delay(1000); lcd.setCursor(0,1); lcd.print(" SATELLITES"); lcd.setCursor(12,1); lcd.write(2); lcd.write(3); lcd.write(4); delay(10000); lcd.clear(); } // end setup void loop() { int start = millis(); int now = millis(); do { while (gpsSerial.available() > 0) { gps.encode(gpsSerial.read()); } now = millis(); } while ((now - start) < serialTime); if (gps.altitude.isUpdated()) { int h; h = (gps.time.hour()) + 9; if( 24 <= h ) { h = h - 24; } if (h < 10) { lcd.setCursor(0,0); lcd.print(" "); lcd.setCursor(1,0); lcd.print(h); } else { lcd.setCursor(0,0); lcd.print(h); } lcd.setCursor(2,0); lcd.print(":"); int m; m = gps.time.minute(); if (m < 10) { lcd.setCursor(3,0); lcd.print("0"); lcd.setCursor(4,0); lcd.print(m); } else { lcd.setCursor(3,0); lcd.print(m); } } if (gps.altitude.isUpdated()) { lcd.setCursor(7,0); lcd.print("Alt:"); int koudo; koudo = (int)(gps.altitude.meters()); if (koudo == 0) { lcd.setCursor(11,0); lcd.print("----"); } else if (koudo < 10) { lcd.setCursor(11,0); lcd.print(" "); lcd.setCursor(14,0); lcd.print(koudo); } else if (koudo < 100) { lcd.setCursor(11,0); lcd.print(" "); lcd.setCursor(13,0); lcd.print(koudo); } else if (koudo < 1000) { lcd.setCursor(11,0); lcd.print(" "); lcd.setCursor(12,0); lcd.print(koudo); } else { lcd.setCursor(11,0); lcd.print(koudo); } lcd.setCursor(15,0); lcd.print("m"); } if (gps.speed.isUpdated()) { int s; s = (int)(gps.speed.kmph()); if (s == 0) { int satV; satV = (int)(gps.satellites.value()); if (satV < 10){ lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(1,1); lcd.print(satV); } else { lcd.setCursor(0,1); lcd.print(satV); } lcd.setCursor(2,1); lcd.write(2); lcd.write(3); lcd.write(4); lcd.print("s "); } else if (s < 10) { lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(2,1); lcd.print(s); lcd.print("Km/h"); } else if (s < 100) { lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(1,1); lcd.print(s); lcd.print("Km/h"); } else { lcd.setCursor(0,1); lcd.print(s); lcd.print("Km/h"); } } if (gps.course.isUpdated()) { if ((gps.course.deg()) == 0) { lcd.setCursor(9,1); lcd.print("WAITING"); } else if ((gps.course.deg()) < 11.3) { lcd.setCursor(9,1); lcd.print("W--N--E"); } else if ((gps.course.deg()) < 33.8) { lcd.setCursor(9,1); lcd.print("--N"); lcd.setCursor(12,1); lcd.write(1); lcd.setCursor(13,1); lcd.print("--E"); } else if ((gps.course.deg()) < 56.3) { lcd.setCursor(9,1); lcd.print("-N-"); lcd.setCursor(12,1); lcd.write(1); lcd.setCursor(13,1); lcd.print("-E-"); } else if ((gps.course.deg()) < 78.8) { lcd.setCursor(9,1); lcd.print("N--"); lcd.setCursor(12,1); lcd.write(1); lcd.setCursor(13,1); lcd.print("E--"); } else if ((gps.course.deg()) < 101.3) { lcd.setCursor(9,1); lcd.print("N--E--S"); } else if ((gps.course.deg()) < 123.8) { lcd.setCursor(9,1); lcd.print("--E"); lcd.setCursor(12,1); lcd.write(1); lcd.setCursor(13,1); lcd.print("--S"); } else if ((gps.course.deg()) < 146.3) { lcd.setCursor(9,1); lcd.print("-E-"); lcd.setCursor(12,1); lcd.write(1); lcd.setCursor(13,1); lcd.print("-S-"); } else if ((gps.course.deg()) < 168.8) { lcd.setCursor(9,1); lcd.print("E--"); lcd.setCursor(12,1); lcd.write(1); lcd.setCursor(13,1); lcd.print("S--"); } else if ((gps.course.deg()) < 191.3) { lcd.setCursor(9,1); lcd.print("E--S--W"); } else if ((gps.course.deg()) < 213.8) { lcd.setCursor(9,1); lcd.print("--S"); lcd.setCursor(12,1); lcd.write(1); lcd.setCursor(13,1); lcd.print("--W"); } else if ((gps.course.deg()) < 236.3) { lcd.setCursor(9,1); lcd.print("-S-"); lcd.setCursor(12,1); lcd.write(1); lcd.setCursor(13,1); lcd.print("-W-"); } else if ((gps.course.deg()) < 258.8) { lcd.setCursor(9,1); lcd.print("S--"); lcd.setCursor(12,1); lcd.write(1); lcd.setCursor(13,1); lcd.print("W--"); } else if ((gps.course.deg()) < 281.3) { lcd.setCursor(9,1); lcd.print("S--W--N"); } else if ((gps.course.deg()) < 303.8) { lcd.setCursor(9,1); lcd.print("--W"); lcd.setCursor(12,1); lcd.write(1); lcd.setCursor(13,1); lcd.print("--N"); } else if ((gps.course.deg()) < 326.3) { lcd.setCursor(9,1); lcd.print("-W-"); lcd.setCursor(12,1); lcd.write(1); lcd.setCursor(13,1); lcd.print("-N-"); } else if ((gps.course.deg()) < 348.8) { lcd.setCursor(9,1); lcd.print("W--"); lcd.setCursor(12,1); lcd.write(1); lcd.setCursor(13,1); lcd.print("N--"); } else { lcd.setCursor(9,1); lcd.print("W--N--E"); } } } Arduino GPS Receiver posted with カエレバ   楽天市場で調べる Amazonで調べる Yahooショッピングで調べる  
📎📎📎📎📎📎📎📎📎📎
BOT