GPS and MSP430 (Japanese)

ソロバン評価ボードについて
Discussions about soft and hard solutions with Soroban development board.

GPS and MSP430 (Japanese)

Postby pascal » Sun Mar 18, 2007 8:05 pm

皆さんこんにちは。


今日は去年開発したGPS端末について報告したいと思います。当初、ソロバン
初期バージョン上で構築しました。今日はソフトの更新を考えて、CCEで
開発されたコードをIARでコンパイルしました。割り込み関数の宣言を変えて、
再コンパイルしただけで動きました。

GPSモジュール


このモジュールはパッチアンテナを搭載するので小型です。


Image


厚さの方は9mm以下です。写真がうまく撮れてなくてすみません。カメラは
7年前に買ったキャノンの初期PowershotG1.

Image

開発プラットホーム
今回はソロバンを使って、電源は小型のリチウムポリマーにしました。GPSモジュールの
仕様書によると、消費電力は28mAです。ソロバン自体(MSP430+RTC+LCD)は合計5mA
位です。バッテリーの方は650mAh。楽観的な値が書いてあるとしても多分400mAhは
期待できると思われます。10時間位連続使用できるので殆どの場合には十分だと考えら
れます。

Image

ソロバン拡張ボードにモジュールを配線する。


配線する前は、アンテナの3ピンはピッチからずれているので穴を開ける事にしました。

Image


モジュールの配線は7本で済みました。電源、UART、Reset. Resetのほうは、
そのままMSP430から配線したら動作できなかった。理由は仕様書によると、Resetは
2V位でなければならないからと分かりました。(モジュールは無事でした)
3.3から2Vに変換するためにチップ抵抗を2個使用して、電圧を3.3から1.65に落しました。
次の写真はチップ抵抗を示しています。左の抵抗はMSP430のP4.3(ピン39)に、右側の
抵抗はGNDに接続されていて、その間の線はGPSモジュールのReset信号になります。

Image

ソフトウエア

ソフトウエアは以下の通りです。
UARTを制御する関数を書きました。下記ソースコードはデモのため大雑把に書いたので
ご了承下さい。

UARTソースコード
ヘッダーファイル(.h)は以下の通り: (types.h defines uint8, uint16, etc...)

Code: Select all
#ifndef _USART_H_
#define _USART_H_
#include <msp430x16x.h>
#include "types.h"

//   Non-realtime functions. These are configuration functions.
//   This is to be changed to reduce the number of functions.
//   USART0 inits:

void InitUsart0(void);
void USART0Enable(void);
void USART0Disable(void);
void SetUSART0Rate(uint16 freq);
void Enable_IE_USART0(void);
void Disable_IE_USART0(void);
void SetTimeout(uint8 which, uint16 t);

//   Realtime functions (USART0 send and receive functions)

void USART0SendByte(uint8 byte);
void USART0SendBuffer(uint8 * buf, uint16 len);
uint8 USART0RecvByte(void);
uint16 USART0RecvBuffer(uint8 * buf, uint16 len);

#endif




Cファイルは以下の通り。
globals.h は外付け水晶の周波数を定義する。(以下XTFREQ).
Timeoutは、UARTデータ待機タイムアウト。
データはだいたい200~300バイトずつ受信されます。データブロックを受信する間は
バイトがほぼ連続的に受信される。すき間はタイムアウトより長ければブロックが
受信完了ですのでリターンする。

Code: Select all
#include  <msp430x16x.h>
#include "USART.h"
#include "globals.h"

static uint16 timeout0;

//---------------------------------------------------------
//         Initializatons USART0
//---------------------------------------------------------

void InitUsart0(void) {
   // P3.4,5 = USART0 TXD/RXD
   P3SEL |= 0x30; 
   P3DIR |= 0x10;  //P3.4 = output direction
   P3DIR &= ~0x20; // P3.5 = input direction
   // 8-bit, UART
   U0CTL = (CHAR | SWRST);     
   // UCLK= SMCLK
   U0TCTL |= SSEL1;       
   // Set baud rate to 9600 (might be changed later).
   SetUSART0Rate(9600);
   // Initalize USART state machine
   U0CTL &= ~SWRST;
   // Enable USART0 RX interrupt
   USART0Enable();
   Enable_IE_USART0();
}

