Receive GPS by interrupt processing
Dependents: Sample_GPS_INT_lib GPS-SD
GPS_INT.cpp@9:9d9e62cebda8, 2018-07-11 (annotated)
- Committer:
- j_rocket_boy
- Date:
- Wed Jul 11 16:26:59 2018 +0000
- Revision:
- 9:9d9e62cebda8
- Parent:
- 3:ba5fb2bb8de5
modify license year
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
j_rocket_boy | 1:fbe835e114bb | 1 | // -*- coding: utf-8 -*- |
j_rocket_boy | 1:fbe835e114bb | 2 | /** |
j_rocket_boy | 1:fbe835e114bb | 3 | @file GPS_INT.cpp |
j_rocket_boy | 1:fbe835e114bb | 4 | @brief Recieve GPS using Interrupt |
j_rocket_boy | 1:fbe835e114bb | 5 | |
j_rocket_boy | 1:fbe835e114bb | 6 | @author D.Nakayama |
j_rocket_boy | 1:fbe835e114bb | 7 | @version 1.0 |
j_rocket_boy | 1:fbe835e114bb | 8 | @date 2018-07-08 D.Nakayama Written for C++/mbed. |
j_rocket_boy | 1:fbe835e114bb | 9 | |
j_rocket_boy | 1:fbe835e114bb | 10 | |
j_rocket_boy | 1:fbe835e114bb | 11 | @see |
j_rocket_boy | 9:9d9e62cebda8 | 12 | Copyright (C) 2018 D.Nakayama. |
j_rocket_boy | 1:fbe835e114bb | 13 | Released under the MIT license. |
j_rocket_boy | 1:fbe835e114bb | 14 | http://opensource.org/licenses/mit-license.php |
j_rocket_boy | 1:fbe835e114bb | 15 | |
j_rocket_boy | 1:fbe835e114bb | 16 | */ |
j_rocket_boy | 1:fbe835e114bb | 17 | |
j_rocket_boy | 0:4b6c377342d9 | 18 | #include "GPS_INT.h" |
j_rocket_boy | 0:4b6c377342d9 | 19 | #include "mbed.h" |
j_rocket_boy | 0:4b6c377342d9 | 20 | |
j_rocket_boy | 0:4b6c377342d9 | 21 | GPS_INT::GPS_INT(PinName tx, PinName rx, int baud) : gps(tx, rx, baud) { |
j_rocket_boy | 0:4b6c377342d9 | 22 | seconds = 0; //時刻(UTC1900年1月1日からの経過時間) |
j_rocket_boy | 0:4b6c377342d9 | 23 | lon = 0; //緯度, 度(北緯が正) |
j_rocket_boy | 0:4b6c377342d9 | 24 | lat = 0; //経度, 度(東経が正) |
j_rocket_boy | 0:4b6c377342d9 | 25 | lock = 0; //位置特定品質(0:位置特定できない, 1:SPS(標準測位サービス), 2:differencial GPS) |
j_rocket_boy | 0:4b6c377342d9 | 26 | n_sat = 0; //使用衛星数 |
j_rocket_boy | 0:4b6c377342d9 | 27 | HDOP = 0; //水平精度低下率 |
j_rocket_boy | 0:4b6c377342d9 | 28 | VDOP = 0; //垂直精度低下率 |
j_rocket_boy | 0:4b6c377342d9 | 29 | PDOP = 0; //位置精度低下率 |
j_rocket_boy | 0:4b6c377342d9 | 30 | h_see = 0; //アンテナ海抜高さ, m |
j_rocket_boy | 0:4b6c377342d9 | 31 | h_geo = 0; //ジオイド高さ, m |
j_rocket_boy | 0:4b6c377342d9 | 32 | location_update = false; |
j_rocket_boy | 0:4b6c377342d9 | 33 | info_update = false; |
j_rocket_boy | 0:4b6c377342d9 | 34 | this->gps.attach(this, &GPS_INT::get_char); |
j_rocket_boy | 0:4b6c377342d9 | 35 | } |
j_rocket_boy | 0:4b6c377342d9 | 36 | |
j_rocket_boy | 0:4b6c377342d9 | 37 | |
j_rocket_boy | 0:4b6c377342d9 | 38 | GPS_INT::~GPS_INT() |
j_rocket_boy | 0:4b6c377342d9 | 39 | { |
j_rocket_boy | 0:4b6c377342d9 | 40 | } |
j_rocket_boy | 0:4b6c377342d9 | 41 | |
j_rocket_boy | 0:4b6c377342d9 | 42 | bool GPS_INT::is_lock(void){ |
j_rocket_boy | 0:4b6c377342d9 | 43 | if(lock == 0){ |
j_rocket_boy | 0:4b6c377342d9 | 44 | return false; |
j_rocket_boy | 0:4b6c377342d9 | 45 | } |
j_rocket_boy | 0:4b6c377342d9 | 46 | return true; |
j_rocket_boy | 0:4b6c377342d9 | 47 | } |
j_rocket_boy | 0:4b6c377342d9 | 48 | |
j_rocket_boy | 0:4b6c377342d9 | 49 | bool GPS_INT::location_is_update(void){ |
j_rocket_boy | 0:4b6c377342d9 | 50 | if(location_update){ |
j_rocket_boy | 0:4b6c377342d9 | 51 | location_update = false; |
j_rocket_boy | 0:4b6c377342d9 | 52 | return true; |
j_rocket_boy | 0:4b6c377342d9 | 53 | } |
j_rocket_boy | 0:4b6c377342d9 | 54 | return false; |
j_rocket_boy | 0:4b6c377342d9 | 55 | } |
j_rocket_boy | 0:4b6c377342d9 | 56 | |
j_rocket_boy | 0:4b6c377342d9 | 57 | bool GPS_INT::info_is_update(void){ |
j_rocket_boy | 0:4b6c377342d9 | 58 | if(info_update){ |
j_rocket_boy | 0:4b6c377342d9 | 59 | info_update = false; |
j_rocket_boy | 0:4b6c377342d9 | 60 | return true; |
j_rocket_boy | 0:4b6c377342d9 | 61 | } |
j_rocket_boy | 0:4b6c377342d9 | 62 | return false; |
j_rocket_boy | 0:4b6c377342d9 | 63 | } |
j_rocket_boy | 0:4b6c377342d9 | 64 | |
j_rocket_boy | 0:4b6c377342d9 | 65 | void GPS_INT::gps_update(char* buffer){ |
j_rocket_boy | 0:4b6c377342d9 | 66 | |
j_rocket_boy | 0:4b6c377342d9 | 67 | //以下捨て変数 |
j_rocket_boy | 0:4b6c377342d9 | 68 | char mode; //モード(M:手動, A:自動) |
j_rocket_boy | 0:4b6c377342d9 | 69 | int type; //特定タイプ(1:存在しない, 2:2D特定, 3:3D特定) |
j_rocket_boy | 0:4b6c377342d9 | 70 | float v_sur; //地表における移動速度, km/h |
j_rocket_boy | 0:4b6c377342d9 | 71 | float ang_v_sur; //地方における移動速度の真方位, 度 |
j_rocket_boy | 0:4b6c377342d9 | 72 | char status; //ステータス(V:警告, A:有効) |
j_rocket_boy | 0:4b6c377342d9 | 73 | |
j_rocket_boy | 0:4b6c377342d9 | 74 | 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)){ |
j_rocket_boy | 0:4b6c377342d9 | 75 | } |
j_rocket_boy | 0:4b6c377342d9 | 76 | |
j_rocket_boy | 0:4b6c377342d9 | 77 | if(sscanf(buffer,"GPGSA,%c,%d", &mode, &type)){ |
j_rocket_boy | 0:4b6c377342d9 | 78 | |
j_rocket_boy | 0:4b6c377342d9 | 79 | char buffer2[256]; |
j_rocket_boy | 0:4b6c377342d9 | 80 | int i = 0; |
j_rocket_boy | 0:4b6c377342d9 | 81 | int j = 0; |
j_rocket_boy | 0:4b6c377342d9 | 82 | int n = 0; |
j_rocket_boy | 0:4b6c377342d9 | 83 | while(n != 15){ //コンマを15個探す(衛星番号の部分を飛ばす) |
j_rocket_boy | 0:4b6c377342d9 | 84 | if(buffer[i] == ','){ |
j_rocket_boy | 0:4b6c377342d9 | 85 | n++; |
j_rocket_boy | 0:4b6c377342d9 | 86 | } |
j_rocket_boy | 0:4b6c377342d9 | 87 | i++; |
j_rocket_boy | 0:4b6c377342d9 | 88 | } |
j_rocket_boy | 0:4b6c377342d9 | 89 | while(buffer[i+j] != '\0'){ //その後ろをコピー |
j_rocket_boy | 0:4b6c377342d9 | 90 | buffer2[j] = buffer[i+j]; |
j_rocket_boy | 0:4b6c377342d9 | 91 | j++; |
j_rocket_boy | 0:4b6c377342d9 | 92 | } |
j_rocket_boy | 0:4b6c377342d9 | 93 | buffer2[j] = '\0'; |
j_rocket_boy | 0:4b6c377342d9 | 94 | if(lock != 0){ |
j_rocket_boy | 0:4b6c377342d9 | 95 | //DOP取得 |
j_rocket_boy | 0:4b6c377342d9 | 96 | sscanf(buffer2,"%f,%f,%f", &PDOP, &HDOP, &VDOP); |
j_rocket_boy | 0:4b6c377342d9 | 97 | |
j_rocket_boy | 0:4b6c377342d9 | 98 | //緯度経度の計算 |
j_rocket_boy | 0:4b6c377342d9 | 99 | lon_int = (int)lon_raw/100; |
j_rocket_boy | 0:4b6c377342d9 | 100 | lon_minute = ( lon_raw - 100*lon_int ); |
j_rocket_boy | 0:4b6c377342d9 | 101 | lon = lon_int + lon_minute / 60; |
j_rocket_boy | 0:4b6c377342d9 | 102 | lat_int = (int)lat_raw/100; |
j_rocket_boy | 0:4b6c377342d9 | 103 | lat_minute = ( lat_raw - 100*lat_int ); |
j_rocket_boy | 0:4b6c377342d9 | 104 | lat = lat_int + lat_minute / 60; |
j_rocket_boy | 0:4b6c377342d9 | 105 | |
j_rocket_boy | 0:4b6c377342d9 | 106 | location_update = true; |
j_rocket_boy | 0:4b6c377342d9 | 107 | } |
j_rocket_boy | 0:4b6c377342d9 | 108 | } |
j_rocket_boy | 0:4b6c377342d9 | 109 | |
j_rocket_boy | 0:4b6c377342d9 | 110 | 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)){ |
j_rocket_boy | 0:4b6c377342d9 | 111 | |
j_rocket_boy | 0:4b6c377342d9 | 112 | if(lock != 0){ |
j_rocket_boy | 0:4b6c377342d9 | 113 | //緯度経度の計算 |
j_rocket_boy | 0:4b6c377342d9 | 114 | lon_int = (int)lon_raw/100; |
j_rocket_boy | 0:4b6c377342d9 | 115 | lon_minute = ( lon_raw - 100*lon_int ); |
j_rocket_boy | 0:4b6c377342d9 | 116 | lon = lon_int + lon_minute / 60; |
j_rocket_boy | 0:4b6c377342d9 | 117 | if(ns == 's'){ |
j_rocket_boy | 0:4b6c377342d9 | 118 | lon *= -1; |
j_rocket_boy | 0:4b6c377342d9 | 119 | } |
j_rocket_boy | 0:4b6c377342d9 | 120 | |
j_rocket_boy | 0:4b6c377342d9 | 121 | lat_int = (int)lat_raw/100; |
j_rocket_boy | 0:4b6c377342d9 | 122 | lat_minute = ( lat_raw - 100*lat_int ); |
j_rocket_boy | 0:4b6c377342d9 | 123 | lat = lat_int + lat_minute / 60; |
j_rocket_boy | 0:4b6c377342d9 | 124 | if(ew == 'w'){ |
j_rocket_boy | 0:4b6c377342d9 | 125 | lat *= -1; |
j_rocket_boy | 0:4b6c377342d9 | 126 | } |
j_rocket_boy | 0:4b6c377342d9 | 127 | |
j_rocket_boy | 0:4b6c377342d9 | 128 | v_sur = (float)1.852 * v_sur; //knotからkm/hへ |
j_rocket_boy | 0:4b6c377342d9 | 129 | |
j_rocket_boy | 0:4b6c377342d9 | 130 | t.tm_sec = ((int)(time_raw ))%100; // 0-59 |
j_rocket_boy | 0:4b6c377342d9 | 131 | t.tm_min = ((int)(time_raw/100 ))%100; // 0-59 |
j_rocket_boy | 0:4b6c377342d9 | 132 | t.tm_hour = ((int)(time_raw/10000))%100; // 0-23 |
j_rocket_boy | 0:4b6c377342d9 | 133 | t.tm_mday = ((int)(date_raw/10000))%100; // 1-31 |
j_rocket_boy | 0:4b6c377342d9 | 134 | t.tm_mon = ((int)(date_raw/100 ))%100; // 0-11 |
j_rocket_boy | 0:4b6c377342d9 | 135 | t.tm_year = ((int)(date_raw ))%100 + 100; // year since 1900(just use only 2000~) |
j_rocket_boy | 0:4b6c377342d9 | 136 | seconds = mktime(&t); |
j_rocket_boy | 0:4b6c377342d9 | 137 | |
j_rocket_boy | 0:4b6c377342d9 | 138 | info_update = true; |
j_rocket_boy | 0:4b6c377342d9 | 139 | } |
j_rocket_boy | 0:4b6c377342d9 | 140 | } |
j_rocket_boy | 0:4b6c377342d9 | 141 | |
j_rocket_boy | 0:4b6c377342d9 | 142 | } |
j_rocket_boy | 0:4b6c377342d9 | 143 | |
j_rocket_boy | 0:4b6c377342d9 | 144 | void GPS_INT::get_char(void){ |
j_rocket_boy | 0:4b6c377342d9 | 145 | static char gps_buffer[256]; |
j_rocket_boy | 0:4b6c377342d9 | 146 | static int gps_n = 0; |
j_rocket_boy | 0:4b6c377342d9 | 147 | char c; //受信文字 |
j_rocket_boy | 0:4b6c377342d9 | 148 | |
j_rocket_boy | 0:4b6c377342d9 | 149 | c = gps.getc(); |
j_rocket_boy | 0:4b6c377342d9 | 150 | |
j_rocket_boy | 0:4b6c377342d9 | 151 | if(c == '\r'){ |
j_rocket_boy | 0:4b6c377342d9 | 152 | gps_buffer[gps_n] = '\0'; |
j_rocket_boy | 0:4b6c377342d9 | 153 | gps_update(gps_buffer); |
j_rocket_boy | 0:4b6c377342d9 | 154 | gps_n = 0; |
j_rocket_boy | 0:4b6c377342d9 | 155 | return; |
j_rocket_boy | 0:4b6c377342d9 | 156 | } |
j_rocket_boy | 0:4b6c377342d9 | 157 | |
j_rocket_boy | 0:4b6c377342d9 | 158 | if(c == '$'){ |
j_rocket_boy | 0:4b6c377342d9 | 159 | gps_n = 0; |
j_rocket_boy | 0:4b6c377342d9 | 160 | return; |
j_rocket_boy | 0:4b6c377342d9 | 161 | } |
j_rocket_boy | 0:4b6c377342d9 | 162 | |
j_rocket_boy | 0:4b6c377342d9 | 163 | gps_buffer[gps_n] = c; |
j_rocket_boy | 0:4b6c377342d9 | 164 | gps_n++; |
j_rocket_boy | 0:4b6c377342d9 | 165 | if(gps_n == 256){ |
j_rocket_boy | 0:4b6c377342d9 | 166 | gps_n = 0; |
j_rocket_boy | 0:4b6c377342d9 | 167 | } |
j_rocket_boy | 0:4b6c377342d9 | 168 | } |