I'm finally getting back to a Teensy-based datalogger project of mine. Among other sensors, one I am using is the ITG-3701 from Invensense. Here is the datasheet and here is the register map.
My confusion stems from the SPI Mode. I've included a few snippets from the datasheet below:
And from page 19 of the datasheet:
From the image, I take it to mean that CPOL=1 as it looks like it wants the clock to idle high. And from the text quoted above, it looks like CPHA=1. So, SPI mode = 3. Except no, only SPI mode = 0 reads back a non-zero value for the who_am_I register, for example (and on mode 0 it returns 0x68 as expected. With SPI mode = 0, I then derrived the below code, which plots nicely on the serial plotter (my first time using it!), and gives fairly reasonable results as I rotate the board along the various axes.
So what am I missing? Surely SPI modes aren't different on Teensy, are they?
EDIT: I guess I should mention this is a Teensy 3.2-based board, currently using Arduino 1.6.12 and Teensyduino 1.31beta1, on Win10Pro.
My confusion stems from the SPI Mode. I've included a few snippets from the datasheet below:
And from page 19 of the datasheet:
SPI Operational Features
1. Data is delivered MSB first and LSB last
2. Data is latched on rising edge of SCLK
3. Data should be transitioned on the falling edge of SCLK
4. SCLK frequency is 1MHz max for SPI in full read/write capability mode. When the SPI frequency
is set to 20MHz, its operation is limited to reading sensor registers only.
From the image, I take it to mean that CPOL=1 as it looks like it wants the clock to idle high. And from the text quoted above, it looks like CPHA=1. So, SPI mode = 3. Except no, only SPI mode = 0 reads back a non-zero value for the who_am_I register, for example (and on mode 0 it returns 0x68 as expected. With SPI mode = 0, I then derrived the below code, which plots nicely on the serial plotter (my first time using it!), and gives fairly reasonable results as I rotate the board along the various axes.
Code:
#include <SPI.h>
// prints data to serial monitor, without labels for use with Serial plotter.
// written 23-Oct-2016
const byte ssPin = 19; //chip select pin
SPISettings GyroSettings(1000000, MSBFIRST, SPI_MODE0);
void setup() {
// put your setup code here, to run once:
pinMode(ssPin, OUTPUT);
digitalWrite(ssPin, HIGH);
Serial.begin(9600);
while(!Serial){}
SPI.begin();
Serial.println("Connected");
SPI.beginTransaction(GyroSettings);
digitalWrite(ssPin, LOW);
SPI.transfer(0x75 | B10000000); // send who_am_I with read flag set
Serial.print("Who am I: ");
Serial.println(SPI.transfer(0), HEX);
SPI.transfer(0x26); // send write command to register 26
SPI.transfer(B00000001); // send data to write to register 26 - 184Hz bandwidth)
SPI.transfer(0x27); // send write command to register 27
SPI.transfer(B00001000); // send data to write to register 27 - 1000dps scaling
digitalWrite(ssPin, HIGH);
SPI.endTransaction();
}
void loop() {
// put your main code here, to run repeatedly:
int16_t tempInt = 0; // temporary integer for assembling data bytes
SPI.beginTransaction(GyroSettings);
digitalWrite(ssPin, LOW);
//Serial.print(" X: ");
SPI.transfer(0x43 | B10000000); // issue read command for register 43, the GYRO_XOUT_H
tempInt = int16_t(SPI.transfer(0) << 8);
tempInt += SPI.transfer(0);
Serial.print(tempInt / 32.8);
tempInt = 0;
//Serial.print(" Y: ");
Serial.print(" ");
tempInt = int16_t(SPI.transfer(0) << 8);
tempInt += SPI.transfer(0);
Serial.print(tempInt / 32.8);
tempInt = 0;
//Serial.print(" Z: ");
Serial.print(" ");
tempInt = int16_t(SPI.transfer(0) << 8);
tempInt += SPI.transfer(0);
Serial.println(tempInt / 32.8);
tempInt = 0;
digitalWrite(ssPin, HIGH);
SPI.endTransaction();
delay(100);
}
So what am I missing? Surely SPI modes aren't different on Teensy, are they?
EDIT: I guess I should mention this is a Teensy 3.2-based board, currently using Arduino 1.6.12 and Teensyduino 1.31beta1, on Win10Pro.
Last edited: