Giter Site home page Giter Site logo

davidarmstrong / scl3300 Goto Github PK

View Code? Open in Web Editor NEW
19.0 5.0 9.0 49 KB

Arduino library for interfacing with the Murata SCL3300 Inclinometer via SPI

License: MIT License

C++ 100.00%
arduino-library murata-inclinometer spi sparkfun-redboard-turbo arduino-uno arduino

scl3300's Introduction

SCL3300

Arduino Library for Murata SCL3300 Inclinometer

Version 3.3.1 - July 4, 2022
Note: This is not a bug fix, nor a new feature release. The only change is adding the new Example10_Mode1 sketch, which is useful for more general tilt angle measurement needs.

By David Armstrong
https://github.com/DavidArmstrong/Arduino-SCL3300
See MIT LICENSE.md file

The Murata SCL3300 inclinometer sensor is a 3.3 volt device used to measure tilt in three axes simultaneously.

Datasheet: https://www.murata.com/-/media/webrenewal/products/sensor/pdf/datasheet/datasheet_scl3300-d01.ashx?la=en-us

Evaluation Board: https://www.murata.com/-/media/webrenewal/products/sensor/pdf/specification/pcbspec_scx3300.ashx?la=en-us

Notes:

  1. The SCL3300 inclinometer will require a bidrectional level shifter to interface the SPI pins to 5 volt devices, such as the Arduino Uno.
  2. A pull-up resistor may be required on the Chip/Slave Select line of the SCL3300. A typical resistor value of 4.7k ohms should connect this pin to +3.3 volts.
  3. Be sure to connect the SCL3300 DVIO pin to +3.3 volts as well. This pin powers the digital pins.
  4. There is a small, but significant, library change starting with Version 3.0.0. This requires a one-line addition to any older sketches when using this updated SCL3300 library. All the example sketches have been updated to include the addtional code. (The backwards incompatibility is due to the improved error detection and handling design.)

For an Arduino Uno, the default SPI pins are as follows:

  • SCK - Digital Pin 13
  • SDO - Digital Pin 12 (MISO)
  • SDI - Digital Pin 11 (MOSI)
  • CS - Digital Pin 10 (SS)

For a SAMD-type Arduino, such as the Sparkfun Redboard Turbo or Arduino Zero, the default SPI pins are only available on the ICSP connector:

  • pin 22 (MISO)
  • pin 23 (MOSI)
  • pin 24 (SCK)
  • Chip/Slave Select uses digital Pin 10 as the default.

======================================

Basic SCL3300 Library Functions:

begin()
This initializes the library and the SPI chip, and by default assigns the SPI Chip Select Pin to Digital Pin 10.

begin(csPinNum)
This variation allows you to choose a different pin as the SPI Chip Select Pin. Replace 'csPinNum' with your pin number.

begin(altSpiPort, csPinNum)
This allows using an alternate SPI port definition for communication to the SCL3300. Please see Example9_AlternateSPI.ino

isConnected()
Returns 'true' if the sensor is still responding as expected, and able to provide valid data. It does not collect a data set from the sensor.

available()
Reads the raw SCL3300 sensor data as a group so that all the data is consistent. Call this first before using the functions below. Starting with Version 3.0.0, this call should be the conditional in an 'if' statement, and an 'else' clause included to call reset() when available() returns false. (See the example sketches in the library.)

getTiltLevelOffsetAngleX()
Returns a double float of the tilt offset from level value in degrees for the X direction.

getTiltLevelOffsetAngleY()
Returns a double float of the tilt offset from level value in degrees for the Y direction.

getTiltLevelOffsetAngleZ()
Returns a double float of the tilt offset from level value in degrees for the Z direction.

getCalculatedAngleX()
Returns a double float of the tilt value in degrees (0-360) for the X direction.

getCalculatedAngleY()
Returns a double float of the tilt value in degrees (0-360) for the Y direction.

getCalculatedAngleZ()
Returns a double float of the tilt value in degrees (0-360) for the Z direction.

getCalculatedAccelerometerX()
Returns a double float of the accelerometer value in units of 'g' for the X direction.

getCalculatedAccelerometerY()
Returns a double float of the accelerometer value in units of 'g' for the Y direction.

getCalculatedAccelerometerZ()
Returns a double float of the accelerometer value in units of 'g' for the Z direction.

getTemperatureCelsius()
Returns a double float of the temperature in Celsius.

getTemperatureFarenheit()
Returns a double float of the temperature in Farenheit.

Utility Functions available:

reset()
Does a software reset of the SCL3300 sensor.

getSerialNumber()
Returns a long integer of the device Serial Number set by the manufacturer.

powerDownMode()
Puts the sensor in a power down mode to reduce power usage.

WakeMeUp()
Revives sensor from being powered down, so that it can start to generate sensor data.

setMode(modeNum)
Sets the sensor mode to the number provided as modeNum. The default mode is '4'. Valid values are 1, 2, 3, and 4.

setFastReadMode()
Using Fast Read Mode in the library works by keeping the SPI connection continuously open. This may or may not affect the behavior of other hardware interactions, depending on the sketch design. Fast Read Mode is considered an advanced use case, and not recommended for the beginner.

stopFastReadMode()
This stops the Fast Read Mode in the library by closing the SPI connection that was open, and doing a reset of the SCL3300. This may or may not affect the behavior of other hardware interactions, depending on the sketch design. Fast Read Mode is considered an advanced use case, and not recommended for the beginner.

scl3300's People

Contributors

davidarmstrong avatar djfurie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

scl3300's Issues

Slow response from sensor, excessive reset calls and error flagging

I am using your library to communicate with an ESP32.

I change the spi pin configuration as follows:
SPI.begin(23,18,19,5)

code works fine when using the Murata breakout board, but when using my own boards with exactly the same layout and pin configuration, and genuine Murata chips, I am getting very poor performance.

i am Printing the error flags inside the else statement before the reset takes place, here is what I am getting:

For error flag one I get a few different flags
512
768
896
2816
3968

Ad for error flag 2
528

Does this indicate a software problem, hardware problem, or a chip malfunction/manufacturer problem?

Thanks 🙏

Need functions for Calculated Tilt Offset from Level values

The current functions getCalculatedAngleX/Y/Z return a value in the range of 0-360 degrees. While this is useful, generally one is more interested in getting a signed value of the offset from level. This is because this device is designed to determine very accurately how level the system is in relation to its environment.
New functions to be implemented:
getTiltLevelOffsetAngleX() -- Returns a double float of the tilt offset from level value in degrees for the X direction.
getTiltLevelOffsetAngleY() -- Returns a double float of the tilt offset from level value in degrees for the Y direction.
getTiltLevelOffsetAngleZ() -- Returns a double float of the tilt offset from level value in degrees for the Z direction.
A new example ino file - Example1_BasicTiltLevelOffset, will be implemented as a result. All the current examples will be moved up by one in number to make room for the new Example ino file.

Workaround needed for PortentaH7 design flaws

Apparently the Arduino port for the "PortentaH7", a platform I've never even heard of, uses some non-standard design decisions when defining global macros. The side effect of this is that is mucks with any other code that just happens to have variables defined with the exact same string pattern.

For example, the library uses a variable called CRC, which is straight from the Murata datasheet for doing CRC calculations. This PortentaH7 port has a macro that ends up replacing every occurrence of that string with its own coding. So now every internal variable may need to be changed to avoid this type of issue coming up in the future.

Connection issues - crcerr

I've tried with a couple different boards, a couple esp32 boards (huzzah32), uno (with logic level converter). I seem to receive the crc error with all transmissions as a result I am unable to connect to the SCL3300 properly.

Do you have any tips to obtain a connection?

Below is an attempt to connect (including debug data):
15:00:06.986 -> Reading Raw register values from SCL3300 Inclinometer
15:00:06.986 -> B4000338 B4 0 3 38 3 0 82 C 1 82 C 61 1
15:00:07.035 -> 180000E5 18 0 0 E5 2 8 20 83 1 820 83 2F 1
15:00:07.035 -> 180000E5 18 0 0 E5 2 8 20 83 1 820 83 2F 1
15:00:07.035 -> 180000E5 18 0 0 E5 2 8 20 83 1 820 83 2F 1
15:00:07.035 -> B0001F6F B0 0 1F 6F 2 8 20 C0 1 820 C0 2F 1
15:00:07.035 -> Murata SCL3300 inclinometer not connected.

A great library once I have the SPI transmitting and receiving properly I think.

Operator error

Hello, this function

//Return value of Error Flag 1 register
uint16_t SCL3300::getErrFlag1(void) {
beginTransmission(); //Set up this SPI port/bus
transfer(SwtchBnk0);
transfer(RdErrFlg1);
transfer(RdErrFlg1);
endTransmission(); //Let go of SPI port/bus
if (crcerr || statuserr) return (uint16_t)(CMD && 0xff); //check CRC and RS bits
return DATA;
}

the operator && maybe is &?

reset() function

Hello!

There is SCL3300::reset(void) function that has this line:

begin(); //Re-init chip

If chipselect pin is not the default then it's going to be failed as I experience.

Compatability

Hello, using v3.0.2 I am seeing some odd behavior. The sensor will report ax, ay, and az readings at 10 hertz (seemingly mode 4) however I am unable to change the mode and the sensor will not return TRUE to the inclinometer.begin() command. Further, the ax, ay, and az readings are all roughly 1/2 of gravity when pointed downward.

The SCA3300 is connected to a Adafruit Feather with a pullup to CSB.

Can anyone opine on a likely source of such behavior?
Thank you

SPI VSPI setting CS Issue

I'm probably barking up the wrong tree here but I've had an SCL3300 working very well off an ESP32 Wroom. I've moved over to the next iteration of my project and I had to move the MISO/MOSI/SCK/CS pins and now it refuses to respond.
Its MISO is on the VSPI GPIO 19, CLK GPIO 18, CS GPIO 32. I have changed the SCL3300.h to change the CS pin to 32, but I'm guessing its the default SPI settings?
Can you help? I think I'm just missing one vital detail.....

Cheers,

Andy

Using the SCL3300 with ESP32

I've been looking into using the SCL3300 with an ESP32. The ESP32 provides 3.3V directly, so that shouldn't be a problem. However, I am attempting to figure out what a PCB should look like exactly.

Unfortunately the pre-soldered PCB's are not available on this side of the world for reasonable prices, so I have to fab one. That's not an issue per-se; I found the schematics in chapter 7 "Application information" of the data sheet (basically 4 caps and some gound/route information)

From the homepage it sais: "A pull-up resistor may be required on the Chip/Slave Select line of the SCL3300. A typical resistor value of 4.7k ohms should connect this pin to +3.3 volts." and "Be sure to connect the SCL3300 DVIO pin to +3.3 volts as well. This pin powers the digital pins."

So... from that I gather:
VDD -> 3.3v ESP32
GND -> GND ESP32
DVIO -> 3.3v ESP32
SCK, MOSI, MISO -> SCK, MOSI, MISO of ESP32
CSB -> 4.7k ohm -> CS GPIO or 3.3v. -- shouldn't this just be a pullup resistor?

That seems correct to you?

However, the manual also sais for the SPI inputs: "3.3V logic compatible Schmitt-trigger input". ESP32 does not have that by default; and while all SPI should have that, it does leaves me wondering if I should add an 74AHCT14 (two times per line) for the SPI lines?

Any input would be appreciated!

SCL3300 Serial Number is not reported correctly

On further testing of the getSerialNumber() function, it was discovered that the number fetched was incorrectly calculated from the two 16-bit registers that had to be read. Opening this issue to fix this, and get the correct value reported and displayed, as outlined in the manufacturer datasheet.

Bitwise leftshift will show a warning on some MCU systems

While doing testing, I noticed that it was possible on some MCUs to generate a warning on this source line:

serialNum = (SCL3300_DATA << 16) | serialNum;

It doesn't always happen, as other MCUs, like SAMD chips, handle the bit shift just fine. The solution is to force a conversion as follows:

serialNum = ((unsigned long)SCL3300_DATA << 16) | serialNum;

Library speed

