GPSモジュール(GMS6-CR6)の動作実験パート2
(GPSをマイコンに繋ぎSDにログを取ります)

〔パート1〕   〔パート3〕 〔パート4〕 〔マイコンのトップに戻る〕


前ページのパート1では、GPSをパソコンと繋ぎリアルタイム?に位置情報を地図に表示しました。
こんどはマイコンと繋ぎSDカードに位置情報を記録しその軌跡を地図に表示する事を行って見ます。
尚、記録データから地図に軌跡を表示する方法は次ページのパート3で行います。

シリアルポートの設定

ボーレートは4800bps固定で、8ビット,stop1ビット,ノンパリティ
だが、GPSにコマンド($PSRF100)を送れば"4800/9600/19200/38400 baud"と変更可能な様である。
例)$PSRF100,0,9600,8,1,0*0C    (未実験)

2017/01/10現在販売されているGMS6-CR6はボーレートが9600bpsに変更されています
  注意しましょう。
 *3)

センテンスについて

GPSが送信してくる位置情報のメッセージをセンテンスと呼んでいます。
このセンテンスは1秒に1回の割合で送信して来ますが、GPSにコマンド($PSRF103)を送れば 1秒〜255秒の範囲で変更可能な様です。 (パート4で実験します)

センテンスの構造
$<トーカーID:GP><センテンスID>,<センテンスパラメータ1>,・・・・・,<センテンスパラメータn>*<チェックサム>
<CR><LF>
例)$GPGGA,060803.585,3252.8010,N,13039.3769,E,1,04,5.2,130.2,M,28.0,M,,0000*5C<CR><LF>
また、チェックサムについてはこちらの毛虫計算機さんブログを参照下さい、 *3)
ここのプログラムではチェックサムのチェックは行っていません。

GMS6-CR6のセンテンスID種類

ID Description
$GPGGA Time, position and fix type data
時間位 置受信衛星数、高度などの修正型 データ
$GPGSA GPS receiver operating mode, satellites used in the position solution, and DOP values
GPS受信機の 動作モード、受信している衛星のID番号、及 びDOP
$GPGSV Number of GPS satellites in view satellite ID numbers, elevation, azimuth, & SNR values
ビュー衛星ID 番号、高度、方位お よびSNR値でのGPS 衛星の数
(これは5秒に1回の間隔で送信されるみたいです)
$GPRMC Time, date, position, course and speed data
時刻、日付位 置進行方向速 度データ、地磁気の偏角
$GPGLL Latitude and longitude of current position, time, and status.
緯度、現在位置、時刻、およびステータスの経度
(オプションらしく送信するようには設定されていない様だ)
$GPVTG Course and speed information relative to the ground
グラウンドを基準とする進行方向と速 度情報
(オプションらしく送信するようには設定されていない様だ)
$GPZDA PPS timing message (synchronized to PPS)
(1PPSに同期したPPSタ イミング(時刻)メッセージ
(オプションらしく送信するようには設定されていない様だ)
$PSRF150 OK to send message
メッセージを送信OK(電源がON時の最初に送信される)
$PSRF156 This is the receiver’s message to request a download.
The download can be started immediately.
メッセージが"有効"になった時に送られて来るが、コールドスタートの時のみか不明?

このGPSは、[$GPGGA][$GPGSA][$GPGSV][$GPRMC]のセンテンスを送信して来ます。
尚、地図でGPSの軌跡を表示させるには[$GPGGA][$GPRMC]が有れば良いので、
SDカードにはこの二つのメッセージのみログとして書き込んでいます。

センテンス内容の少し詳しい説明は、"hiramine.com"さんのこちらのページ、 *3)
又は、"NMEA Reference Manual"を を参照下さい。

