Teensy 3.2 w/ Prop Shield - Pressure Sensor causing sketch to run very slow...

Status
Not open for further replies.

mikeleslie

Active member
I have a Teensy 3.2 and a protoshield and I'm having an issue: When I use the MPL3115 the reads are very slow, either 958 or 969ms.

I've tried the other sensors and they run great, I even have attached a dotstar and it's all good, but the pressure sensor is slow.
I usually use the BMP085 which has no problem at 50x this rate.

I'm using the Adafruit_MPL3115A2 library. Any thoughts?
Code:
#include <SPI.h>     
#include <Adafruit_MPL3115A2.h>
Adafruit_MPL3115A2 baro = Adafruit_MPL3115A2();
unsigned long time;
unsigned long oldtime;

void setup() 
{
 baro.begin();
}

void loop() {
  float pascals = baro.getPressure();
  Serial.print(pascals/3377); Serial.print(" Inches (Hg) Read Time is: "); 
  time=millis();
  Serial.println(time-oldtime);
  oldtime = time;
  }
 
The pressure sensor is slow. It simply doesn't produce a lot of readings per second.

You need a library which tells you whether it's made a new measurement, so your code can go on doing other stuff. Sadly, Adafruit's library doesn't offer this. You could hack their library (their code is very simple), or you could use NXPMotionSense (which I wrote).
 
The pressure sensor is slow. It simply doesn't produce a lot of readings per second.

You need a library which tells you whether it's made a new measurement, so your code can go on doing other stuff. Sadly, Adafruit's library doesn't offer this. You could hack their library (their code is very simple), or you could use NXPMotionSense (which I wrote).

Could someone help me out with a line of code demonstrating how to get the pressure sensor data from the MPL3115 on the prop shield ? Thanks in adv
 
I was hoping to use the NXPmotionsense, like Paul suggest. So i am looking for that line of code providing altitude or pressure as easily as it provides roll, pitch and heading.
 
Still hoping for some help here - Its probably not at all difficult - Just me being newbie here :)

I just want to get the pressure reading from the Propshield (using the NXPMotionSense library that is) ? anyone, pleease

-I already have everything wired up and reading roll, pitch and heading super fast..
 
In the kriswiner github URL in post #6, it runs the MPL3115A at 1 Hz (just as NXPMotionSense does). At one time, I modified the kriswiner code to configure the MPL3115A with oversampling of 1 and polling of status reg with one-shot option, and new pressure/temperature data was available every 6 ms. With max oversamples (128), data is available after 373 ms. With kris's code as a model and with the MPL3115A datasheet, you should be able to modify the NPXMotionSense lib and determine if it is "not at all difficult". ;)
 
Last edited:
@manitou - @stiganielsen

Just took a look at the lib and a little funny. In the NXPMotionSense.h it has the pressure and altitude read call as private and I don't see any way you can get it out. You would have to move this line to the public section of the class from the private, or am I missing something?

Code:
	bool MPL3115_read(int32_t *altitude, int16_t *temperature);
Not sure why I never noticed it before. Its about line 96. Then you can call it like you would to read the motion sensor I think.

If you want to make other changes then you would need to read the MPL3115 datasheet and make the changes in the library as you stated and Kris's code is a good place to start.
 
I think the structure of the NXPMotionSense lib is such that the private functions/variables are accessed via variations of public readMotionSensor(...). So you would add additional public variations to fetch temperature and altitude data(pressure option would have to be developed).
 
@manitou

Yep. Looking at it a little more closely the function I referenced returns the raw temperature so some conversion would have to be done.

Well guess I will put it on my short list of things to do, think I may have it already shouldn't be too difficult. Probably work it and try it tomorrow.
 
@manitou

Pretty much copied over Kris's MPL stuff into the nxpmotionsens library but getting very strange altitude readings. Not sure if its my mpl3115 or something in the library. The updated library is: https://github.com/mjs513/NXPMotionSense

It does a toggleoneshot to get the data. The press and temp readings match what I get out of the Sparkfun library, but the altitude for both libs are are 30K and 96K meters respectively. Note I am only about 18meters above sea level here.

To print the data just call imu.altitude, imu.pressure, imu.temperature.
 
You may need to calibrate altimeter, so sensor knows that current elevation is x feet with current barometric pressure -- what one does in an airplane before taking off. my tests with kris's propshield1 lib and with sparkfun lib seem to give about same values for pressure and altitude (300 m ish)
 
Thanks for info. I know the Sparkfun lib has a baro calibration function that I may add to the Paul's lib.
 
Thanks for info. I know the Sparkfun lib has a baro calibration function that I may add to the Paul's lib.

Sounds pretty invasive. I experimented in the other direction. Just enabling the print's in NXPMotionSense MPL3115_read() and also printing tempc and meters from these calculations
Code:
    float tempc = buf[4] + ((buf[5]>>4)/16.);
    float meters = (buf[1] << 8) + buf[2] + ((buf[3]>>4)/16.);