David, thanks for all the work so far. Very helpful.
One issue I ran into is the fact that the SCL3300 datasheet specifies an ODR of 2000Hz and suggests we read out the registers at the same rate to meet the sensor's noise performance. However I have never been able to get anywhere over 1130 readings in 1 second even with a modified version of several functions.
First issue I found is with the scl3300::transfer() function where I found 2 occurrences of a 1ms delay ( L396 and L407). This will already get us a maximum of 500Hz. I suggest changing all the millis() to micros(), since the only requirement from the datasheet is a 10µs delay between consecutive reads.
Still I have not been able to reach the 2000Hz on a custom board running nrf52832, a Particle Boron (nrf52840) and an MKRZERO (SAMD21).

Also the startup sequence doesn't match the one suggest on p. 21 but I haven't found it to mess with performance so far.

datasheet: link

Assistance debugging?

Hi David,

I wasn't sure how to contact you other than through this method. I have tried using this library with both an Arduino Uno and Mega and neither seem to be working. Perhaps it is an issue with my wiring? I followed the wiring suggestions from here: https://www.mouser.com/datasheet/2/281/pcbspec_scx3300-1568230.pdf

and am using a sparkfun bi-directional level shifter as you recommended. Here is my current wiring diagram:

(Lo--Hi) is the bi directional level shifter.

On the left half of the chip I have:
AVSS-GND
XReset -
INT -
CLK 0
DVDD- +3.3V
DVSS - GND
DVSS - GND
NC -

On the right half of the chip I have
AVSS- GND
AVDD - +3.3V
CSB - Lo--Hi--Pin D10 Uno
|
5kOhm
|
+3.3V

MISO- Lo--Hi -- Pin D12 Uno

MOSI- Lo--Hi--Pin D11 Uno

SCK - Lo--Hi-- Pin D13 Uno

NC-

If you have any suggestions I would greatly appreciate it! Please feel free to email me at [email protected]

SPI Issues

First of all, thanks for the library. It is very handy and useful. I am trying to connect SCL3300-D01-PCB to arduino uno through a bidirectional logic converter. Also using a pull up resistor for chip select - 4.7K. DVIO pin is at +3.3 Volts. I have checked all the connections but still I am not getting the communication established. I have provided the serial outputs with debug.

image

I have also added more serial prints in the code (below output) and still not able to figure out the issue.

14:33:39.307 -> Reading basic Tilt Level Offset values from SCL3300 Inclinometer
14:33:39.384 -> FC000073 Inside transfer I FC 0 0 73 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:39.502 -> B4002098 Inside transfer I B4 0 20 98 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:39.618 -> B4000338 Inside transfer I B4 0 3 38 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:39.739 -> 180000E5 Inside transfer I 18 0 0 E5 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:39.868 -> 180000E5 Inside transfer I 18 0 0 E5 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:39.989 -> 180000E5 Inside transfer I 18 0 0 E5 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:40.101 -> B0001F6F Inside transfer I B0 0 1F 6F In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:40.244 -> 40000091 Inside transfer I 40 0 0 91 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:40.358 -> 40000091 Inside transfer I 40 0 0 91 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:40.484 -> B4000338 Inside transfer I B4 0 3 38 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:40.605 -> 180000E5 Inside transfer I 18 0 0 E5 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:40.725 -> 180000E5 Inside transfer I 18 0 0 E5 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:40.841 -> 180000E5 Inside transfer I 18 0 0 E5 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:40.968 -> B0001F6F Inside transfer I B0 0 1F 6F In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:41.085 -> 40000091 Inside transfer I 40 0 0 91 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:41.202 -> 40000091 Inside transfer I 40 0 0 91 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:41.320 -> getErrFlag1
14:33:41.320 -> FC000073 Inside transfer I FC 0 0 73 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:41.447 -> 1C0000E3 Inside transfer I 1C 0 0 E3 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:41.600 -> 1C0000E3 Inside transfer I 1C 0 0 E3 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:41.712 -> 65535
14:33:41.712 -> getErrFlag2
14:33:41.712 -> FC000073 Inside transfer I FC 0 0 73 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:41.838 -> 200000C1 Inside transfer I 20 0 0 C1 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:41.960 -> 200000C1 Inside transfer I 20 0 0 C1 In CRC TrueIn RS True Inside transfer II Status err1 CRC err1 3 FFFF FF 7A 1
14:33:42.092 -> 65535
14:33:42.092 -> Murata SCL3300 inclinometer not connected.

