Arduino에서 GPS 모듈 (GMS7-CR6)에서 날짜 및 시간 획득
소개
RandyHoo( @RandyHoo_ )라고 합니다.
닉시 관 시계를 만들거나하는 임베디드 프로그래머입니다.
닉시 관 시계를 만들 때 빠진 부분이므로 전개합니다.
이번 해설하는 코드는 GitHub 에서 공개하고 있습니다.
실장·해설
이번에 사용한 GPS 모듈은 GMS7-CR6 입니다.
Nixcie_Clock.ino#include <SoftwareSerial.h>
#include <string.h>
#include <stdlib.h>
#include <MsTimer2.h>
#include <Wire.h>
int CalenderArray[6] = {}; //0:Year1桁目, 1:Year2桁目, 2:Month1桁目, 3:Month2桁目, 4:Day1桁目, 5:Day2桁目
int ClockArray[6] = {}; //0:Hour1桁目, 1:Hour2桁目, 2:Min1桁目, 3:Min2桁目, 4:Sec1桁目, 5:Sec2桁目
boolean data_get_flag = false; //GPSデータ取得確認用フラグ
void loop() {
data_get_flag = GPSDataCatch();//初期値設定用のデータ取得
}
GPSDataCatch.inoint GPSDataCatch(){
String year_1; //現在の年1桁目
String year_2; //現在の年2桁目
String month_1; //現在の月1桁目
String month_2; //現在の月2桁目
String day_1; //現在の日1桁目
String day_2; //現在の日2桁目
String hour_1; //現在の時1桁目
String hour_2; //現在の時2桁目
String min_1; //現在の分1桁目
String min_2; //現在の分2桁目
String sec_1; //現在の秒1桁目
String sec_2; //現在の秒2桁目
char GPS_Rx_buf[256]; //受信用バッファ(255文字分)
char GPS_Rx_count; //受信データカウンタ
String want_frame = "$GPRMC"; //データを取り出したいフレーム
String WantStatus = "A"; //ステータス判別用
char data_read_count = 0; //データ読み出しカウンタ
int data_get_flag = false; //データ取得結果
GPS로부터 수신한 데이터를 해석해 갑니다.
문자 변환을 실시하기 위해(때문에), String형으로 취급합니다.
GPSDataCatch.ino //Ackフレームを受信するまでループを回す
do {
if ( sGps.available() ) {
GPS_Rx_buf[ GPS_Rx_count ] = sGps.read();
GPS_Rx_count++;
}
//バッファが溢れそうなら
if ( GPS_Rx_count > 250 ) {
break;
}
} while ( GPS_Rx_buf[ GPS_Rx_count - 1 ] != 0x0A );
GPS_Rx_buf[ GPS_Rx_count ] = '\0'; //一番最後の要素に改行を入れる
String buf_str = GPS_Rx_buf; //Stringで処理するために変換
데이터는 「,」로 단락지어지고 있으므로, 「,」의 위치를 취득해, 필요한 데이터만을 취득해 갑니다.
일시를 취득할 수 없었던 경우에는 이 함수의 반환값으로 false 를 돌려줍니다.
GPSDataCatch.ino //欲しいデータかどうか調べる
//LogSample : $GPRMC,142152.000,A,3247.4679,N,12957.0161,E,0.00,36.32,250116,,,A*5A
if ( want_frame == buf_str.substring( 0, 6 ) && WantStatus == buf_str.substring( 18, 19 ) ) {
data_read_count = buf_str.indexOf( ",", data_read_count ); //1つ目の区切り文字を探す
data_read_count++; //不要データなので次のデータへ
data_read_count = buf_str.indexOf( ",", data_read_count ); //2つ目の区切り文字を探す(時刻)
data_read_count++; //時計・カレンダーでは文字列位置を直指定するので次のデータへ
시각은 UTC(협정 세계시)로 취득하므로, 일본 시간에 수정합니다.
또, 10 이하의 숫자를 「0X」 표시하기 위해서 변환 처리를 씹고 있습니다.
GPSDataCatch.ino String UTC_time = buf_str.substring( 7, 9 ); //時刻修正処理の為にHourを抜き出す
int JP_time = atoi( UTC_time.c_str() ) + 9; //日本時間に修正
//変換した際に24時以上になった場合
if ( JP_time > 23 ) {
JP_time -= 24;
}
String JP_time_str = String( JP_time ); //日本時間に差し換えるためにStringに変換
//時刻が1桁だった場合
if ( JP_time < 10) {
String change_double_digit_calc = JP_time_str.substring( 0, 1 ); //1桁目を保持
JP_time_str = "00"; //JP_time_strのデータ長を2に増設する
char hoge_cddc = *change_double_digit_calc.c_str(); //1桁目に0を差し込むためにchar型に変換
JP_time_str.setCharAt( 0, '0' ); //1桁目を0に差し替える
JP_time_str.setCharAt( 1, hoge_cddc ); //2桁目に1桁目を差し込む
String JP_time_str = String( JP_time ); //もう一度Stringに変換
}
String JP_time_first_digit = JP_time_str.substring( 0, 1 ); //1桁目を取り出す
char hoge_1 = *JP_time_first_digit.c_str(); //char型に変換
String JP_time_second_digit = JP_time_str.substring( 1, 2 ); //2桁目を取り出す
char hoge_2 = *JP_time_second_digit.c_str(); //char型に変換
buf_str.setCharAt( 7, hoge_1 ); //1桁目を差し替える
buf_str.setCharAt( 8, hoge_2 ); //2桁目を差し替える
일시를 취득할 수 있었으므로 각각 int형으로 변환해 배열에 넣어 갑니다.
GPSDataCatch.ino //時1桁目を取得
hour_1 = buf_str.substring( 7, 8 );
ClockArray[0] = hour_1.toInt();
//時2桁目を取得
hour_2 = buf_str.substring( 8, 9 );
ClockArray[1] = hour_2.toInt();
//分1桁目を取得
min_1 = buf_str.substring( 9, 10 );
ClockArray[2] = min_1.toInt();
//分2桁目を取得
min_2 = buf_str.substring( 10, 11 );
ClockArray[3] = min_2.toInt();
//秒1桁目を取得
sec_1 = buf_str.substring( 11, 12 );
ClockArray[4] = sec_1.toInt();
//秒2桁目を取得
sec_2 = buf_str.substring( 12, 13 );
ClockArray[5] = sec_2.toInt();
//3~9つ目までの区切り文字をスキップする
for (int i = 0; i < 7; i++) {
data_read_count = buf_str.indexOf( ",", data_read_count ); //3つ目の区切り文字を探す
data_read_count++; //不要データなので次のデータへ
}
//日1桁目を取得
day_1 = buf_str.substring( data_read_count, data_read_count + 1 );
CalenderArray[4] = day_1.toInt();
data_read_count++;
//日2桁目を取得
day_2 = buf_str.substring( data_read_count, data_read_count + 1 );
CalenderArray[5] = day_2.toInt();
data_read_count++;
//月1桁目を取得
month_1 = buf_str.substring( data_read_count, data_read_count + 1 );
CalenderArray[2] = month_1.toInt();
data_read_count++;
//月2桁目を取得
month_2 = buf_str.substring( data_read_count, data_read_count + 1 );
CalenderArray[3] = month_2.toInt();
data_read_count++;
//年1桁目を取得
year_1 = buf_str.substring( data_read_count, data_read_count + 1 );
CalenderArray[0] = year_1.toInt();
data_read_count++;
//年2桁目を取得
year_2 = buf_str.substring( data_read_count, data_read_count + 1 );
CalenderArray[1] = year_2.toInt();
이상입니다.
Reference
이 문제에 관하여(Arduino에서 GPS 모듈 (GMS7-CR6)에서 날짜 및 시간 획득), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/RandyHoo/items/c623438efd73d7df1f0e
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
이번에 사용한 GPS 모듈은 GMS7-CR6 입니다.
Nixcie_Clock.ino
#include <SoftwareSerial.h>
#include <string.h>
#include <stdlib.h>
#include <MsTimer2.h>
#include <Wire.h>
int CalenderArray[6] = {}; //0:Year1桁目, 1:Year2桁目, 2:Month1桁目, 3:Month2桁目, 4:Day1桁目, 5:Day2桁目
int ClockArray[6] = {}; //0:Hour1桁目, 1:Hour2桁目, 2:Min1桁目, 3:Min2桁目, 4:Sec1桁目, 5:Sec2桁目
boolean data_get_flag = false; //GPSデータ取得確認用フラグ
void loop() {
data_get_flag = GPSDataCatch();//初期値設定用のデータ取得
}
GPSDataCatch.ino
int GPSDataCatch(){
String year_1; //現在の年1桁目
String year_2; //現在の年2桁目
String month_1; //現在の月1桁目
String month_2; //現在の月2桁目
String day_1; //現在の日1桁目
String day_2; //現在の日2桁目
String hour_1; //現在の時1桁目
String hour_2; //現在の時2桁目
String min_1; //現在の分1桁目
String min_2; //現在の分2桁目
String sec_1; //現在の秒1桁目
String sec_2; //現在の秒2桁目
char GPS_Rx_buf[256]; //受信用バッファ(255文字分)
char GPS_Rx_count; //受信データカウンタ
String want_frame = "$GPRMC"; //データを取り出したいフレーム
String WantStatus = "A"; //ステータス判別用
char data_read_count = 0; //データ読み出しカウンタ
int data_get_flag = false; //データ取得結果
GPS로부터 수신한 데이터를 해석해 갑니다.
문자 변환을 실시하기 위해(때문에), String형으로 취급합니다.
GPSDataCatch.ino
//Ackフレームを受信するまでループを回す
do {
if ( sGps.available() ) {
GPS_Rx_buf[ GPS_Rx_count ] = sGps.read();
GPS_Rx_count++;
}
//バッファが溢れそうなら
if ( GPS_Rx_count > 250 ) {
break;
}
} while ( GPS_Rx_buf[ GPS_Rx_count - 1 ] != 0x0A );
GPS_Rx_buf[ GPS_Rx_count ] = '\0'; //一番最後の要素に改行を入れる
String buf_str = GPS_Rx_buf; //Stringで処理するために変換
데이터는 「,」로 단락지어지고 있으므로, 「,」의 위치를 취득해, 필요한 데이터만을 취득해 갑니다.
일시를 취득할 수 없었던 경우에는 이 함수의 반환값으로 false 를 돌려줍니다.
GPSDataCatch.ino
//欲しいデータかどうか調べる
//LogSample : $GPRMC,142152.000,A,3247.4679,N,12957.0161,E,0.00,36.32,250116,,,A*5A
if ( want_frame == buf_str.substring( 0, 6 ) && WantStatus == buf_str.substring( 18, 19 ) ) {
data_read_count = buf_str.indexOf( ",", data_read_count ); //1つ目の区切り文字を探す
data_read_count++; //不要データなので次のデータへ
data_read_count = buf_str.indexOf( ",", data_read_count ); //2つ目の区切り文字を探す(時刻)
data_read_count++; //時計・カレンダーでは文字列位置を直指定するので次のデータへ
시각은 UTC(협정 세계시)로 취득하므로, 일본 시간에 수정합니다.
또, 10 이하의 숫자를 「0X」 표시하기 위해서 변환 처리를 씹고 있습니다.
GPSDataCatch.ino
String UTC_time = buf_str.substring( 7, 9 ); //時刻修正処理の為にHourを抜き出す
int JP_time = atoi( UTC_time.c_str() ) + 9; //日本時間に修正
//変換した際に24時以上になった場合
if ( JP_time > 23 ) {
JP_time -= 24;
}
String JP_time_str = String( JP_time ); //日本時間に差し換えるためにStringに変換
//時刻が1桁だった場合
if ( JP_time < 10) {
String change_double_digit_calc = JP_time_str.substring( 0, 1 ); //1桁目を保持
JP_time_str = "00"; //JP_time_strのデータ長を2に増設する
char hoge_cddc = *change_double_digit_calc.c_str(); //1桁目に0を差し込むためにchar型に変換
JP_time_str.setCharAt( 0, '0' ); //1桁目を0に差し替える
JP_time_str.setCharAt( 1, hoge_cddc ); //2桁目に1桁目を差し込む
String JP_time_str = String( JP_time ); //もう一度Stringに変換
}
String JP_time_first_digit = JP_time_str.substring( 0, 1 ); //1桁目を取り出す
char hoge_1 = *JP_time_first_digit.c_str(); //char型に変換
String JP_time_second_digit = JP_time_str.substring( 1, 2 ); //2桁目を取り出す
char hoge_2 = *JP_time_second_digit.c_str(); //char型に変換
buf_str.setCharAt( 7, hoge_1 ); //1桁目を差し替える
buf_str.setCharAt( 8, hoge_2 ); //2桁目を差し替える
일시를 취득할 수 있었으므로 각각 int형으로 변환해 배열에 넣어 갑니다.
GPSDataCatch.ino
//時1桁目を取得
hour_1 = buf_str.substring( 7, 8 );
ClockArray[0] = hour_1.toInt();
//時2桁目を取得
hour_2 = buf_str.substring( 8, 9 );
ClockArray[1] = hour_2.toInt();
//分1桁目を取得
min_1 = buf_str.substring( 9, 10 );
ClockArray[2] = min_1.toInt();
//分2桁目を取得
min_2 = buf_str.substring( 10, 11 );
ClockArray[3] = min_2.toInt();
//秒1桁目を取得
sec_1 = buf_str.substring( 11, 12 );
ClockArray[4] = sec_1.toInt();
//秒2桁目を取得
sec_2 = buf_str.substring( 12, 13 );
ClockArray[5] = sec_2.toInt();
//3~9つ目までの区切り文字をスキップする
for (int i = 0; i < 7; i++) {
data_read_count = buf_str.indexOf( ",", data_read_count ); //3つ目の区切り文字を探す
data_read_count++; //不要データなので次のデータへ
}
//日1桁目を取得
day_1 = buf_str.substring( data_read_count, data_read_count + 1 );
CalenderArray[4] = day_1.toInt();
data_read_count++;
//日2桁目を取得
day_2 = buf_str.substring( data_read_count, data_read_count + 1 );
CalenderArray[5] = day_2.toInt();
data_read_count++;
//月1桁目を取得
month_1 = buf_str.substring( data_read_count, data_read_count + 1 );
CalenderArray[2] = month_1.toInt();
data_read_count++;
//月2桁目を取得
month_2 = buf_str.substring( data_read_count, data_read_count + 1 );
CalenderArray[3] = month_2.toInt();
data_read_count++;
//年1桁目を取得
year_1 = buf_str.substring( data_read_count, data_read_count + 1 );
CalenderArray[0] = year_1.toInt();
data_read_count++;
//年2桁目を取得
year_2 = buf_str.substring( data_read_count, data_read_count + 1 );
CalenderArray[1] = year_2.toInt();
이상입니다.
Reference
이 문제에 관하여(Arduino에서 GPS 모듈 (GMS7-CR6)에서 날짜 및 시간 획득), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/RandyHoo/items/c623438efd73d7df1f0e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)