センテンスの出力例
$PSRF150,1*3E            // メッセージの送信準備完了かも
$GPGGA,,,,,,0,00,,,M,0.0,M,,0000*48
$GPGSA,M,1,,,,,,,,,,,,,,,*12
$GPRMC,,V,,,,,,,,,,N*53
$GPGGA,,,,,,0,00,,,M,0.0,M,,0000*48
$GPGSA,M,1,,,,,,,,,,,,,,,*12
$GPRMC,,V,,,,,,,,,,N*53
$GPGGA,,,,,,0,00,,,M,0.0,M,,0000*48
$GPGSA,M,1,,,,,,,,,,,,,,,*12
$GPRMC,,V,,,,,,,,,,N*53
$GPGGA,,,,,,0,00,,,M,0.0,M,,0000*48
$GPGSA,M,1,,,,,,,,,,,,,,,*12
$GPRMC,,V,,,,,,,,,,N*53
$GPGGA,,,,,,0,00,,,M,0.0,M,,0000*48
$GPGSA,M,1,,,,,,,,,,,,,,,*12
$GPGSV,3,1,12,01,00,000,,02,00,000,,03,00,000,,04,00,000,*7C
$GPGSV,3,2,12,05,00,000,,06,00,000,,07,00,000,,08,00,000,*77
$GPGSV,3,3,12,09,00,000,,10,00,000,,11,00,000,,12,00,000,*71
$GPRMC,,V,,,,,,,,,,N*53
// ここまでの様にGPSが受信可能状態になるまではセンテンスパラメータ値が空で出力される


// ここから下は受信可能状態になり"有効:"A""なので正常に位置情報が出力される
$PSRF156,23,1,0*09       // 受信して良いですよかも?
$GPGSA,M,3,04,17,20,28,06,01,23,10,32,,,,1.8,1.0,1.5*3E
$GPRMC,075452.000,A,3252.8026,N,13039.3711,E,0.00,2.83,150814,,,A*69
$GPGGA,075453.000,3252.8026,N,13039.3711,E,1,09,1.0,112.7,M,28.0,M,,0000*5D
$GPGSA,M,3,04,17,20,28,06,01,23,10,32,,,,1.8,1.0,1.5*3E
$GPGSV,3,1,12,04,64,002,30,17,62,340,33,20,55,056,28,28,53,204,31*79
$GPGSV,3,2,12,06,33,275,26,01,26,056,15,23,20,115,26,10,17,208,24*72
$GPGSV,3,3,12,32,15,041,21,11,12,080,15,13,09,140,21,57,83,182,*79

《Arduino》

下図が配線図です。
GPSモジュールのピン構成図等の内容は前ページを見るか、詳しい情報はデータシートを参照下さい。

Arduino配線図

GPSの動作電源は5Vです、LEDは470Ω抵抗を介してデジタル出力の7番ピンと配線されていて、
スイッチはデジタル入力の6番ピンと接続し内部プルアップを行っています。

スイッチサイエンスの「マイクロSDシールド」を使い標準の"SD Library"でログを記録しています。
このシールドは、デジタルピンの 8,10,11,12,13 を使っているので、他では使用出来ません。
2017/01/10現在、上記の「マイクロSDシールド」は販売終了となっています、
  代替えの「microSD Shield」を使いましょう。 *3)

GPSとのシリアル通信は標準の"SoftwareSerialライブラリ"を利用しています、
使用しているピンは 受信:RX(2番) 送信:TX(3番) です。

( ス ケ ッ チ )

"ここ"をクリックしダウンロードして下さい。
Arduino Uno R3 を使用し、Arduino IDE 1.0.5-r2 でコンパイルを行っています。

デバッグ用でArduinoIDEのシリアルモニターに出力している記述が有りますが、必要なければ削除
して下さい、プログラムサイズが若干少なくなるでしょう。

ボーレートを4800bpsから9600bpsに変更する場合 *3)
  // GPSとの通信を初期化する
  GPSserial.begin(4800) ;
の記述が有ります。
  // GPSとの通信を初期化する
  GPSserial.begin(9600) ;
と書き換えて下さい。

スケッチの動作について