Error checking redesign

The current means of checking for errors when receiving a response from the SCL3300 is really inadequate, for lack of a better word. While running some tests to improve this functionality, I discovered that the current design won't allow for modifications on the error checking code without adverse effects being seen. So, to avoid this, I need to re=code the error checking portions, while maintaining all the working functionality and compatibility.
Therefore, I'm opening this issue to track this change. As stated, there will be no change in functionality, or in calling the library as it stands. However, if one needs to check to see if there was an error reported by the SCL3300, that will be explicitly laid out for the user to include in their usage of the library.

Duplicates

I do have a strange issue and I even don't know if its related to this lib.
But maybe you guys can help me out.

I have a custom Arduino Due compatible board and the SCL3300 is also mounted on this board.
The board is mounted in a chassis and the chassis lays flat on a leveling table (~0°).

When I measure the angle with function getTiltLevelOffsetAngleX() a few times, I get the following output:

-0.148315429687500

-0.153808593750000

-0.164794921875000
-0.164794921875000

-0.170288085937500
-0.170288085937500
-0.170288085937500
-0.170288085937500
-0.170288085937500
-0.170288085937500

-0.175781250000000
-0.175781250000000
-0.175781250000000
-0.175781250000000

-0.181274414062500
-0.181274414062500
-0.181274414062500
-0.181274414062500
-0.181274414062500
-0.181274414062500
-0.181274414062500
-0.181274414062500
-0.181274414062500
-0.181274414062500
-0.181274414062500
-0.186767578125000
-0.186767578125000

-0.192260742187500

-0.197753906250000

The values are sorted in ascending order. As you can see, I get a lot of duplicates. In fact, there are only about 5-6 unique values. From my point of view, that should never ever happen in real life. Lib version 3.0.0 is used.
The measurements are trigger by a command through the Serial interface from my computer. It's about one measurement per second.
When I rotate to chassis, the value changes and I measure angles about 90° (what I have expected).
But again, when the sensor is not moved and multiple measurements are triggered, I see duplicate values.

Does anybody have an idea, why this could happen?
Thanks a lot!

Reading accelerometer values

Hello,

I use the Murata PCB SCL3300 and an Arduino MKR WIFI 1010.

It seems to me that there is a problem with the values of the accelerometer.
Serial monitor with "Example3_BasicAccelerometerReading" program :
X Accelerometer: 0.01 Y Accelerometer: 5.44 Z Accelerometer: 0.99

The value of the y axis is false.

I think the problem is the variable type for acceleration datas.
The datasheet specifies that values are in complement format so you should declare signed int instead of unsigned int.

The modifications are to be made in :
struct of SCL3300data
the fonction double acceleration(int16_t ACC)

Thank you so much for this library which is of the greatest help !

Accuracy in Mode 4

Hello!

I would like to use this sensor in Mode 4, 10 Hz mode (I know it is the default mode) however when I use your code without delay(100) I get around 250 Hz data.
I get good values however it jumps around +/-3 in RAW values which is too much for my application. As I get values it does not get limited at +/- 10 degree.

How can I correctly initiate 10 Hz low noise mode?

Also I would like to use the sensor to measure tilt on the X-axis. However this picture from datasheet is a bit confusing:
pic
My sensor position is like the third one. Is it possible or should I change the direction?

Thank you!

Update to standard library release practices

Version 1.0.0 does not follow all recommendations for creating an Arduino library. I have rewritten major portions of the library to bring it much closer to what is expected. Since the library is only a few weeks old, I still feel it is time to do major corrections like this. However, version 2.0.0 will stay this way now, with only minor tweaking, if needed, in the future.

Acceleration Readings

Hi!
I think the acceleration read process is incorrect. The Datasheet specifies the following:

Acceleration:
= reading [LSB] / sensitivity [LSB/g]
= acceleration[g]

In your code you use MSB and LSB combined.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.