//   Enable USART0 TXD/RXD
void USART0Enable(void) {
   //   Enable module
   ME1 = UTXE0 | URXE0;
   //   Remove reset flag
   U0CTL &= ~SWRST;
}

//   Disable USART0
void USART0Disable(void) {
   //   Set reset flag
   U0CTL |= SWRST;
   //   Disable module
   ME1 &= ~UTXE0;
   ME1 &= ~URXE0;
}

//   Set USART baud rate
void SetUSART0Rate(uint16 BaudRate) {
   uint16 divisor;
   uint8 * div;
   //   Temporarily disable the module
   U0CTL |= SWRST;
   //   Calculate the divisor
   divisor = XTFREQ / BaudRate;
   timeout0 = 2* divisor;
   //   Superpose a uint8 pointer
   div = (uint8 *)(&divisor);
   U0BR1 = div[1];
   U0BR0 = div[0];
   //   Re-enable the module
   U0CTL &= ~SWRST;
}

//   Enable USART0 Rx Interrupt
void Enable_IE_USART0(void){   
   IE1 |= URXIE0;
}

//   Disable USART0 Rx Interrupt

void Disable_IE_USART0(void){   
   IE1 &= ~URXIE0;
}

void SetTimeout(uint16 t) {
   timeout0 = t;
}

//---------------------------------------------------------
//          Transmit and receive USART0
//---------------------------------------------------------

//   Send a single byte
void USART0SendByte(uint8 byte) {
   IFG1 &= ~UTXIFG0;
   /* Send the byte */
   U0TXBUF = byte;
   /* Wait for the byte to be sent */
   while (!(IFG1 & UTXIFG0)) { }
}

void USART0SendBuffer(uint8 * buf, uint16 len) {
   int i;
   for(i = 0 ; i < len ; ++i) {
      USART0SendByte(buf[i]);
   }
}

//   Receive a single byte
uint8 USART0RecvByte(void) {
   uint8 retval;
   IFG1 &= ~URXIFG0;
   //   Wait for the receive flag.
   while (!(IFG1 & URXIFG0)) {}
   retval = U0RXBUF;
   return retval;
}

uint16 USART0RecvBuffer(uint8 * buffer, uint16 len) {
   uint16 retlength = 0;
   uint16 timeout;
   while(retlength < len) {
      timeout = 0;
      IFG1 &= ~URXIFG0;
      while(!(IFG1 & URXIFG0) && (timeout++ < timeout0)) {}
      if(timeout >= timeout0) break;
      buffer[retlength] = U0RXBUF;
      retlength++;
   }
   return retlength;
}



以上です。

GPSモジュールソースコード

GPSモジュールソースコードは以下の通り。

Code: Select all
#ifndef _GPS_H_
#define _GPS_H_

#include "Types.h"

#define GPSRESET   0x08

// GPS specific
void   InitGPS(void);
void   ResetGPS(void);
uint16   ReadNMEA(void);

// Custom functions for parsing NMEA data
uint8   GetAltitude(uint8 * str);
uint8   GetCap(uint8 * str);
uint16   GetCompass();
uint8   GetGMTTime(uint8 * str);
uint8   GetLatitude(uint8 * str);
uint8   GetLongitude(uint8 * str);
uint8   GetLocalTime(uint8 * str);
uint8   GetNSats(void);
uint8   GetSpeed(uint8 * str);
void   SetTimeZone(int8 zone);

#endif



受信データはNMEA
データとなっています。この説明によると、NMEAデータはただのテキストデータ
です。モジュールの仕様書によると、1秒毎に1組のデータが受信される。実験の結果、
最高400バイト位受信することが分かりました。そこで、搭載には512バイトのバッファーを
使用しました。
Staticバッファーでデータを保管する。18文字の文字列を用意して、その文字列で
NMEAデータから適切な情報を取り出す。
TimezoneではGMT時刻を使用される現地時刻に合わせます。

