SPI communication problem with Murata SCC2130-D08 & Adafruit Feather M0 basic

I try to communicate via SPI protocol the sensor SCC2130-D08, which is a 3-axis accelerometer and x-axis gyroscope sensor of Murata, with the Adafruit Feather M0 basic microcontroller. The datasheet of the sensor is the following: https://www.murata.com/~/media/webrenewal/products/sensor/gyro/scc2000/scc2130-d08%20datasheet%2082177500b0.ashx?la=en-gb

Thr problem is that I have been trying and following other threads of this forum like the one asking for an inclinometer of Murata: http://forum.arduino.cc/index.php?topic=112074.0 But with no success!

My code is similar to the post of the link of the inclinometer but slightly modified to suit the requirements of the IMU sensor:

// inslude the SPI library:
#include <SPI.h>

// set pin 10 as the slave select for the digital pot:
const int slaveSelectPin = 8; //Slave select(SS)
const int dataINPin = 21; //MISO
const int dataOUTPin = 19; //MOSI
const int serialClockPin = 20; //CSK

// Commands for Murata SCC2130-D08:
const byte WHOAMI = B01110100;
const byte RATE = B00000100;

void setup() {
Serial.begin(9600);
// initialize SPI:
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(0);
// set the slaveSelectPin as an output:
pinMode(slaveSelectPin, OUTPUT);

pinMode(dataINPin, INPUT);
pinMode(dataOUTPin, OUTPUT);
pinMode(serialClockPin, OUTPUT);

//!!!Allow self-test to initialize on start-up
delay(500);
}

void loop() {

//!!!assigns integer to store ID value:
long ID = readCommand(WHOAMI);

Serial.println("Device ID: ");
Serial.println(ID, BIN);

Serial.println("\n");
delay(1000);

}

long readCommand(byte Command) {
byte firstByte = 0;
byte secondByte = 0;
byte thirdByte = 0;
byte lastByte = 0;
long result = 0; //result to return

// take the chip select low to select the device:
digitalWrite(slaveSelectPin, LOW);
//!!!SCAT datasheet specifies a 620 microsecond pause to get correct reading
//!!!Page 22 of datasheet
delayMicroseconds(620); // pauses for 620 microseconds

for(int i = 0;i<3;i++) {
//!!! Send dummy command to slave(sensor):
SPI.transfer(Command);
}

//!!!Reads output by using measure command
firstByte = SPI.transfer(Command);
// shift the first byte left, then get the second byte:
firstByte = firstByte << 8;

secondByte = SPI.transfer(Command);
firstByte = firstByte | secondByte;
firstByte = firstByte << 8;

thirdByte = SPI.transfer(Command);
firstByte = firstByte | thirdByte;
firstByte = firstByte << 8;

lastByte = SPI.transfer(Command);

// combine the byte you just got with the previous one:
result = firstByte | lastByte;

// Result is in 32 bit word format with MSB first

// take the chip select high to de-select:
digitalWrite(slaveSelectPin, HIGH);
// return the result:
return(result);
}

Contact Adafruit.

It is their board; they should be able to provide technical support.

But actually the problem is not with their board! I am using ARDUINO IDE, and I would like to have some advice regarding the code and how to use SPI appropriately for this specific case of Murata sensor.

Does someone have any past experience with Murata and Arduino IDE, a part from the example of the Inclinometer?

LINK: http://forum.arduino.cc/index.php?topic=112074.0

Hi myman. I have got also similar sensor SCC2230, since a week I am unable to interface it. Have you been successful?

Hello, I am a graduate student from China.
Recently I was using Murata’s SCC2130. I saw your post on the Internet. Have you solved the problem?
I have been stuck in SPI communication for a long time and look forward to your help.
It’s a pleasure to communicate with you. Please contact baolin.ma@whu.edu.cn

whu_ma:
Hello, I am a graduate student from China.
Recently I was using Murata’s SCC2130. I saw your post on the Internet. Have you solved the problem?
I have been stuck in SPI communication for a long time and look forward to your help.
It’s a pleasure to communicate with you. Please contact baolin.ma@whu.edu.cn

looking at the datasheet here, maybe something like this to read the sensor data blocks:

(Compiles, NOT tested!)

#include <SPI.h>

