Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: Teensy Prop Shield Increasing IMU Data Rate

  1. #1
    Junior Member
    Join Date
    Aug 2021
    Posts
    4

    Teensy Prop Shield Increasing IMU Data Rate

    Hello,

    I'm working on a project with the Teensy Prop Shield (which is awesome by the way) and I'm running into trouble with increasing the IMU sensors output rate from 100 Hz to 200 Hz. I think the problem is related to the fact that there are two sensors on the I2C bus that I'm trying to read near-simultaneously. Let me explain:

    First, the datasheets for the FXOS8700CQ and FXAS21002 have a table in their CTRL_REG_01 section that explains what binary values correspond to what data rates. I changed the gyro from 0x0E to 0x0D and the accel/mag from 0x15 to 0x0D.

    Now, when I try to read each one individually, I get a data rate of just over 5 ms. However, when I read both together (the same way the library normally does it--literally the only change I've made is those hex values) the data rate collapses to every 10 ms. Clearly there is something about I2C I do not understand, but I am struggling to find resources online. Any help would be much appreciated!

    For reference, I've attached the version of the NXPMotionSense library I made the changes in. Literally two lines of code are changed, but whatever.

    PS: I've also tried an iterative version, where it reads one sensor repeatedly until it gets a value, then it reads the other sensor. This gets my data rate down to 5.4 ms, but it doesn't scale if, for example, I add another I2C device. This makes me thing I'm doing something wrong with I2C in general.

    NXPMotionSense.zip

  2. #2
    Senior Member
    Join Date
    Dec 2016
    Location
    Wales
    Posts
    122
    Hi Lopenguin,

    Welcome to the forum. If you could post your top-level code
    Code:
    int wrappedInTagsLikeThis;
    that would help. Look for the hash symbol at the top to get the tags. I presume you're using one of the examples in that library, but it would be easier if you posted so people don't have to download and figure out which one.

  3. #3
    Junior Member
    Join Date
    Aug 2021
    Posts
    4
    Makes sense. Here are the highlights:

    First, the changes to the library:
    Code:
    bool NXPMotionSense::FXOS8700_begin()
    {
    	const uint8_t i2c_addr=FXOS8700_I2C_ADDR0;
    	uint8_t b;
    
    	//Serial.println("FXOS8700_begin");
    	// detect if chip is present
    	if (!read_regs(i2c_addr, FXOS8700_WHO_AM_I, &b, 1)) return false;
    	//Serial.printf("FXOS8700 ID = %02X\n", b);
    	if (b != 0xC7) return false;
    	// place into standby mode
    	if (!write_reg(i2c_addr, FXOS8700_CTRL_REG1, 0)) return false;
    	// configure magnetometer
    	if (!write_reg(i2c_addr, FXOS8700_M_CTRL_REG1, 0x1F)) return false;
    	if (!write_reg(i2c_addr, FXOS8700_M_CTRL_REG2, 0x20)) return false;
    	// configure accelerometer
    	if (!write_reg(i2c_addr, FXOS8700_XYZ_DATA_CFG, 0x01)) return false; // 4G range
    	if (!write_reg(i2c_addr, FXOS8700_CTRL_REG2, 0x02)) return false; // hires
    	if (!write_reg(i2c_addr, FXOS8700_CTRL_REG1, 0x0D)) return false; // 100Hz A+M (changed from 0x15 to 0x0D to increase to 200  Hz)
    	//Serial.println("FXOS8700 Configured");
    	return true;
    }
    Very simple: I changed the CTRL_REG1 from 0x15 to 0x0D, which does in fact double the data rate of the sensor. I did something similar to the
    Code:
    NXPMotionSense::FXAS21002_begin()
    function.

    The top-level code is just the main example for this library: "Orientation.ino". Biggest issue is (I think) that I just don't understand how I2C timing works well enough. In leiu of an answer, links to good resources would be much appreciated (Google is of surprisingly little help).

    Thanks!

  4. #4
    Senior Member
    Join Date
    Dec 2016
    Location
    Wales
    Posts
    122
    Code:
    filter.begin(100);
    tells the filter function that you're update is 100Hz, so maybe you need to change this.

    https://www.circuitbasics.com/basics...tion-protocol/
    is a sensible intro to i2c.

    inside the NXPMotionSense.cpp
    Code:
    Wire.setClock(400000);
    sets the I2C clock to 400k, which is plenty fast enough to run the two devices simultaneously. If you're finding they work individually with 5ms update rates, but not together, I'd suspect it's a code issue. It's also worth noting the
    Code:
    Serial.begin(9600) ;
    is actually a pretty slow serial, and not fast enough to print your data. If you consider that you're sending a bunch of data every 5ms, if your total message length is greater than 9600/200 = 48 characters or bytes, then the serial won't be able to keep up.

  5. #5
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    416
    Code:
    Serial.begin(9600) ;
    is actually a pretty slow serial, and not fast enough to print your data. If you consider that you're sending a bunch of data every 5ms, if your total message length is greater than 9600/200 = 48 characters or bytes, then the serial won't be able to keep up.
    The "9600" has NO EFFECT upon USB Serial speed.

  6. #6
    Junior Member
    Join Date
    Aug 2021
    Posts
    4
    Thanks for the reply. I agree that it is likely something more subtle than the Wire speed, and I've tried changing the filter rate (the filter class is separate from the IMU class, so it can even be completely omitted). I'll check out that resource you sent. and see what I can do.

    Thanks!

  7. #7
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,555
    You might what to look at this implementation of the propsheild IMU: https://github.com/kriswiner/Teensy_Prop_Shield to give you ideas.

    Edit:
    If you look in the file NXPMotionSense.h file you will see where the sample rate is set. If you want a different rate you can change it here. Of course make sure you configure your sensors for the correct sampleRates.

    Code:
    class NXPSensorFusion {
    public:
    	void begin(float sampleRate=100.0f);

  8. #8
    Junior Member
    Join Date
    Aug 2021
    Posts
    4
    Wow, thanks so much mjs513! That implementation really has all the details that go with setting up the data rate. I will sift through it today but I suspect it has all the answers I'm looking for.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •