2014/06/08

GPS redio clock Act.3

PA6H GPSモジュール
AE-FT231X USBモジュール
ACM1602NI-FLW-FBW-M01 I2C_LCD
AVRマイコンATMEGA328P-PU(3.3V 8MHz (内蔵CR))
74HC14AP
2SC1815GR

の組み合わせで、
1PPS
GPS radio clock
を組んでみました。

$GPGGAの行からデータを抽出しています。

参考にさせていただいたスケッチは
↓ 弦木考忘さんのサイト
http://baticadila.dip.jp/arduino_105.html

AE-FT231X USBモジュールは、PA6HからのNMEAデータをPCに
取り込むためのものです。

スケッチは、ICSP経由で書き込んでいます。

ボーレートは、デフォルトの9600bpsにしましたので
データ更新は、0.5秒です。

GPSからのデ-タ更新には、関係なく
1PPSからの割り込みで1秒ごとに「秒」
を更新しています。

6/20 追記
GPSからのデ-タ更新を、2秒に設定した場合。
1PPSからの割り込みは、2秒ごとにかかるしい。
よってこのスケッチは間違った動きをします。

秒針の遅れは、ほんのわずかです。
ソースを簡略にするため、59~00間の1秒は「マヤカシ」です。

TR5822 1Hzの周期は、1.0000003 s (10^2)と表示しています。
表示は、動きません。なお室温は、25℃です

/*
GPS radio clock 1.56
2014/06/08 daikunomokichi
*/
#include <Wire.h>                       //I2C
#include <wI2cLcdACM1602.h>             //LCD
wI2cLcdACM1602 lcd;
/*
 MTK3339 コマンドのメモ
 $PMTK251,19200*22 CR+LF                 19200bps
 $PMTK251,57600*2C CR+LF                 57600bps
 $PMTK220,500*2B CR+LF                   データ更新レート 2Hz 9600bps以上
 $PMTK220,200*2C CR+LF                   データ更新レート 5Hz 38400bps以上
*/
int dHour = 0;                          //JST時
int dHour0 = 0;
int dHour1 = 0;
int dHour2 = 0;
int dMin = 0;                           //内部分
int dMin0 = 0;
int dMin1 = 0;
int dSec = 0;                           //内部秒
int dSec0 = 0;
int dSec1 = 0;
int dSec2 = 0;
int dIntpin = 2;                        //割込D2
char buf[256];
char c;
int count = 0;
char *gpsTime, *gpsCnt;                 //個別データ用の文字列用ポインタ
char dRun = 0;                          //補足完了
void setup()
{
    Serial.begin(9600);
    Serial.println("$PMTK220,500*2B");    //データ更新レート 2Hz
    Wire.begin();                         //I2C初期化
    lcd.begin();                          //LCD初期化
    lcd.clear();                          //全クリア
    lcd.noBlink();                        //カーソル点滅なし
    lcd.noCursor();                       //カーソル表示なし
    lcd.setCursor(0, 0);
    lcd.print("Preliminary GPS");         //最初のメッセージ表示
    lcd.setCursor(0, 1);
    lcd.print("1.56 by mokichi");         //最初のメッセージ表示
    pinMode(dIntpin, INPUT);
    attachInterrupt(0, yCnt, RISING);
    //attachInterrupt(0,yCnt, FALLING);   //HIGHからLOW
    delay(1000);
    lcd.clear();
}
void loop()
{
    count = 0;
    do {
        if (Serial.available()) {
            buf[count] = Serial.read();
            count++;
        }
        if (count > 250) {
            break;
        }
    } while (buf[count - 1] != 0x0A);
    buf[count] = '\0';
    if (0 == strncmp("$GPGGA", buf, 6)) {
        strtok(buf, ",");
        gpsTime = strtok(NULL, ",");        //m1>UTC時刻の抽出
        strtok(NULL, ",");                  //m2
        strtok(NULL, ",");                  //c1
        strtok(NULL, ",");                  //m3
        strtok(NULL, ",");                  //c2
        strtok(NULL, ",");                  //d1
        gpsCnt = strtok(NULL, ",");         //d2>測位に使用した人工衛星の個数
        lcd.setCursor(14, 1);
        lcd.print(gpsCnt);
        lcd.print("  ");
        dMin0 = gpsTime[2];
        dMin1 = gpsTime[3];
        dMin = ((dMin0 - 48) * 10) + dMin1 - 48;
        dSec0 = gpsTime[4];
        dSec1 = gpsTime[5];
        dSec2 = ((dSec0 - 48) * 10) + dSec1 - 48;
        dHour0 = gpsTime[0];
        dHour1 = gpsTime[1];
        dHour2 = ((dHour0 - 48) * 10) + dHour1 - 39;
        switch (dHour2) {
            case 24:
            case 25:
            case 26:
            case 27:
            case 28:
            case 29:
            case 30:
            case 31:
            case 32:
                dHour = dHour2 - 24;
                break;
            default:
                dHour = dHour2;
                break;
        }
    }
    if (dRun != 0) {
        lcd.setCursor(0, 0);
        lcd.print("GPS radio clock");
    }
    lcd.setCursor(6, 1);
    lcd.print(dSec / 10);
    lcd.print(dSec % 10);

    lcd.setCursor(0, 1);
    lcd.print(dHour / 10);
    lcd.print(dHour % 10);
    lcd.print(":");
    lcd.print(dMin / 10);
    lcd.print(dMin % 10);
    lcd.print(":");
    lcd.setCursor(8, 1);
    lcd.print("(JST)");
    lcd.print(char(222));
}
void yCnt()
{
    dSec++;
    if (dSec > 59) {
        dSec = 0;
    }
    if (59 == dSec2) {
        dRun = -1;
        dSec = 0;
    }
}

0 件のコメント:

コメントを投稿