スイッチがON(LED点灯)でログを記録します、OFF(LED消灯)で記録は停止です。
スイッチがONでも受信したメッセージが"有効"になるまでは記録されません、
"有効"になるまでは時間が掛かります、コールドスタートで約35秒以上・ホットスタートで約1秒程です。
"有効"の判断は、"$GPRMC"センテンスのステータスパラメータが"A"になれば"有効"としています。
(有効の目安はGPSのLEDが点滅したら有効です)

尚、電源の入切りやSDカードの抜き差し時はOFFにしてから行って下さい。
(OFFにしてもSDの電源は接続されている事に注意下さい)

ログのファイル名について
G[ddmmyy][A-Z].TXT
ddmmyy :$GPRMCの日付パラメータから設定します。(UTC)
A-Z   :スイッチをONにする度にA-Zに切替えます、"A-Z"データはEEPROMの0番地に保存します。
      ですのでスイッチをON/OFFする度にファイル名が変わります
例) G220814A.TXT  SWをOFF/ONさせたら次は G220814B.TXT となります。

ログの内容について

GPSの軌跡を地図で表示させるには"$GPGGA"と"$GPRMC"のセンテンスが必要です、
他のセンテンスを記録する場合は、
struct {                                // 受信したセンテンスの書き込み情報
  char sentencesID[7] ;                 // $<センテンスID;3>
  int  WriteFlag ;                      // 1:書き込む  0:書き込まない
} WritingInfo[] = {                     // "$GPGGA"と"$GPRMC"は書込み必須です
  {"$GPGGA",1} ,{"$GPGSA",0} ,{"$GPRMC",1} ,
  {"$GPGLL",0} ,{"$GPGSV",0} ,{"$GPVTG",0} ,{"$GPZDA",0} ,
} ;
と有りますので WriteFlag を0から1に書き換えます。

ログは約3秒に1回の割合で記録されます、
#define WRITE_INTERVAL        3         // センテンスを書き込む間隔の指定
を変更すれば書き込みの間隔を変更できるでしょう。
尚、"有効"+3秒後に記録開始です。


因みにGPSへコマンド($PSRF103)を送りセンテンスの送信される間隔(1秒〜255秒)を変更すれば、
この処理は削除されるのですっきり出来るのですがぁ、パート4で実験します。

( 実験風景 )

実験風景
 最近、目が....
 GPSの配線コネクター線が細くて
 ヘッダピンに半田付けするのも一苦労
 メガネ欲しいかもぉ....。

 このコネクターといい、
 GPSの取付け穴無しといい
 もう少し考えてほしい気がしなくもないがぁ。
 

《PIC》

下図が配線図です。
GPSモジュールのピン構成図等の内容は前ページを見るか、詳しい情報はデータシートを参照下さい。
マイクロSDのピン構成と基本記事はこちらを参照下さい。
I2C接続小型LCDモジュールののピン構成と基本記事はこちらを参照下さい。

GPSはUSART接続、SDはSPI接続、LCDはI2Cでの接続です。
SPIとI2Cの両方を利用するのでPICはMSSP機能が2個ないとダメです、
なので手持ちからPIC16F1827/18F25K22ですが、
16F1827はプログラム容量が足りない(約13K程消費)ので18F25K22としています。
なお、SPIはMSSP1側でLCDはMSSP2側を使っています、またUSARTも2個有るのですがUSART1側を
使いました。

PIC配線図

この回路の電源は3.3Vとしています、
LCDのI2C用プルアップ抵抗とスイッチのプルアップ抵抗はPIC内蔵のプルアップを使っています。
尚、LEDの足が長い方(+:アノード)をPIC側に接続です。

( プログラム )

↓ここからサンプルプログラムソースファイルをダウンロードして下さい。
GPS1.lzh (14/09/27 skSPIlib.cを変更) *1)
GPS1.lzh (skSPIlibを変更 & skSDlibを更新) *2)
GPS1.zip ライブラリ更新による変更 *3)
GPS1.zip"skSDlib.c"の変更により入れ替え *5)

