工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

GPS搭載高精度クロック - 安価で信頼性の高い時計製作

必要な部品と材料

Arduino UNO ×1
LCDディスプレイ(I2Cアダプター付き、16×2または20×4) ×1
ブレッドボード ×1
ジャンパーワイヤー ×1セット
GPS受信機(GY-GPS6MV2、u-blox NEO-6M搭載) ×1

使用するアプリとオンラインサービス

プロジェクト概要

これまで時計プロジェクトではRTCモジュールやNTPサーバーを使ってきましたが、今回はGPS衛星からのNMEA文字列を解析して時刻を取得する方法を紹介します。

GPS受信機が驚くほど安価になっています(ここではGY-GPS6MV2を使用)。

GPS搭載高精度クロック - 安価で信頼性の高い時計製作

事前テスト

  1. PCで動作確認(任意): u-bloxの「u-center」ソフトをインストール。FTDIアダプターでGPSモジュールをPCのCOMポートに接続。約1分で衛星捕捉(赤LED点滅)。F8「Text Console」でNMEA文を確認可能。
  2. オンラインデコーダーでテスト: https://rl.se/gprmc でNMEA文をペーストして解析確認。

衛星捕捉(空が見える場所で)が確認できたら、必要な情報をNMEA文から抽出します。

GPS搭載高精度クロック - 安価で信頼性の高い時計製作

回路

GPS搭載高精度クロック - 安価で信頼性の高い時計製作
GPS搭載高精度クロック - 安価で信頼性の高い時計製作
GPS搭載高精度クロック - 安価で信頼性の高い時計製作

I2C LCD接続:


#include 
#include 
LiquidCrystal_I2C lcd(0x3F, 20, 4); // アドレスは0x27や0x3Fが多い

GPS接続(SoftwareSerial使用):


#include 
#include 
SoftwareSerial mySerial(8, 7); // RX, TX
Adafruit_GPS GPS(&mySerial);

※ GPS受信機は3.3V/5V両対応。

表示項目

この時計では以下を表示:

位置情報は不要(窓辺に固定するため)。

タイムゾーン変換

NMEA文の時刻はUTC標準。ローカルタイムへの変換が必要。


int timezone = +1; // Europe/Berlin (UTC+0100)

お住まいのタイムゾーンに合わせて調整。表示時はGPS.hourの代わりにこのhour変数を使用。


// LCD出力例
lcd.setCursor(5, 0);
int hour = (GPS.hour) + timezone;
if (hour < 10) lcd.print('0');
lcd.print(hour, DEC); lcd.print(':');
// 分、秒も同様に0埋めして表示

風速表示(ノット→km/h変換&ビューフォート風力階級)

ヨーロッパでは風速にkm/hを使用。1ノット = 1.852 km/hで変換。


float speed = (GPS.speed) * 1.852; // ノット → km/h

Wikipediaのビューフォート風力階級に基づき分類表示:


if (speed <= 1)        lcd.print(" Windstille");           // 静穏
else if (speed <= 9)   lcd.print(" leiser Zug");            // 微風
else if (speed <= 46)  lcd.print(" Brise");                 // 弱風〜やや強風
else if (speed <= 56)  lcd.print(" starker Wind");          // 強風
else if (speed <= 74)  lcd.print(" stuerm. Wind");          // 疾風
else if (speed <= 83)  lcd.print(" Sturm");                 // 暴風
else if (speed <= 102) lcd.print(" schwerer Sturm");        // 大暴風
else                   lcd.print(" Orkan");                 // 颶風

表示例

GPS搭載高精度クロック - 安価で信頼性の高い時計製作

更新頻度はループ内で2秒ごと。秒表示と高度を省けば16×2ディスプレイでも収まります。

GPS搭載高精度クロック - 安価で信頼性の高い時計製作
GPS搭載高精度クロック - 安価で信頼性の高い時計製作

GPSの多彩な機能を探求してみてください!

ヨーロッパではDCF77電波時計も選択肢ですが、こちらは高価で受信がデリケートと言われています。

スケッチ


// Adafruit GPSライブラリの例をベースに調整
// GPRMC & GPGGA デコーダー: https://rl.se/gprmc

#include 
#include 
LiquidCrystal_I2C lcd(0x3F, 20, 4); // 0x27や0x3Fで試行

#include 
#include 

SoftwareSerial mySerial(8, 7); // RX, TX
Adafruit_GPS GPS(&mySerial);

#define GPSECHO true
int timezone = +1; // UTC+0100 (Europe/Berlin)

