This is the multi-page printable view of this section. Click here to print...

Return to the regular view of this page

As of 2025-07-24

TWELITE STAGE SDK / act

Develop firmware for TWELITE
By using the TWELITE STAGE SDK, you can develop custom firmware for TWELITE.

MWX Library and act

The MWX library aims to simplify the code representation for TWELITE wireless modules. Programs created with MWX are called act. There are two types of act: loop-based description and event-driven description (called behavior).

Loop-based description (setup(), loop())

Suitable for describing small-scale functions.

#include <TWELITE>
const uint8_t PIN_LED = 5;

void setup() {
  pinMode(PIN_LED, OUTPUT);
}

void loop() {
  if (TickTimer.available()) {
    uint32 t_now = millis();

    // blink LED every 1024ms
    digitalWrite(PIN_LED, (t_now >> 10) & 1 ? HIGH : LOW);
  }
}

Event-driven application description

You can define a state machine within a class to handle various events and interrupt handlers, enabling clear code for complex application behaviors. This method is called behavior.

// myApp.hpp
...
class myApp : MWX_APPDEFS_CRTP(myApp) {
...
  void loop() {
    // main loop
  }

  void receive(mwx::packet_rx& rx) {
    // on receive
  }
};

// myApp.cpp
...
MWX_DIO_EVENT(12, uint32_t arg) {
		// on event from DIO12
}

Simplifying peripheral procedures

Classes are defined to handle commonly used UART, I2C, SPI, ADC, DIO, timers, and pulse counters.

