ソフト ハード 電子班

Mbedで位置情報発信器を作ってみた

2022-04-28

Mbedの開発環境

開発の準備

Mbedを初めて使う方はこちらの記事をご覧下さい。Mbed IDEについて詳しく説明してます。

Mbedでマイコン開発をする方法

2022/5/7  

こんにちは、hiroです!今回はMbedIDEという開発環境を使ってマイコンに書き込む方法をご紹介します。 Mbedを使おう! Mbedとは? マイコンの開発環境ってたくさんあるよね!例えばArdui ...

IM920を使う方法

IM920のライブラリ

今回使用するライブラリはhttps://os.mbed.com/users/okini3939/code/IM920/です。

ライブラリの導入方法が分からない方はこちらの記事をご覧下さい。

Mbed ライブラリ追加方法

2022/10/12  

こんにちは、hiroです!今回はMbedIDEのライブラリのインポート(追加)方法について紹介します。また、ライブラリのリビジョン(バージョン変更)方法についても紹介します。 MbedIDEについてあ ...

サンプルコード

環境が整ったら、早速コードを書いていきます。

このライブラリは主に次のような機能を持っています.

1IM920(RX,TX,BUSY,STATUS);[コンストラクタ、ピン宣言]

2 void im920::imSend(char 文字列);[文字列の送信]

サンプルコードを以下に示します。

#include "mbed.h"
#include "GPS.h"
#include "IM920.h"
#include <stdio.h>

char sendData[256]; //送るデータのchar型配列(im920はchar型でしか送れない。)

Serial pc(USBTX, USBRX);
GPS gps(PA_9,PA_10); //GPSの初期化(tx,rx)mbed:D1,D0
IM920 im920(PA_2,PA_3,PF_0,PB_3); //IM920の初期化(tx,rx,busy,reset)mbed:A7,A2,D7,D13 arduinoシールド:D9,D8,D10,- *resetは使用しなかった*

void imSend(char *send){//無線で送信する関数
    im920.send(send,strlen(send)+1);
    pc.printf(send);
    pc.printf("\r\n");
}

void sendDatas(float latitude, float longtitude, float altitude, float time){//データを文字列に変換してimSendを呼び出して送信する関数
        sprintf(sendData,"data1,%.3f,%.3f,%.3f,%.3f", latitude, longtitude, altitude, time);
        imSend(sendData);
}

void getGPS(){//GPSの値を取得してsendDatesに値を入れる関数
    //NVIC_SetPriority(UART2_IRQn,0); //割り込み優先順位(必要に応じて)
    gps.GetData();
    if(gps.readable == true){
       sendDatas(gps.latitude, gps.longtitude, gps.altitude, gps.time);
    }
}





int main(){
    //pc.baud(115200); //mbedのボーレート(必要に応じて)
    gps.attach(getGPS);//割り込み処理設定(関数名)
    while(1){
        //gps.GetDefault(); //元のデータ
        //pc.printf("%c",gps.datadefault);  //書き込み
    }
}

コードの説明、ライブラリの注意点

8行目のIM920 im920(tx,rx,busy,reset)のtx,rx,busy,resetは自身のマイコンの環境のtx,rxに書き換えて下さい。busyはGPIOピンならどのピンでも正常に機能します。RESETは配線しなくても大丈夫ですが、ライブラリの仕様上何らかのピンを指定するようにしてください。

sprintf(sendData,"data1,%.3f,%.3f,%.3f,%.3f", latitude, longtitude, altitude, time);では、IM920で送信したい数値を文字列に変換しています。IM920は文字列としてしかデータを送信することができないため、sprintf関数を使って文字列に変換する必要があります。

このsprintfの処理はかなり思い処理のため、マイコンの性能によっては処理が間に合わずバグを起こすことがあります。そこで、待機時間wait_ms(100)をsprintf文の後に記述することをおすすめします。

IM920は、通信頻度をプログラム側で指定することができます。上で紹介したライブラリのIM920_conh.hというファイルを見て下さい。10行目の#define CFG_TIMEOUT 50005000という数字は無線受信機がデータを受信したことを確認したという情報が5秒待っても返ってこなかったら次の処理に移行する設定に繋がっています。この5000という数字を500に返ることで、0.5秒間に1回の送信を行うことができます。

#ifndef _IM920_conf_h_
#define _IM920_conf_h_
 
//#define DEBUG
//#define DEBUG_DUMP
 
#define IM920_BAUD 19200
 
#define CFG_BUF_SIZE 150
#define CFG_DATA_SIZE 64
#define CFG_CMD_SIZE 16
 
#define DEFAULT_WAIT_RESP_TIMEOUT 500
#define CFG_TIMEOUT 5000
 
