SPI on Teensy 3.1 - negative values wrong

Status
Not open for further replies.

Massel

Well-known member
I'm using SPI to communicate with a MPU6000.
The used code worked with the Arduino Uno, with the Teensy 3.1 I get the same values AS LONG AS THEY ARE POSITIV.
Negative values are shown like 2^16 - "the value it should have".
My question is, what is wrong?
Why are these values not interpreted as negative values?


Code:
void setup()
{
  ...
  // MPU6000 chip select setup
  pinMode(MPU6000_CHIP_SELECT_PIN, OUTPUT);
  digitalWrite(MPU6000_CHIP_SELECT_PIN, HIGH);
    
  // SPI initialization
  SPI.begin();    
  SPI.setClockDivider(SPI_CLOCK_DIV8);
  SPI.setBitOrder(MSBFIRST);  // data delivered MSB first
  SPI.setDataMode(SPI_MODE0);
  ...
}

byte MPU6000_SPI_read(byte reg)
{
  byte dump;
  byte return_value;
  byte addr = reg | 0x80; // Set most significant bit
  digitalWrite(MPU6000_CHIP_SELECT_PIN, LOW);
  dump = SPI.transfer(addr);
  return_value = SPI.transfer(0);
  digitalWrite(MPU6000_CHIP_SELECT_PIN, HIGH);
  return(return_value);
}

void loop() {
  ...
  byte_H = MPU6000_SPI_read(MPUREG_ACCEL_XOUT_H);
  byte_L = MPU6000_SPI_read(MPUREG_ACCEL_XOUT_L);
  int accelX = (byte_H<<8)| byte_L;
  ...
  Serial.println(accelX);

  ...
}
 
This problem comes up regularly when code written for 8 bit AVR takes 2 bytes (representing a signed integer, which is common with motion sensors) and puts them into an integer without explicitly specifying the integer is 16 bits.

It's easily solved by just casting to int16_t, like this:

Code:
  int accelX = (int16_t)((byte_H<<8)| byte_L);

Edit: this works even when you put the data into a 32 bit int or a float or double. Once you've casted the data to int16_t, the compiler "knows" those 16 bit are a signed 16 bit integer and it will do the right thing when you put the data into larger-size variables.
 
Last edited:
One more question.

The prototype is running great right now!
As I am routing a board for a MPU and an OLED display which is really small I would love to use different pins for SPI.
On the Teensy 3.1 pin card the pins "SCK DIN DOUT" are also shown light green on different pins.
The first question is how can I change the SPI pins to the light green ones.
And the second question is, can I choose any pin to be the SCK pin?

I can't really use the pins 11 - 14 due to board layout issues ;)

Thank you.
 
Just chiming in here, SCK pin (& etc.) needs to be that specific pin. However there are two sets of SPI pins on the 3.1.
 
Status
Not open for further replies.
Back
Top