PAL AMBIENT SENSE PAL is used to acquire sensor values.
[BEHAVIOR] (./) is used to describe the Parent Node Child Node.
The sensor is described directly using Wire
instead of using the board behavior function to obtain values.
Child Nodes are described by a state machine.
See the explanation of BRD_APPTWELITE, the explanation of PAL_AMB, and the explanation of PAL_AMB-usenap before the explanation of this ACT. Also see the description of BEHAVIOR.
This sample shows how to write BEHAVIOR. BEHAVIORS are used to describe more complex applications.
Uses the environmental sensor PAL AMBIENT SENSE PAL to acquire sensor values.
Use the sleep function to operate with coin cell batteries.
Role | Example |
---|---|
When using PAL as the Parent Node, coin cell batteries cannot be used. As a rule of thumb, prepare a power supply environment that can provide a stable current of 50 mA or more.
PAL_AMB-behavior.hpp : Only setup()
is defined. read DIP-SW and if D1..D3 is upper position, it works as Parent Node, otherwise it sets ID corresponding to DIP SW as Child Node.
Parent/myAppBhvParent.hpp : behavior class definition for Parent Node
Parent/myAppBhvParent.cpp : implementation
Parent/myAppBhvParent-handlers.cpp : implementation of handlers
Parent/myAppBhvParent.hpp : behavior class definition for Child Nodes
Parent/myAppBhvParent.cpp : implementation
Parent/myAppBhvParent-handlers.cpp : implementation of handlers
The Parent Node's BEHAVIOR name is <MY_APP_PARENT>
and the Child Node is <MY_APP_CHILD>
.
Build files can be added by Makefile description /... /install_n_build/makefile.md).
If the DIP SW reading is 0, register the behavior <MY_APP_PARENT>
for the Parent Node, otherwise register the behavior <MY_APP_CHILD>
for the Child Node.
If the Parent Node is MONOSTICK, the DIP SW for PAL reads 0 and behaves as the Parent Node. However, this behavior is not defined in the MONOSTICK specifications.
The Parent Node behaves as a non-sleeping receiver and outputs packet information to the serial port when it receives a packet from a Child Node.
When a packet is received for the Parent Node, if the first four characters of the packet can be matched (FOURCHARS
), the contents of the packet are displayed.
The Parent Node's interrupt handler blinks the LED.
When the button (5) on the PAL is pressed, the E_ORDER_KICK
event is issued to the state machine.
The state machine is described as a reference for state transitions and is not meaningful for the operation of the application. It executes state transitions by the E_ORDER_KICK event sent from the button, timeouts, and so on.
The behavior flow of the Child Node is the same as that of the PAL_AMB-usenap. From the initial sleep, "wake up → start sensor operation → short sleep → wake up → acquire sensor value → wireless transmission → wait for wireless transmission completion → sleep" is repeated.
The _begin()
function, called from on_begin()
, executes the first sleep.
(*It is acceptable to describe this process directly in on_begin()
without describing it in _begin()
function.)
This is a description of the process of waking up from sleep.
The first time Wire.begin()
is executed here, which is redundant for the second and later times when the device wakes from sleep. This process can be moved to on_begin()
.
Processes E_ORDER_KICK
messages to the state machine upon completion of transmission.
Defines the state name.
This is an example of sensor acquisition implementation for SHTC3. For details on sending commands, etc., refer to the SHTC3 datasheet.
This is an example of LTR308ALS sensor acquisition implementation. Please refer to the LTR308ALS datasheet for details on sending commands, etc.
WireWriteAndGet()
sends 1 byte of cmd
to the device of addr
, then receives 1 byte and returns the value.
State 0 has a special meaning. It is the state immediately after startup or after returning from sleep.
Immediately after startup PEV_is_coldboot(ev,evarg)
judgment becomes true
and is called. Since it goes straight to sleep from on_begin()
, it does not contain any code that transitions the state. **At this point, the major initialization has not yet been completed, so complex processing such as sending wireless packets cannot be performed. **In order to perform the first state transition for such processing, send an event from on_begin()
and perform the state transition according to that event.
After returning from sleep, there is a first call to PEV_is_warmboot(ev,evarg)
which will be true
. A call to PEV_SetState()
will transition to the STATE_SENSOR
state.
When the transition is made from STATE_IDLE
after returning from sleep, the state handler for STATE_SENSOR
is called continuously. The event ev
at this time is E_EVENT_NEW_STATE
.
Here, the operation of two sensors, SHTC3 and LTR308ALS, is started. After a certain period of time, the sensors will be ready to acquire data. This time wait is done with the sleep setting of 66
ms. Note that PEV_KeepStateOnWakeup()
is called before sleep. After this call, the state after returning from sleep is not STATE_IDLE
, but the state it was in when it went to sleep, i.e. STATE_SENSOR
.
When returning from a short sleep, a call is first made with the PEV_is_warmboot(ev,evarg)
decision set to true
. At the time of this call, wireless packets can be sent, etc. Transition to STATE_TX
.
Here, at the time of the E_EVENT_NEW_STATE
event, the sensor data reading and wireless packet transmission procedures are started. Please refer to other act sample examples for details of the transmission procedure.
Unlike the ACT description in the loop, the process of waiting for the message by PEV_Process()
from transmit_complete()
is used as a confirmation of completion. Sleep is performed upon receipt of the message. Sleep processing is done by transitioning to STATE_SLEEP
.
Finally, timeout processing is performed. This is in case the completion message of the sent packet has not been returned. PEV_u32Elaspsed_ms()
returns the elapsed time since the transition to that state in milliseconds [ms]. If the time has elapsed, the above will perform a system reset the_twelite.reset_system()
(assuming this timeout is too much).
Perfom sleep. Describe it in E_EVENT_NEW_STATE
immediately after the transition from the previous state. Since other events may be called just before sleep, be sure to execute the_twelite.sleep()
in a decision expression that is executed only once.
Parent Node
Child Node
BEHAVIOR can be defined by defining the class in the specified way, so that the_twelite
class object. The registered BEHAVIOR will be embedded in TWENET, allowing the user code to describe the application's behavior. It is possible to define callback functions for interrupts and events from TWENET, which is not possible in a loop description. Although it requires more definitions than a loop description, it is suitable for describing more complex applications.
See sample BEHAVIOR PAL_AMB-behavior.
BEHAVIOR definition requires a class definition as shown below.
The above example defines a BEHAVIOR class with the name MY_APP_CLASS. MY_APP_CLASS must be described in several places.
Define the class name and the base (parent) class. MWX_APPDEFS_CRTP()
is a macro.
Here, the necessary definitions are imported by #include
.
Constructor definition.
This is the main loop and has the same role as loop()
in the global definition.
on_create()
is called at object creation time (use<>()
method). The val
is a parameter for future extension.
on_begin()is called after
setup()ends.
val` is a parameter for future extension.
Called before sleep. val
is a parameter for future extension.
Called in the initial stage when returning from sleep. The val
is a parameter for future expansion.
At this point, the peripherals have not yet been initialized. The sleep wake-up factor can be checked.
Called when waking up from sleep. The val
is a parameter for future extension.
Sleep can also be called here.
When a packet is received, it is called with the received packet information as rx
.
The transmission information is called as evTx
when packet transmission is completed. The evTx.u8CbId
is the ID at the time of transmission and evTx.bStatus
is the flag indicating success (1
) or failure (0
) of the transmission.
BEHAVIOR handlers (interrupt, event, and state definitions) are defined in a cpp file. The file cannot be split and all handler definitions must be in one file.
Even in the case of BEHAVIORs that do not define handlers, be sure to create the following cpp file.
The required definitions of the MWX library (#include "_mwx_cbs_cpphead.hpp"
) must be included at the beginning and end of the cpp file.
At the beginning of the file, include the .hpp file of the BEHAVIOR definition as shown above. Specify the class name of the behavior in __MWX_APP_CLASS_NAME
. In the above, it is MY_APP_CLASS
.
At the end of the file, include the necessary definitions (#include "_mwx_cbs_cpptail.cpp"
).
The handler definition is written as shown in the following example. Types of definitions are described later. The definition of the handler to be used is described by using the macro for definition. Do not write handlers that are not used.
The MWX_????? _INT()
is the definition of an interrupt handler, and MWX_? _EVENT()
is the definition of an event handler, and MWX_STATE()
is the state definition of a state machine.
Interrupt handlers are executed when a microcontroller interrupt occurs, interrupting the code currently being executed. For this reason, it is desirable to write as short a process as possible, and great care must also be taken with regard to manipulation of variables and the like.
The interrupt handler has a parameter uint8_t& handled
, and setting this value to true
will prevent subsequent event calls from being made.
If the interrupt handler exits with handled
set to false
, the event handler will be called in the application loop (normal code). The event handler has no handled
parameter. Since the event handler is normal code, it can perform relatively large processing. However, the event handler also incurs overhead, so it may not be able to handle the processing that is called at each frequent interrupt. In addition, since events are processed by the system's internal FIFO queue, events may be lost if they cannot be processed within a certain period of time.
The following is an explanation of macros for defining handler functions.
DIO (digital IO) interrupt event. N
specifies the target DIO number. The arg
is a definition for future extension.
To generate an interrupt, use pinMode()
, attachDioInt()
.
TickTimer interrupt and event. The arg
is a definition for future extension.
The handled
flag of the TickTimer must not be set to true
, otherwise TWENET will not work.
Timer interrupt event. TheN
specifies the number of the target timer. The arg
is a definition for future extension.
In order to generate an interrupt, the Timer object is started with software interrupts enabled.
Definition of other interrupts and events that are not defined standardly in the MWX library and require an understanding of the AHI Peripherals Manual.
Other interrupt events can be received by the following handler functions. These will not be available in the future when dedicated handlers are defined.
Peripheral (AHI) interrupt handler u32DeviceId
corresponds to arg
and u32ItemBitmap
corresponds to arg2
.
A state machine (state machine) is a method of describing an application that receives messages and operates by transitioning its state in response to those messages.
The PAL_AMB-behavior sample describes the flow of the application's operation, including the start of sensor operation, acquisition of sensor values, wireless packet transmission to completion of transmission, and sleep transition. Please refer to it as an actual example.
The events to be received are as follows.
The state is set to s
.
Exiting the state handler causes a transition to the next state, followed by a state handler being called with the E_EVENTS_NEW_STATE
event.
Returns the elapsed time ≪ ms] since the state transition. It is used for purposes such as managing timeouts.
In the above example, a system reset is performed after 100 ms.
Called from outside the state handler. Execute the state handler with the event ev
parameter u32evarg
.
The transmission completion event is communicated to the state machine. In other words, call the state handler.
Do not call the state handler directly. It will cause problems such as E_EVENT_NEW_STATE
not being executed.
Set just before sleep. After returning from sleep, the previous state is maintained. That is, the state handler is called with E_EVENT_START_UP
with sleep started.
Determine if the event is E_EVENT_START_UP
on wake-up.
Judges whether the event is E_EVENT_START_UP
when returning from sleep.
Event Name | Description |
---|---|
E_EVENT_START_UP
It is called at system startup. Immediately after power-on, it is called with 0
parameters. Because it is in the initial stage of execution, PEV_Process()
is called once from the begin() method to start the operation when transitioning to the normal processing state.
It is still called after returning from sleep, but with parameters other than 0
. Normal processing can be performed from this state.
E_EVENT_NEW_STATE
It is called in a new state immediately after a state transition. Describes the process that is first executed when a transition is made to a certain state.
E_EVENT_TICK_TIMER
Called by TickTimer every 1ms
E_EVENT_TICK_SECOND
It is called every second.