#endif
 
            
Repository toolbox
Import into Keil Studio
 Export to desktop IDE
Repository details
Type:	 Library
Created:	26 12月 2014
Imports:	 74
Forks:	 0
Commits:	 6
Dependents:	 6
Dependencies:	 0
Followers:	 6
Developers
 Suga koubou
 ide al

IM920には「高速通信モード」と「長距離通信モード」という2つのモードが存在します。モードの設定は送信機側と受信機側の両方で行います。送信機側のモードと受信機側の設定が異なると通信ができないので注意して下さい。ここでは、送信機側の設定方法を紹介します。IM920.cppというファイルを見て下さい。

#include "IM920.h"
 
IM920::IM920 (PinName tx, PinName rx, PinName busy, PinName reset, int baud) : _im(tx, rx) {
 
    memset(&_state, 0, sizeof(_state));
    _state.data = new CircBuffer<char>(CFG_DATA_SIZE);
 
    initUart(busy, reset, baud);
    setReset(true);
    wait_ms(100);
    setReset(false);
}
 
int IM920::init () {
 
    cmdRDID();
    cmdRDNN();
    cmdSTPO(3);  // 10dBm
    cmdSTRT(2);  // 1.25kbps
    return 0;
}
 
void IM920::poll () {
 
    if (_state.received && _state.buf != NULL)
      if (!_state.data->isEmpty()) {
        _func.call();
        if (_state.data->isEmpty()) {
            _state.received = false;
        }
    }
}
 
int IM920::send (char *buf, int len) {
 
    if (len > 64) len = 64;
 
    return sendData(buf, len);
}
 
int IM920::recv (char *buf, int len) {
    int i;
 
    if (_state.data == NULL) return 0;
    while (!_state.received && _state.mode != MODE_COMMAND);
    _state.received = false;
    for (i = 0; i < len; i ++) {
        if (_state.data->dequeue(&buf[i]) == false) break;
    }
    return i;
}
 

12、13行目の cmdSTPO(3); // 10dBm cmdSTRT(2); // 1.25kbpsの部分に注目していきます。ここでは引数に3と2が使われていますが、これは長距離通信モードの設定になります。高速通信モードで使いたい場合は、引数を2と1に変更して下さい。よほど高頻度の通信を行いたい場合を除いて、基本的に長距離通信モードを使用することをお勧めします。ここまでできれば送信機側の設定は以上です。

IM920の受信機側の設定

次に、受信機側の設定を行っていきます。その際コマンド表が必要になるので、https://www.interplan.co.jp/support/solution/IM315/manual/IM920_SW_manual.pdfをダウンロードしてください。コマンド一覧は12ページに記載されています。IM920-USBとPCを使ってコマンドを送信していきます。TeraTermやArduinoIDEのシリアルモニタの送信機能を使うと良いと思います。転送レートを19200に設定して下さい。文字を送信した際に、OKまたはNGが返ってくれば正常に通信できている証拠です。

主に使用するコマンドを順に紹介していきます。

1ENWR;IM920の設定変更を保存するためには、このコマンドを送信する必要があります。

2RDID;送信機をIM920-USBに装着して、このコマンドを送信して下さい。「D33D」や「D33C」のような文字列が返ってくれば大丈夫です。これは送信機の固有IDとよばれる  もので、いわばメールアドレスのようなものです。これを受信機側に登録することで、通信が可能になります。

3SRID;受信ID登録といって先程読み出した送信機の固有IDを受信機側に登録します。SRID 固有IDの形式でコマンドを打ってください。

4STCH;無線には複数のチャンネルがあって、チャンネルごとに周波数が異なります。

  送信機側と受信機側で周波数が異なると通信できないため、同じチャンネルを設定する必要があります。両方にSTCH 01というコマンドを打って下さい。

5STRT;通信速度設定です。先程も紹介したように、IM920には高速通信モードと長距離通信モードがあります。高速通信モードで使う場合STRT 1というコマンドを、長距離通信モードで使いたい場合はSTRT 2というコマンドを打って下さい。その際、送信機側にプログラムで指定しているモードと一致していることを確認して下さい。

6DCIO;送信機側にこのコマンドを打つと10進数でのデータの送信が可能になります。16進数で会話できる人はこのコマンドを打つ必要はありません。

7ECIO;受信機側にこのコマンドを打つと10進数でのデータの受信が可能になります。送信機側にはDCIO、受信機側にはECIOを打ちます。

おわりに

IM920の解説は以上になります。GPSとIM920を組み合わせて、サンプルコードを書き込んでみましょう。受信機側に緯度・経度が送られてきたら成功です。

  • この記事を書いた人
  • 最新記事
katoshunsuke

katoshunsuke

FTEの電子班員。今の所バキバキ

-ソフト, ハード, 電子班