Teensy 3.1 & freeIMU

Status
Not open for further replies.

roger08

New member
HI! I am trying to use teensy 3.1 (buy here: teensy 3.1 ) and sensor stick 9 DOF (buy here: IMU) using freeIMU library modified by Paul Stoffregen (freeIMU). I tried the originally freeIMU library with arduino UNO and works well but when I try with teensy 3.1 it doesn't work probably because the I2C comunication doesn't work. I tried to run the ADXL345_run sketch but when I moved the IMU the accelerometer value, on the serial monitor, arrive at 246 g improbable values ​​for an accelerometer. I think it's a I2C problem.
Untitled Sketch_bb.jpg

I use arduino 1.0.5 ide with teensyduino in ubuntu 12.04.

p.s.
The final project is a quadcopter controlled with teensy 3.1

thank you!!
 
Last edited:
I took a quick look at the code, even though I do not have any hardware for testing.

I believe the bug may be here:

Code:
// Reads the acceleration into three variable x, y and z
void ADXL345::readAccel(int *x, int *y, int *z) {
  readFrom(ADXL345_DATAX0, TO_READ, _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
  *x = (((int)_buff[1]) << 8) | _buff[0];
  *y = (((int)_buff[3]) << 8) | _buff[2];
  *z = (((int)_buff[5]) << 8) | _buff[4];
}

Please give this a try:

Code:
  *x = (int16_t)((((int)_buff[1]) << 8) | _buff[0]);
  *y = (int16_t)((((int)_buff[3]) << 8) | _buff[2]);
  *z = (int16_t)((((int)_buff[5]) << 8) | _buff[4]);
 
ok now the accelerometer works well.
following your advice I also modified the gyroscope library from this:
Code:
void ITG3200::readGyroRaw(int *_GyroX, int *_GyroY, int *_GyroZ){
  readmem(GYRO_XOUT, 6, _buff);
  *_GyroX = ((_buff[0] << 8) | _buff[1]);
  *_GyroY = ((_buff[2] << 8) | _buff[3]); 
  *_GyroZ = ((_buff[4] << 8) | _buff[5]);
}

to this:
Code:
void ITG3200::readGyroRaw(int *_GyroX, int *_GyroY, int *_GyroZ){
  readmem(GYRO_XOUT, 6, _buff);
  *_GyroX = (int16_t)(((_buff[0] << 8) | _buff[1]));
  *_GyroY = (int16_t)(((_buff[2] << 8) | _buff[3])); 
  *_GyroZ = (int16_t)(((_buff[4] << 8) | _buff[5]));
}

and now also works the gyroscope but if I try to run the freeIMU library it still doesn't work. I don't think I will use the library
 
Hi.

I have been using and extending the capabilities of the FreeIMU library for quite awhile now and just finished hooking up a Teensy 3.1 with a Invensense 9250 breakout board. Works great with the Teensy. Been using a mega 2560 for most of the development but I am running into an issue that is more of a compiler issue between the arm and the avr. Specifically it is with the 'constexpr' constructor. Work fine when compiling on the Teensy 3.1 but with the arduino boards have to change it to 'const' and the 3.1 doesn't like when I use 'const'. Below is a portion of the code:

#ifndef __FILTER_BUTTER_H__
#define __FILTER_BUTTER_H__

//#include <AP_HAL.h>

template <typename Coefficients>
class Butter2
{
public:
float filter(float input)
{
float newhist = input + Coefficients::A1*hist[1] + Coefficients::A2*hist[0];
float ret = (newhist + 2*hist[1] + hist[0])/Coefficients::GAIN;
hist[0] = hist[1]; hist[1] = newhist;
return ret;
}
private:
float hist[2];
};

struct butter100_025_coeffs
{
static constexpr float A1 = 1.9777864838f;
static constexpr float A2 = -0.9780305085f;
static constexpr float GAIN = 1.639178228e+04f;
};

I will be testing the 3.1 with the a couple of other sensors (DFROBOT, Sparkfun 10724, Altimu-10, Generic 6050 and 9150 as well as the Freeimu board) I have to see how it works and what library changes I have to make. So far only tested it tonight with the 9250. At least it looks like it is working except for the issue above. Any help would be appreciated.

Thanks
Mike
 
Good day Mike,

A good way to think of "const" and "static" is with reference to the object that is being declared.

In C++ especially, declaration is "assignment of space" where definition is "establish structure/shape/semantic-rules". The difference between the two concepts becomes important with respect to "static" and "const" modifiers.

Inside a class or structure definition, using "const" sets rules on whether the data members may be modified, and "static" tells the compiler that the member is class-wide rather than instance-specific.

The code fragment defines a structure called butter100_025_coeffs. Using "static" in the structure definition is rarely what one needs. If it were me, I would build a structure whose contents are never intended for modification (for instance being assigned to flash rather than RAM in an embedded device) by using "static const" in the declaration. In the code below, the compiler complains about the line in main() that tries to modify the contents of the structure.

Code:
typedef struct
{
    float A1;
    float A2;
} Coeffs;

static const Coeffs myCoeffs =
{
    .A1 = -0.993,
    .A2 = 1.044
};

int main(int argc, char** argv)
{
    printf("coeff A1 is %.3f, A2 is %.3f\n", myCoeffs.A1, myCoeffs.A2);
    myCoeffs.A1 = 33.5;
    return 0;
}

Code:
$ g++ -o /tmp/cppe /tmp/cppe.cc
/tmp/cppe.cc: In function ‘int main(int, char**)’:
/tmp/cppe.cc:18:17: error: assignment of member ‘Coeffs::A1’ in read-only object
     myCoeffs.A1 = 33.5;

<<<commenting out the assignment and trying again>>>

$ g++ -o /tmp/cppe /tmp/cppe.cc
$ /tmp/cppe
coeff A1 is -0.993, A2 is 1.044
$

The bottom line is that the declaration of myCoeffs places the data in a non-writeable place.

The topics of definition, declaration, static, const and other stuff could involve weeks of study...
 
Good Afternoon Len

Thanks for getting back to me so quickly. Your explanation is probably the best on using static and const that I have seen. The code snippet is actually from a library that I modified for use with the FreeIMU that is used in the Ardupilot software. In the actual implementation the A1, A2 etc., change depending on the butterworth filter selected. But you have given me a possible solution on how to modify the library so i can use it across multple controllers.

Another question I do have is in searching for an answer before I posted, is there a off chance that the issue may be compiler dependent within the ide itself for the board selected. From what i was reading if gcc ++11 is used then constexpr works but if gcc ++0.x is used only const is supported. Just curious on how things work - and its driving me crazy. But like I said think your recommendation may be the key.

Thanks
Mike
 
I welcome an opportunity to help, but my knowledge is more from a generic workstation/server perspective. The earliest g++ that I worked with is 2.93, and the current one is 4.9. So I can't offer much wisdom W.R.T. (what appear to be semi-custom) compilers for the embedded bare metal devices. In yet another admission... I haven't done any heavy lifting in C++ since 2007. :)
 
