トワイライト(TWELITE)のソフト開発環境の作り方の手順

組み込みエンジニア

こんにちは、ENGかぴです。

ZigBeeモジュールであるトワイライト(TWELITE)の開発環境としてMWSTAGEが提供されています。MWSTAGEはArduinoライブラリに近い開発環境であり初期設定などを簡素化しており自作のアプリ開発がしやすいのが特徴です。MWSTAGEによる開発環境の作り方をまとめています。

最近エナジーハーベストの検討で無線タグアプリにはまっているユーザーとしての視点からMWSTAGEを使ってのアプリ開発について感じた点をまとめてみます。2021年6月の段階で最新バージョンであるMWSTAGE2020_12(2020/12月3日)について開発環境を作っています。

トワイライトを太陽光パネルで動作させたことやMWSTAGEの環境でソフト開発して無線通信したことなどについてまとめています。

トワイライト(TWELITE)のソフト開発と無線通信でできること

ソフト開発環境を作り方

トワイライト(TWELITE)にはソフトウェア開発環境としてTWELITE SDKが提供されていました。このTWELITE SDKを使うことで自作のアプリを製作することができましたが、少し敷居が高い感じでした。

MWSTAGEはこのSDKによる開発の難しさを工夫して改善したツールだといえます。ACTのサンプルの関数(ライブラリ)を利用することでマイコンの初期設定などが簡単に行えます。ユーザーは自作したい部分に適応するライブラリを意味と使い方が分かれば簡単にアプリが作れそうなのが良い点だと感じました。

actサンプルからトワイライトの強みである低消費電力が活かせられるようなアプリを自作して楽しんでみたいと考えています。

マイコンのメーカは自社のマイコンを採用してもらおうと必死にアピールしています。マイコンの初期設定をGUI上で行いライブラリを読みだすだけで設定できるようになってきています。

開発環境が使いやすければユーザーにとって採用しやすくなりますし、メーカーにとっても製品が採用されやすくなるため開発環境が分かりやすいことも今後の製品(マイコン)の採用の決め手になってきます。

モノワイヤレス社のHPに開発環境の作り方を含めて詳細に説明されていますが、記録のために残しておきます。参考にしていただければと思います。

MWSTAGEの現在の仕様ではトワイライターなど専用の書き込みツールを接続していない場合「シリアルポートが見つかりません」と表示されコンパイルや書き込みはできません。トワイライター以外でアプリを書き込む場合は「TWE-Programmer.exe」で書き込む必要があります。

TWE-Programmer.exeはMWSTAGE内のフォルダ>MWSDK>Tools>TWE-Programmer内にあります。

MinGWをインストールしなくてもMWSTAGE内ではコンパイルもできるため便利だと感じていましたが、トワイライターがない場合に内部の項目に遷移できずにコンパイルができないため今後のアップデートによってコンパイルだけはできるように改善されることを期待しています。

ダウンロードと環境変数の設定

MWSTAGEはモノワイヤレス社のHPからダウンロードすることができます。

モノワイヤレス社ーMWSTAGEダウンロード

MWSTAGEをダウンロードして任意のフォルダーに展開します。C:\にWorkSpaceのフォルダーを作成しその中に入れています。

MWSTAGEの保存先の例
MWSTAGEの保存先の例

保存する場所は任意の場所でよいのですが管理しやすいようにWorkSpaceのフォルダーに追加しています。保存した後はMWSTAGEとコンパイル環境をリンク付けするために環境変数の設定を行います。

コンパイルをMWSTAGE上で行う場合はこの処理は必要ありません。VScode上でタスクを選択してコンパイルする場合に必要です。

MWSTAGEの環境設定
MWSTAGEの環境設定

MWSTAGEのフォルダーの内層に下っていきToolsの中にある「SET_ENV」をクリックすると環境変数の設定が行われます。「UNSET_ENV」はMWSTAGE関係の環境変数を削除する時に使用します。

SET_ENVをクリックするとcmd.exeが起動し環境変数としてMWSDK_ROOTとMWSDK_ROOT_WINNAMEが登録されます。cmd.exe内で何かキーを入力すると環境変数が登録されていることの確認ができます。確認のため表示されているため特に操作する必要はありません。

Toolsの中にはCコンパイラーのMinGWのインストーラーが入っています。Cコンパイラ-をインストールしていない場合はインストーラーから次の2つの項目をインストールしてください。

  1. mingw32-base-bin
  2. mingw32-gcc-g++-bin

詳細については次章の「エディターとコンパイル環境」で説明しているリンクを参考にしてください。

エディターとコンパイル環境

MWSTAGEのエディターはVSCodeが推奨されています。VSCodeのインストールや環境の作り方については下記リンクにまとめていますので参考にしてください。

VSCodeをインストールしてC/C++の開発環境を作る

MWSTAGEを使用してソフト開発する

MWSTAGEのACTのサンプルをそのまま書き込んで動作確認してもよいのですが、それだけでは面白みがないので流用して簡単なプログラムを作ります。