プログラムソースをダウンロードしたら、MPLAB Xにてプロジェクトを作成します。
以下のファイルをプロジェクトディレクトリにコピーしてプロジェクトに取込んで下さい。
次にコンパイルPIC書き込みを実行して下さい。
MPLAB(R) XC8 C Compiler Version 1.32コンパイラを使用しています。

ダウンロードしたら解凍して下さい、以下のファイル構成です。
 GPS.c・・・・・・・・・・・メインのGPSデータロガーサンプルソースプログラム *2) *3) *5)
 skI2CLCDlib.c・・・・I2C接続LCDライブラリ関数ソースファイル *3)
 skI2CLCDlib.h・・・・I2C接続LCDライブラリ用ヘッダファイル *3)
 skI2Clib.c・・・・・・・・I2C通信を行う関数ソースファイル *3)
 skI2Clib.h・・・・・・・・I2C通信を行う関数のヘッダファイル *3)
 skUARTlib.c・・・・・・USART通信を行う関数ソースファイル *3)
 skUARTlib.h・・・・・・USART通信を行う関数のヘッダファイル *3)
 skSDlib.c・・・・・・・・・SDライブラリ関数ソースファイル *2) *5)
 skSDlib.h・・・・・・・・・SDライブラリ用ヘッダファイル *2) *5)
 skSPIlib.c・・・・・・・・ SPI通信を行う関数ソースファイル *2)
 skSPIlib.h・・・・・・・・ SPI通信を行う関数のヘッダファイル *2)

 尚、CPUのクロックは16MHzを想定しています。
 なので通信速度等(USART/I2C)はシステムクロック16MHzで計算されています。

"XC8 Version 1.40"でコンパイルすると"eeprom_read/write"の関数でエラーが出ます、
  この話は、こちらの記事を参照下さい、上プログラムの変更は現在考えていません。
m(_ _)m *3)
  PS.下記の方に修正した変更版を載せて置きました。 *4)

GPS.c

基本動作は上記のArduinoと同様です。
違いはLCD表示部分で、スイッチに応じて[ON]/[OFF]をLCDの1行目に表示させ、スイッチ"ON"後に
受信状態が"有効"であれば1行目にセンテンスからの[日付:ddmmyy]を表示させています。
(有効の目安はGPSのLEDが点滅したら有効です)
LCDの2行目にはSD書き込み時の異常を表示します。

ボーレートを4800bpsから9600bpsに変更する場合(CPU=16MHz) *3)
  // USART通信の初期化を行う(4800bps)
  InitUART(0,0,207) ;
の記述が有ります。
  // USART通信の初期化を行う(9600bps)
  InitUART(0,0,103) ;
と書き換えて下さい。

skI2CLCDlib.c
skI2CLCDlib.h
skI2Clib.c
skI2Clib.h

この内容は”秋月電子I2C接続小型LCDモジュールに表示を行う”を参照下さい。
但し、"skI2Clib.h"はMSSP2側を利用する様に#define定義しています。

skUARTlib.c
skUARTlib.h

この内容は”FT232RL使用によりUSBをシリアル変換してマイコンと繋ぎます”を参照下さい。
但し、"skUARTlib.h"はUSART1側を利用する様に#define定義しています。
また、USARTの受信バッファサイズは128byteとしています。

skSDlib.c
skSDlib.h
skSPIlib.c
skSPIlib.h

この内容は”MMC/SDカードを接続し読書きを行って見ます”を参照下さい。
但し、"skSPIlib.h"はMSSP1側を利用する様に#define定義しています。
また、システムクロックは"16MHz"でSPIの通信速度は"Fosc/4(4MHz)"に変更しています。
尚、SPIの通信速度はSDカードの"スピードクラス"によって異なるので注意が必要かもね。

( MPLAB X の設定 )

コンパイルオプション

