CUE and ARIA are finished sensor products. Insert a battery, place the unit, and it starts transmitting. There is nothing to set up on the transmitting side.
What you need is the receiving side. To receive on a PC, read the TWELITE STICK guide. To pass data to a Wi-Fi network, read the TWELITE SPOT guide.
Transmit digital and analog signals using the Extremely Simple! Standard App
The Extremely Simple! Wireless Module TWELITE DIP is a product with TWELITE mounted on a 2.54mm pitch board. It is suitable for prototyping and small-scale production because it can be easily wired by hand.
TWELITE can communicate immediately after startup. Pairing like Bluetooth is not required.
Broadcast communication is performed between devices set to the same frequency channel. Therefore, multiple devices cannot transmit simultaneously on the same channel. Packets not addressed to the device are ignored. You can think of it as working like a transceiver or intercom.
TWELITE can transmit without receiving, enabling the realization of devices with excellent power-saving performance.
What is the wireless communication standard?
TWELITE is a wireless module that uses 2.4GHz radio waves and complies with IEEE 802.15.4, which is a different standard from Bluetooth (IEEE 802.15.1). Other products conforming to IEEE 802.15.4 include Zigbee modules, but TWELITE is not a Zigbee module. Zigbee modules use the Zigbee protocol stack on top of IEEE 802.15.4, whereas TWELITE implements a simple, proprietary protocol stack instead.
Although it is not suitable for large-volume data communication, it is optimal for simple signal transmission and similar applications.
Small amounts of data can be transmitted efficiently.
Pin Functions
Pin Layout Table
The pins used by the Extremely Simple! Standard App have several functions.
Transmit digital and analog signals using the Extremely Simple! Standard App
Extremely Simple! The Extremely Simple! Standard App (App_Twelite) allows you to achieve basic signal transmission just by wiring.
Using the Extremely Simple! Standard App pre-installed on the factory-default TWELITE DIP, let’s try reflecting the signal input to one DIx/AIx port onto the other DOx/PWMx port.
TWELITE DIP can be either the BLUE series or the RED series.
One-Way Signal Transmission
Signals input to the Parent can be output from the Child.
The Parent sends data to all Children
When multiple Children are prepared, the Parent’s DIx can simultaneously control the DOx of all Children.
Digital Signal
Pressing the switch connected to the Parent lights the LED connected to the Child, and releasing the switch on the Parent turns off the LED on the Child.
Parent Wiring
Child Wiring
In the above example, only DI1 and DO1 are used, but there are a total of 4 ports. Other ports can be used similarly.
Connect the M1 pin of one TWELITE DIP to GND. This unit will act as the Parent.
Also, connect unused AIx ports to VCC to disable them (this can be omitted by changing settings in Interactive Mode).
Please connect a current-limiting resistor to the LED.
Output current capacity is limited
Supply Voltage
Drive Capacity
2.7V-3.6V
4mA
2.2V-2.7V
3mA
2.0V-2.2V
2.5mA
If exceeding the drive capacity, please use a MOSFET or transistor.
Analog Signal
Turning the potentiometer connected to the Parent changes the brightness of the LED connected to the Child.
Parent Wiring
Child Wiring
In the above example, only AI1 and PWM1 are used, but there are a total of 4 ports. Other ports can be used similarly.
About input/output voltage
The analog input operates at 2.0V or below.
In the above example, the supply voltage is divided in half by a potentiometer (10KΩ) and a resistor (10KΩ). In the initial state of the Extremely Simple! Standard App, the output adjusted for the potentiometer is applied to PWMx. When the duty cycle is \(duty\), the input voltage \(V_{input}\), and the supply voltage \(V_{cc}\), the calculation formula is as follows:
\(duty=min(230\frac{V_{input}}{V_{cc}}-5, 100)\)
If you set the option bit 0x00000040 using Interactive Mode, full scale output is possible for inputs below 1.8V (inputs above 2.0V are treated as unused).
\(duty=100\frac{min(V_{input}, 1.8)}{1.8}\)
If anything is wired to PWM2 or PWM3, firmware writing may fail.
These pins have functions used during firmware writing (Details).
Two-Way Signal Transmission
Signal transmission can be performed not only from Parent to Child but also from Child to Parent in the same way.
The Parent receives data from all Children
When multiple Children are prepared, the exclusive DIx of each Child can control the Parent’s DOx in parallel.
(Example: Reflect one Child’s DI1 to the Parent’s DO1, and another Child’s DI2 to the Parent’s DO2)
Pressing the switch connected to the Parent lights the LED connected to the Child, and releasing the switch on the Parent turns off the LED on the Child.
At the same time, pressing the switch connected to the Child lights the LED connected to the Parent, and releasing the switch on the Child turns off the LED on the Parent.
Parent Wiring
Child Wiring
In the above example, only DI1 and DO1 are used, but there are a total of 4 ports. Other ports can be used similarly.
Installing a Repeater
By placing a unit configured as a Repeater between the Parent and Child, communication distance can be extended. Up to 3 stages of repeaters can be used.
By using Interactive Mode, you can change various parameters such as network grouping and enabling low latency mode.
What is Interactive Mode
Interactive Mode is a mode used when connecting the TWELITE series to a PC for configuration. By connecting the TWELITE series to a PC via a USB adapter TWELITE R series, you can change various parameters through UART communication.
We recommend using the TWELITE STAGE app. The TWELITE STAGE app is a tool that includes functions for firmware configuration and writing, as well as features to evaluate communication with the parent device. The TWELITE STAGE app is included in the TWELITE STAGE SDK.
For more details about the TWELITE STAGE app, please refer to the TWELITE APPS Manual.
Prepare a pair of parent and child devices and configure so that transmission occurs only when the parent’s button is pressed
Network Grouping
By default, all TWELITE DIP devices can communicate with each other. When you prepare two pairs of parent and child devices, the inputs of the parent are reflected to both children, and the inputs of the children are reflected to both parents.
Using Interactive Mode, change the Application ID and frequency channel to separate the two pairs so they can be used independently at the same time.
The Application ID logically separates the network, and the frequency channel physically separates it. If the number of groups is 16 or less, it is recommended to change both.
It is recommended to space frequency channels as much as possible.
Customization Procedure
Insert the TWELITE DIP into the TWELITE R2 and connect it to the PC using a USB-C cable
Pressing the switch on Group A’s parent lights only Group A’s child LED
Pressing the switch on Group B’s parent lights only Group B’s child LED
Change the Application ID of Group B’s child to 0xAAAAAAAA and the frequency channel to 11.
Pressing the switch on Group A’s parent lights LEDs on both children
Using Low Latency Mode
By default, there is a delay of about 30-70ms from when the source DIx changes until it is reflected on the destination DOx. This delay exists due to processing to avoid chattering and wireless packet interference.
Low Latency Mode shortens this delay to about 3-10ms by simplifying these processes.
Enable low latency mode on the transmitting device (parent) via Interactive Mode.
The option bits value is a 32-bit unsigned integer. You can enable corresponding settings by setting flags on each bit.
To enable multiple settings simultaneously, take the logical OR of all.
Customization Procedure
Insert the TWELITE DIP into the TWELITE R2 and connect it to the PC using a USB-C cable
Pressing the parent’s switch lights the child’s LED
The operation is the same as the default state, but you might notice slightly improved response
Connect an oscilloscope to the parent’s DO1 and child’s DI1 to compare and confirm the effect
Transmit Only When Button is Pressed
By default, transmission occurs when the input state changes and also once every second.
In this case, for example, if the transmitting device’s button is held down and the power is cut, the output on the receiving side remains.
The Transmit Only When Button is Pressed setting causes the transmitting device to repeatedly send when DIx is Low, and continue sending for one second after transitioning to High. If the receiving device’s DOx is set Low and reception stops, it returns to High.
Change the setting via Interactive Mode to transmit only when the button is pressed.
This is useful for applications such as rotating a motor while a remote control button is pressed.
Since transmission continues at short intervals while DIx is Low, increasing the number of transmitters on the same frequency channel is not recommended. Apply this option only for 1:1 communication.
Set the Interactive Mode values as follows to change the behavior of digital input/output on the transmitting device (parent) and receiving device (child).
Connect the Parent to a PC and send/receive data via UART
By using UART communication, you can integrate the Parent with a PC.
Use the TWELITE STAGE app and Python scripts to communicate over UART, allowing you to acquire and control Child device data from your PC via the Parent.
The data sent from the Child running the Extremely Simple! Standard App includes information such as the input state of the DIx/AIx ports, power supply voltage, and the logical device ID of the sender.
Displaying Serial Strings
Data received by the Parent from the Child can be obtained by interpreting the strings output by the Parent over serial (UART). Let’s display this string first.
The default serial communication settings are 115200bps 8-N-1.
When data is received from the Child, a message like the following will be displayed:
:78811501C98201015A000391000C2E00810301FFFFFFFFFB
By interpreting such strings output by the Parent, you can obtain the data sent by the Child.
The above string represents the following data
#
Data
Description
Value
:
char
Header
:
78
0
uint8
Sender Logical Device ID
0x78
81
1
uint8
Command Number
0x81
15
2
uint8
Packet Identifier
0x15
01
3
uint8
Protocol Version
0x01
C9
4
uint8
LQI
201/255
8201015A
5
uint32
Sender Serial ID
0x201015A
00
9
uint8
Destination Logical ID
0x00
0391
10
uint16
Timestamp
approx. 14.27 seconds
00
12
uint8
Number of Relays
0
0C2E
13
uint16
Power Supply Voltage
3118mV
00
15
int8
-
81
16
uint8
Digital Signal
DI1LDI2H DI3HDI4H (Periodic Tx)
03
17
uint8
Digital Signal Mask
DI1DI2
01
18
uint8
AI1 Converted Value
16mV
FF
19
uint8
AI2 Converted Value
Not used
FF
20
uint8
AI3 Converted Value
Not used
FF
21
uint8
AI4 Converted Value
Not used
FF
22
uint8
AIx Correction Value
AI10x03
FB
uint8
Checksum
0xFB
char
Footer
\r
char
Footer
\n
The strings output by the TWELITE Parent follow the format below:
Header
Payload
Checksum
Footer
:
repeated 00-FF
LRC8 of payload
CRLF
All ASCII characters*
Starts with : (0x3A)
Ends with CRLF (\r\n/0x0D 0x0A)
Big-endian
*Except for binary format in serial communication apps
Standard App Viewer
The above format is machine-friendly, but to check the content as a human, you need to interpret it. The TWELITE STAGE app provides a function to interpret and display strings representing data sent from Children running the Extremely Simple! Standard App. The Python library described below also performs this interpretation.
Commander sends strings from the PC to the Parent over serial communication. In other words, it works in the opposite direction to the Standard App Viewer.
Both the “Standard App Viewer” and “Commander” in the TWELITE STAGE app simply exchange strings over serial communication. If you have an environment that supports serial communication, you can integrate your own application with the Parent.
Here, let’s use a Python script to display the input state of DI1, and then control the output of DO1.
By leveraging Python scripts, you can process and save received data, or control output ports from your own software.
This section assumes the reader has knowledge and experience with Python.
Installing the MWings Library
The MWings library makes it easy to integrate TWELITE and Python scripts. Specifically, it interprets strings representing data received from the Child and constructs data to be sent to the Child.
This creates a Twelite object, which serves as the interface for communicating with the Parent.
You specify the serial port as an argument, but here we use the mw.utils.ask_user_for_port() utility to select it dynamically. This function outputs an error message if no serial port exists, returns the port if only one is found, or prompts the user if multiple are present.
Registering a Receive Event Handler
@twelite.on(mw.common.PacketType.APP_TWELITE)
defon_app_twelite(packet):
if packet.di_state[0]:
print("DI1 Pressed")
This registers an event handler that is called when a packet is received from a Child running the Extremely Simple! Standard App.
Event handler registration uses a Python decorator (?). Here, since we are targeting data from the Extremely Simple! Standard App (App_Twelite), we use @twelite.on(mw.common.PacketType.APP_TWELITE). The function defined immediately after this decorator becomes the handler. The function name can be anything, but it must be defined after initializing the Twelite object.
To detect when the Child’s DI1 becomes Low, the receive handler checks the first boolean value in the List-like object di_state (digital interface state) of the packet variable (mwings.parsers.app_twelite.ParsedPacket). Each value in di_state is True when Low.
Handling Other Data
The packet variable contains not only input states but also information about the sender and receiver. For example, by using to_json(), you can output all data in JSON format as follows:
This creates a Twelite object, which serves as the interface for communicating with the Parent.
You specify the serial port as an argument, but here we use the mw.utils.ask_user_for_port() utility to select it dynamically. This function outputs an error message if no serial port exists, returns the port if only one is found, or prompts the user if multiple are present.
This initializes a command object (mwings.serializers.app_twelite.Command), which represents the packet to be sent to a Child running the Extremely Simple! Standard App.
The dictionary initial represents the initial state of the command. Here, the destination logical device ID is set to 0x78 (all Children), with DI1 as the target for change, and initially set to High.
Here, the command data is converted to a string and sent to the Parent every second.
Blinking is achieved by toggling the first boolean value in the List-like object di_state (digital interface state) of the command data, which controls the state of DOx.
Rewrite the TWELITE firmware to the Serial Communication App (App_Uart), which is specialized for wireless serial communication. While the “Extremely Simple! Standard App” also has a function for transmitting binary data via serial communication, its functionality is very limited.
Press Enter several times until the write is complete
By default, after a successful write, the device transitions to the following Interactive Mode screen.
--- CONFIG/TWE UART APP V1-04-5/SID=0x82018ca0/LID=0x78 -- ---
a: set Application ID (0x67720103)
i: set Device ID (120=0x78)
c: set Channels (18)
x: set RF Conf (3)
r: set Role (0x0)
l: set Layer (0x1)
b: set UART baud (38400)
B: set UART option (8N1)
m: set UART mode (E)
k: set Tx Trigger (sep=0x0d0a, min_bytes=0 dly=0[ms])
h: set header format [;U;%t;%i;0x%A;%q;%s;<*>;%X;\n]
C: set crypt mode (0)
o: set option bits (0x00000100)
---
S: save Configuration
R: reset to Defaults
List of Communication Modes
The Serial Communication App provides five communication modes, allowing you to select the most suitable one for your application.
Format Mode (ASCII): Applies a format to both transmission and reception.
Format Mode (Binary): The binary version of Format Mode (ASCII).
Set the i: Logical Device ID to 0 (Parent) on one terminal, and to 1 (Child, ID 1) on the other.
For an overview and usage instructions for Interactive Mode, please refer to the TWELITE APPS Manual.
Prepare an Environment that Supports Binary Data
The terminal features of the TWELITE STAGE App and TeraTerm do not support binary data. You need to use a terminal software that supports binary format.
For the sender’s response message format A5 5A 80 04 DBA1..., see the manual.
3. Sending from the Child Side
Just as with the Parent, select the Child window, then go to Connection > Send String... to open the send window, and make sure the Hex radio button is selected.
Enter the following content and click Send to transmit to the Parent.
For the sender’s response message format A5 5A 80 04 DB A1..., see the manual.
3. Send from the Child Side
As with the Parent, select the Child window, then go to Connection > Send String... to open the send window, and make sure the Hex radio button is selected.
Enter the following and click Send to transmit to the Parent.
1.5 - Advanced Digital Transmission with Remote Control App
Use the Remote Control App to access advanced features specialized for digital signals
By writing the firmware from Extremely Simple! Standard App (App_Twelite) to the Remote Control App (App_IO), you can access advanced features specialized for digital signals.
Use the Remote Control App to utilize advanced features specialized for digital signal transmission. For example, you can increase the number of Child digital inputs to 12 channels.
Write the TWELITE firmware to the Remote Control App (App_IO), which is specialized for digital signal transmission. While the Extremely Simple! Standard App supports digital signal transmission, its I/O is limited to 4 lines. The Remote Control App expands the number of I/O and allows you to switch their combinations.
Writing the Firmware
Write the firmware to all Parent, Child, and other devices as follows:
Press Enter several times until writing is complete
With the default settings, after a successful write, the device will switch to the following Interactive Mode screen:
--- CONFIG/APP_IO V1-03-2/SID=0x86300001/LID=0x00 ---
a: set Application ID (0x67720107)
i: set Device ID (--)
c: set Channels (16)
x: set Tx Power (3)
t: set mode4 sleep dur (1000ms)
y: set mode7 sleep dur (0s)
f: set mode3 fps (16)
d: set hold mask (000000000000)
D: set hold dur (1000ms)
o: set Option Bits (0x00000000)
b: set UART baud (38400)
p: set UART parity (N)
C: set crypt mode (0)
K: set crypt key []
---
S: save Configuration
R: reset to Defaults
In the default state, the Parent can receive up to 12 digital signals.
Parent wiring diagram
In the diagram above, DIP pin 9 (O3) is used as an output, but other Ox pins can be used similarly. To test the channel override function, which is not available in the Extremely Simple! Standard App, a tactile switch is connected to DIP pin 23 (C1).
Child Wiring
In the default state, the Child can send up to 12 digital signals.
Child wiring diagram
In the diagram above, DIP pin 17 (I3) is used as an input, but other Ix pins can be used similarly. Similarly, to test the channel override function, a tactile switch is connected to DIP pin 23 (C1).
Operation Check
Press and release the button connected to the Child’s I3.
The LED connected to the Parent’s O3 will turn on and off accordingly.
While pressing the button connected to the Child’s C1, press and release the button on I3.
Communication will not occur because the Child’s frequency channel is temporarily overridden.
While pressing the buttons connected to both the Parent’s and Child’s C1, press and release the button connected to the Child’s I3.
Communication will resume because both Parent and Child frequency channels are overridden to match.
The C1/C2 pins override the frequency channel as follows:
Compared to the Extremely Simple! Standard App, you can handle two more digital signals!
Reflecting Child Input to Parent Output as Fast as Possible
When using the Child’s continuous mode, there is usually a delay of about 30-70ms from Child input to Parent output. If you need faster response, set Option Bits 0x00000001: Low Latency Mode via Interactive Mode.
Press Enter and confirm that the settings list is shown
Enter o (lowercase), input the Option Bits value 00000001, and press Enter
Enter S (uppercase) to save, then press ESC to exit
If multiple inputs change almost simultaneously, they are transmitted in order, which may cause delays for subsequent inputs.
Also, if input chattering occurs, it may be reflected directly to the output.
When Low Latency Mode is applied to the Child’s intermittent mode, its behavior differs from continuous mode:
Upon wake-up by interrupt, only the value of the corresponding interrupt port is sent
If a port is used as an interrupt wake-up pin, the states of other ports cannot be read simultaneously upon wake-up
When returning from sleep, the IO port state is determined in 1/4 the usual time
Best suited for sending digital outputs from sensors, rather than buttons that may have chattering!
Restoring Output Signals When Packets Are Lost
If radio communication is interrupted while any input is held Low, the output will remain Low even if the actual input returns to High.
To return the signal to its original state when packets are lost, enable Remote Long Press Mode. In this mode, after the sending side input changes, the signal is sent continuously for a while. On the receiving side, if no packet indicating a Low state is received for a certain period, the output times out and returns to High.
Press Enter and confirm that the settings list is shown
Enter o (lowercase), input the Option Bits value 00000100 and press Enter
Enter d (lowercase), input the hold/long-press target (for example, 000000001010 for O2 and O4), and press Enter
Enter D (uppercase), input the hold/long-press time (the duration to return the output from Low to High after signal loss), and press Enter
Enter S (uppercase) to save, then press ESC to exit
Ideal for applications such as remotely controlling motors from a remote control!
Using the Child as a Low Power Remote
If the Child is battery-powered, intermittent mode, which alternates sleep and wake, is effective. By combining Low Latency Mode and Hold Mode, the Parent’s output can be maintained for a set time when the Child’s button is pressed.
Press Enter and confirm that the settings list is shown
Enter d (lowercase), input the hold/long-press target (for example, 000000001010 for O2 and O4), and press Enter
Enter D (uppercase), input the hold/long-press time (hold time), and press Enter
Enter S (uppercase) to save, then press ESC to exit
Set the hold/long-press time according to your remote control requirements. For example, to keep a lamp on for a while when a button is pressed, use a longer time such as 3000 ms; for frequent button operations, a shorter time such as 50 ms is suitable.
Ideal for applications such as remotely controlling LEDs from a low-power remote!
Using the Child as a Low Power Remote with Long Press
If the Child is battery-powered, intermittent mode is effective. By combining Low Latency Mode and Remote Long Press Mode, the Child can continuously send data to the Parent while a button is held. Even after the button is released, the Child continues sending for a set period, and on the Parent side, if radio packets indicating the button remains pressed are lost for a set period, the output returns to its original state. This ensures reliable delivery of the Child’s input even in low-power operation.
The TWELITE STICK USB dongle integrates the TWELITE module, antenna, and the functionality of the TWELITE R3 into a single case. As the successor to the MONOSTICK series, it is ideal for linking TWELITE with a PC.
For product specifications, please refer to the data sheet.
TWELITE STICK
USB Dongle
The TWELITE STICK combines the TWELITE module and antenna with the functionality of the TWELITE R series USB adapter.
TWELITE STICK Configuration
It can relay packets from other TWELITE devices to the PC, or from the PC to other TWELITE devices. It can also act as a repeater when connected to a USB power source.
Difference from MONOSTICK
TWELITE STICK is fully compatible with the same packets used in the previous MONOSTICK and functions as its successor.
Its compact size—comparable to that of a typical USB flash drive—makes it less likely to interfere with adjacent USB ports.
Size comparison between MONOSTICK and TWELITE STICK
By using the second-generation GOLD series for the TWELITE module, it achieves approximately 10mA lower current consumption during receive standby compared to the previous RED series, while maintaining equivalent transmission power and slightly improved receive sensitivity.
Current consumption from receive standby to transmission on TWELITE STICK (4 retransmissions, LED disabled)
Current consumption from receive standby to transmission on MONOSTICK RED (4 retransmissions)
Wireless packets of the TWELITE BLUE / RED / GOLD series are mutually compatible and can communicate with each other.
TWELITE APPS
The factory-shipped TWELITE STICK comes pre-installed with the TWELITE APPS Unified Edition. This unified edition takes advantage of the program size of the TWELITE GOLD series to consolidate the functions of previous firmware into a single image.
By using Interactive Mode operations, you can instantly switch between these functions without rewriting the firmware. Some apps change the logo LED color according to their state and blink when receiving packets.
Parent
Repeater
Children
Magenta
Yellow
Cyan
By default, the Parent and Repeater App (magenta LED) runs in parent mode, just like on MONOSTICK.
Simple Wireless Communication
TWELITE can communicate immediately after startup. Pairing like Bluetooth is not required.
Broadcast communication is performed between devices set to the same frequency channel. Therefore, multiple devices cannot transmit simultaneously on the same channel. Packets not addressed to the device are ignored. You can think of it as working like a transceiver or intercom.
TWELITE can transmit without receiving, enabling the realization of devices with excellent power-saving performance.
What is the wireless communication standard?
TWELITE is a wireless module that uses 2.4GHz radio waves and complies with IEEE 802.15.4, which is a different standard from Bluetooth (IEEE 802.15.1). Other products conforming to IEEE 802.15.4 include Zigbee modules, but TWELITE is not a Zigbee module. Zigbee modules use the Zigbee protocol stack on top of IEEE 802.15.4, whereas TWELITE implements a simple, proprietary protocol stack instead.
Although it is not suitable for large-volume data communication, it is optimal for simple signal transmission and similar applications.
Small amounts of data can be transmitted efficiently.
2.1 - Evaluation and Configuration with TWELITE STAGE APP
How to evaluate communication and change settings using TWELITE STAGE APP
By using the TWELITE STAGE APP included in the TWELITE STAGE SDK development and evaluation environment, you can verify communication and change settings.
Much of the content on this page is also applicable to the MONOSTICK series.
Basic Operation Check
Connect the TWELITE STICK
Connect the TWELITE STICK to the USB port of your PC.
The factory-shipped TWELITE is set to Parent mode of the Parent and Repeater App. It can send and receive data with child devices of the TWELITE series, and the logo mark should light up magenta.
By using a TWELITE STICK in place of a TWELITE DIP parent, you can detect the button state on the PC side or control the LED from the PC.
Connecting the TWELITE STICK
Connect the TWELITE STICK to the USB port of your PC.
If it is set to Parent mode of the Parent and Repeater App, it will light up magenta.
Waiting in Parent Mode
Device Settings
No configuration changes are required. Communication will begin immediately using the factory default settings.
However, for confirmation, let’s check the current configuration.
To change TWELITE settings via UART, start the device in Interactive Mode. TWELITE STAGE APP provides functionality for working with Interactive Mode.
From the main menu, select Interactive Mode.
Main Menu
On the next screen, click anywhere or press the Enter key to continue.
Confirmation Screen
If the following screen appears, the mode has started successfully.
Interactive Mode
If the Channel value, which physically separates networks, is 18, and the Application ID value, which logically separates networks, is 67720102, communication with the factory-shipped TWELITE DIP will be possible.
How to Operate Interactive Mode
Enter the ID shown on the left to edit each item (e.g., enter a to edit the Application ID)
After selecting an item, type the value and press the Enter key to confirm, or press the ESC key to cancel
Press the S key to apply the settings you’ve entered
To reset all settings to default, press the R key to reset, then press the S key to apply
With the TWELITE STICK connected to your PC, press the switch connected to DI1 on the TWELITE DIP.
If operating correctly, the logo will glow red and brighter while the button is pressed.
Logo lights up red when DI1 is pressed
If a switch is connected to DI2, the TWELITE STICK will glow green. If AI1 is disconnected from VCC and a voltage between 0–2V is applied, the brightness will vary depending on the button press on DI1 or DI2.
Standard App Viewer
TWELITE STAGE APP includes a feature to display data received from child devices running the Extremely Simple! Standard App.
Let’s read the status of the switch connected to DI1.
Serial Number: Serial ID of the child device (engraved on the can)
Dx: State of the DIx pins
Ax: Voltage input to the AIx pins (in mV, ranging from 0mV to 2000mV)
Standard App Commander
TWELITE STAGE APP also includes a function to send data to child devices running the Extremely Simple! Standard App. Let’s try controlling the LED connected to DO1.
By using a TWELITE STICK as the parent device for TWELITE ARIA, you can obtain temperature, humidity, and magnetic proximity data on your PC.
Connecting the TWELITE STICK
Connect the TWELITE STICK to the USB port of your PC.
If it is set to Parent mode of the Parent and Repeater App, it will light up magenta.
Waiting in Parent Mode
Device Settings
No configuration changes are needed. Communication will start immediately with the factory default settings.
If the Channel, which physically separates networks, is set to 18, and the Application ID, which logically separates networks, is set to 67720102, then communication with the factory-configured TWELITE ARIA is possible.
Logo Lighting
With TWELITE STICK connected to the PC, bring a magnet close to the Hall sensor on TWELITE ARIA.
If working properly, TWELITE ARIA will send a packet each time a magnet is brought near, and TWELITE STICK’s logo will flash in response.
The logo will flash not only for ARIA packets but for any packets with the same channel and application ID.
Simple Monitor
TWELITE STAGE APP includes a simple monitor feature to display data received from TWELITE ARIA.
2.2 - Communicating with Child Devices Using Python (Basic)
How to communicate with child devices using Python
By using a dedicated library, you can communicate with TWELITE child devices via TWELITE STICK from Python.
Much of the content on this page also applies to the MONOSTICK series.
Basic Operation Check
Connect the TWELITE STICK
Connect the TWELITE STICK to your PC’s USB port.
The factory-default TWELITE is configured in Parent mode of the Parent and Repeater App. It can send and receive data to and from child devices in the TWELITE series, and the logo should light up magenta.
Factory default state
Installing the MWings Library
Prepare a Python 3.12 or later environment.
Install the MWings module, which interprets the output of the Parent and Repeater App.
pip install mwings
The MWings module allows communication with TWELITE child devices via a TWELITE parent device connected to the host.
Interprets data received from the parent and converts it into a dictionary, JSON, or pandas DataFrame format*
Sends commands generated from dictionaries to the parent device
*The Lite version does not support pandas
For detailed installation instructions and full feature documentation, refer to the MWings for Python Manual.
In modern Python development, managing Python versions and project-level dependencies is essential. The manual introduces how to set up an environment using pyenv and poetry.
This version removes the dependency on pandas, avoiding potential conflicts with numpy. Although it does not support DataFrame output, it retains output functions for dictionaries and JSON strings.
Because of its lightweight nature, it can also be a good option on regular PCs if you do not need pandas functionality.
Confirming Data Reception
Verify that TWELITE STICK can interpret the received data.
This script will print the contents of all types of packets received by the TWELITE STICK in JSON format to the terminal, allowing you to confirm the data.
# -*- coding:utf-8 -*-# Written for Python 3.12# Formatted with Black# MWings example: Receive data, print JSON, typedfrom zoneinfo import ZoneInfo
import mwings as mw
# Main functiondefmain() ->None:
# Create a twelite object twelite = mw.Twelite(mw.utils.ask_user_for_port())
# Use JST for received data twelite.set_timezone(ZoneInfo("Asia/Tokyo"))
# Register event handlers@twelite.on(mw.common.PacketType.APP_ARIA)
defon_app_aria(packet: mw.parsers.app_aria.ParsedPacket) ->None:
print(packet.to_json(verbose=False, spread=True))
@twelite.on(mw.common.PacketType.APP_CUE)
defon_app_cue(packet: mw.parsers.app_cue.ParsedPacket) ->None:
print(packet.to_json(verbose=False, spread=True))
@twelite.on(mw.common.PacketType.APP_CUE_PAL_EVENT)
defon_app_cue_pal_event(packet: mw.parsers.app_cue_pal_event.ParsedPacket) ->None:
print(packet.to_json(verbose=False, spread=True))
@twelite.on(mw.common.PacketType.APP_IO)
defon_app_io(packet: mw.parsers.app_io.ParsedPacket) ->None:
print(packet.to_json(verbose=False, spread=True))
@twelite.on(mw.common.PacketType.APP_TWELITE)
defon_app_twelite(packet: mw.parsers.app_twelite.ParsedPacket) ->None:
print(packet.to_json(verbose=False, spread=True))
@twelite.on(mw.common.PacketType.APP_PAL_AMB)
defon_app_pal_amb(packet: mw.parsers.app_pal_amb.ParsedPacket) ->None:
print(packet.to_json(verbose=False, spread=True))
@twelite.on(mw.common.PacketType.APP_PAL_MOT)
defon_app_pal_mot(packet: mw.parsers.app_pal_mot.ParsedPacket) ->None:
print(packet.to_json(verbose=False, spread=True))
@twelite.on(mw.common.PacketType.APP_PAL_OPENCLOSE)
defon_app_pal_openclose(packet: mw.parsers.app_pal_openclose.ParsedPacket) ->None:
print(packet.to_json(verbose=False, spread=True))
@twelite.on(mw.common.PacketType.APP_UART_ASCII)
defon_app_uart_ascii(packet: mw.parsers.app_uart_ascii.ParsedPacket) ->None:
print(packet.to_json(verbose=False, spread=True))
@twelite.on(mw.common.PacketType.APP_UART_ASCII_EXTENDED)
defon_app_uart_ascii_extended(
packet: mw.parsers.app_uart_ascii_extended.ParsedPacket,
) ->None:
print(packet.to_json(verbose=False, spread=True))
@twelite.on(mw.common.PacketType.ACT)
defon_act(packet: mw.parsers.act.ParsedPacket) ->None:
print(packet.to_json(verbose=False, spread=True))
# Start receivingtry:
# Set as daemon thread twelite.daemon =True# Start the thread, Join to the main thread twelite.start()
print("Started receiving")
whileTrue:
twelite.join(0.5)
exceptKeyboardInterrupt:
# Stop the thread print("Flushing...")
twelite.stop()
print("Completed")
if __name__ =="__main__":
# Call the main function main()
For example, if you have prepared a factory-default TWELITE DIP running the Extremely Simple! Standard App as a child device, just like in the previous section Using TWELITE STAGE APP, you should see an output like the following. To stop the script, press Ctrl+C.
It is useful as a command-line tool for logging received data over extended periods.
python rx_export_csv_durable.py -h
usage: rx_export_csv_durable.py [-h][-v][-s]Log packets from App_Wings to csv, line by line
options:
-h, --help show this help message and exit
-v, --verbose include system information
-s, --sort sort columns in the output
Sending and Receiving Arbitrary Data
Here, let’s create a script that specifically communicates with a TWELITE DIP child device prepared just like in Using TWELITE STAGE APP.
Example wiring of TWELITE DIP child device
The goal is to display the state of a switch connected to the DI1 pin of the TWELITE DIP and control an LED connected to the DO1 pin.
Receiving Only Standard App Data
Modify rx_print_json.py to create a simplified script that only receives data from the Extremely Simple! Standard App.
# -*- coding:utf-8 -*-from zoneinfo import ZoneInfo
import mwings as mw
# Main functiondefmain() ->None:
# Create a twelite object twelite = mw.Twelite(mw.utils.ask_user_for_port())
# Use JST for received data twelite.set_timezone(ZoneInfo("Asia/Tokyo"))
# Register event handlers@twelite.on(mw.common.PacketType.APP_TWELITE)
defon_app_twelite(packet: mw.parsers.app_twelite.ParsedPacket) ->None:
print(packet.to_json(verbose=False, spread=True))
# Start receivingtry:
# Set as daemon thread twelite.daemon =True# Start the thread, Join to the main thread twelite.start()
print("Started receiving")
whileTrue:
twelite.join(0.5)
exceptKeyboardInterrupt:
# Stop the thread print("Flushing...")
twelite.stop()
print("Completed")
if __name__ =="__main__":
# Call the main function main()
Script Mechanism
By calling twelite.start(), a thread for receiving is launched, and twelite.on registers an event handler for each application type (in this case, on_app_twelite()), which is invoked upon each packet reception.
In the previous script, we used the to_json() method to output all data as a JSON string.
Here, we’ll extract only the state of the DI1 pin from parsers.app_twelite.ParsedPacket using the di_state field and display a virtual LED in the terminal.
If pressing the switch connected to the DI pin of TWELITE DIP causes the red light to appear, it indicates success.
Example display
Sending Commands to the Parent Device
In addition to displaying data received by the TWELITE STICK, you can also send data from the TWELITE STICK.
In the script’s main loop, we call threading.Thread.join() every 0.5 seconds so that the receiving thread can also terminate when the main thread ends.
# Start the thread, Join to the main thread twelite.start()
print("Started receiving")
whileTrue:
twelite.join(0.5)
Using this mechanism, let’s control the DO1 pin of the TWELITE DIP from the main loop and try blinking the LED every 0.5 seconds.
Modify the previous script as follows. The full script below includes all changes made so far.
# -*- coding:utf-8 -*-from zoneinfo import ZoneInfo
from typing import Any
import mwings as mw
# Main functiondefmain() ->None:
# Create a twelite object twelite = mw.Twelite(mw.utils.ask_user_for_port())
# Use JST for received data twelite.set_timezone(ZoneInfo("Asia/Tokyo"))
# Register event handlers@twelite.on(mw.common.PacketType.APP_TWELITE)
defon_app_twelite(packet: mw.parsers.app_twelite.ParsedPacket) ->None:
print(f"\rDO1 LED: {"🔴"if packet.di_state[0] else"⚪"}", end='', flush=True)
# Initialize command initial: dict[str, Any] = {
"destination_logical_id": 0x78, # All child devices"di_to_change": [True, False, False, False], # Enable DI1"di_state": [False, False, False, False], # Initial state of DIx }
command = mw.serializers.app_twelite.Command(**initial)
# Toggle the DI1 statedeftoggle_di1() ->None:
command.di_state[0] =not command.di_state[0]
twelite.send(command)
# Start receivingtry:
# Set as daemon thread twelite.daemon =True# Start the thread, Join to the main thread twelite.start()
print("Started receiving")
whileTrue:
toggle_di1() # Send twelite.join(0.5) # ReceiveexceptKeyboardInterrupt:
# Stop the thread print("Flushing...")
twelite.stop()
print("Completed")
if __name__ =="__main__":
# Call the main function main()
Script Mechanism
First, the contents of serializers.app_twelite.Command are initialized. Then, a closure toggle_di1() is defined to invert di_state[0] and send it. By calling toggle_di1() from the main loop, the LED is made to blink.
When you run this script, it displays a virtual LED just like before.
Example display
At the same time, the LED connected to the DO1 pin of TWELITE DIP should continuously blink. When you stop the script, the blinking stops.
Packet reception and command transmission can be handled asynchronously.
2.2.1 - Communicating with Child Devices Using Python (Web Server IoT)
Send data from child devices to a web server using Python
As a practical application, this guide demonstrates how to build an IoT system using a web server.
The content on this page also applies to the MONOSTICK series.
Collecting Temperature and Humidity Data from TWELITE ARIA
Let’s build a simple IoT system that receives temperature and humidity data from the sensor tag TWELITE ARIA, sends it to a web server, and displays it on a graph.
In the basic script for TWELITE DIP, we only performed simple operations on DI1 and DO1. However, in an actual IoT system, it is necessary to send acquired data to an upstream server using methods such as REST APIs.
The former does not require TWELITE R2/R3, while the latter allows smoother operation.
Starting TWELITE ARIA
Insert a CR2032 battery to power up TWELITE ARIA.
Insert CR2032 battery
Writing and Running the Script
Installing Required Modules
Prepare Python 3.12 or later and install the mwings (or mwingslite) and requests modules.
pip install mwings requests
Creating the Script
Create the script stick_aria_thingspeak.py as shown below. Use mwings.parsers.app_aria to receive data and the requests module to send HTTP GET requests to ThingSpeak.
Replace the initial API_KEY with the key you saved earlier.
# -*- coding:utf-8 -*-from zoneinfo import ZoneInfo
from time import perf_counter
import mwings as mw
import requests
API_KEY ="XXXXXXXXXXXXXXXX"# Replace with your ThingSpeak API keyBASE_URL ="https://api.thingspeak.com/update"SEND_MIN_INTERVAL =20# Minimum interval in seconds to send data to ThingSpeak# Main functiondefmain() ->None:
# Create a twelite object twelite = mw.Twelite(mw.utils.ask_user_for_port())
# Use JST for received data twelite.set_timezone(ZoneInfo("Asia/Tokyo"))
# Initialize last send time last_send_time = perf_counter() - SEND_MIN_INTERVAL
# Initialize the target serial ID target_serial_id =-1# Register event handlers@twelite.on(mw.common.PacketType.APP_ARIA)
defon_app_aria(packet: mw.parsers.app_aria.ParsedPacket) ->None:
# Filter packets by serial IDif target_serial_id <0:
# Set the serial ID from the received packet target_serial_id = packet.source_serial_id
print(f"Serial ID set to {target_serial_id:08X}")
elif packet.source_serial_id != target_serial_id:
# Ignore packets from other serial ID devices print(
f"Ignoring packet from serial ID {packet.source_serial_id:08X}, expected {target_serial_id:08X}" )
return# Throttle sending to ThingSpeakif perf_counter() - last_send_time < SEND_MIN_INTERVAL:
print("Skipping send due to minimum interval")
return# Skip sending if within the minimum interval last_send_time = perf_counter() # Update last send time# Send data to ThingSpeak payload = {
"api_key": API_KEY,
"field1": f"{packet.temp_100x /100.0:.2f}", # Temperature"field2": f"{packet.humid_100x /100.0:.2f}", # Humidity"field3": f"{packet.supply_voltage}", # Supply voltage (mV)"field4": f"{packet.lqi}", # Link Quality Indicator }
response = requests.get(BASE_URL, params=payload)
# Check the response statusif response.status_code ==200:
print(f"OK: entry ID = {response.text}")
else:
print(f"NG: status code = {response.status_code}")
# Start receivingtry:
# Set as daemon thread twelite.daemon =True# Start the thread, Join to the main thread twelite.start()
print("Started receiving")
whileTrue:
twelite.join(0.5) # ReceiveexceptKeyboardInterrupt:
# Stop the thread print("Flushing...")
twelite.stop()
print("Completed")
if __name__ =="__main__":
# Call the main function main()
Running the Script
Execute the script.
python stick_aria_thingspeak.py
If data is successfully received from TWELITE ARIA and sent correctly, you will see the following output showing entry IDs in sequence:
Started receiving
Serial ID set to 8201C2DC
OK: entry ID = 1
OK: entry ID = 2
OK: entry ID = 3
OK: entry ID = 4
OK: entry ID = 5
...
Click the “Private View” tab on ThingSpeak. The transmitted data should appear as a graph.
By default, the Y-axis range adjusts dynamically. You can configure the min and max values for each graph via the ✏️ icon.
For example, based on the operating voltage of TWELITE, you can set Y-Axis Min and Y-Axis Max for the Field 3 Chart.
Displaying approximately 2 days of data
You’ve successfully built a simple IoT system integrated with a web server!
Script Overview
Filtering for Sending and Receiving
To prevent overloading the server, data is sent only at intervals defined by SEND_MIN_INTERVAL.
To avoid mixing data from multiple devices, the serial ID of the first device is used as the target.
The data sent to the server is constructed in the following section:
# Send data to ThingSpeakpayload = {
"api_key": API_KEY,
"field1": f"{packet.temp_100x /100.0:.2f}", # Temperature"field2": f"{packet.humid_100x /100.0:.2f}", # Humidity"field3": f"{packet.supply_voltage}", # Supply voltage (mV)"field4": f"{packet.lqi}", # Link Quality Indicator}
response = requests.get(BASE_URL, params=payload)
From mwings.parsers.app_aria, we retrieve the temperature, humidity, coin cell voltage, and signal quality (LQI) expressed as a value between 0 and 255, then convert these to strings to construct the query for the GET request.
In the basic script for TWELITE DIP, we only performed simple operations with DI1 and DO1. However, applications designed for actual monitoring require a user interface like the one found in TWELITE STAGE APP.
Dear PyGui (DPG) is a UI toolkit based on Dear ImGui written in C++ and OpenGL.
It is commonly used in development tool interfaces. While it is not suited for highly customized designs, it features lightweight performance and simple syntax.
Wiring and Starting the TWELITE DIP
In this application, when a signal is received via DIx or AIx of the TWELITE DIP, a signal is simultaneously output to DOx or PWMx.
In addition to VCC and GND, freely connect any of the following 16 pins:
Type
Pin
1
2
3
4
Range
Notes
Digital Input
DIx
#15
#16
#17
#18
0.0V - VCC
Internal pull-up
Analog Input
AIx
#22
#23
#24
#25
0.0V - 2.0V
Invalid if exceeded
Digital Output
DOx
#5
#8
#9
#12
0.0V - VCC
Connect LED cathode
PWM Output
PWMx
#4
#6
#7
#11
0% - 100%
Voltage at VCC level
Creating and Running the Script
Installing Modules
Install the mwings (or mwingslite) and dearpygui modules.
The initialization of Dear PyGui is handled by initialize_viewport().
This function sets up the font file and defines the size of the OS window (referred to as the Viewport).
definitialize_viewport(self) ->None:
"""Set up Dear PyGui context, fonts, and viewport."""...
The interface within the OS window is defined in create_windows().
Child windows on the screen are created using dpg.window(), and components are defined within them.
By assigning a tag to a component, you can modify its values and attributes from the program (similar to the id= in HTML).
defcreate_windows(self) ->None:
"""Create and configure all Dear PyGui windows and their contents."""...
Buttons, combo boxes, sliders, and checkboxes that accept user input can register a callback.
defon_select_port(self, sender: Any, app_data: str, user_data: Any) ->None:
"""Handle serial port selection from the combo box."""...
As with other scripts, data received from a child TWELITE is handled by an event handler.
When building an executable with Nuitka
When building an executable (e.g., .exe) using Nuitka, converting method bindings into C may cause self to be duplicated, resulting in too many arguments. In such cases, implement the callback by returning a closure as shown below.
from typing import Any, Callable
...defcb_for_select_port(self) -> Callable[[Any, str, Any], None]:
"""Make a callback for serial port selection from the combo box."""defcallback(sender: Any, app_data: str, user_data: Any) ->None:
self.selected_port = app_data
return callback
... dpg.add_combo(
... callback=self.cb_for_select_port(),
)
In on_app_twelite(), data to be reflected in DOx is registered immediately using tag, and data for PWMx is passed to update_plot() via member variables.
defon_app_twelite(self, packet: mw.parsers.app_twelite.ParsedPacket) ->None:
"""Update the GUI based on incoming TWELITE DIP packet data."""...
When the “Connect” button is pressed, start() is called.
This function initializes mwings.Twelite and registers the receive handler.
Since the receive handler is defined as a method, the add_listener method is used instead of the decorator @on used previously.
defstart(self) ->None:
"""Start TWELITE communication and register listeners."""...
Because Dear PyGui is built on a low-level API, the application controls frame rendering directly, allowing you to define your own rendering loop. While the OS window is open, loop() is repeatedly called.
Once connected to the serial port, loop() performs the following three tasks:
defloop(self) ->None:
"""Perform periodic updates while the application is running."""...
The entire application runs when show() is called.
defshow(self) ->None:
"""Main execution loop of the application."""...
The program exits the rendering loop either when dpg.is_dearpygui_running() becomes False after closing the window, or upon receiving a KeyboardInterrupt (Ctrl+C), and then cleans up mwings.Twelite and dearpygui.
The wireless LAN gateway TWELITE SPOT is a product that combines the low-power wireless microcontroller module TWELITE with the wireless LAN microcontroller module ESP32. By developing firmware for the ESP32, you can integrate the TWELITE network with Wi-Fi networks.
For product specifications, please refer to the Datasheet.
Expanding Possibilities with TWELITE and ESP32
TWELITE SPOT is a product that combines the compact, low-power, and pairing-free TWELITE series—which allows many devices to be used simultaneously—with the wireless LAN microcontroller module ESP32.
Appearance
Internal Structure
For customers who frequently use the TWELITE series
Share data from TWELITE Child devices within the LAN
Use data from TWELITE Child devices within the LAN
Use data from TWELITE Child devices in the cloud
Local Server
The ESP32 is used as a server. For example, you can display acceleration data measured by a TWELITE CUE on a smartphone or operate the output ports of a TWELITE DIP from a smartphone.
The ESP32 connects to the LAN. For example, data sent from TWELITE ARIA devices installed throughout a building can be received by TWELITE SPOT devices on each floor, aggregating temperature and humidity data from all floors on a server within the LAN.
The ESP32 connects to the Internet. For example, by attaching a TWELITE CUE and a magnet to a door, you can detect on the cloud whether the door remains open based on the acquired door open/close status.
Development with Arduino IDE and Dedicated Library
To build a system using TWELITE SPOT, you need to develop firmware for the ESP32.
Arduino IDE can be used for firmware development on the ESP32.
Development using Arduino IDE
There is a vast amount of information online about firmware development using Arduino IDE.
For example, try searching for esp32 arduino.
The MWings library, distributed via the Arduino Library Manager, makes it easy to receive packets from TWELITE Child devices and send commands to them.
The start guide uses third-party open-source software.
We cannot provide detailed instructions on the use of third-party software. We also assume no responsibility for any damages resulting from the use of third-party software.
3.1 - Getting Started
Display acceleration data from TWELITE CUE on your smartphone using TWELITE SPOT
TWELITE SPOT can host dynamic pages on a web server running on ESP32, distributing data received from TWELITE Child devices within the network.
Connect the USB-C cable to the side of TWELITE SPOT and supply power from the USB AC adapter.
Connecting USB Power
2. Power On TWELITE CUE ⚡
Insert a CR2032 coin battery into TWELITE CUE. It will start operating immediately.
Inserting Coin Battery
When TWELITE CUE starts normally, the LED on the side with the logo will blink.
TWELITE CUE cannot communicate with TWELITE SPOT unless it is in the default factory settings.
If you have changed the settings of TWELITE CUE, please change the settings again to return it to factory default.
3. Connect Your Smartphone 📱
Connect your smartphone to the Wi-Fi network TWELITE SPOT (XXXX) from the Wi-Fi settings.
The password is twelitespot. The XXXX in the SSID is a device-specific identifier.
4. Open a Web Browser 🌐
Open a web browser on your smartphone and access spot.local.
If you cannot connect, try accessing 192.168.1.1.
If that still does not work, try accessing http://192.168.1.1/.
You will see a screen like the following.
Top Page
5. Open the CUE Viewer 📈
Tap on CUE Viewer to open the CUE viewer screen.
You will see a screen like the following.
Try changing the orientation of TWELITE CUE.
The CUE viewer displays the number on the dice printed on TWELITE CUE.
You have confirmed the operation of TWELITE SPOT using TWELITE NET and wireless LAN!
For more details about the features, please refer to the TWELITE SPOT Manual.
3.2 - Basics of Firmware Development with ESP32
Try Hello World on ESP32 for TWELITE SPOT firmware development
ESP32 can build a system using wireless LAN on its own. For example, you can display data on a hosted web page, send data to a server within the LAN via WebSocket, or send REST API requests to cloud services.
TWELITE SPOT is a product that combines this ESP32 with TWELITE, enabling the use of many small, low-power wireless tags.
First, let’s try Hello World to learn the basics of firmware development for ESP32.
We will set up the development environment, create and write the Hello World sketch, and verify its operation.
This content also serves as an operation check for TWELITE SPOT. Even if you have experience developing firmware for ESP32 using Arduino IDE, please review the following.
TWELITE SPOT is equipped with both TWELITE and ESP32, but usually, you only develop firmware for the latter. For TWELITE firmware, please use the pre-installed Parent and Repeater applications.
Although the latest Arduino IDE 2.x can also write sketches similarly to Arduino IDE 1.x, as of May 2023, the Java-based plugin does not work, so the Legacy IDE is recommended.
2. Install the Toolchain 🚚
If you have not installed Arduino core for the ESP32 in Arduino IDE, add the following URL to the Board Manager URLs and install the esp32 board definition.
From here, the content is specific to TWELITE SPOT.
Configure Arduino core for the ESP32 to match TWELITE SPOT.
Select the Board Type
From the toolbar, select Tools -> Board -> ESP32 Arduino -> ESP32 Dev Module.
Location of ESP32 Dev Module
Configure Board Settings
Configure as shown in the figure below.
Settings after configuration
Change Flash size from 4MB (32Mb) to 16MB (128Mb).
Prepare TWELITE SPOT
1. Remove the Cover ⛏️
Remove the cover on the top of the TWELITE SPOT case.
Switches and connectors will be exposed.
Names of each part
For details of each part, please see the datasheet.
2. Connect TWELITE R3 / R2 🔌
Connect TWELITE R3 / R2 to the 7P interface for ESP32 (marked ESP32).
Connection example (ESP32)
Always connect TWELITE R3 / R2 to TWELITE SPOT in the same orientation as shown above. Connecting in the wrong orientation may damage TWELITE SPOT or TWELITE R3 / R2.
Tip 👉 Face the surface of TWELITE R3 / R2 towards the connection target.
The VCC pin of each 7P interface is not connected. Since TWELITE R series cannot supply power, you need to supply power from the USB-C connector on the side.
3. Connect USB-C Power ⚡
Supply 5V power to the USB-C connector on the side.
Run the Sketch
In Arduino, programs/projects are called sketches.
1. Create the Sketch 👨💻
Create a Hello World sketch that outputs a string from ESP32 to the serial port and displays it on the Arduino IDE serial monitor.
Click the Serial Monitor button at the top right of the Arduino IDE.
Serial Monitor Button at Top Right
Configure
Set the serial monitor baud rate to 115200.
6. Restart ESP32 🚀
After writing is complete, press and release the ESP32 reset switch EN(RST) on the TWELITE SPOT to reset the ESP32.
Reset Switch Location
Restarting ESP32 also restarts TWELITE.
When ESP32 starts, the LED on the ESP32 side of the board blinks.
When TWELITE starts, the LED on the TWELITE side of the board lights for 1 second.
7. Confirm Startup 💬
If the following string appears on the serial monitor, startup was successful.
Monitor example for TWELITE SPOT: App_CUE (CUE Mode)
Successful Startup Display
For TWELITE ARIA, the display will look like this:
Monitor example for TWELITE SPOT: App_ARIA (ARIA Mode)
8. Start TWELITE CUE ⚡
Insert a CR2032 coin battery into the TWELITE CUE. It will start operating immediately.
Inserting the Coin Battery
When TWELITE CUE starts normally, the LED on the logo side will blink.
If you have changed TWELITE CUE settings, please change the settings again and restore factory defaults (TWELITE CUE mode, Application ID 0x67720102, Frequency Channel 18).
9. Confirm Reception 💬
If the following string appears on the serial monitor, data reception from TWELITE CUE was successful.
Packet Number: #3
Source Logical ID: 0x1
LQI: 147
Supply Voltage: 3310 mV
Accel Event: Dice (1)
Accel X Axis [0]: 72 mG
Accel Y Axis [0]: -64 mG
Accel Z Axis [0]: 1000 mG
Magnet State: Leaving or Not found
Successful Reception Display
For TWELITE ARIA, temperature and humidity data is output instead of acceleration data, so some parts of the display differ.
You have successfully read acceleration data from TWELITE CUE via the TWELITE installed on TWELITE SPOT!
Lines 19-21 initialize the serial ports and output the startup message to the serial monitor.
Serial.begin(115200);
Serial.println("Monitor example for TWELITE SPOT: App_CUE (CUE Mode)");
Serial2.begin(115200);
Serial is used for communication with the Arduino IDE serial monitor. The baud rate is set to 115200 bps to match the serial monitor settings.
Serial2 is used for communication with the TWELITE Parent installed on TWELITE SPOT. This is also set to 115200 bps to match the Parent’s initial settings.
The TWELITE Parent’s serial communication initial settings are 115200 bps / 8N1.
TWELITE Initialization
Lines 24-26 call Twelite.begin() to configure and start the TWELITE Parent on TWELITE SPOT.
Twelite.update() reads packet data (ModBus ASCII format) from the TWELITE Parent one byte at a time.
By repeatedly calling Twelite.update() inside loop(), the parsing of packet data from the TWELITE Parent progresses. When packet parsing is complete, events like those described above are called.
Blocking calls such as delay() may cause packet data reading to fall behind. Always implement time-consuming processes asynchronously and keep the loop() function running as fast as possible.
You have learned how to read acceleration data from TWELITE CUE via TWELITE installed on TWELITE SPOT!
For further steps, see the sketch explanation below and Related Information.
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>constuint8_t PIN_LED =5;
voidsetup() {
pinMode(PIN_LED, OUTPUT);
}
voidloop() {
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
...
classmyApp: MWX_APPDEFS_CRTP(myApp) {
...
void loop() {
// main loop
}
voidreceive(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.
voidloop() {
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>voidsetup() {
...
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.
}
voidloop() {
...
vTransmit();
...
}
voidvTransmit() {
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!
}
Compatibility with TWELITE APPS packets is not guaranteed
In TWELITE APPS, the relay count is basically limited to 3 times, but act packets can be relayed up to 64 times.
When increasing the relay count, please note that packets that have already been relayed (whose duplicate packet management table has been cleared) may be relayed again if they return after a certain time due to taking a detour.
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
voidsetup() {
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();
}
voidloop() {
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);
}
}
}
4.1 - Development Environment
About the development environment (OS, etc.)
To build the development environment, you need to install software packages and agree to their licenses. Additionally, security settings may be required on your PC or workstation.
Although we take great care during distribution, please also ensure to check for viruses and other threats on your side.
Please consult your environment administrator regarding your security policies and operations (e.g., whether external applications can be installed).
Furthermore, when installing or running the development environment, the OS may be involved and require configuration (e.g., running applications from unknown developers. Many of the development environment tools or introduced tools do not have mechanisms to verify the developer). Please refer to general information for configuration methods.
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)
You can run the compiler in WSL (Windows Subsystem for Linux) environments. However, writing firmware and similar operations should be done using utilities on Windows 10.
WSL environment is not mandatory.
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
32-bit systems are not supported.
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.
For efficient code writing, we recommend using Visual Studio Code (VSCode).
Since the MWX library requires more header files than typical C development, VSCode demands more PC resources for code interpretation.
VSCode is not mandatory. You may use any editor you are comfortable with.
Build results on Linux/WSL/macOS differ from those on Windows 10. Although we have not observed differences affecting normal operation, disabling gcc’s LTO tends to increase binary size by a few percent.
If you have doubts about operation, please always build and verify reproduction on Windows 10 or 11 before contacting us.
4.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
Setting Environment Variables
When building from the command line, please set the environment variables. This is not necessary for the TWELITE STAGE app as it sets them automatically.
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:
To uninstall the TWELITE STAGE SDK from your PC, please do the following:
Run UNSET_ENV.cmd to clear the environment variable settings.
Delete the MWSTAGE folder.
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.
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.
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.
To apply MWSDK_ROOT system-wide, use launchd.
Some VSCode settings reference environment variables, but they are not required for building.
4.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)
This page describes several build methods, but all of them ultimately execute the make command. For details, please refer to the explanation of the Makefile.
Depending on the OS environment, security warnings may appear when running each executable program (build toolchain such as make or gcc). You will need to configure settings to suppress these warnings. Whether to operate the program with warnings suppressed should be decided by the customer or system administrator after consultation.
About the build folder structure
Open the folder where you installed MWSDK (MWSDK_ROOT, e.g., C:\MWSDK). It has the following structure:
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.
Parent
Child
Explanation
BRD_APPTWELITE
BRD_APPTWELITE
The parent device boots with M1 pin set to LOW (GND level). In normal mode (always running), you can verify operation like App_Twelite.
PingPong
PingPong
Operates with two child devices. When one sends a Ping packet, the other returns a Pong packet.
Parent-MONOSTICK
Others
You can verify packet transmission from child acts.
Now, let’s look inside the PingPong folder among the acts.
You can also build other acts in Act_samples. In that case, please replace folder and file names accordingly.
A .cpp file with the same name as the folder is always required directly under the folder.
For small acts, write all in this .cpp file. For larger projects, refer to the Makefile explanation to split into multiple files for building.
There is an act file PingPong.cpp directly under the PingPong folder. If you rename the folder, be sure to rename the .cpp file to the same name as 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.
TWELITE is a delicate electronic component, so handle it with care. Below are typical precautions.
Especially when using TWELITE R, often the electronic board is exposed without a case, which may cause unintended shorts or noise leading to malfunction of the USB device.
In such cases, quitting the application and unplugging/replugging the USB device usually recovers it. Worst case, USB device or PC damage may occur.
Handle the board carefully.
Circuit mistakes
Check the circuit again before powering.
Be careful of reverse battery insertion or overvoltage.
Static electricity
Even voltages that are not felt can cause semiconductor failure. Simple measures like touching metal before work, wristbands, or dedicated mats have significant effects.
Shorts caused by metal objects
Keep metal objects away from the board. Cluttered clips may cause shorts, and batteries could discharge heavily and heat dangerously.
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
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)
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.
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
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.)
If an error occurs here, return to the main menu and reselect the menu. If unresolved, try clearing serial port selection with Alt(⌘) + 0 in the TWELITE STAGE app, and check USB connections. Some USB errors require restarting your computer.
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.
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
This requires configuration in the TWELITE STAGE app.
Set “Open folder with code (VSCode)” to 1 in STAGE settings.
Open with VSCode
For Windows, Linux, and macOS, the executable TWELITE_Stage_VSCode.{extension} with this setting enabled is distributed by default.
If VSCode is already running, necessary settings may not be reflected. In that case, close VSCode and launch it again from the TWELITE STAGE app.
Because system environment variables are used for info reflection, problems may occur when running multiple TWELITE STAGE instances referencing different library folders simultaneously. If the environment variable MWSDK_ROOT is set correctly in the VSCode terminal, builds are expected to work properly.
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
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
Build progress is output in the terminal at the bottom.
Build progress
If built correctly, a message showing the .elf file generated with size info (text data bss dec hex filename) appears as shown in the inverted part of the example.
Also, a BIN file (e.g., BRD_APPTWELITE_BLUE_???.bin) should be created under the build folder. Please check.
The VSCode task definition includes a conversion for folder names incompatible with Windows file system (e.g., /c/User/... to C:/User/...).
The conversion rule in .vscode/tasks.json is not perfect but rewrites drive name parts in output messages to a format recognized by VSCode. This allows error file names and line numbers to be displayed in VSCode from compile messages.
If the build fails, first check the error messages. Messages containing the word error often help identify the cause easily.
Also, try cleaning (deleting intermediate files in objs_??? folders) and rebuilding. (If intermediate files from other environments remain, all operations including make clean may fail.)
Building from command line
Additional information for building from the command line.
Knowledge of command line (bash, zsh, etc.) usage is required.
Security warnings may appear when running executables depending on OS. Configuration to suppress warnings is needed. (Whether to operate with warnings suppressed should be decided by the customer or system administrator.)
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.
On Linux, install via package manager (APT example):
sudo apt install make
or
sudo apt install build-essential
On macOS, included in Command Line Tools for Xcode.
xcode-select --install
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 casemake 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.
Deleting objs_??? folders directly may resolve make errors.
4.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 destination folder does not have to be under the MWSDK directory. However, the folder name must not contain spaces or Japanese characters.
The project file structure is as follows (using PingPong as an example):
The only file that needs editing is the PingPong.cpp file name. Change it to the same name as the folder, AlphaBravo.cpp.
Run build\build-BLUE.cmd to generate the BIN file (on Windows 10).
On Linux/WSL/macOS, run make TWELITE=BLUE to verify that the build succeeds.
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.
4.5 - Installing VSCode for act
Install Visual Studio Code for act development
This page explains the introduction of VSCode for firmware development of the TWELITE wireless module. It does not cover general VSCode usage.
We apologize to those who arrived here via search engines.
We hope you will remember TWELITE, a wireless module characterized by ultra-low power consumption.
To facilitate writing the source code of act, we include configuration files for code interpretation in Visual Studio Code (VSCode).
VSCode reads source files and header files to interpret the source code, which helps with function definition information and completion of function and method names (LSP). Compared to traditional C libraries, the MWX library loads a larger amount of header files. Depending on your environment, the editor may feel slow.
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
Our support does not cover inquiries about how to install or use VSCode. Please refer to publicly available information.
Depending on your environment, security settings may be required for installation. Please check with your system administrator about installation feasibility and refer to official sources and general information for the procedure.
Features of VSCode
Editing source code
Intellisense based on source code interpretation(* This does not guarantee that all definitions are interpreted correctly)
MWX library samples include a .vscode definition. This definition uses the MWSDK_ROOT environment variable to locate the library source code (under {MWSDK_ROOT}/TWENET/current).
When starting VSCode from TWELITE STAGE, the above environment variables and others are set. If VSCode is already running, these settings may not be applied.
VSCode’s source code interpretation does not always exactly match compiler interpretation (due to differences between GCC and clang, etc.). Also, depending on the editing state, interpretation may become more incomplete.
4.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.
In MWSDK 2020-04, the .cpp files in the project folder are automatically detected, so usually there is no need to modify the Makefile.
Editing is required when source files are placed in subfolders.
In MWSDK 2019-12 and earlier, if there are multiple .cpp files, editing the Makefile is necessary.
After copying the project folder from another environment, always delete the build/objs_??? folder. If intermediate files from another environment remain, make will result in an error.
(From MWSDK 2020-04 onwards) You can avoid errors by running clean with USE_APPDEPS=0 and then running the make command again.
make USE_APPDEPS=0 TWELITE=BLUE clean
...
make TWELITE=BLUE
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 =0VERSION_SUB =1VERSION_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 =0VERSION_SUB =1VERSION_VAR =0
During compilation, these are passed as definitions like -DVERSION_MAIN=0-DVERSION_SUB=1-DVERSION_VAR=0.
Adding source files
(From MWSDK 2020-04 onwards) If files are not placed in subfolders, no additional specification is required. All .c and .cpp files in the project folder are added automatically.
What is needed when adding source files are APPSRC_CXX and APP_COMMON_SRC_DIR_ADD?.
When placing source files in subfolders, specifying the folder APP_COMMON_SRC_DIR_ADD? is mandatory.
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).
You can also pass several other options to the compiler and linker.
Option
Description
CXXFLAGS
Specify compile options for C++ source files.
CFLAGS
Specify compile options for C/C++ source files.
INCFLAGS
Specify include paths for header files.
OPTFLAGS
Define when you want to apply compile options other than the default -Os for special reasons.
LDFLAGS
Specify linker options. (Although not mentioned in the comments of the above Makefile, you can specify this.)
4.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.