以下はGPS端末のソースコードの一部です。データを取り出す関数はただの文字列処理
なので省略しました。

Code: Select all
#include <msp430x16x.h>
#include "GPS.h"
#include "Usart.h"
#include "Clock.h"
#include "AltitudeFilter.h"

//   This implementation is a "hardcoded" implementation which assumes
//   that the GPS module has been set to UART0.
//   This file keeps a buffer of the NMEA data.

#define NMEA_BUF_LEN   0x200

//   Static variables and buffers
static uint8 NMEABuffer[NMEA_BUF_LEN];
static uint8 RawString[18];
static int8 timezone;

//   Configures the UART first for 9600 baud. This will be subject to
//   changes later.

void InitGPS(void) {
   empty_buffer(NMEABuffer, NMEA_BUF_LEN);
   SetTimeZone(9);
   ResetGPS();
   InitUsart0();
}

void ResetGPS(void) {
   P4DIR |= GPSRESET;
   P4OUT &= ~GPSRESET;
   delay(100);
   P4OUT |= GPSRESET;
}

uint16 ReadNMEA(void) {
   uint16 len;
   empty_buffer(NMEABuffer, NMEA_BUF_LEN);
   len = USART0RecvBuffer(NMEABuffer, 0x200);
   return len;
}




ソースコードは以上です。NMEAデータが受信できたら、適切な部分を取り出して
表示する。

結果

GPS端末の外観は以下の通り。
Image

写真は歩きながら撮ったものです。南方向に進んでいたので写真が示す179度は妥当
と思われます。黒い領域はコンパスです。中心の表示は現在の移動方角です。左は
SE(South-Est, 南東)、右はSW(South-West, 南西)です。
モジュール以外ボードに乗っているチップは気圧センサーです。GPSは標高の値が
不正確なので、気圧センサーにより調整できます。これについては、また別の機会に
お話します。

次の画像は画面の詳細を示す。

Image

結論

この報告では、ソロバンに新しいハードウエアを開発・搭載する一例を示しました。
完全に動作するGPS端末器をわずか7本の配線で開発できました。ハードウエア的に
データが蓄積可能ですが今回はその機能は未開発です。
ソースコードは改善の余地があります。
現在のバージョンは立ち上がり難いです。理由は、現在地不明で起動する「cold start」
と呼ばれる起動方法によります。現在地を常にマイコンのフラッシュに書き込むこと
により、起動時間は短縮できます。

注意
完全に動作できるサンプルコードはSoroban+GPSモジュールを購入された方に
提供致します。GPSモジュールは4月中旬に発売予定です。
Last edited by pascal on Sun Oct 07, 2007 3:41 pm, edited 2 times in total.
pascal
Site Admin
 
Posts: 231
Joined: Sun Mar 04, 2007 11:47 am

日本語版もできましたね

Postby hamayan » Sun Mar 18, 2007 9:25 pm

どうもです。
日本語版もできましたね。

ところで英語版には、稼働時間が10時間も有れば自転車旅行には十分だろう!と書いて有りましたが、パスカルさんの趣味はサイクリングですか?。
このソロバン+GPSはまさにうってつけですね。

それでは、モジュールの販売を楽しみにしています。
hamayan
 
Posts: 6
Joined: Wed Mar 14, 2007 1:17 am

Postby pascal » Sun Mar 18, 2007 9:43 pm

こんばんは!

ところで英語版には、稼働時間が10時間も有れば自転車旅行には十分だろう!
と書いて有りましたが、パスカルさんの趣味はサイクリングですか?。
このソロバン+GPSはまさにうってつけですね。


そうです。今日も鞍馬・貴船に行って来ました(25km位です)。

パスカル
pascal
Site Admin
 
Posts: 231
Joined: Sun Mar 04, 2007 11:47 am


Return to MSP430 development board Soroban hard & soft

Who is online

Users browsing this forum: TurnitinBot [Bot] and 1 guest

cron