STWIN Datalogger Sensing the world

A bit of context

Stacks Image 8
The STWIN board has a range of embedded industrial-grade sensors and an ultra-low-power microcontroller. The STSW-STWINKT01 firmware package provides a set of applications to demonstrate the hardware capabilities.

This ODeV project is inspired by the Serial_Datalog.

Firmware package architecture

The Idea

The goal is to use the multi sensors data logging feature from the STWIN firmware and to integrate it with the ODeV framework in order to add:
  • Modularity
  • Low power support
  • A well-defined sensor application framework to use the sensors on the board in two scenarios:
    • User not expert with the hardware implementation of a MEMS. In this case the sensor framework provides a high level API to select the sensors to use, and to modify the common parameters like ODR, full scale etc.
    • Power user who want to take advantage of the low level driver, provided by ST, but still integrate their code with the sensor framework. In this case the developer documentation provides all the information to extend a sensor class and to overwrite some of the key virtual methods.

Main Components

  • STWIN. I am not an hardware engineer, so I have to select what is available, and this is a good board to prototype the idea presented in this page. The board has a range of embedded industrial-grade sensors and an ultra-low-power microcontroller.
  • ODeV framework. Of course it is the base for the firmware.
  • FatFS, a generic FAT/exFAT filesystem module for small embedded systems.
  • Parson, a lightweight json library written in C.
  • STMems Standard C drivers, a platform independent drivers (PID) for STMicroelectronics sensors.
  • STM32CubeIDE. The preferred IDE.

Fig.01 displays an high level block diagram of the prototype.
Stacks Image 44

Fig.1 - Block diagram

The box with yellow background (e.g. SPIBusTask) have been developed for this demo. Following the design pattern of the framework the code is encapsulated in well defined classes to be easy to reuse across different project based on ODeV_f. The box with red foreground (e.g. FATFS) are open sure projects. The box with light cyan background (e.g. MX generated drv) include the PID sensor driver provided by ST and part of the code generated by STM32CubeMX.

In this page I will discuss the application specific code. Note that this is based on ODeV and its design pattern.

Firmware architecture

sensors
Sensors and bus
STWIN embeds nine MEMS sensors. They are connected to STM32 via SPI or I2C bus. ST provides for each sensor a PID driver that I want to reuse. So, the sensor framework models this hardware layout through a set of interfaces and abstract classes as displayed in Fig.2. This architecture allows a managed task, like the SPIBusTask, to export an easy-to-use API to connect and disconnect sensor objects at application level.
Stacks Image 79

Fig.2 - Bus IF class diagram

For example, let’s give a look at the code to connect an ISM330DHCX sensor object to an SPI bus object.
sys_error_code_t SysLoadApplicationContext(ApplicationContext *pAppContext) {
assert_param(pAppContext);
sys_error_code_t xRes = SYS_NO_ERROR_CODE;

// Allocate the task objects
s_pxSPIBusObj = SPIBusTaskAlloc();
s_pxISM330DHCXObj = ISM330DHCXTaskAlloc();

// Add the task object to the context.
xRes = ACAddTask(pAppContext, (
AManagedTask*)s_pxISM330DHCXObj);
xRes = ACAddTask(pAppContext, (
AManagedTask*)s_pxSPIBusObj);

return xRes;
}

sys_error_code_t SysOnStartApplication(ApplicationContext *pAppContext) {
UNUSED(pAppContext);

//connect the sensor task to the bus.
SPIBusTaskConnectDevice((
SPIBusTask*)s_pxSPIBusObj, ISM330DHCXTaskGetSPISensorIF((ISM330DHCXTask*)s_pxISM330DHCXObj));

return SYS_NO_ERROR_CODE;
}
By implementing the IBus interface the SPIBusTask exports the IBusConnectDevice() method that is wrapped, for convenience, in the SPIBusTaskConnectDevice() method. A sensor object that wants to use the SPI bus to control the physical sensor, must implement the SPIBusIF. The initialization of the interface is done in the virtual method ISM330DHCXTask_vtblOnCreateTask() according the ODeV design pattern.
xRes = SPIBusIFInit(&pObj->m_xSensorIF, 0, ISM330DHCX_SPI_CS_GPIO_Port, ISM330DHCX_SPI_CS_Pin);
if (SYS_IS_ERROR_CODE(xRes)) {
return xRes;
}
// set the SPIBusIF object as handle the IF connector because the SPIBus task
// will use the handle to access the SPIBusIF.
ABusIFSetHandle(&pObj->
m_xSensorIF.super, &pObj->m_xSensorIF);
When the sensor is connected to the bus, the Connector object of its interface is initialized with the functions to read and write from the bus that are provided by the bus object. Note that the Connector is the same type of the stmdev_ctx_t used in the ST PID sensor driver. This allows us to reuse that driver (in the ODeV framework the PID is not a driver, but a service, while the driver is the I2C master driver) to control the sensor.

Many sensors can be connected to the same bus. This brings a possible concurrency issue in a multitask application. For this reason, a bus task (e.g. the SPIBusTask) is a gate keeper, that means it is the only one to access the peripheral through the SPIMasterDriver, as displayed in Fig.3.
Stacks Image 101

Fig.3 - SPI Bus subsystem

All the read and write request are incapsulated into a message and posted into a task input queue.
settings_input_component
Processing the sensor data (Event – Listener)
How can the application receive and process the data coming from the sensors? The sensor framework provides a set of class extending the Event Listener IF and the Event IF.
The Event block of Fig.1 shows the classes provided by the framework to implement the Event / Listener design pattern. A sensor class implement the SensorEvtSrc interface. An application defined object must (1) implement the ISensorEventListener interface and (2) it must add itself as a listener of the sensor object, in order to receive SensorEvt.

For example, in the demo application, the SDCardTask uses this approach to receive the data from all enabled sensors and log them into the SDCARD. This is the code to add the SDCardTask to the sensor task:
sys_error_code_t SysOnStartApplication(ApplicationContext *pAppContext) {
UNUSED(pAppContext);

//add the SD task to the sensors as event listener
IEventListener *pxListener = SDCardTaskGetEventListenrIF((SDCardTask*)s_pxSDCardObj);
IEventSrcAddEventListener(ISM330DHCXTaskGetEventSrcIF((
ISM330DHCXTask*)s_pxISM330DHCXObj), pxListener);
IEventSrcAddEventListener(IIS3DWBTaskGetEventSrcIF((
IIS3DWBTask*)s_pxIIS3DWBObj), pxListener);

return SYS_NO_ERROR_CODE;
}
First we get the IEventListener interface of the SDCartTask with the ISDCardTaskGetEventListenerIF() method. Then we add this listener interface to the event source of the sensor object.

The same thing can be done with all sensors, and one objects can receive data from multiple sensors.
edit
Modify the sensor parameters
A sensors DB provides an easy way to access and modify the most common sensor parameters. The polymorphic nature of a sensor class gives to a power user a more detailed control over the sensor. These two sets of API cover different scenarios and make the sensor framework reusable in different kind of embedded applications.
A Power user can take advantage of the polymorphism and overwrite the virtual functions of a sensor class. In this way it possible to use directly the PID service that provides full access to the physical sensor capabilities.

The above approach is powerful but it can be also complex and it requires a deep knowledge of the hardware component as well as the sensor framework implementation. Another way to configure the most common parameters of a sensor is to use the sensor DB (sensor_db.h). It contains, at runtime, a hierarchical model of all sensors of the application. In fact, during the startup each sensor registers itself with the sensor DB. There is only one instance of the sensor DB in the application that can be obtained using the SDB_GetIstance() method. The DB is organized in JSON format to be easy to store in a file and used at runtime. Fig.4 shows the structure of the sensor DB.
Stacks Image 148

Fig.4 - Sensor DB

battery_alert
Low Power Mode
The sensor framework has been designed to support low power embedded application. The demo application provides an AppPowerModeHelper class to support the low power feature of the ODeV framework.
The AppPowerModeHelper define a Low Power Mode state machine as displayed in Fig.5.
Stacks Image 166

Fig.5 - Low Power Mode state machine

When the application is in RUN it waits for a Push Button event to start the data logging. If there is no event for a given amount of time (10” by default) a software timer expires and triggers the transaction in SLEEP_1.

The current implementation supports only two sensors (ISM330DHCX and IIS3DWB) and the SDCARD. All other components of the board are not supported. In this scenarios this is the current consumption in each state of the power mode state machine:
  • RUN: 27.8 mA
  • DATALOG: 27.9 .. 29.7 mA
  • SLEEP_1: 16.7 mA

Note: the RED LED has been disconnected for the measurement.

For more information about the Power mode State Machine look at the main documentation of the ODeV framework.

The demo application

A demo application to test the sensor framework is available in the GITHUB repository.

To test the low power mode:
  • the demo application must be compiled in RELEASE configuration.
  • after programming the STWIN perform an hard reset.

After the reset the application is in RUN mode and the GREEN user LED is on. To start the data logging:
  • insert an SDCARD on the SDCARD slot.
  • press the user push button.

The application goes in DATALOG mode and the GREEN LED start blinking. To stop the data logging press the user push button. The application goes back to RUN mode and the GREEN LED stop blinking.

When the application is in RUN, if there is no event for 10" then the low power mode timer triggers a power mode transaction and the application goes in SLEPP_1. The GREEN LED is turned off to signal the new power mode. The exit the SLEEP_1 mode press the user button and the application goes in RUN mode.

Even if this application is simple, it show the main feature of the sensor framework.

The source code

The source code is available in the ODeV_f GITHUB repository in the datalog_stwin branch.

Project status

The project is still in development. The main features have been implemented, but not all sensor of the STWIN are supported yet.

Supported sensors:
  • ISM330DHCX
  • IIS3DWB

The project introduce also a new version of the ODeV framework with new features. I will discuss it in a separate page.

The folder structure of the project is not final and it will change during the development.

The HTML API documentation is not updated.

We use cookies to personalize content and to provide a comment feature. To analyze our traffic, we use basic Google Analytics implementation with anonymized dat. If you continue without changing your settings, we'll assume that you are happy to receive all cookies on the stf12.org website. To understand more about the cookies please see this web page.