MWSTAGEのACTのサンプルを見るとファイルの中にsetup()とloop()関数があります。setup()にはポートの設定などの初期設定を記述し、loop()にユーザーが動作させたいプログラムを記述するようになっています。詳細は下記リンクを参考にしてください。

モノワイヤレス社ーact TWELITEプログラム 手軽にプログラミング

ACTを流用する

Actサンプルからact2を流用してプログラムを作ります。

act2の流用
act2の流用

act2をコピーしフォルダの名前を「act2-LED」にします。ファイルの編集はVSCodeで行います。VSCodeを起動してファイルの中から「フォルダーを開く」を選択します。フォルダーは「act2-LED」を選択します。

act-LEDをVSCodeのフォルダーを開くで編集
act-LEDをVSCodeのフォルダーを開くで編集

フォルダーを開いた後はファイル名をact2.cppからact2-LED.cppに変更します。変更は任意ですが、管理しやすいように変更しています。今回使用する関数(ライブラリ)はpinMode()とdigitalWrite()です。

ファイルを開いて編集してもMWSTAGE上でコンパイルできるため問題ありませんが、フォルダーを開くで編集しない場合はリンクなどが参照できないためVSCodeのデバッカーとしての機能や表示アシストなどが使用できないためフォルダーを開いて編集することをお勧めします。

動作確認用の回路図

act-LEDの動作確認回路
act-LEDの動作確認回路

DOを操作してLEDを点灯させます。電池2本で3V程度になるので電池でもよいのですが、今回はTWE-EH-S(エナジーハーベスト用のオプション基板)で電源を生成して使用します。

TWE-EH-Sは無線タグアプリとセットで使用するものなので長期間の連続運転するような電源には向きませんが、電気二重層コンデンサを使ってチャージしておき電源として使用します。

動作までの電源に関する手順:

  1. TWE_VCCを切り離した状態で太陽光パネルでC1に電荷が溜まるようにする
  2. C1の電圧が3V以上であるのを確認する。余剰電力分のC2も電圧が3Vになっていることが理想
  3. TWE_VCCとVCCを接続する
  4. TWELITEが起動するので起動時にDO1(シルクの18)からLOWを出力しBOOTがLOWになるようにする。

4のDO1からLOWを出力しない場合はTWE_GNDとGNDが切り離されるため起動して停止しての繰り返しになり安定しません。DO1を起動時にLOWにする処理はTWE-EH-S基板を使用する場合に必要な処理です。

LEDの点灯をタイマー管理で行う

MWSTAGEでは割り込みなどイベントが終了するたびにLoop()関数に遷移するように構成されているためLoop()関数内に処理を作っていきます。

act2のサンプルではtimer1を使用していますが、今回はTickTimer(1msのカウント)を使ってタイマーの管理を行います。タイマー管理の考え方は下記リンクと同様です。

PICマイコン(PIC12F675)のタイマーの管理の仕方の一例

定義や変数の実装

#define TIME_OFF -1
#define TIME_UP 0
#define LED_CNT1_MAX 20
#define LED_CNT2_MAX 80
#define BASE_TIMER 10  //ベースタイマーを10msにする

const uint8_t PIN_DO1 = 18;
const uint8_t PIN_DO2 = 19;
short LedTimer1 = TIME_OFF;
short LedTimer2 = TIME_OFF;
unsigned char CntBaseTim = 0;

PIN_DO1とPIN_DO2はポートの設定と出力の設定時の引数として使用します。18と19は実際のピン番号ではなくシルクの番号によるものです。

変数のCntBaseTimをTickTimerイベントが発生するごとにカウントし、10回分カウントした時(10ms経過)したときのタイミングをベースタイマーとし変数のLedTimer1とLedTimer2を更新するようにします。BASE_TIMERの値を変更することで任意の値に変更できます。

初期化部分の実装

void setup() {
    pinMode(PIN_DO1, OUTPUT);
    pinMode(PIN_DO2, OUTPUT);
    LedTimer1 = LED_CNT1_MAX;
    digitalWrite(PIN_DO1, LOW);
    digitalWrite(PIN_DO2, HIGH);
    Serial << "--- Led (using a timer) ---" << crlf;
}

setup()関数は初期化時に一度だけコールされます。DO設定やシリアル設定などをこの関数の中に記述します。pinMode()やdigitalWrite()はArduino環境と同じように記述できます。

DO1はTWE-EH-SのBOOTにLOWを出力して電源のGNDレベルを維持するのに使用します。DO2はLEDを点灯/消灯されるために使用します。

Serialは”Led (using a timer)”をターミナル上で表示するために使用します。<<はシフト演算で使われますが、ここではC++の標準出力として使用しています。

タイマーの管理とLedの切り替え

void loop() {
    if(TickTimer.available()){
        ++CntBaseTim;
    }

    mainTimer();

    if( LedTimer1 == TIME_UP ){
        LedTimer1 = TIME_OFF;
        LedTimer2 = LED_CNT2_MAX;
        digitalWrite(PIN_DO2, LOW);
    }
    if( LedTimer2 == TIME_UP ){
        LedTimer2 = TIME_OFF;
        LedTimer1 = LED_CNT1_MAX;
        digitalWrite(PIN_DO2, HIGH);
    }
}