//Murata's SCC2130 example code
//datasheet link - https://www.murata.com/-/media/webrenewal/products/sensor/pdf/datasheet/datasheet_scc2130-d08.ashx?la=en
/*
  //Read Commands (SPI Frame in Hex: [OP/RS][Data][CRC])
  const uint32_t ACC_Status = 0x3C0000D3;
  const uint32_t ACC_X = 0x100000E9;
  const uint32_t ACC_Y = 0x140000EF;
  const uint32_t ACC_Z = 0x180000E5;
  const uint32_t CommonStatus = 0x6C0000AB;
  const uint32_t Angular_Rate = 0x040000F7;
  const uint32_t Angular_Rate_Status_1 = 0x240000C7;
  const uint32_t Angular_Rate_Status_2 = 0x280000CD;
  const uint32_t Serial_ID0 = 0x600000A1;
  const uint32_t Serial_ID1 = 0x640000A7;
  const uint32_t Status_Summary = 0x7C0000B3;
  const uint32_t TEMP = 0x1C0000E3;
  //Write Command (SPI Frame in Hex: [OP/RS][Data][CRC])
  const uint32_t HardReset = 0xD8000431;
  const uint32_t MonitorST = 0xD80008AD;
  const uint32_t Set_10Hz_Filter = 0xFC1000C7;
  const uint32_t Set_60Hz_Filter = 0xFC200006;
*/
//Read Commands (SPI Frame in Hex: [OP/RS][Data][CRC])
const uint8_t ACC_Status [4] = {0x3C, 0x00, 0x00, 0xD3};
const uint8_t ACC_X [4] = {0x10, 0x00, 0x00, 0xE9};
const uint8_t ACC_Y [4] = {0x14, 0x00, 0x00, 0xEF};
const uint8_t ACC_Z [4] = {0x18, 0x00, 0x00, 0xE5};
const uint8_t CommonStatus [4] = {0x6C, 0x00, 0x00, 0xAB};
const uint8_t Angular_Rate [4] = {0x04, 0x00, 0x00, 0xF7};
const uint8_t Angular_Rate_Status_1 [4] = {0x24, 0x00, 0x00, 0xC7};
const uint8_t Angular_Rate_Status_2 [4] = {0x28, 0x00, 0x00, 0xCD};
const uint8_t Serial_ID0 [4] = {0x60, 0x00, 0x00, 0xA1};
const uint8_t Serial_ID1 [4] = {0x64, 0x00, 0x00, 0xA7};
const uint8_t Status_Summary [4] = {0x7C, 0x00, 0x00, 0xB3};
const uint8_t TEMP [4] = {0x1C, 0x00, 0x00, 0xE3};
//Write Command (SPI Frame in Hex: [OP/RS][Data][CRC])
const uint8_t HardReset [4] = {0xD8, 0x00, 0x04, 0x31};
const uint8_t MonitorST [4] = {0xD8, 0x00, 0x08, 0xAD};
const uint8_t Set_10Hz_Filter [4] = {0xFC, 0x10, 0x00, 0xC7};
const uint8_t Set_60Hz_Filter [4] = {0xFC, 0x20, 0x00, 0x06};

//-----------------------------

byte CS_pin = 10; //SPI chip-select pin

void setup() {
  //configure serial port baud rate for Serial Monitor
  Serial.begin(115200);

  //configure SPI port and Chip-select pin
  SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); //SCLK 4MHZ, MSB first, SPI_Mode 0
  pinMode(CS_pin, OUTPUT);
  digitalWrite(CS_pin, HIGH);

}

void loop() {
  //print temperature to serial monitor
  Serial.print(Get_Temperature(), 1);
  Serial.println("degC");

  //print Angular_Acceleration to serial monitor
  Serial.print(Get_Angular_Rate(), 1);
  Serial.println("deg/s");

  //print X_Acceleration to serial monitor
  Serial.print(Get_Acceleration(ACC_X), 1);
  Serial.println("g    ");

  //print Y_Acceleration to serial monitor
  Serial.print(Get_Acceleration(ACC_Y), 1);
  Serial.println("g    ");

  //print Z_Acceleration to serial monitor
  Serial.print(Get_Acceleration(ACC_Z), 1);
  Serial.println("g    ");

  delay(1000); //1 second loop. arbitrary delay.
}

float Get_Acceleration(uint8_t *acc) {
  int32_t acc_l = 0;
  float acc_sensitivity = 1962; //1962/g

  //request sensor angular rate (based on example in datasheet on pg.29)
  //send data, MSByte first
  for (int8_t i = 0; i < 4; ++i) {
    acc_l <<= 8;
    acc_l = SPI.transfer(acc[i]);
  }

  acc_l = (acc_l >> 8) & 0xFFFF; //get rid of op_code,rs and CRC

  return acc_l / acc_sensitivity;
}

float Get_Angular_Rate() {
  int32_t ang_rate_l = 0;
  float ang_sensitivity = 50; //50 deg/s

  //request sensor angular rate (based on example in datasheet on pg.29)
  //send data, MSByte first
  for (int8_t i = 0; i < 4; ++i) {
    ang_rate_l <<= 8;
    ang_rate_l = SPI.transfer(Angular_Rate[i]);
  }

  ang_rate_l = (ang_rate_l >> 8) & 0xFFFF; //get rid of op_code,rs and CRC

  return ang_rate_l / ang_sensitivity;
}

float Get_Temperature() {
  int32_t temp_l = 0;

  //request sensor angular rate (based on example in datasheet on pg.29)
  //send data, MSByte first
  for (int8_t i = 0; i < 4; ++i) {
    temp_l <<= 8;
    temp_l = SPI.transfer(TEMP[i]);
  }

  temp_l = (temp_l >> 8) & 0xFFFF; //get rid of op_code,rs and CRC

  float temp_f = 60 + (temp_l / 14.7); //See section 2.4 for temperature conversion equation

  return temp_f;
}

// Calculate CRC for 24 MSB's of the 32 bit dword
// (8 LSB's are the CRC field and are not included in CRC calculation)
uint8_t CalculateCRC(uint32_t Data)
{
  uint8_t BitIndex;
  uint8_t BitValue;
  uint8_t CRC;
  CRC = 0xFF;
  for (BitIndex = 31; BitIndex > 7; BitIndex--)
  {
    BitValue = (uint8_t)((Data >> BitIndex) & 0x01);
    CRC = CRC8(BitValue, CRC);
  }
  CRC = (uint8_t)~CRC;
  return CRC;
}

uint8_t CRC8(uint8_t BitValue, uint8_t CRC)
{
  uint8_t Temp;
  Temp = (uint8_t)(CRC & 0x80);
  if (BitValue == 0x01)
  {
    Temp ^= 0x80;
  }
  CRC <<= 1;
  if (Temp > 0)
  {
    CRC ^= 0x1D;
  }
  return CRC;
}
//----------------

hope that helps…

datasheet_scc2130-d08.pdf (1000 KB)