Arduino code for the MPL115A1 Pressure Sensor (SPI)

Your source for all things Atmel.

Moderator: phalanx

stupsi99
Posts: 1
Joined: Sun Apr 07, 2013 2:22 am

Re: Arduino code for the MPL115A1 Pressure Sensor (SPI)

Post by stupsi99 » Sun Apr 07, 2013 2:28 am

Hi Everyone,

is there a way to get miah's code from the first post? Still existing anywhere? :)

Thanks a lot!

-Phil

ekatzenstein
Posts: 3
Joined: Fri Aug 16, 2013 9:33 am

Re: Arduino code for the MPL115A1 Pressure Sensor (SPI)

Post by ekatzenstein » Fri Aug 16, 2013 9:34 am

The link at the top is no longer working. Could someone please post an update? This seems to be the only shot I have at documentation for this device.

jremington
Support Volunteer
Posts: 2148
Joined: Fri Jun 15, 2007 9:41 pm
Location: Eugene, Or

Re: Arduino code for the MPL115A1 Pressure Sensor (SPI)

Post by jremington » Fri Aug 16, 2013 9:15 pm

Do you mean the chip data sheet? It is still available at http://www.freescale.com/files/sensors/ ... L115A1.pdf

ekatzenstein
Posts: 3
Joined: Fri Aug 16, 2013 9:33 am

Re: Arduino code for the MPL115A1 Pressure Sensor (SPI)

Post by ekatzenstein » Mon Aug 19, 2013 10:25 am

I was referring to this link at the very beginning of the discussion: http://www.miah.com/files/ArdMPL115A1.zip

Apparently this was a sample sketch for reading values from the sensor.

ekatzenstein
Posts: 3
Joined: Fri Aug 16, 2013 9:33 am

Re: Arduino code for the MPL115A1 Pressure Sensor (SPI)

Post by ekatzenstein » Thu Aug 22, 2013 11:38 am

Alright, so this page:

http://bugariu-catalin.com/laboratory/p ... ation.html

Led me to this page:

http://robofun.ro/docs/ArdMPL115A1.pde

Both were very helpful.

pavi017
Posts: 2
Joined: Wed Nov 20, 2013 1:54 am

Re: Arduino code for the MPL115A1 Pressure Sensor (SPI)

Post by pavi017 » Wed Nov 20, 2013 2:02 am

hey am not sure how it is different to write code from arduino to atmega16 but i am connecting this same sensor to an atmega16 and am not sure how to write the code for it to receive the temp and pressure values and display it through USART.

Code: Select all

#define Waitfor1(register, BIT) while(!(register & (1<<BIT)));
#define Waitfor0(register, BIT) while((register & (1<<BIT)));
void mastermode()
{
DDRB = DDRB | ob10110000; \\ this sets the sck mosi and ss as outputs
DDRB = DDRB & ob10111111; \\ this sets miso as output
SPCR |=(1<<MSTR); \\ set as master
SPCR | = (1<<SPR0)|(1<<SPR1); \\ clock divided by 128
SPCR | = (1<<SPE);
} 
char RecieveByte()
{   Waitfor1(SPSR, SPIF);
    return SPDR;
}

 Void SendByte (char byte, int slavenumber)
{   PORTB = PORTB & ob1110111;
    SPDR = byte;
    Waitfor1(SPSR, SPIF);
} 
these codes initialize spi for the atmega16 as the master. and the sendbyte and recieve byte help getting information from the spi connected sensor.
I would like to know how to get the values for the tempHigh, tempLOW, pressureHIGH, pressureLOW from its respective memory locations of the sensor which are 0x80, 0x82, 0x84, 0x86. After geting these readings how do i convert them into one value.
Ayone can help me with this

miah
Posts: 4
Joined: Thu Sep 30, 2010 8:33 pm

Re: Arduino code for the MPL115A1 Pressure Sensor (SPI)

Post by miah » Thu Dec 26, 2013 12:50 pm

I changed hosting providers a while back, so the link is now dead. Here's a new url for the zip file.

ArdMPL115A1.zip - http://ubuntuone.com/2lM3CUGghDDERGbtMYAl2S

dcs
Posts: 2
Joined: Wed Feb 26, 2014 5:32 pm

