今週の放送に関係する資料をアップしておきます。
訂正記事がありますので、必ず!訂正記事を参照してください。
http://p.tl/nOPE
毎週土曜21:00~24:00位まで?週刊Android
Android、Arduino ソフト~ハードまで、IT関連情報、スポーツ(モトクロス等)、海外ドラマ(洋限定)など、
すき放題、やっちゃいますw
twitter:@weeklyandroidjp
USTREAM:http://p.tl/zY22
ニュース(9月):http://p.tl/v76B
月刊Android SNS: http://p.tl/4HTR
エクスレリアレイ評価:http://p.tl/C-WF
今週は、「夜はハードに」Vol6です。
GPSの位置情報取得と表示までやります!
今週もやれるとこまでやりますよ。
1.先週の最後に上げておいたGPSの回路図
2.ソースコード
#include <LiquidCrystal.h>
//LCDのライブラリ初期化
//RS, E, DB4, DB5, DB6, DB7に接続したピン番号
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int DATA_MAX = 20;
int BUFF_MAX = 100;
const int TRUE = 0;
const int FALSE = -1;
const int SPEEDUP_OFFSET = 10;
char gpggaNC[] = "$GPGGA,120042.000,0000.0000,N,0000.0000,E,0,00,0.0,0.0,M,0.0,M,,0000*68\n";
char gpgga[] = "$GPGGA,093227.976,3500.1335,N,13701.2415,E,2,08,1.1,4.7,M,39.4,M,,0000*5B\n";
//初期化
void setup(){
//LCDの桁数、行数指定
lcd.begin(16, 2);
lcd.clear();
//シリアル通信の初期化(9600bpm)
Serial.begin(9600);
char cmd[100] = {"$PMTK314,GLL,RMC,VTG,GGA,GSA,GSV,0,0,0,0,0,0,0,0,0,0,0,ZDA,MCHN,"};
char cmd2[100];
long chksum = calcCheckSum(cmd);
char cchksum[10];
sprintf(cmd2, "%s%2x", cmd, chksum);
Serial.println(cmd2);
//シリアル通信(GPGSV開始)
//Serial.println("$PSRF103,3,0,1,1*26");
//シリアル通信(GPGSV停止)
//Serial.println("$PSRF103,3,0,0,1*27");
//シリアル通信(GPZDA開始)
//Serial.println("$PSRF103,8,0,1,1*2D");
//シリアル通信(GPZDA停止)
//Serial.println("$PSRF103,8,0,0,1*2C");
}
void loop()
{
char str[BUFF_MAX];
char *data[DATA_MAX];
char *pChar = NULL;
int ii = 0;
//データ受信
recvStr(str);
//チェックサム取得
long gotValue = getCheckSum(str);
//チェックサム計算
long calcValue = calcCheckSum(str);
//チェックサム一致?
if(gotValue != calcValue){
return;
}
//データ分解
for(ii=0; ii<DATA_MAX; ii++){
if(0 == ii){
pChar = (char*)strtok(str, ",");
// if(0 == strcmp(pChar, "$GPGGA")){
// lcd.clear();
// lcd.setCursor(0,0);
// lcd.print(pChar);
// delay(700);
// } else if(0 == strcmp(pChar, "$GPGSA")){
// lcd.clear();
// lcd.setCursor(0,0);
// lcd.print(pChar);
// delay(700);
// } else if(0 == strcmp(pChar, "$GPRMC")){
// lcd.clear();
// lcd.setCursor(0,0);
// lcd.print(pChar);
// delay(700);
// } else if(0 == strcmp(pChar, "$GPGSV")){
// lcd.clear();
// lcd.setCursor(0,0);
// lcd.print(pChar);
// delay(700);
// } else if(0 == strcmp(pChar, "$GPGLL")){
// lcd.clear();
// lcd.setCursor(0,0);
// lcd.print(pChar);
// delay(700);
// } else if(0 == strcmp(pChar, "$GPVTG")){
// lcd.clear();
// lcd.setCursor(0,0);
// lcd.print(pChar);
// delay(700);
// } else if(0 == strcmp(pChar, "$GPZDA")){
// lcd.clear();
// lcd.setCursor(0,0);
// lcd.print(pChar);
// delay(700);
// }
if(0 == strcmp(pChar, "$GPGGA")){
data[ii] = pChar;
} else {
//不要
return;
}
} else {
data[ii] = strtok(NULL, ",");
if(NULL == data[ii]){
break;
}
}
}
if(calcValue != gotValue){
//チェックサムNG
lcd.clear();
lcd.setCursor(0,0);
lcd.print("got:");
lcd.print(gotValue);
lcd.setCursor(0,1);
lcd.print("calc:");
lcd.print(calcValue);
} else {
//チェックサムOK
lcd.clear();
lcd.setCursor(0,0);
lcd.print((char*)data[2]);
lcd.print( ":");
// lcd.print(millis());
lcd.print(gotValue);
lcd.setCursor(0,1);
lcd.print((char*)data[4]);
lcd.print( ":");
lcd.print(calcValue);
}
delay(500);
}
/*
* GPSデータ受信用
*/
void recvStr(char *buf)
{
int ii = 0;
char cc;
while (1) {
if (Serial.available()) {
cc = Serial.read();
if (cc == '\n'){
break;
} else if (cc == '\r'){
//何故かこのロジック削ると表示される
break;
} else {
buf[ii] = cc;
}
ii ++;
}
}
//nullをセット
buf[ii] = '\0';
// strcpy(buf, gpgga);
}
/*
* 受信データからチェックサムを取得(正)
* @param 受信バッファ
*/
long getCheckSum(char *buf)
{
char strTmp[3];
long checkSum = 0;
long len = strlen(buf);
char *astPos = NULL;
if(len > SPEEDUP_OFFSET){
astPos = strchr(&buf[len - SPEEDUP_OFFSET], '*');
if(NULL != astPos){
memset(strTmp, 0x00, sizeof(strTmp));
//アスタの次からコピー
strncpy(strTmp, &astPos[1], 2);
checkSum = strtol(strTmp, NULL, 16);
}
}
return(checkSum);
}
/*
* チェックサムを計算
* @return チェックサムの下位1Byte
* @param 受信バッファ
*/
long calcCheckSum(char *buf)
{
int ii = 0;
long lTotal = 0;
long lMasc = 0xFF; //マスク用
long len = strlen(buf);
for(ii=0; ii<len; ii++){
if('$' == buf[ii]){
continue;
} else if('!' == buf[ii]){
continue;
} else if('*' == buf[ii]){
break;
}
//xor
lTotal = lTotal ^ (unsigned char)buf[ii];
}
//念のため1Byteのみ抽出
lTotal = lTotal & lMasc;
return(lTotal);
}
3.注意
参考:トラ技 2011/11 P154~P158
GPSモジュール:GT-723F
記事内容の誤り&ちょっとした情報
今回参考にさせていただいた、トラ技ですが、ちょっとだけ訂正&お得情報がありますので、
報告いたします。
1.TTLレベル出力の話
GT-720Fは、Pin5,6がN.Cになって慰安すが、実はTTLレベルでシリアル通信ができます(仕様では認められていません)ので、ADM3202は必要ないかもです。
2.チェックサムの話
チェックサムの説明(P158)で、「データ先頭からチェックサム直前までの値をすべて加算し、下位2バイトの
データを通信により得た・・・」のくだりですが、性格には次のようになります。
データ先頭から'$','!'を省いた文字コードをxorをとります。チェックサムに使用するバイト数は1バイトです。
4.エクスペリアレイ資料