void loop() {
  while(Serial.available() {
    auto x = Serial.read(); ... } // serial message
  if (Analogue.available() {
    auto x = Analogue.read(...); } // adc values
  if (Buttons.available() {
    Buttons.read(...); } // DIO changes
  if (the_twelite.receiver.available()) {
    auto&& rx = the_twelite.receiver.read(); } // on rx packet
}

Defining a simple relay network

This relay network is implemented equivalently to the TWELITE standard application. It manages device addresses with 8-bit logical IDs and does not perform network construction communication, allowing wireless packets to be sent to the network immediately after power-on.

#include <TWELITE>
#include <NWK_SIMPLE>

void setup() {
  ...
  auto&& nwksmpl = the_twelite.network.use<NWK_SIMPLE>();
	nwksmpl << NWK_SIMPLE::logical_id(0xFE)
	           // set Logical ID. (0xFE means a child device with no ID)
	        << NWK_SIMPLE::repeat_max(3);
	           // can repeat a packet up to three times.
}

void loop() {
  ...
  vTransmit();
  ...
}

void vTransmit() {
  if (auto&& pkt =
    the_twelite.network.use<NWK_SIMPLE>().prepare_tx_packet();
  pkt << tx_addr(0x00)  // to parent
	  	<< tx_retry(0x3); // set retry

	pack_bytes(pkt.get_payload() // prepare payload data
	    , uint8_t(0x01)
	    , uint16_t(analogRead(PIN_ANALOGUE::A1))
	    , uint16_t(analogRead_mv(PIN_ANALOGUE::VCC)));

	pkt.transmit(); // transmit!
}

Board definitions for PAL and MONOSTICK

Easily handle sensors and other components on the board.

#include <TWELITE>
#include <PAL_AMB> // include the board support of PAL_AMB

void setup() {
	auto&& brd = the_twelite.board.use<PAL_AMB>(); // use PAL AMB
	uint8_t u8dip = brd.get_DIP_SW();   // check DIP switch status
	brd.set_led(LED_TIMER::BLINK, 100); // LED switches on/off every 100ms
	...

	// start capture of sensors
	brd.sns_SHTC3.begin();
}

void loop() {
	if (TickTime.available()) { // check every ms
		auto&& brd = the_twelite.board.use<PAL_AMB>();

		if (brd.sns_LTR308ALS.available()) {
		  Serial << brd.sns_SHTC3.get_temp();
		} else {
		  // notify sensor that 1ms passed.
			brd.sns_SHTC3.process_ev(E_EVENT_TICK_TIMER);
		}
	}
}

1 - Development Environment

About the development environment (OS, etc.)

To write applications using the MWX library, the following are required:

  • MWSDK (Software Development Kit)
  • Development editor (We recommend Microsoft Visual Studio Code)

Windows

The compiler toolchain is relatively less dependent on the environment, so it is expected to work on many systems; however, we recommend currently supported Windows 10 and 11 versions. If your environment differs and causes issues, please prepare an environment based on the ones we have verified.

Below are the versions used in development:

  • Windows 11 21H2 (Visual Studio 2019)
  • FTDI driver installed and working (required for MONOSTICK, TWELITE R operation)

Linux

The compiler toolchain is relatively less dependent on the environment, so it is expected to work on many systems; however, we recommend currently supported distributions. If your environment differs and causes issues, please prepare an environment based on the ones we have verified.

Below are the versions used in development:

  • Ubuntu 18.04 LTS 64bit
  • Ubuntu 20.04 LTS 64bit

macOS

The compiler toolchain is relatively less dependent on the environment, so it is expected to work on many systems; however, we recommend currently supported macOS versions. If your environment differs and causes issues, please prepare an environment based on the ones we have verified.

Below are the versions used in development:

  • macOS 10.14 Mojave (Intel)
  • macOS 12 Monterey (Apple Silicon)

Development Tools such as Visual Studio Code

For tools and usage to run the development environment, please refer to information from the developers or communities.

Differences Due to Build Environments

2 - Installing the SDK

Installing the TWELITE SDK

Installing the TWELITE STAGE SDK

Download the TWELITE STAGE SDK distribution archive (ZIP, etc.) and extract it to an appropriate folder.

Once extracted as shown below, the installation is complete.

Example Folder

Example Folder

Setting Environment Variables

Set MWSDK_ROOT and MWSDK_ROOT_WINNAME (Windows only).

Windows

Here, the extracted folder name is assumed to be C:\MWSTAGE. If you installed to a different folder, please adjust accordingly.

Run C:\MWSTAGE\Tools\SET_ENV.CMD. This sets the following environment variables:

  • MWSDK_ROOT
  • MWSDK_ROOT_WINNAME

For example, the settings will look like this:

MWSDK_ROOT=C:/MWSTAGE/MWSDK/
MW_ROOT_WINNAME=C:\MWSTAGE\MWSDK\

Linux

Set the MWX_ROOT environment variable in your development environment or shell.

There are several ways to do this, but you can add the following settings to your home folder’s .profile file (create it if it doesn’t exist). This will enable building in VSCode as well. Make sure the environment variables are applied.

MWSDK_ROOT=/foo/bar/MWSTAGE/MWSDK/
export MWSDK_ROOT

To add this without an editor, run the following commands. The $ is the prompt and may differ depending on your environment. Replace /foo/bar/MWSTAGE with the folder where you installed the SDK.


cd $HOME
echo MWSDK_ROOT=/foo/bar/MWSTAGE/MWSDK>>.profile
echo export MWSDK_ROOT>>.profile

macOS

Set the MWX_ROOT environment variable so that it is reflected in your development environment or shell.

There are several ways to do this, but you can add the following settings to your home folder’s .profile file (create it if it doesn’t exist). This will enable building in VSCode as well.

MWSDK_ROOT=/foo/bar/MWSTAGE/MWSDK/
export MWSDK_ROOT

To add this without an editor, run the following commands. The $ is the prompt and may differ depending on your environment. Replace /foo/bar/MWSTAGE with the folder where you installed the SDK.

3 - Building Act

Building act

An application program written with the MWX library is called an act. First, build and write it.

  • About the build folder structure
  • Building with Visual Studio Code (referred to as VSCode)

About the build folder structure

Open the folder where you installed MWSDK (MWSDK_ROOT, e.g., C:\MWSDK). It has the following structure:

MWSDK_ROOT
  |
  +-ChipLib      : Semiconductor library
  +-License      : Software license agreement
  +-MkFiles      : makefile
  +-Tools        : Compiler and other tools
  +-TWENET       : TWENET/MWX library
  +-Act_samples  : Act samples
  ...

Act files are stored under Act_samples. (Some parts are omitted below)

Act_samples
  |
  +-CoreAppTwelite    : Act for the board with the same structure as App_TweLite
  +-PAL_AMB           : Act for environmental sensing PAL
  +-PAL_MAG           : Act for open/close sensing PAL
  +-PAL_MOT           : Act for motion sensing PAL
  ..
  +-Parent-MONOSTICK  : Parent act for MONOSTICK
  +-PingPong          : PingPong act
  +-PulseCounter      : Act using pulse counter
  +-act0              : Scratch (just to try writing) act

These acts are simple examples that serve as a reference for writing MWX library programs, but many acts have the following functions:

  • Acquire sensor values
  • After acquiring sensor values, send a wireless packet to the parent device
  • After sending is complete, sleep for a fixed time (or wait for an interrupt)

The Parent-MONOSTICK act receives and displays packets. This parent act outputs in ASCII format. (It starts with : like :00112233AABBCC...FF[CR][LF], and the middle part expresses bytes in hexadecimal with two ASCII characters. The ending ?? is also two characters representing a byte called LRC checksum. Reference: ASCII format)

When actually running, try the following combinations.

ParentChildExplanation
BRD_APPTWELITEBRD_APPTWELITEThe parent device boots with M1 pin set to LOW (GND level). In normal mode (always running), you can verify operation like App_Twelite.
PingPongPingPongOperates with two child devices. When one sends a Ping packet, the other returns a Pong packet.
Parent-MONOSTICKOthersYou can verify packet transmission from child acts.

Now, let’s look inside the PingPong folder among the acts.

Act_samples
  +-PingPong
    +-PingPong.cpp   : Act file
    +-build          : Build folder
    +-.vscode        : VSCode configuration files

A .cpp file with the same name as the folder is always required directly under the folder.

Next, open the build folder.

Act_samples
  +-PingPong
    +-build
      +-Makefile        : makefile
      +-build-BLUE.cmd  : Build script for TWELITE BLUE (Windows)
      +-build-RED.cmd   : Build script for TWELITE RED (Windows)
      +-build-clean.cmd : Delete obj_* files

Scripts and Makefile required for building are stored here.

By running make TWELITE={BLUE or RED} in the folder containing this Makefile, the build is executed. Building in VSCode also internally calls make.

Building with TWELITE STAGE app

Using the TWELITE STAGE app, you can build, write, and run. Here, we explain from launching the TWELITE STAGE app up to building.

0. Connect TWELITE

Connect MONOSTICK or TWELITE R to your USB port.

1. Launch TWELITE STAGE app

Launch the executable TWELITE_Stage.{extension} in the {TWELITE SDK installation} folder (Reference: TWELITE STAGE app manual).

Below is a screen example during TWELITE STAGE app operation. There is a main screen on the left and a command prompt screen, but operate the main screen. The command prompt shows various info and input data from the TWELITE microcontroller serial port but is usually not used.

Screen example

Screen example

Main operations on the main screen are:

  • Left mouse click (select)
  • Right double-click (go back to previous screen)
  • Quickly press ESC twice, or once on some screens (go back)
  • Hold Alt(⌘) key (help screen)
  • Normal keyboard input (follow screen instructions)

(Reference: TWELITE STAGE app manual)

2. Select serial port

This screen appears first when launching the TWELITE STAGE app. If TWELITE R or MONOSTICK is connected beforehand, it will be listed here. Select the TWELITE device to operate. You can also select it later by other operations.

Serial port selection screen

Serial port selection screen

(Reference: TWELITE STAGE app manual)

3. Main menu

After exiting the serial port selection screen, the main menu appears. Select the “App write” menu to build and write.

Main menu

Main menu

(Reference: TWELITE STAGE app manual)

4. App write menu

Before selecting the app write menu, confirm TWELITE connection and serial port selection. You can check the serial port selection status by holding the Alt(⌘) key to display the help screen.

App write menu

App write menu

Projects accessible from the TWELITE STAGE app are categorized. The right Help shows related info in a browser. The Folder opens the project folder.

If TWELITE is connected, the model is identified when selecting the menu. (The app internally builds according to the identified TWELITE model.)

(Reference: TWELITE STAGE app manual)

4. Select project

Here, select “act build & write” from the app write menu.

App write menu

App write menu

5. Build & write

Here, select BRD_APPTWELITE in the project selection screen.

When selected, writing proceeds as shown in the screen example below. If an error appears, follow the instructions or go back and retry.

Writing in progress (with verify setting)

Writing in progress (with verify setting)

Write complete

Write complete

(Reference: TWELITE STAGE app manual)

6. Move to interactive mode

After writing completes successfully, it proceeds to interactive mode (settings screen). The screen appears only if the firmware supports interactive mode.

In interactive mode, you can configure various settings such as the TWELITE wireless channel.

Interactive mode

Interactive mode

(Reference: TWELITE STAGE app manual)

7. Terminal screen

Return to the root menu and select “Viewer” → “Terminal”.

A very simple serial terminal. You can check messages from TWELITE and send messages to TWELITE.

Terminal screen

Terminal screen

The screen shows messages sent wirelessly approximately every second. You can also enter + + + to enter interactive mode screen.

(Reference: TWELITE STAGE app manual)

Building with VSCode

VSCode is a powerful editor for source editing, but you can also build firmware for TWELITE microcontrollers within VSCode.

Launch VSCode from the project list under the “Build & Write” menu in the TWELITE STAGE app.

Press the [VSCode] button on the right of the build list.

VSCode settings

VSCode settings

This requires configuration in the TWELITE STAGE app.

Set “Open folder with code (VSCode)” to 1 in STAGE settings.

Open with VSCode

Open with VSCode

VSCode build tasks

Open the workspace you want to build first. The workspace included with the TWELITE STAGE SDK has build task definitions.

Below is an example with an English interface, showing the opened workspace.

Open [Terminal>Run Task...].

Run task menu

Run task menu

Select the TWELITE wireless module type (BLUE/RED) and act name to build. In the example below, Build for TWELITE BLUE is selected. The build starts immediately after selection.

Select build task

Select build task

Build progress is output in the terminal at the bottom.

Build progress

Build progress

Building from command line

Additional information for building from the command line.

Linux, macOS environment

Run make in a window running bash or zsh (or other shell). Confirm the environment variable MWSDK_ROOT is set correctly. For example, if installed at /work/MWSDK, add the following to ~/.profile or similar:

MWSDK_ROOT=/work/MWSDK
export MWSDK_ROOT

Run make from the command line. If make is missing, install the package.

Windows environment

Run {MWSTAGE SDK installation}/MWSDK/WIN_BASH.cmd. Environment variables and make utility are set.

Build

Build as follows:


cd $MWSDK_ROOT
cd Act_samples/PingPong/build
pwd
/mnt/c/MWSDK/Act_samples/PingPong/build

ls
... list files

rm -rfv objs_*
... delete intermediate files just in case

make TWELITE=BLUE
... build for BLUE

make -j8 TWELITE=BLUE
... parallel build for BLUE (8 processes)

Command examples

See the Makefile explanation for details.

  • make TWELITE=BLUE: Build for TWELITE BLUE
  • make TWELITE=RED: Build for TWELITE RED
  • make cleanall: Delete intermediate files

About intermediate files

When building, objs_??? folders are created containing intermediate files. These files depend on the build environment, so leftover files from other environments cause make errors and build failures.

4 - Creating a New Project

Creating a new project

To create a new project, copy an existing sample act folder with a different name and edit the file names.

The project file structure is as follows (using PingPong as an example):

Act_samples
  +-PingPong
    +-PingPong.cpp   : Act file
    +-build          : Build folder
    +-.vscode        : VSCode configuration files

Copy this PingPong folder to another location (but the folder name must not contain Japanese characters or spaces).

SomeDir
  +-AlphaBravo
    +-PingPong.cpp -> AlphaBravo.cpp ※ Rename the file
    +-build          : Build folder
    +-.vscode        : VSCode configuration files

The only file that needs editing is the PingPong.cpp file name. Change it to the same name as the folder, AlphaBravo.cpp.

Editing the Build Definition

If you need to add files to the build target, edit build/Makefile. .c and .cpp files directly under the project folder are added automatically, but other files require manual editing.

See the Makefile documentation for editing instructions.

VSCode Configuration

If you use VSCode, edit the definitions under .vscode as needed.

Many samples included in the TWELITE STAGE SDK are set up as follows:

  • The TWELITE STAGE SDK library source code references ${env:MWSDK_TWENET_LIBSRC}/include/** and ${env:MWSDK_TWENET_LIBSRC}/src/**. This environment variable MWSDK_TWENET_LIBSRC is automatically set when opening the project from the TWELITE STAGE app in VSCode.
  • By default, no additional options such as -D are set for the build tasks.

5 - Installing VSCode for act

Install Visual Studio Code for act development

To facilitate writing the source code of act, we include configuration files for code interpretation in Visual Studio Code (VSCode).

To analyze source code and build from VSCode, information such as the folder where the library source code is stored is required. This information is reflected by launching VSCode from the TWELITE STAGE app. (Specifically, appropriate environment variables are set when starting VSCode. The project settings refer to these environment variables.)

Installing VSCode

Features of VSCode

  • Editing source code
  • Intellisense based on source code interpretation
    (* This does not guarantee that all definitions are interpreted correctly)

VSCode can be downloaded from the official site.

Installing Plugins

To enable Visual Studio Code to interpret C/C++ language, install the following plugin:

  • C/C++ for Visual Studio Code

Notes for Each OS

To launch VSCode from TWELITE STAGE, the code command must be enabled.

The following information is from code.visualstudio.com:

Notes

6 - Build Definition Makefile

Build definition with Makefile

The Makefile is stored in build/Makefile. By running the make command, the act is pre-defined to be built.

make parameters

TWELITE=

Specify the build target as BLUE or RED. For TWELITE BLUE, specify make TWELITE=BLUE.

all

Executes the build. Usually omitted, and run like make TWELITE=BLUE.

clean

Deletes intermediate build files. Run like make TWELITE=BLUE clean.

cleanall

Deletes all intermediate files. Run like make cleanall. This is equivalent to deleting all objs_??? folders in the build folder.

USE_APPDEPS=0 or 1

Setting 1 (default) determines build files based on file dependencies. For example, if a header file changes, related source files will be recompiled.

Setting 0 disables dependency evaluation. If set to 0, make will not error even if inconsistent intermediate files remain.

Makefile definition

Depending on the size of the act and when defining behaviors, source files are usually split and built.

One of the build files is project_folder_name.cpp.

If you want to define other files, edit the build/Makefile in the project folder.

Below is an example Makefile from the sample PAL_AMB-behavior.

##############################################################################
# Copyright (C) 2019 Mono Wireless Inc. All Rights Reserved.
# Released under MW-SLA-*J,*E (MONO WIRELESS SOFTWARE LICENSE
# AGREEMENT).
##############################################################################
# USER PROJECT BUILD DEFINITION.
##############################################################################

#####################################################################
## set TWELITE model
TWELITE ?= BLUE
#TWELITE = RED

#####################################################################
## set application version (MUST SET THIS.)
VERSION_MAIN = 0
VERSION_SUB  = 1
VERSION_VAR  = 0

#####################################################################
## set an additional source file
##   the default file name is dirname.

## for C++ files compiled with g++ (must have .cpp suffix)
APPSRC_CXX += myAppBhvParent.cpp
APPSRC_CXX += myAppBhvParent-handlers.cpp
APPSRC_CXX += myAppBhvChild.cpp
APPSRC_CXX += myAppBhvChild-handlers.cpp

## for C files compiled with gcc (must have .c suffix)
#APPSRC += my_c_file.c

## Additional Src/Include Path
# if set, find source files from given dirs.
#
APP_COMMON_SRC_DIR_ADD1 = ../Parent
APP_COMMON_SRC_DIR_ADD2 = ../Child
#APP_COMMON_SRC_DIR_ADD3 =
#APP_COMMON_SRC_DIR_ADD4 =

#####################################################################
## set misc option for compiler

## C++ flags passed to g++
# e.g. CXXFLAGS += -DMY_DEFS
#CXXFLAGS +=

## C++/C flags passed to g++/gcc
# e.g. CFLAGS += -DMY_DEFS
#CFLAGS +=

## include opts
# e.g. INCFLAGS += -I../my_common_src/
#INCFLAGS +=

## optimize flag (default is -Os, normally no need to change)
#OPTFLAG=-O2

#####################################################################
## must include mwx.mk (the makefile body part.)
MWSDK_PATH?=$(realpath $(MWSDK_ROOT))
include $(MWSDK_PATH)/MkFiles/mwx.mk
#####################################################################

VERSION_???

Specify the version number. It will be reflected in the built file name.

## set application version (MUST SET THIS.)
VERSION_MAIN = 0
VERSION_SUB  = 1
VERSION_VAR  = 0

During compilation, these are passed as definitions like -DVERSION_MAIN=0 -DVERSION_SUB=1 -DVERSION_VAR=0.

Adding source files

What is needed when adding source files are APPSRC_CXX and APP_COMMON_SRC_DIR_ADD?.

Append the source file names to APPSRC_CXX. These file names must not include folder names. Even if they are in subfolders, specify them without folder names (i.e., if the same file name exists in multiple subfolders, the build will fail).

APPSRC_CXX += myAppBhvParent.cpp
APPSRC_CXX += myAppBhvParent-handlers.cpp
APPSRC_CXX += myAppBhvChild.cpp
APPSRC_CXX += myAppBhvChild-handlers.cpp

Next, specify the search paths if source files are stored outside the project folder. You can set up to four.

APP_COMMON_SRC_DIR_ADD1 = ../Parent
APP_COMMON_SRC_DIR_ADD2 = ../Child

Folder paths are relative to the Makefile.

Compiler and linker options

You can also pass several other options to the compiler and linker.

OptionDescription
CXXFLAGSSpecify compile options for C++ source files.
CFLAGSSpecify compile options for C/C++ source files.
INCFLAGSSpecify include paths for header files.
OPTFLAGSDefine when you want to apply compile options other than the default -Os for special reasons.
LDFLAGSSpecify linker options. (Although not mentioned in the comments of the above Makefile, you can specify this.)

7 - Other Platforms

Using other platforms

Build definitions are prepared so that some functions (serparser, pktparser, Serial objects for console) can be built on other platforms as well. Only the necessary files are extracted.

Build definitions are stored in the {mwx library directory}/stdio folder. For build instructions, please refer to README.md (link is on GitHub).

  • Must be able to compile with C++11.
  • Must have access to C++11 standard library headers (such as utility, algorithm, functional, iterator).
  • new/delete/virtual are not used.
  • Memory allocation using new may be used exceptionally.
    • In serparser/pktparser, delete is used in alloc_heap that uses the new operator.
    • (Reference) However, some parts of the mwx library are designed under the assumption that delete is not considered.