Re: Arduino code for the MPL115A1 Pressure Sensor (SPI)

Post by dcs » Wed Feb 26, 2014 5:35 pm

This sounds like just what I need. But where is the sketch?

dcs
Posts: 2
Joined: Wed Feb 26, 2014 5:32 pm

Re: Arduino code for the MPL115A1 Pressure Sensor (SPI)

Post by dcs » Wed Feb 26, 2014 5:40 pm

Never mind. I found a link to it further into the posts.

dwkennedy
Posts: 1
Joined: Sun Mar 30, 2014 11:30 pm

Re: Arduino code for the MPL115A1 Pressure Sensor (SPI)

Post by dwkennedy » Sun Mar 30, 2014 11:44 pm

The information listed under "resolution" for the temperature seems wrong, when converted to degrees C it reads much too low. The alternate figures given above (510 digital units@24C, -5.5 units per deg) also seem wrong.

Revision 6 and 7 of the data sheet totally remove reference to computing the actual temp from the 10 bit value. The formula to compensate the pressure uses temp in straight digital units.

I'm guessing freescale doesn't really intend this device to give the user a meaningful temperature?

The pressure is a little coarse for my application too. I want to be able to sense small changes in altitude, but 10 bits will only give about 20 ft. intervals, and the reading jumps around +/- 40 feet just sitting on the ground.

tytower
Posts: 3
Joined: Tue Nov 18, 2014 5:02 pm

Re: Arduino code for the MPL115A1 Pressure Sensor (SPI)

Post by tytower » Tue Nov 18, 2014 5:08 pm

I tend to agree with the previous poster. I attach here some arduino code that runs well on my 328P but gives silly temperature values. Its worth trying though . If you get a good temperature please post corrected code .
I have 50 of these bloody things to get gone

Code: Select all

/*
 MPL115A1 SPI Digital Barometer Test Code
 Created on: September 30, 2010
       By: Jeremiah McConnell - miah at miah.com
 Portions: Jim Lindblom - jim at sparkfun.com
 
 This is a simple test program for the MPL115A1 Pressure Sensor (SPI version).
 
 Hardware: ATmega168, ATmega328
 Powered at 3.3V or 5V, running at 8MHz or 16MHz.
 
 MPL115A1 Breakout ------------- Arduino
 -----------------               -------
         SDN ------------------- D9
         CSN ------------------- D10
         SDO ------------------- D12 *
         SDI ------------------- D11 *
         SCK ------------------- D13 *
         GND ------------------- GND
         VDD ------------------- VCC +
 
         * These pins physically connect to the SPI device so you can't change them
         + 5V board use 5V VDD, 3.3V board use 3.3V VDD
 
 License: CCAv3.0 Attribution-ShareAlike (http://creativecommons.org/licenses/by-sa/3.0/)
 You're free to use this code for any venture, but I'd love to hear about what you do with it,
 and any awesome changes you make to it. Attribution is greatly appreciated.
 */

// Includes
#include <SPI.h>

// Get your current altimiter setting from from the National
// Weather Service - http://www.weather.gov
// This value is often labeled "Barometer" or "Barometric Pressure" or just "Pressure"
#define NWS_BARO 29.92 

// Pin definitions
#define MPL115A1_ENABLE_PIN 9
#define MPL115A1_SELECT_PIN 10

// Masks for MPL115A1 SPI i/o
#define MPL115A1_READ_MASK  0x80
#define MPL115A1_WRITE_MASK 0x7F 

// MPL115A1 register address map
#define PRESH   0x00    // 80
#define PRESL   0x02    // 82
#define TEMPH   0x04    // 84
#define TEMPL   0x06    // 86

#define A0MSB   0x08    // 88
#define A0LSB   0x0A    // 8A
#define B1MSB   0x0C    // 8C
#define B1LSB   0x0E    // 8E
#define B2MSB   0x10    // 90
#define B2LSB   0x12    // 92
#define C12MSB  0x14    // 94
#define C12LSB  0x16    // 96
#define C11MSB  0x18    // 98
#define C11LSB  0x1A    // 9A
#define C22MSB  0x1C    // 9C
#define C22LSB  0x1E    // 9E