PICの動作する速度を若干ですが早く出来ます。
(だったら動作クロックを上げろってか、プログラムを変更するのがめんどいので実験していません!)

IDEメニューバーの「File」 → 「Project Properties (xxxx)」をマウスで順番にクリックします。

MPLABX画面1
Categories:」のパネル内で"XC8 compiler"を選択します。
右のパネルの「Option categories:」で"Optimizations"を選択します。
Speed」項の□にチェックを入れ、[OK]ボタンをクリックします。

"$GPGGA"と"$GPRMC"のセンテンスをSDに書込んでいますがぁ、$GPGSVや$GPGSAも
書込もうとするとするとデータ抜けが発生する様です、
私のSDライブラリが冗長で稚拙でヘタレなので速度がちょっとぉ掛かるみたいでぇ....
沢山書込む場合は調整が必要かもね、でも"GPSBabel"は変換してくれます。

EEPROM書き込み

ファイル名の可変部分をEEPROMに書込んでいますが、デフォルトではコンパイル後PICに書込むと
EEPROMは初期化され書き込まれます、なのでぇちょっとぉ嫌かもぉな人は下記を操作して下さい。

IDEメニューバーの「File」 → 「Project Properties (xxxx)」をマウスで順番にクリックします。

MPLABX画面2
Categories:」のパネル内で"PICkit3"を選択します。
右のパネルの「Option categories:」で"Memories to Progrm"を選択します。
Preserve EEPROM .....」項の□にチェックを入れ、[OK]ボタンをクリックします。


( 32MHz対応プログラムについて ) *4)

上記の方で、XC8 V1.40だとEEPROMのエラーが出ると書きましたがこれに対応した修正版と、
CPUのクロックを32MHzに対応させた変更版をリリースして置きます。

↓ここからプログラムソースファイルをダウンロードして下さい。
GPS1_32.zip
GPS1_32.zip"skSDlib.c"の変更により入れ替え *5)

プログラムソースファイル構成は上記構成に、下のファイルがプラスされています。
 memory.c・・・・・・・・ EEPROMにアクセスする関数のソースファイル
 memory.h・・・・・・・・ EEPROMにアクセスする関数のヘッダファイル
このファイルは、MPLAB X MCC機能で"Generate"させたそのままの出力ファイルです。
又、"skUARTlib"ライブラリのバージョンがアップしています。

※ GPSとの通信速度は4800bpsとなっています、9600bpsにする人は"GPS.c"ファイル内の記述を、
  InitUART(0,0,207) ; と変更しましょう。
※ 私のSDカードは動作していますが、エラー等が出た場合は、SPIの通信速度を落として見て下さい。
  SPI_Init(SPI_MODE3,SPI_CLOCK_DIV4,0) ; の記述をSPI_CLOCK_DIV16にして見ましょう。
  それでもエラーが出る場合は、ノイズ等が考えられます、電池電源にして見ましょう。

( 実験風景 )

実験風景
 ただ単純にロガー機能のみを作るので
 あればLCD機能は取り外しても良いでしょう。
 でも折角自作するなら他のセンサー
 (温度・大気圧・方位等)を取付けて
 見たいよねぇみたいなぁ。


《その他》

GPSへコマンドを送る実験と、センテンスから日付を取り出してLCDに表示する実験はパート4
少し記事にして置きます。

沢山のメッセージを受信しながらSDに書き込むとデータ抜けが発生するでしょう、その場合は
システムクロックを上げたり、USART通信速度を落としたり、
または、マイコンから問合わせてメッセージを受信する等の対策が必要になるかもね。



"skSDlib.c"を変更(*5) 2017/02/26
32MHzとXC8 V1.40対応版のリリース(*4) 2017/02/06
ライブラリ更新による変更と見直し(*3) 2017/01/10
"skSPIlib"のSPI_MODEのCKE(クロック位相)を変更(*2) 2016/06/16
"skSPIlib.c"を変更(*1) 2014/09/27


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2017 Shigehiro Kimura All Rights Reserved.