SCL3300
Overview
The Murata SCL3300-D01 is a 3-axis MEMS inclinometer. It measures the acceleration on three axes and computes the inclination of each axis relative to the horizontal plane. It has a 4-wire SPI interface only and no interrupt or data-ready pin, so the driver polls it.
This driver uses the uorb interface. All section and table numbers below refer to the Murata SCL3300-D01 Data Sheet, Doc.No. 4921, Rev. 4.
uORB topics and units
Registering the driver creates these topics, where n is devno:
/dev/uorb/sensor_inclinometer<n>(struct sensor_inclinometer)The tilt of the X, Y and Z axes relative to the horizontal plane, in degrees. Each value is signed, in the range [-90, +90]. 0 means the axis is horizontal. +90 means the axis points straight up, away from gravity (an accelerometer on that axis reads +1 g). -90 means it points straight down. The
temperaturefield is in degrees Celsius./dev/uorb/sensor_accel<n>(struct sensor_accel)Only when
CONFIG_SENSORS_SCL3300_ACCELis enabled. The acceleration in m/s², converted with the datasheet value of g, 9.819 m/s² (Table 2).temperatureis in degrees Celsius.
When the sensor flags its temperature as out of range, the event still goes
out, but temperature is set to NAN, or to INT32_MIN in
CONFIG_SENSORS_USE_B16 builds.
Both topics read in the same SPI burst carry the same timestamp.
SENSOR_TYPE_INCLINOMETER and SENSOR_TYPE_ANGLE are different.
SENSOR_TYPE_ANGLE (topic sensor_hinge_angle) is one scalar: the
angle between two mechanical parts of a device, such as a hinge or fold,
with no reference to gravity. SENSOR_TYPE_INCLINOMETER is three
per-axis tilt angles relative to the horizontal plane, referenced to
gravity, plus temperature. Tilt angles are only meaningful while the device
is not accelerating.
Operation modes
Mode |
Range |
Sensitivity |
LPF |
Noise (RMS) |
Settling |
|---|---|---|---|---|---|
1 (default) |
±1.2 g, ±90° tilt |
6000 LSB/g |
40 Hz |
0.32 mg |
25 ms |
2 |
±2.4 g, ±90° tilt |
3000 LSB/g |
70 Hz |
0.49 mg |
15 ms |
3 |
Inclination, about ±10° |
12000 LSB/g |
10 Hz |
0.13 mg |
100 ms |
4 |
Inclination, about ±10° |
12000 LSB/g |
10 Hz |
0.08 mg (X, Z), 0.06 mg (Y) |
100 ms |
The angle outputs have the same scale in every mode: 2^14 / 90, about 182 LSB per degree. The output data rate is fixed at 2000 Hz (§4.1).
Mode 1 is the general-purpose mode.
Mode 2 has the widest range and bandwidth. Use it when the device sees vibration or dynamic motion.
Mode 4 is for very small tilts near level. Keep the tilt within ±10° and do not mount the device with the Y axis parallel to gravity (§2.11.1). The bandwidth is 10 Hz. For the best accuracy, average several samples and zero the readings after mounting.
Mode 3 behaves like Mode 4, with higher noise.
In Modes 3 and 4 the accelerometer topic is still published, but its values are only meaningful within the ±10° inclination range of these modes.
Configuration
CONFIG_SENSORS_SCL3300(defaultn)Enable the driver. Selects
CONFIG_SPI.CONFIG_SENSORS_SCL3300_ACCEL(defaulty)Also publish
sensor_accel<n>.CONFIG_SENSORS_SCL3300_SPI_FREQUENCY(default2000000)SPI clock in Hz, from 100 kHz to 8 MHz (Table 8). The datasheet recommends 2 to 4 MHz.
CONFIG_SENSORS_SCL3300_POLL(defaulty)Poll the sensor from a kernel thread. If disabled, data is read only on
fetch().CONFIG_SENSORS_SCL3300_POLL_INTERVAL(default10000)Default interval in µs. Applications can change it, down to 500 µs.
CONFIG_SENSORS_SCL3300_THREAD_STACKSIZE(default1024)Stack size of the poll thread.
The operation mode and the idle power policy are not Kconfig options. They are set by the board (platform data) and can be changed at run time.
Board integration
#include <nuttx/sensors/scl3300.h>
enum scl3300_mode_e
{
SCL3300_MODE_1 = 1, /* +/-1.2 g, 40 Hz LPF (default) */
SCL3300_MODE_2 = 2, /* +/-2.4 g, 70 Hz LPF */
SCL3300_MODE_3 = 3, /* Inclination mode, 10 Hz LPF */
SCL3300_MODE_4 = 4 /* Inclination mode, 10 Hz LPF, low noise */
};
enum scl3300_power_e
{
SCL3300_POWER_ALWAYS_ON = 0, /* Stay powered when idle (default) */
SCL3300_POWER_DOWN_IDLE = 1 /* Power down when no topic is active */
};
struct scl3300_config_s
{
uint8_t mode; /* enum scl3300_mode_e, 0 = default */
uint8_t power; /* enum scl3300_power_e */
};
int scl3300_register(int devno, FAR struct spi_dev_s *spi,
FAR const struct scl3300_config_s *config);
The driver copies *config, so the structure does not need to outlive
the call. Pass NULL for Mode 1 and SCL3300_POWER_ALWAYS_ON. An
invalid mode or power value returns -EINVAL and registers nothing.
At registration the driver runs the start-up sequence of Table 11 and
checks WHOAMI. If CONFIG_DEBUG_SENSORS_INFO is enabled, it also logs
the serial number.
The chip select is SPIDEV_ACCELEROMETER(devno), so the board’s
<chip>_spiNselect() function must handle that device ID.
/* Defaults: Mode 1, always on */
ret = scl3300_register(0, spi, NULL);
/* Low-noise inclination mode, powered down while no one listens */
static const struct scl3300_config_s config =
{
.mode = SCL3300_MODE_4,
.power = SCL3300_POWER_DOWN_IDLE,
};
ret = scl3300_register(0, spi, &config);
STM32 boards can use the common helper board_scl3300_initialize(devno,
busno) from boards/arm/common/stm32, which registers the driver with
NULL.
Run-time control
These ioctls go through any of the two topics and apply to the whole device:
Command |
Argument |
Behaviour |
|---|---|---|
|
|
Store the mode and,
if the device is
powered, rerun the
start-up in it.
|
|
|
Change the idle power policy. It takes effect at once |
|
none |
SW reset and start-up with the stored mode. Also clears a failed state |
|
|
Returns WHOAMI (0xC1) |
#include <fcntl.h>
#include <sys/ioctl.h>
#include <nuttx/sensors/ioctl.h>
#include <nuttx/sensors/scl3300.h>
int fd = open("/dev/uorb/sensor_inclinometer0", O_RDONLY);
if (fd >= 0)
{
if (ioctl(fd, SNIOC_SET_OPERATIONAL_MODE, SCL3300_MODE_4) < 0)
{
printf("Mode change failed: %d\n", errno);
}
close(fd);
}
SNIOC_GET_INFO returns the range and resolution of the current mode.
For the inclinometer that is 90° and 0.0054932°. For the accelerometer it
is the mode’s full scale and g / sensitivity.
Self-test and error handling
SNIOC_SELFTEST checks three things:
WHOAMI reads 0xC1.
STATUS reports no fault.
16 consecutive self-test (STO) readings are within the threshold of the current mode (Table 23: ±1800, ±900, ±3600 and ±3600 LSB).
If the device is powered down, the self-test wakes it and powers it down
again afterwards. The result is 0 or -EIO. Run it with the device at
rest.
Every response frame is checked for CRC, for the echoed operation code and for its return status:
A bad CRC or a wrong echo drops the sample. After three failed bursts in a row, the driver resets the device.
When the sensor reports an error (RS = 11), the driver reads STATUS:
Saturation (SAT) drops the sample. A rate-limited warning reports the number of dropped samples.
A temperature flag publishes the sample with an unused temperature.
Internal faults (DIGI1, DIGI2, CLK, MEM, an unexpected PWR, PD or MODE_CHANGE, pin continuity) trigger a SW reset and a full start-up.
If the fault comes back before a good sample was read, the device is marked failed. It stops publishing,
fetchand the self-test return-EIO, and an error is logged once.SNIOC_RESETcan bring it back.
Usage
The stm32f4discovery:scl3300 configuration is a ready-to-use example.
nsh> uorb_listener -n 3 sensor_inclinometer
Monitor objects num:1
object_name:sensor_inclinometer, object_instance:0
sensor_inclinometer(now:18850000):timestamp:18850000,x:3.856201,y:35.403442,z:54.316406,temperature:25.994720
sensor_inclinometer(now:18870000):timestamp:18870000,x:3.823242,y:35.419922,z:54.305420,temperature:25.994720
sensor_inclinometer(now:18890000):timestamp:18890000,x:3.839722,y:35.403442,z:54.316406,temperature:25.994720
Object name:sensor_inclinometer0, received:3
Total number of received Message:3/3
nsh> sensortest -n 3 -i 100000 inclinometer0
SensorTest: Test /dev/uorb/sensor_inclinometer0 with interval(100000us), latency(0us)
inclinometer0: timestamp:14050000 x:3.78 y:35.29 z:54.44, temperature:25.41
inclinometer0: timestamp:14150000 x:3.76 y:35.29 z:54.44, temperature:25.41
inclinometer0: timestamp:14250000 x:3.77 y:35.36 z:54.37, temperature:25.41
SensorTest: Received message: inclinometer0, number:3/3
nsh> sensortest -n 3 accel0
SensorTest: Test /dev/uorb/sensor_accel0 with interval(1000000us), latency(0us)
accel0: timestamp:29370000 x:0.65 y:5.61 z:7.86, temperature:25.89
accel0: timestamp:30380000 x:0.64 y:5.61 z:7.87, temperature:25.89
accel0: timestamp:31390000 x:0.65 y:5.61 z:7.87, temperature:25.89
SensorTest: Received message: accel0, number:3/3
This output comes from an STM32F4Discovery with the sensor tilted about 35 degrees around its X axis. The tilt angles match the acceleration vector: for example, asin(5.61 / 9.68) = 35.4 degrees for Y.
Limitations
No internal oversampling. The sensor runs at 2000 Hz, and the datasheet noise figures assume that every sample is read (§4.1). The driver reads only one sample per interval.
No stored offset calibration (
calibrateandset_calibvalueare not implemented).The absolute offset can be up to ±1.15° (Table 2). For precise work, zero the readings after mounting.
There is no interrupt pin, so the driver always polls.