// Unit conversion macros
#define FT_TO_M(x) ((long)((x)*(0.3048)))
#define KPA_TO_INHG(x) ((x)*(0.295333727))
#define KPA_TO_MMHG(x) ((x)*(7.50061683))
#define KPA_TO_PSIA(x) ((x)*(0.145037738))
#define KPA_TO_KGCM2(x) ((x)*(0.0102))
#define INHG_TO_PSIA(x) ((x)*(0.49109778))
#define DEGC_TO_DEGF(x) ((x)*(9.0/5.0)+32)


void setup() {
    
    // initialize serial i/o
    Serial.begin(9600);
    
    // initialize SPI interface
    SPI.begin();
    
    // these are the defaults
    //SPI.setDataMode(SPI_MODE0);
    //SPI.setClockDivider(SPI_CLOCK_DIV4);  // MPL115A1 supports up to 8MHz
    //SPI.setBitOrder(MSBFIRST);
    
    // initialize the chip select and enable pins
    pinMode(MPL115A1_SELECT_PIN, OUTPUT);
    pinMode(MPL115A1_ENABLE_PIN, OUTPUT);
    
    // sleep the MPL115A1
    digitalWrite(MPL115A1_ENABLE_PIN, LOW);
    
    // set the chip select inactive, select signal is CS LOW
    digitalWrite(MPL115A1_SELECT_PIN, HIGH);
    
    // spam welcome banner
    Serial.print("\n************************************************************************************\n");
    Serial.print("* Using Altimiter Setting: ");
    Serial.print(NWS_BARO, 2);
    Serial.print(" in Hg                                             *\n");
    Serial.print("* Visit http://www.weather.gov for your current local value.                       *\n");
    Serial.print("************************************************************************************\n");
}


void loop() {
    
    float pressure_pKa = 0;
    float temperature_c= 0;
    long altitude_ft = 0;
    
    // wake the MPL115A1
    digitalWrite(MPL115A1_ENABLE_PIN, HIGH);
    delay(20);  // give the chip a few ms to wake up
    
    pressure_pKa = calculatePressurekPa();
    temperature_c = calculateTemperatureC();
    altitude_ft = calculateAltitudeFt(pressure_pKa);
    
    // put the MPL115A1 to sleep, it has this feature why not use it
    // while in shutdown the part draws ~1uA
    digitalWrite(MPL115A1_ENABLE_PIN, LOW);
    
    // print table of altitude, pressures, and temperatures to console
    Serial.print(altitude_ft);
    Serial.print(" ft | ");
    Serial.print(FT_TO_M(altitude_ft));
    Serial.print(" m | ");
    Serial.print(KPA_TO_INHG(pressure_pKa), 2);
    Serial.print(" in Hg | ");
    Serial.print(KPA_TO_MMHG(pressure_pKa), 0);
    Serial.print(" mm Hg | ");
    Serial.print(KPA_TO_PSIA(pressure_pKa), 2);
    Serial.print(" psia | ");
    //Serial.print(KPA_TO_KGCM2(pressure_pKa), 3);
    ///Serial.print(" kg/cm2 | ");
    Serial.print(pressure_pKa, 1);
    Serial.print(" kPa | ");
    
    // At a res of -5.35 counts/°C, digits lower than 0.1°C are not significant
    Serial.print(temperature_c, 1);
    Serial.print(" C | ");
    Serial.print(DEGC_TO_DEGF(temperature_c), 1);
    Serial.print(" F\n");
    
    // wait a few seconds before looping
    delay(5000);
}


long calculateAltitudeFt(float pressure_kPa) {
    
    float delta;
    long altitude_ft;
    
    
    // See http://en.wikipedia.org/wiki/Barometric_formula
    // If you're a pilot you need to know what's going on here,
    // otherwise just know these steps calculate the barometric altitude (ft)
    // based on the ratio of absolute barometric pressure (psia) to the
    // altimiter setting (psia).
    delta = KPA_TO_PSIA(pressure_kPa) / INHG_TO_PSIA( NWS_BARO );
    altitude_ft = (1 - pow(delta, (1 / 5.25587611))) / 0.0000068756;
    
    return altitude_ft;
}