Loop()関数内に処理を追加してきます。TickTImer更新するイベントが完了した場合に変数CntBaseTimを更新しています。availableは空いているという意味でイベント完了したことを示すものです。

LedTimer1がタイムアップするとDO2をLOWにしてLedTimer2に値をセットしLedTimer2がタイムアップするとDO2をHIGHにしてLedTimer1に値をセットすることを繰り返して点灯と消灯を繰り返します。

mainTimer()は自作の関数で10ms経過するとタイマーを更新する処理を実装しています。

/*内部タイマ管理関数*/
void  mainTimer(void){

    if( CntBaseTim >= BASE_TIMER ){
        CntBaseTim -= BASE_TIMER;

        if( LedTimer1 > TIME_UP){
            --LedTimer1; 
        }
        if( LedTimer2 > TIME_UP){
            --LedTimer2; 
        }
    }
}

BASE_TIMERを10にしているため10ms経過すると内部に遷移して変数の更新を行います。BASE_TIMERを100にすると100ms経過で変数の更新になります。

メイン処理(LOOP()関数)の遷移のタイミングやmainTimer()関数までの処理時間が影響するため誤差が気になる場合は今回のようなソフトウェアタイマでなくマイコンのタイマ機能を使用したほうがいいでしょう。

ソフトの書き込みを行う

MWSTAGEを使用して作成したactファイルを書き込んでいきます。MWSTAGEのフォルダー内のTWELITE_Stage.exeを起動します。基本的な操作は矢印キーとENTERキーやマウスでカーソルを合わせて操作で行います。

actの書き込み1
actの書き込み1
actの書き込み2
actの書き込み2

シリアルポートを選択してENTERを押すと各種モードが表示されます。アプリ書換を選択してENTERを押します。(右クリックでも進みます)

actの書き込み3
actの書き込み3
actの書き込み4
actの書き込み4

Actビルド&書換を選択してENTERを押すとActの一覧が表示されます。自作したActであるact2-LEDを選択してENTERを押すとビルドと書換がスタートします。ビルドに失敗した場合は書換ができずエラー終了になりますので、プログラムの修正を行います。

actの書き込み5
actの書き込み5
actの書き込み6
actの書き込み6

書換が成功しENTERを押すとターミナルとなります。

気づいた点

MinGWをインストールしなくてもMWSTAGEでコンパイルしてソフトを書き込むことができるのは良い点ですが、ソフト書き込みのライターを接続してCOMポートを認識させていない場合はデバイスを認識しないため、コンパイルができなくなります。

コンパイルとファームの書き換えを分けてコンパイルだけでもできるような仕組みになると使い勝手が良くなると感じています。

ソースコード全体

以下のソースコードはコンパイルして動作確認をしております。チェックはしておりますがコメントなど細かな部分で間違っている可能性があります。参考としてお使いいただければと思います。

#include <TWELITE>

#define TIME_OFF -1
#define TIME_UP 0
#define LED_CNT1_MAX 20
#define LED_CNT2_MAX 80
#define BASE_TIMER 10  //ベースタイマーを10msにする

const uint8_t PIN_DO1 = 18;
const uint8_t PIN_DO2 = 19;
short LedTimer1 = TIME_OFF;
short LedTimer2 = TIME_OFF;
unsigned char CntBaseTim = 0;

/* Function */
void    mainTimer(void);

/*** the setup procedure (called on boot) */
void setup() {
    pinMode(PIN_DO1, OUTPUT);
    pinMode(PIN_DO2, OUTPUT);
    LedTimer1 = LED_CNT1_MAX;
    digitalWrite(PIN_DO1, LOW);
    digitalWrite(PIN_DO2, HIGH);
    Serial << "--- Led (using a timer) ---" << crlf;
}

/*** the loop procedure (called every event) */
void loop() {
    if(TickTimer.available()){
        ++CntBaseTim;
    }

    mainTimer();

    if( LedTimer1 == TIME_UP ){
        LedTimer1 = TIME_OFF;
        LedTimer2 = LED_CNT2_MAX;
        digitalWrite(PIN_DO2, LOW);
    }
    if( LedTimer2 == TIME_UP ){
        LedTimer2 = TIME_OFF;
        LedTimer1 = LED_CNT1_MAX;
        digitalWrite(PIN_DO2, HIGH);
    }
}

/*内部タイマ管理関数*/
void    mainTimer(void){

    if( CntBaseTim >= BASE_TIMER ){
        CntBaseTim -= BASE_TIMER;

        if( LedTimer1 > TIME_UP){
            --LedTimer1; 
        }
        if( LedTimer2 > TIME_UP){
            --LedTimer2; 
        }
    }
}

関連リンク

トワイライトを太陽光パネルで動作させたことやMWSTAGEの環境でソフト開発して無線通信したことなどについてまとめています。

トワイライト(TWELITE)のソフト開発と無線通信でできること

RUNTEQ-プログラミングで自由を手に入れる

最後まで、読んでいただきありがとうございました。

タイトルとURLをコピーしました