The temperature and meters printed agrees with Sparkfun lib. Tested with example CalibrateSensors.

Of course, Paul's sensor is configured for max oversampling (MPL3115_begin()) and is not using one-shot. In fact MPL3115_read() enforces a delay of 980 ms. The OP was wanting faster sampling, so one would have to disable oversampling and alter the enforced delay, and add public functions to convert raw data to float.
 
Last edited:
@manitou

Spent the day playing around with just the MPL3115 and getting familiar with it as well as looking at the datasheet :) - I hate datasheets - they always talk in code :)

Anyway as a start I went back to the original NXPMotionsense code base - added in 3 functions:
1. set sea level pressure (and before you ask: https://aviationweather.gov/metar, use closest airport);
2. toggleOneShot for the pressure
3. readPressure which has to switch between altimeter and barometer modes. The switch does cause a delay.

I did see in the code where Paul has hard coded the delay of 980ms as well as using 512ms oversampling. Not sure 512ms oversampling is really needed - haven't played with it yet.

Also, I am now returning temp in degC, pressure in mb's and altitude in meters. So that piece is covered.

After I did all this I am now getting good readings for all 3 values comparable to other pressure sensors I used in the past. I did update my GitHub fork with the way it stands now. The sketch I am using to test is a simple mod of the orientation sketch:
Code:
// Full orientation sensing using NXP's advanced sensor fusion algorithm.
//
// You *must* perform a magnetic calibration before this code will work.
//
// To view this data, use the Arduino Serial Monitor to watch the
// scrolling angles, or run the OrientationVisualiser example in Processing.

#include <NXPMotionSense.h>
#include <Wire.h>
#include <EEPROM.h>

NXPMotionSense imu;
NXPSensorFusion filter;

void setup() {
  Serial.begin(9600);
  imu.begin();
  filter.begin(100);

  //sets local sea level pressure
  //you can get this from your closest airport from
  //     https://aviationweather.gov/metar
  imu.setSeaPressure(102100);
}

void loop() {
  float ax, ay, az;
  float gx, gy, gz;
  float mx, my, mz;
  float roll, pitch, heading;

  if (imu.available()) {
    // Read the motion sensors
    imu.readMotionSensor(ax, ay, az, gx, gy, gz, mx, my, mz);

    // Update the SensorFusion filter
    filter.update(gx, gy, gz, ax, ay, az, mx, my, mz);

    // print the heading, pitch and roll
    roll = filter.getRoll();
    pitch = filter.getPitch();
    heading = filter.getYaw();
    Serial.print("Orientation: ");
    Serial.print(heading);
    Serial.print(" ");
    Serial.print(pitch);
    Serial.print(" ");
    Serial.println(roll);
    if(imu.altimeter_rdy == 1){
      //reading pressure causes a noticable delay as a result of
      //switching between altimeter and barometer modes of the
      //MPL3115.
      //imu.readPressure();
      Serial.printf("Alt: %f, TempC: %f, Press: %f\n", imu.altitudeM, imu.temperatureC, imu.pressure);
      imu.altimeter_rdy = 0;  //after MPL3115 is read you need to reset data rdy
    }
  }
}

Now to get some coffee and breakfast then back to work on expanding this and see if I can get better performance.
 
UPDATE:
Switched to OneShot mode for altitude and temperature as well. Changed Oversample to 32ms, while 6ms is nice needs some OS. Now the temp/press/alt is updating at the same rate as the orientation and relatively smooth.

If someone can give it a try with example sketch above and let me know what they think. If ok I will clean up and use function calls to MPL data.

Test sources: https://github.com/mjs513/NXPMotionSense
 
Good work. (Nice of you to write the code for the OP) I ran your sketch with your lib and set pressure from my local airport. Temperature and altitude looked good. experimented with oversampling. For altitude (meters) :
Code:
oversamples  RMSE  max-min  sampletime (ms)
    1       1.529   9.8          6
   32       0.288   1.6         95
  128       0.198   1.1        373
 
Last edited:
Good work. (Nice of you to write the code for the OP) I ran your sketch with your lib and set pressure from my local airport. Temperature and altitude looked good. experimented with oversampling. For altitude (meters) :
Code:
oversamples  RMSE  max-min  sampletime (ms)
    1       1.529   9.8          6
   32       0.288   1.6         95
  128       0.198   1.1        373

Thanks for trying it out for me. It was working for me but just wanted to make sure. Going to clean up the library.

Going to clean up the code and debating whether to make Altitude callable or just pressure. Probably will make both callable. Going to leave initial setup to default to altimeter mode though and remove the auto call to MPL3115_read and just let the user call it when needed.

Hopefully @Paul will accept the changes.
 
Status
Not open for further replies.
Back
Top