Adafruit ISM330DHCX not working in SPI mode on Teensy 4.1

Status
Not open for further replies.

MatArnold

Member
Having trouble with SPI connections to my Teensy 4.1. Specifically an IMU breakout from Adafruit, the ISM330DHCX. I did look at the other thread on an Adafruit IMU in SPI mode but I could not find a solution to my problem. My code is below, simply the provided Adafruit testing example.

Code:
#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <Adafruit_ISM330DHCX.h>
#include <Adafruit_Sensor.h>





// For SPI mode, we need a CS pin
#define LSM_CS 10
// For software-SPI mode we need SCK/MOSI/MISO pins
#define LSM_SCK 13
#define LSM_MISO 12
#define LSM_MOSI 11





Adafruit_ISM330DHCX ism330dhcx;


void setup(void) {
  pinMode(10,OUTPUT); // set default spi CS to high

  Serial.begin(9600);
  while (!Serial)
    delay(10); // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit ISM330DHCX test!");

  // if (!ism330dhcx.begin_I2C()) {
    if (!ism330dhcx.begin_SPI(LSM_CS)) {
    // if (!ism330dhcx.begin_SPI(LSM_CS, LSM_SCK, LSM_MISO, LSM_MOSI)) {
    Serial.println("Failed to find ISM330DHCX chip");
    while (1) {
      delay(10);
    }
  }

  Serial.println("ISM330DHCX Found!");

  //ism330dhcx.setAccelRange(LSM6DS_ACCEL_RANGE_4_G);
  Serial.print("Accelerometer range set to: ");
  switch (ism330dhcx.getAccelRange()) {
  case LSM6DS_ACCEL_RANGE_2_G:
    Serial.println("+-2G");
    break;
  case LSM6DS_ACCEL_RANGE_4_G:
    Serial.println("+-4G");
    break;
  case LSM6DS_ACCEL_RANGE_8_G:
    Serial.println("+-8G");
    break;
  case LSM6DS_ACCEL_RANGE_16_G:
    Serial.println("+-16G");
    break;
  }

  ism330dhcx.setGyroRange(LSM6DS_GYRO_RANGE_250_DPS);
  Serial.print("Gyro range set to: ");
  switch (ism330dhcx.getGyroRange()) {
  case LSM6DS_GYRO_RANGE_125_DPS:
    Serial.println("125 degrees/s");
    break;
  case LSM6DS_GYRO_RANGE_250_DPS:
    Serial.println("250 degrees/s");
    break;
  case LSM6DS_GYRO_RANGE_500_DPS:
    Serial.println("500 degrees/s");
    break;
  case LSM6DS_GYRO_RANGE_1000_DPS:
    Serial.println("1000 degrees/s");
    break;
  case LSM6DS_GYRO_RANGE_2000_DPS:
    Serial.println("2000 degrees/s");
    break;
  case ISM330DHCX_GYRO_RANGE_4000_DPS:
    Serial.println("4000 degrees/s");
    break;
  }

  // ism330dhcx.setAccelDataRate(LSM6DS_RATE_12_5_HZ);
  Serial.print("Accelerometer data rate set to: ");
  switch (ism330dhcx.getAccelDataRate()) {
  case LSM6DS_RATE_SHUTDOWN:
    Serial.println("0 Hz");
    break;
  case LSM6DS_RATE_12_5_HZ:
    Serial.println("12.5 Hz");
    break;
  case LSM6DS_RATE_26_HZ:
    Serial.println("26 Hz");
    break;
  case LSM6DS_RATE_52_HZ:
    Serial.println("52 Hz");
    break;
  case LSM6DS_RATE_104_HZ:
    Serial.println("104 Hz");
    break;
  case LSM6DS_RATE_208_HZ:
    Serial.println("208 Hz");
    break;
  case LSM6DS_RATE_416_HZ:
    Serial.println("416 Hz");
    break;
  case LSM6DS_RATE_833_HZ:
    Serial.println("833 Hz");
    break;
  case LSM6DS_RATE_1_66K_HZ:
    Serial.println("1.66 KHz");
    break;
  case LSM6DS_RATE_3_33K_HZ:
    Serial.println("3.33 KHz");
    break;
  case LSM6DS_RATE_6_66K_HZ:
    Serial.println("6.66 KHz");
    break;
  }

  // ism330dhcx.setGyroDataRate(LSM6DS_RATE_12_5_HZ);
  Serial.print("Gyro data rate set to: ");
  switch (ism330dhcx.getGyroDataRate()) {
  case LSM6DS_RATE_SHUTDOWN:
    Serial.println("0 Hz");
    break;
  case LSM6DS_RATE_12_5_HZ:
    Serial.println("12.5 Hz");
    break;
  case LSM6DS_RATE_26_HZ:
    Serial.println("26 Hz");
    break;
  case LSM6DS_RATE_52_HZ:
    Serial.println("52 Hz");
    break;
  case LSM6DS_RATE_104_HZ:
    Serial.println("104 Hz");
    break;
  case LSM6DS_RATE_208_HZ:
    Serial.println("208 Hz");
    break;
  case LSM6DS_RATE_416_HZ:
    Serial.println("416 Hz");
    break;
  case LSM6DS_RATE_833_HZ:
    Serial.println("833 Hz");
    break;
  case LSM6DS_RATE_1_66K_HZ:
    Serial.println("1.66 KHz");
    break;
  case LSM6DS_RATE_3_33K_HZ:
    Serial.println("3.33 KHz");
    break;
  case LSM6DS_RATE_6_66K_HZ:
    Serial.println("6.66 KHz");
    break;
  }

  ism330dhcx.configInt1(false, false, true); // accelerometer DRDY on INT1
  ism330dhcx.configInt2(false, true, false); // gyro DRDY on INT2

}

void loop() {
  // IMU
  //  /* Get a new normalized sensor event */
  sensors_event_t accel;
  sensors_event_t gyro;
  sensors_event_t temp;
  ism330dhcx.getEvent(&accel, &gyro, &temp);

  Serial.print("\t\tTemperature ");
  Serial.print(temp.temperature);
  Serial.println(" deg C");

  /* Display the results (acceleration is measured in m/s^2) */
  Serial.print("\t\tAccel X: ");
  Serial.print(accel.acceleration.x);
  Serial.print(" \tY: ");
  Serial.print(accel.acceleration.y);
  Serial.print(" \tZ: ");
  Serial.print(accel.acceleration.z);
  Serial.println(" m/s^2 ");

  /* Display the results (rotation is measured in rad/s) */
  Serial.print("\t\tGyro X: ");
  Serial.print(gyro.gyro.x);
  Serial.print(" \tY: ");
  Serial.print(gyro.gyro.y);
  Serial.print(" \tZ: ");
  Serial.print(gyro.gyro.z);
  Serial.println(" radians/s ");
  Serial.println();

  delay(1000);

  //  // serial plotter friendly format

  //  Serial.print(temp.temperature);
  //  Serial.print(",");

  //  Serial.print(accel.acceleration.x);
  //  Serial.print(","); Serial.print(accel.acceleration.y);
  //  Serial.print(","); Serial.print(accel.acceleration.z);
  //  Serial.print(",");

  // Serial.print(gyro.gyro.x);
  // Serial.print(","); Serial.print(gyro.gyro.y);
  // Serial.print(","); Serial.print(gyro.gyro.z);
  // Serial.println();
  //  delayMicroseconds(10000);




}

I have a barometer from Adafruit running in SPI mode with no issues, and I've run the ISM330DHCX in SPI mode off of my Arduino MEGA 2560 without issue. What's strange is ism330dhcx.begin_SPI(LSM_CS) returns true, however the accelerometer options can't be changed and the output is a set of values that do not update as the ISM330DHCX is moved, and they do work in I2C mode or in SPI mode running from the MEGA. I think the wiring is correct, the Barometer runs fine off of the same SPI pins, just with CS set to 9.

The outputs look like:

Adafruit ISM330DHCX test!
ISM330DHCX Found!
Accelerometer range set to: +-2G
Gyro range set to: Accelerometer data rate set to: 1.66 KHz
Gyro data rate set to: 1.66 KHz

Temperature 25.50 deg C
Accel X: 0.00 Y: 0.00 Z: -9.79 m/s^2
Gyro X: 0.00 Y: 0.00 Z: 0.00 radians/s

Temperature 25.50 deg C
Accel X: 0.00 Y: 0.00 Z: -9.79 m/s^2
Gyro X: 0.00 Y: 0.00 Z: 0.00 radians/s

I'm probably overlooking something, hopefully someone is able to offer some guidance. Thank you!
 
Update, tried with another Teensy 4.1 I had, same exact result. If someone is able to point me in a direction to investigate, that would be extraordinarily helpful.

Here is a picture of the wiring:

20210608_205929._2jpg.jpg
 
Sorry, I am not seeing that Adafruit library anywhere... At least the library manager does not show it nor does quick look on github. Is this part of a different Adafruit library?

Could be something like a timing issue, where you may need to put well placed delays in, as the teensy 4.1 will run things a lot faster than an 16mhz AVR board
 
Sorry I have not had a chance to look at their source code or look at the devices manual to know what the timing requirements are.

Some of the things I would look at include:

Does the code use SPI transactions? that is SPI.beginTransaction(....) If not maybe try to convert.

Other things like: if the code does:
digitalWrite(CS_PIN, LOW);
SPI.transfer(...)

Maybe the device need a small delay between setting the CS and doing transfer.
 
I completely replaced Platform IOs version of teensyduino with the latest release, and it worked! I completely replaced the teensy>avr>cores and the teensy>avr>libraries contents and got everything working. Thank you so much!
 
Status
Not open for further replies.
Back
Top