ADXL345 giving strange results on the Teensy 3.1

Status
Not open for further replies.

mikeleslie

Active member
I have an app I've been using for a while which runs on a Mega and I decided that a Teensy would be a great fit. Very few issues in migrating except for the accelerometer. Instead of producing negative values like the Mega (or Uno or Micro I tried it on) it gives me a 65,5xx(ish) The value is an INT, so I'm guessing there's an issue with how the sign is being interpreted...
I thought it was the library I was using and so I went back to the simplest example sketch for the ADXL and it produces the same result.
If I compile the sketch for the Mega, Uno etc, it runs fine. Any help would be much appreciated.


Here's some output:
x: 20 y: 4 z: 115
x: 12 y: 2 z: 119
x: 6 y: 1 z: 116
x: 0 y: 2 z: 117
x: 65525 y: 3 z: 118
x: 65520 y: 3 z: 118
x: 65522 y: 3 z: 112






and here's the code.

Code:
// Bare bones ADXL345 i2c example for Arduino 1.0
// by Jens C Brynildsen <http://www.flashgamer.com>
// This version is not reliant of any external lib

// Demonstrates use of ADXL345 (using the Sparkfun ADXL345 breakout) with i2c communication
// Datasheet [url]http://www.sparkfun.com/datasheets/Sensors/Accelerometer/ADXL345.pdf[/url]
// If you need more advanced features such as freefall and tap detection, check out
// [url]https://github.com/jenschr/Arduino-libraries[/url]
// (Adapted for Arduino 1.0 from [url]http://code.google.com/p/adxl345driver[/url])

// Cabling for i2c using Sparkfun breakout with an Arduino Uno / Duemilanove:
// Arduino <-> Breakout board
// Gnd      -  GND
// 3.3v     -  VCC
// 3.3v     -  CS
// Analog 4 -  SDA
// Analog 5 -  SLC

// Cabling for i2c using Sparkfun breakout with an Arduino Mega / Mega ADK:
// Arduino <-> Breakout board
// Gnd      -  GND
// 3.3v     -  VCC
// 3.3v     -  CS
// 20       -  SDA
// 21       -  SLC

// This example code is in the public domain.

#include <Wire.h>

#define DEVICE (0x53) // Device address as specified in data sheet 

byte _buff[6];

char POWER_CTL = 0x2D;	//Power Control Register
char DATA_FORMAT = 0x31;
char DATAX0 = 0x32;	//X-Axis Data 0
char DATAX1 = 0x33;	//X-Axis Data 1
char DATAY0 = 0x34;	//Y-Axis Data 0
char DATAY1 = 0x35;	//Y-Axis Data 1
char DATAZ0 = 0x36;	//Z-Axis Data 0
char DATAZ1 = 0x37;	//Z-Axis Data 1

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(57000);  // start serial for output. Make sure you set your Serial Monitor to the same!
  Serial.print("init");
  
  //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
  writeTo(DATA_FORMAT, 0x01);
  //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
  writeTo(POWER_CTL, 0x08);
}

void loop()
{
  readAccel(); // read the x/y/z tilt
  delay(500); // only read every 0,5 seconds
}

void readAccel() {
  uint8_t howManyBytesToRead = 6;
  readFrom( DATAX0, howManyBytesToRead, _buff); //read the acceleration data from the ADXL345

  // each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!
  // thus we are converting both bytes in to one int
  int x = (((int)_buff[1]) << 8) | _buff[0];   
  int y = (((int)_buff[3]) << 8) | _buff[2];
  int z = (((int)_buff[5]) << 8) | _buff[4];
  Serial.print("x: ");
  Serial.print( x );
  Serial.print(" y: ");
  Serial.print( y );
  Serial.print(" z: ");
  Serial.println( z );
}

void writeTo(byte address, byte val) {
  Wire.beginTransmission(DEVICE); // start transmission to device 
  Wire.write(address);             // send register address
  Wire.write(val);                 // send value to write
  Wire.endTransmission();         // end transmission
}

// Reads num bytes starting from address register on device in to _buff array
void readFrom(byte address, int num, byte _buff[]) {
  Wire.beginTransmission(DEVICE); // start transmission to device 
  Wire.write(address);             // sends address to read from
  Wire.endTransmission();         // end transmission

  Wire.beginTransmission(DEVICE); // start transmission to device
  Wire.requestFrom(DEVICE, num);    // request 6 bytes from device

  int i = 0;
  while(Wire.available())         // device may send less than requested (abnormal)
  { 
    _buff[i] = Wire.read();    // receive a byte
    i++;
  }
  Wire.endTransmission();         // end transmission
}
 
Last edited:
OK, I'm an idiot.....although I stated in my post that I thought it was a sign issue, it never dawned on me that it was int that was different (even though it says it is, hence me being an idiot) Once that thought hit me in the head again, it was a quick fix. ....int16.
 
OK, I'm an idiot.....although I stated in my post that I thought it was a sign issue, it never dawned on me that it was int that was different (even though it says it is, hence me being an idiot) Once that thought hit me in the head again, it was a quick fix. ....int16.

Hey, im facing the same issue. How did you solve it?

Im running exactly the same code over a sparkcore unit.
 
Look through the code for all int, unsigned, and unsigned int declarations. Determine whether the value should be 16-bits, and if so, change the declarations to int16_t, uint16_t, or uint16_t respectively.

Also look for double declarations, and change them to float. Change all floating point constants to have a F suffix.
 
Status
Not open for further replies.
Back
Top