今週の放送に関係する資料をアップしておきます。

訂正記事がありますので、必ず!訂正記事を参照してください。
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の回路図



WeeklyAndroidJpのブログ




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.エクスペリアレイ資料


http://p.tl/C-WF