void setup() {
  lcd.init();
  lcd.backlight();
  Serial.begin(115200);
  delay(5000);
  Serial.println("Adafruit GPS library basic test!");

  GPS.begin(9600); // UBLOX 6Mの場合

  // RMC(推奨最小)+ GGA(測位データ、高度含む)を出力
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  // GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY); // 最小のみの場合

  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1Hz更新
  GPS.sendCommand(PGCMD_ANTENNA);            // アンテナステータス要求
  delay(1000);
  mySerial.println(PMTK_Q_RELEASE);          // ファームウェアバージョン問合せ
}

uint32_t timer = millis();

void loop() {
  char c = GPS.read();
  if (c && GPSECHO) Serial.write(c);

  if (GPS.newNMEAreceived()) {
    if (!GPS.parse(GPS.lastNMEA())) return; // パース失敗なら次待ち
  }

  if (timer > millis()) timer = millis(); // millis()オーバーフロー対策

  if (millis() - timer > 2000) { // 約2秒ごとに表示更新
    timer = millis();

    // シリアル出力(デバッグ用)
    Serial.print("\nTime: ");
    if (GPS.hour < 10) Serial.print('0');
    Serial.print(GPS.hour, DEC); Serial.print(':');
    if (GPS.minute < 10) Serial.print('0');
    Serial.print(GPS.minute, DEC); Serial.print(':');
    if (GPS.seconds < 10) Serial.print('0');
    Serial.print(GPS.seconds, DEC); Serial.print('.');
    // ミリ秒表示...
    
    Serial.print("Date: ");
    Serial.print(GPS.day, DEC); Serial.print('/');
    Serial.print(GPS.month, DEC); Serial.print("/20");
    Serial.println(GPS.year, DEC);
    Serial.print("Fix: "); Serial.print((int)GPS.fix);
    Serial.print(" quality: "); Serial.println((int)GPS.fixquality);

    // LCD表示
    lcd.setCursor(5, 0);
    int hour = (GPS.hour) + timezone;
    if (hour < 10) lcd.print('0');
    lcd.print(hour, DEC); lcd.print(':');
    if (GPS.minute < 10) lcd.print('0');
    lcd.print(GPS.minute, DEC); lcd.print(':');
    if (GPS.seconds < 10) lcd.print('0');
    lcd.print(GPS.seconds, DEC);

    lcd.setCursor(5, 1);
    if (GPS.day < 10) lcd.print('0');
    lcd.print(GPS.day, DEC); lcd.print('.');
    if (GPS.month < 10) lcd.print('0');
    lcd.print(GPS.month, DEC); lcd.print('.');
    lcd.print(GPS.year, DEC);

    if (GPS.fix) { // 衛星捕捉できていれば追加情報表示
      // 位置、速度、角度、高度、衛星数をシリアル出力...

      // 風速換算表示(3行目)
      lcd.setCursor(0, 2);
      float speed = (GPS.speed) * 1.852; // km/h
      // lcd.print("Speed km/h: "); lcd.print(speed);
      
      if (speed <= 1)        lcd.print(" Windstille");
      else if (speed <= 9)   lcd.print(" leiser Zug");
      else if (speed <= 46)  lcd.print(" Brise");
      else if (speed <= 56)  lcd.print(" starker Wind");
      else if (speed <= 74)  lcd.print(" stuerm. Wind");
      else if (speed <= 83)  lcd.print(" Sturm");
      else if (speed <= 102) lcd.print(" schwerer Sturm");
      else                   lcd.print(" Orkan");

      // 高度表示(4行目)
      lcd.setCursor(0, 3);
      lcd.print("Hoehe: ");
      lcd.print(GPS.altitude);
    }
  }
}

製造プロセス

  1. DIY 低コストグローブコントローラー & プロペラカー – 自分だけの Arduino ハンドコントローラーを作ろう
  2. DHT11温湿度センサーで作る温度アラート – LEDとピエゾブザーで視覚/聴覚通知
  3. GPSデータロガー構築と Azure IoT Hub での空間分析
  4. Arduinoで温湿度ロガーを作る – DHT11とEthernetシールドでSDカード記録
  5. Arduino Dueと3.2インチTFTで作る温度監視付きリアルタイムクロック
  6. アナログ風LED POVクロック – Arduino Nanoで作る残像時計
  7. 光と音で祝おう:Arduinoで作るDIYバースデープロジェクト
  8. u-blox LEA-6H 02 GPSモジュール: Arduino & Python 統合ガイド
  9. Arduino Nanoと128x64 OLEDで実行するセルラーオートマトン「ライフゲーム」
  10. Arduinoで高速・高精度RPM測定 – レーザーとIRセンサーによる新アルゴリズム
  11. DIYギター高速ピック&ストンプペダル - 3Dプリントモーター駆動ピックの自作