STM32でSC2004とMAX7219を使ってGPSから時刻を取得表示してみる。

投稿者: | 2020/01/04

u-blox M8を使ったGPSモジュールを入手しました。今回はこのGPSから測位情報、時刻情報を取得しLCDのSC2004とMAX7219を使った7セグLEDに情報を表示するようにしてみます。今回もArduino用ではありません。(部分的にはArduinoでも使えない事はないと思いますが)

SC2004は以前紹介したSC1602を20文字x4行にしたものです。ドライバICはSC1602と同じで、表示用のアドレスのみ異なります。SC1602と同様にI2Cを使って制御します。
MAX7219は7セグLED 8桁をドライブできるICです。こちらはSPIで制御します。今回も、I2C,SPIともにH/Wペリフェラルは使わず、S/Wで制御します。MAX7219にはTM1638で作ったドライバが小修正で使えます。

GPSは秋月電子で購入したu-blox M8モジュールを使います。UARTの通信速度はデフォルトの9600bpsです。
SC2004は表示できる文字も多いので、ついでにBME280で測定した気温、湿度、気圧も合わせて表示します。

マイコンはいつもの通り、STM32F103C8T6を搭載したBlue Pillボードを使いました。FreeRTOSを使用し、C++でコーディングしています。(組み込みなので、クラスが使えるCレベルの使い方です)

こんな感じです。(デモ表示用に、緯度経度の小数点以下は強制的に0で表示しています)

SC2004は、I2Cで通信するのに加え液晶ですので応答が遅く、時刻表示の更新速度を上げるのが難しいため、秒までの表示とし、秒以下の時刻は、MAX7219の7セグLEDに表示することにします。上位4桁のLEDはダブルコロン付きのものに変更しています。GPSモジュールからの1ppsパルスに同期し、内部クロックで10ms毎に更新します。1PPSパルスの立ち上がりエッジとMAX7219のCSの立ち上がりエッジまでの遅延はだいたい0.5ms程度でした。表示例は、13時56分20秒+760msです。毎0秒に秒のコロンを100ms間点灯します。(こちらも約0.5ms程度のディレイがあります)
また、Blue Pillボードの緑LEDも1pps出力に同期し100ms間点灯します。こちらは1ppsに対して50us程度(割り込み+α)のディレイでした。

STM32CubeIDE(CubeMX)でのConfigurationはSTM32_RTOS_SC1602_BME280_GPSを参照してください。I2Cを使用するSC2004とBME280は別タスクにしましたので、ポートを分けました。
RTCも設定していますが、結局使用していません。

MAX7219のドライバです。

フォントはTM1638で作ったものを再利用しています。
TM1638は、LSBファーストのフォーマットでしたので、MSBファーストに変換するのが面倒でfontConvert()を使って変換しています。無駄な処理ですね…

実際にMAX7219で表示させる処理はTaskMax7219()で行なっています。

実装部分です。FreeRTOSのTaskとしています。
別のタスクからMailQueueで送られた文字列を表示します。

SC1602からSC2004用に改造した部分です。文字の表示位置を設定するsetCursorPosition()を変更します。

GPSモジュールから送られてくるNMEAセンテンスを解析する関数です。
RMCとGGAのみ解析し、日付、時刻、位置情報、衛星の受信数を取得しています。
UARTで受信したNMEAセンテンス(NULL終端)をparseNmea()に渡します。
NMEAセンテンスのチェックサムはUARTの受信処理で確認してしています。
mStrlen()はstrlen()と同じですが、最大文字列長を制限しています。
日付、時刻情報が取得できない場合は、2001/1/1/09:00(JST)になります。(1秒前の値を設定しています)

 

mStrtok_r()はstrtok()の自作リエントラント版です。トークンは一つしか指定できません。GPSがきちんと受信できるまでNMEAセンテンスは”,”が連続し”,,”となることがあります。strtok()では無視されるのでmStrtok()ではちょっと仕様を変えています。c2i()はcharからintに変換する関数です。atoi()でも良いですが、小数点以下、文字列の制限などを考え一文字だけ変換にしました。

GPSの時刻は表示するときに+9時間してJSTに変換しています。

最後まで読んでいただいた貴方にバイナリを差し上げます。STM32_RTOS_SC1602_BME280_GPS.elf
ピンアサインは以下の通りです。詳細はSTM32_RTOS_SC1602_BME280_GPS.pdfを参照してください。

  • SC2004 は、 PCF8574(スレーブアドレス 0x27)が接続されたものを使用してください。
    PB8: SDA, PB9:SCL に接続してください。
  • BME280は、I2Cモード(スレーブアドレス 0x76)を使用してください。
    PB6: BME_SDA, PB7:BME_SCLに接続してください。
  • MAX7219は、PB12:MAX_DOUT, PB13:MAX_CS, PB14:MAX_CLKに接続してください。
    PB15への接続は不要です。
  • GPSモジュールからのUART-TXはPA3:UART_RXに接続してください。
    GPSモジュールからのUART-RXは接続不要です。
  • GPSモジュールの1PPS出力はPB4:PPS_INに接続してください。

気温がマイナスの時の表示と南半球での緯度経度表示は確認していませんので正しく表示されないかも知れません。

本バイナリオブジェクトは、Arduino用ではありませんので、このバイナリオブジェクトを書き込むとArduino用のブートローダーが消えてしまいます。復元の方法は当方ではサポートできません。動作しない、誤動作する、本記事および関連記事、バイナリオブジェクトを使用して発生したいかなる被害、損失等についても当方は責任を負いません、また、いかなる保証もしません。自己責任でお使いください。無断転載、及び商用利用は禁止します。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください