Accelerometer

ModuCop features an integrated accelerometer, which is a LIS2DW12 3-axis accelerometer. It is implemented on the CPU01 microcontroller (CPU01UC).

Features

The CPU01UC has a LIS2D motion sensor function block to capture accelerometer data and provide it as a stream of samples to the host application.

The device is always operated in high performance mode (focus on low noise), supporting 14 bit resolution of the sampled data.

Note that the LIS2D sensor is a 3-axis accelerometer, so the data stream contains samples for all three axes (X, Y, Z). It has no gyroscope functionality, so it does not provide angular velocity data.

Configurable parameters are:

  • Sample rate: 12.5 Hz to 1600 Hz
  • Full scale range: 2g to 16g
  • Filter band width
  • Select high pass or low pass path

Not supported:

  • Temperature sensor
  • Orientation functions
  • Free-fall detection
  • Tap detection

Functional Description

After configuration and starting the stream, the device will continuously sample the accelerometer data and send it to the host application. The data is sent as a stream of samples, where each sample contains the timestamp, X, Y, and Z values of the accelerometer.

Note that X, Y, Z values are provided in the same coordinate system as the LIS2D accelerometer is mounted. The application may need to account for the device’s orientation when interpreting the data.

X, Y, Z values are provided as float values in g (acceleration due to gravity). The values are scaled according to the configured full scale range. For example, if the full scale range is set to 2g, the values will be in the range of -2g to +2g.

Using the io4edge API to access the MVB Sniffer

There is currently no python client for the MotionSensor function block. The following code is for the Go client only.

First, install the io4edge client library.

Want to have a quick look to the examples? See our Github repository.

First, install the io4edge client library.

Want to have a quick look to the examples? See our Github repository.

Connect to the Motion Sensor Function

To access the Motion Sensor Function, create a Client and save it to the variable c. Pass as address either a service address or an ip address with port. Example:

  • As a service address: S101-CPU01UC-accel
  • As an IP/Port: e.g. 192.168.200.1:10001

We need this client variable for all further access methods.

import (
	"fmt"
	"os"
	"time"
	"log"
	"github.com/ci4rail/io4edge-client-go/functionblock"
	"github.com/ci4rail/io4edge-client-go/motionsensor"
)

func main() {
	const timeout = 0 // use default timeout

	c, err := canl2.NewClientFromUniversalAddress("S101-CPU01UC-accel", timeout)
	if err != nil {
		log.Fatalf("Failed to create client: %v\n", err)
	}

Configure the Motion Sensor Function

Configuration parameters are:

  • Sample Rate: 12.5 Hz, 25 Hz, 50 Hz, 100 Hz, 200 Hz, 400 Hz, 800 Hz, 1600 Hz
  • Full Scale: 2g, 4g, 8g, 16g
  • High Pass Filter: On/Off
  • Bandwidth Ratio: 2, 4, 10, 20

Meaning of high pass filter and bandwidth ratio:

  • If High Pass Filter is enabled, the sensor will filter out low frequencies and only pass high frequency signals. The cut off frequency is sample rate / bandwidth ratio.
  • If High Pass Filter is disabled, the sensor will filter out high frequencies. The cut off frequency is sample rate / bandwidth ratio.
	// set configuration
	if err := c.UploadConfiguration(
		motionsensor.WithSampleRate(12.5*1000.0),  // in milli Hertz
		motionsensor.WithFullScale(2.0),
		motionsensor.WithHighPassFilterEnable(true),
		motionsensor.WithBandWidthRatio(2)); err != nil {
		log.Fatalf("Failed to set configuration: %v\n", err)
	}

Start a Stream

To receive telegrams from the Motion Sensor, the API provides functions to start a Stream.

The stream behavior can be fine-tuned to the application needs. If you do not specify any parameters, the default values are used.

  • The BucketSamples parameter (default: 25) defines the number of samples per bucket. If the bucket contains BucketSamples, it is sent to the client.

  • The KeepAliveInterval parameter (default: 1000) defines the maximum time in ms between two buckets. If the bucket is not full, it is sent after the configured interval.

  • The BufferedSamples parameter (default: 50) defines the number of samples that can be buffered in the device. If the buffer is full, the oldest samples are overwritten. As a rule of thumb, BufferedSamples should be at least two times the BucketSamples. Select a higher number if your reception process is slow to avoid buffer overruns.

	// start stream
	err = c.StartStream(
		functionblock.WithBucketSamples(10),
		functionblock.WithBufferedSamples(200),
		functionblock.WithLowLatencyMode(*lowLatency),
	)
	if err != nil {
		log.Fatalf("StartStream failed: %v\n", err)
	}

Receive Telegrams

In the stream the firmware generates Buckets, where each Bucket contains a number of Samples.

To read samples from the stream:

	...
	prevTs := uint64(0)
	for {
		// read next bucket from stream
		sd, err := c.ReadStream(time.Second * 1)

		if err != nil {
			fmt.Printf("ReadStreamData failed: %v\n", err)
		} else {
			samples := sd.FSData.GetSamples()
			fmt.Printf("got stream data seq=%d with %d samples\n", sd.Sequence, len(samples))

			for _, sample := range samples {
			nSamples++
			record := []string{
				fmt.Sprintf("%d", sample.Timestamp),
				fmt.Sprintf("%.6f", sample.X),
				fmt.Sprintf("%.6f", sample.Y),
				fmt.Sprintf("%.6f", sample.Z),
			}

			fmt.Printf("t: %15d dt: %7d x: %.6f, y: %.6f, z: %.6f\n",
				sample.Timestamp, sample.Timestamp-prevTs, sample.X, sample.Y, sample.Z)

			prevTs = sample.Timestamp
			}
		}
	}

NOTE: At the moment, timestamps are expressed in micro seconds relative to the start of the CPU01UC. Future client libraries will map the time to the host’s time domain

Orientation of the Accelerometer in ModuCop

The orientation of the accelerometer in the ModuCop Edge Computer is fixed and cannot be changed. The X, Y, and Z axes are defined as follows:

Accelerometer Orientation