float calculateTemperatureC() {
    
    unsigned int uiTadc;
    unsigned char uiTH, uiTL;
    
    unsigned int temperature_counts = 0;
    
    writeRegister(0x22, 0x00);  // Start temperature conversion
    delay(2);                   // Max wait time is 0.7ms, typ 0.6ms
    
    // Read pressure
    uiTH = readRegister(TEMPH);
    uiTL = readRegister(TEMPL);
    
    uiTadc = (unsigned int) uiTH << 8;
    uiTadc += (unsigned int) uiTL & 0x00FF;
    
    // Temperature is a 10bit value
    uiTadc = uiTadc >> 6;
    
    // -5.35 counts per °C, 472 counts is 25°C
    return 25 + (uiTadc - 472) / -5.35;
}


float calculatePressurekPa() {
    
    // See Freescale document AN3785 for detailed explanation
    // of this implementation.
    
    signed char sia0MSB, sia0LSB;
    signed char sib1MSB, sib1LSB;
    signed char sib2MSB, sib2LSB;
    signed char sic12MSB, sic12LSB;
    signed char sic11MSB, sic11LSB;
    signed char sic22MSB, sic22LSB;
    signed int sia0, sib1, sib2, sic12, sic11, sic22, siPcomp;
    float decPcomp;
    signed long lt1, lt2, lt3, si_c11x1, si_a11, si_c12x2;
    signed long si_a1, si_c22x2, si_a2, si_a1x1, si_y1, si_a2x2;
    unsigned int uiPadc, uiTadc;
    unsigned char uiPH, uiPL, uiTH, uiTL;
    
    writeRegister(0x24, 0x00);      // Start Both Conversions
    //writeRegister(0x20, 0x00);    // Start Pressure Conversion
    //writeRegister(0x22, 0x00);    // Start temperature conversion
    delay(2);                       // Max wait time is 1ms, typ 0.8ms
    
    // Read pressure
    uiPH = readRegister(PRESH);
    uiPL = readRegister(PRESL);
    uiTH = readRegister(TEMPH);
    uiTL = readRegister(TEMPL);
    
    uiPadc = (unsigned int) uiPH << 8;
    uiPadc += (unsigned int) uiPL & 0x00FF;
    uiTadc = (unsigned int) uiTH << 8;
    uiTadc += (unsigned int) uiTL & 0x00FF;
    
    // Placing Coefficients into 16-bit Variables
    // a0
    sia0MSB = readRegister(A0MSB);
    sia0LSB = readRegister(A0LSB);
    sia0 = (signed int) sia0MSB << 8;
    sia0 += (signed int) sia0LSB & 0x00FF;
    
    // b1
    sib1MSB = readRegister(B1MSB);
    sib1LSB = readRegister(B1LSB);
    sib1 = (signed int) sib1MSB << 8;
    sib1 += (signed int) sib1LSB & 0x00FF;
    
    // b2
    sib2MSB = readRegister(B2MSB);
    sib2LSB = readRegister(B2LSB);
    sib2 = (signed int) sib2MSB << 8;
    sib2 += (signed int) sib2LSB & 0x00FF;
    
    // c12
    sic12MSB = readRegister(C12MSB);
    sic12LSB = readRegister(C12LSB);
    sic12 = (signed int) sic12MSB << 8;
    sic12 += (signed int) sic12LSB & 0x00FF;
    
    // c11
    sic11MSB = readRegister(C11MSB);
    sic11LSB = readRegister(C11LSB);
    sic11 = (signed int) sic11MSB << 8;
    sic11 += (signed int) sic11LSB & 0x00FF;
    
    // c22
    sic22MSB = readRegister(C22MSB);
    sic22LSB = readRegister(C22LSB);
    sic22 = (signed int) sic22MSB << 8;
    sic22 += (signed int) sic22LSB & 0x00FF;
    
    // Coefficient 9 equation compensation
    uiPadc = uiPadc >> 6;
    uiTadc = uiTadc >> 6;
    
    // Step 1 c11x1 = c11 * Padc
    lt1 = (signed long) sic11;
    lt2 = (signed long) uiPadc;
    lt3 = lt1*lt2;
    si_c11x1 = (signed long) lt3;
    
    // Step 2 a11 = b1 + c11x1
    lt1 = ((signed long)sib1)<<14;
    lt2 = (signed long) si_c11x1;
    lt3 = lt1 + lt2;
    si_a11 = (signed long)(lt3>>14);
    
    // Step 3 c12x2 = c12 * Tadc
    lt1 = (signed long) sic12;
    lt2 = (signed long) uiTadc;
    lt3 = lt1*lt2;
    si_c12x2 = (signed long)lt3;
    
    // Step 4 a1 = a11 + c12x2
    lt1 = ((signed long)si_a11<<11);
    lt2 = (signed long)si_c12x2;
    lt3 = lt1 + lt2;
    si_a1 = (signed long) lt3>>11;
    
    // Step 5 c22x2 = c22*Tadc
    lt1 = (signed long)sic22;
    lt2 = (signed long)uiTadc;
    lt3 = lt1 * lt2;
    si_c22x2 = (signed long)(lt3);
    
    // Step 6 a2 = b2 + c22x2
    lt1 = ((signed long)sib2<<15);
    lt2 = ((signed long)si_c22x2>1);
    lt3 = lt1+lt2;
    si_a2 = ((signed long)lt3>>16);
    
    // Step 7 a1x1 = a1 * Padc
    lt1 = (signed long)si_a1;
    lt2 = (signed long)uiPadc;
    lt3 = lt1*lt2;
    si_a1x1 = (signed long)(lt3);
    
    // Step 8 y1 = a0 + a1x1
    lt1 = ((signed long)sia0<<10);
    lt2 = (signed long)si_a1x1;
    lt3 = lt1+lt2;
    si_y1 = ((signed long)lt3>>10);
    
    // Step 9 a2x2 = a2 * Tadc
    lt1 = (signed long)si_a2;
    lt2 = (signed long)uiTadc;
    lt3 = lt1*lt2;
    si_a2x2 = (signed long)(lt3);
    
    // Step 10 pComp = y1 + a2x2
    lt1 = ((signed long)si_y1<<10);
    lt2 = (signed long)si_a2x2;
    lt3 = lt1+lt2;
    
    // Fixed point result with rounding
    //siPcomp = ((signed int)lt3>>13);
    siPcomp = lt3/8192;
    
    // decPcomp is defined as a floating point number
    // Conversion to decimal value from 1023 ADC count value
    // ADC counts are 0 to 1023, pressure is 50 to 115kPa respectively
    decPcomp = ((65.0/1023.0)*siPcomp)+50;
    
    return decPcomp;
}