Note, in the Arduino world, the AVR compiler is stuck in time at 4.3.2 (released August 27, 2008). The last 4.3 release was 4.3.6 in June 27, 2011. GCC 4.9.0 was released in April 22, 2014, GCC 4.8.3 was released in May 22, 2014, and the final 4.7 release was made on June 12th, 2014. GCC 4.9 had quite a bit of C++ 11 support in it. So forget about any recent (and many older) C++ features for AVR processors.
 
Len - Michael

Thanks for all your help. I'm not a heavy c++ programmer, my main experience has been with Fortran, many, many years ago, learning c++ as I go.

I dislike having to have separate code that appears dependent on whether the compiler used in the IDE has been updated or not. It seems to me that the folks in the Arduino world need to get the compiler updated. Would save alot of work arounds. Think I can make due with Len's solution, will try it over the next couple of days. Going to have to find the common denominator to make it work across the platforms that I am playing with (Uno, Mega, Due, Galileo, Teensy 3.1). So far this is the only one that seems to be an issue but I haven't tested all the libraries with the IMUs for compatibility.

Thanks again for all the help.
Mike
 
Len

Tried your approach and it would work but it required a lot of rework to the library so I took the lazy man's way out. I am attaching the code segment just for info.

Code:
struct butter100_025_coeffs
{
	#if(__AVR__)
		static const float A1 = 1.9777864838f;
		static const float A2 = -0.9780305085f;
		static const float GAIN = 1.639178228e+04f;	
	#else
		static constexpr float A1 = 1.9777864838f;
		static constexpr float A2 = -0.9780305085f;
		static constexpr float GAIN = 1.639178228e+04f;
   #endif
};

Thanks again for the help.
Mike
 
Thanks Paul will make the changes as you suggest.

Just ran into another problem that you all may be able to help with. Everything in the FreeIMU serial sketch seems to be working (at least appears to be) but when I try to run Fabio's calibration GUI with the Teensy I run into problems. I am not sure if its with Python and or with the writeArr function that Fabio was using. It looks like the function is getting the right values but when I look at the acc and magn files the data is out of order and incorrect based on what is being passed. I am still a novice at c++ so it would take me a while to sort out, so any pointers would be appreciated.

From looking at zrcommerce github it appears there is still some interest in the freeimu library so i wondering if anyone has run into this problem. Wish Fabio was still with us. His library is fantastic and I have learned a lot using it.

I have not posted the changes to github (mjs513/freeimu-updates) as a result of using the Teensy and the Galileo yet as I still have a few bugs that I want to work out and testing with other boards.

thanks in advance
Mike
 
Hi All,

Figure out a solution to the problem I just described. Python is looking for int16 or 2bytes and the current code in the sketch is defaulting to int32 or 4 bytes. Couldn't figure out how to fix Python so I wound up declaring raw_values as int16_t and changing the sizeof(int) to sizeof(int16_t). I also had to change FreeIMU.h and FreeIMU.cpp references to raw_values (int * raw_values to int16_t). Now all works with the Teensy, at least with the MPU-9250 breakout board still have to test a couple of other boards in case I broke anything along the way.

Thanks
Mike
 
Status
Not open for further replies.
Back
Top