Receive GPS by interrupt processing

Dependents:   Sample_GPS_INT_lib GPS-SD

GPS_INT.cpp

Committer:
j_rocket_boy
Date:
2018-07-11
Revision:
9:9d9e62cebda8
Parent:
3:ba5fb2bb8de5

File content as of revision 9:9d9e62cebda8:

// -*- coding: utf-8 -*-
/**
 @file      GPS_INT.cpp
 @brief     Recieve GPS using Interrupt
 
 @author    D.Nakayama
 @version   1.0
 @date      2018-07-08  D.Nakayama  Written for C++/mbed.
 
 
 @see 
 Copyright (C) 2018 D.Nakayama.
 Released under the MIT license.
 http://opensource.org/licenses/mit-license.php
 
*/

#include "GPS_INT.h"
#include "mbed.h"

GPS_INT::GPS_INT(PinName tx, PinName rx, int baud) : gps(tx, rx, baud) {
    seconds = 0;        //時刻(UTC1900年1月1日からの経過時間)
    lon = 0;            //緯度, 度(北緯が正)
    lat = 0;            //経度, 度(東経が正)
    lock = 0;           //位置特定品質(0:位置特定できない, 1:SPS(標準測位サービス), 2:differencial GPS)
    n_sat = 0;          //使用衛星数
    HDOP = 0;           //水平精度低下率
    VDOP = 0;           //垂直精度低下率
    PDOP = 0;           //位置精度低下率
    h_see = 0;          //アンテナ海抜高さ, m
    h_geo = 0;          //ジオイド高さ, m
    location_update = false;
    info_update = false;
    this->gps.attach(this, &GPS_INT::get_char);
}


GPS_INT::~GPS_INT()
{
}

bool GPS_INT::is_lock(void){
    if(lock == 0){
        return false;
    }
    return true;
}

bool GPS_INT::location_is_update(void){
    if(location_update){
        location_update = false;
        return true;
    }
    return false;
}

bool GPS_INT::info_is_update(void){
    if(info_update){
        info_update = false;
        return true;
    }
    return false;
}

void GPS_INT::gps_update(char* buffer){
    
    //以下捨て変数
    char mode;       //モード(M:手動, A:自動)
    int type;           //特定タイプ(1:存在しない, 2:2D特定, 3:3D特定)
    float v_sur;        //地表における移動速度, km/h
    float ang_v_sur;    //地方における移動速度の真方位, 度
    char status;     //ステータス(V:警告, A:有効)

    if(sscanf(buffer,"GPGGA,%f,%lf,%c,%lf,%c,%d,%d,%f,%f,M,%f,M", &time_raw, &lon_raw, &ns, &lat_raw, &ew, &lock, &n_sat, &HDOP, &h_see, &h_geo)){
    }

    if(sscanf(buffer,"GPGSA,%c,%d", &mode, &type)){

        char buffer2[256];
        int i = 0;
        int j = 0;
        int n = 0;
        while(n != 15){             //コンマを15個探す(衛星番号の部分を飛ばす)
            if(buffer[i] == ','){
                n++;
            }
            i++;
        }
        while(buffer[i+j] != '\0'){   //その後ろをコピー
            buffer2[j] = buffer[i+j];
            j++;
        }
        buffer2[j] = '\0';
        if(lock != 0){
            //DOP取得
            sscanf(buffer2,"%f,%f,%f", &PDOP, &HDOP, &VDOP);
    
            //緯度経度の計算
            lon_int    = (int)lon_raw/100;
            lon_minute = ( lon_raw - 100*lon_int );
            lon = lon_int + lon_minute / 60;
            lat_int    = (int)lat_raw/100;
            lat_minute = ( lat_raw - 100*lat_int );
            lat = lat_int + lat_minute / 60;        
    
            location_update = true;
        }
    }

    if(sscanf(buffer,"GPRMC,%f,%c,%lf,%c,%lf,%c,%f,%f,%d", &time_raw, &status, &lon_raw, &ns, &lat_raw, &ew, &v_sur, &ang_v_sur, &date_raw)){

        if(lock != 0){
            //緯度経度の計算
            lon_int    = (int)lon_raw/100;
            lon_minute = ( lon_raw - 100*lon_int );
            lon = lon_int + lon_minute / 60;        
            if(ns == 's'){
                lon *= -1;
            }
            
            lat_int    = (int)lat_raw/100;
            lat_minute = ( lat_raw - 100*lat_int );
            lat = lat_int + lat_minute / 60;        
            if(ew == 'w'){
                lat *= -1;
            }
    
            v_sur = (float)1.852 * v_sur;     //knotからkm/hへ        
    
            t.tm_sec  = ((int)(time_raw      ))%100;        // 0-59
            t.tm_min  = ((int)(time_raw/100  ))%100;        // 0-59
            t.tm_hour = ((int)(time_raw/10000))%100;        // 0-23
            t.tm_mday = ((int)(date_raw/10000))%100;        // 1-31
            t.tm_mon  = ((int)(date_raw/100  ))%100;        // 0-11
            t.tm_year = ((int)(date_raw      ))%100 + 100;  // year since 1900(just use only 2000~)
            seconds = mktime(&t);
            
            info_update = true;
        }
    }

}

void GPS_INT::get_char(void){
    static char gps_buffer[256];
    static int gps_n = 0;
    char c; //受信文字
    
    c = gps.getc();
    
    if(c == '\r'){
        gps_buffer[gps_n] = '\0';
        gps_update(gps_buffer);
        gps_n = 0;
        return;
    }
    
    if(c == '$'){
        gps_n = 0;
        return;
    }

    gps_buffer[gps_n] = c;
    gps_n++;
    if(gps_n == 256){
        gps_n = 0;
    }
}