unsigned int readRegister(byte thisRegister) {
    
    byte result = 0;
    
    // select the MPL115A1
    digitalWrite(MPL115A1_SELECT_PIN, LOW);
    
    // send the request
    SPI.transfer(thisRegister | MPL115A1_READ_MASK);
    result = SPI.transfer(0x00);
    
    // deselect the MPL115A1
    digitalWrite(MPL115A1_SELECT_PIN, HIGH);
    
    return result;  
}


void writeRegister(byte thisRegister, byte thisValue) {
    
    // select the MPL115A1
    digitalWrite(MPL115A1_SELECT_PIN, LOW);
    
    // send the request
    SPI.transfer(thisRegister & MPL115A1_WRITE_MASK);
    SPI.transfer(thisValue);
    
    // deselect the MPL115A1
    digitalWrite(MPL115A1_SELECT_PIN, HIGH);
}

tytower
Posts: 3
Joined: Tue Nov 18, 2014 5:02 pm

Re: Arduino code for the MPL115A1 Pressure Sensor (SPI)

Post by tytower » Mon May 25, 2015 3:00 pm

Has anyone got these thing going?
I think they are a batch of duds passed off by Sparkfun

User avatar
Ross Robotics
Support Volunteer
Posts: 2007
Joined: Thu Jun 07, 2012 9:33 pm
Contact:

Re: Arduino code for the MPL115A1 Pressure Sensor (SPI)

Post by Ross Robotics » Tue May 26, 2015 8:30 am

And you if you did get some "duds," Sparkfun will replace them. But threatening Sparkfun is not a good way to get help.
------------------------------------------------------------------------------------------------------------------------------------------------------------
//codlink
Available for circuit and PCB design, just PM me!

Post Reply