Arduino & Capteur de pression MPL115A1
Répondre à la discussion
Affichage des résultats 1 à 12 sur 12

Arduino & Capteur de pression MPL115A1



  1. #1
    invitead51e543

    Arduino & Capteur de pression MPL115A1


    ------

    Bonjour à tous,

    Étant en train de découvrir l'Arduino, j'ai suivit différents tutoriels pour l'apprentissage (connaissant le C, ça aide).

    Je suis en train d'essayer de mettre en œuvre un capteur de pression (MPL115A1) ; j'ai trouvé le code sur internet, mais le but est de réussir à comprendre ce code pour pouvoir le mettre à ma sauce, et essayer de le simplifier pour comprendre chaque ligne.

    Est ce quelqu'un a déjà travaillé avec ce capteur, histoire de m'aider à y voir plus clair, surtout au niveau de la configuration des registres et des conversions?

    Merci d'avance.

    -----

  2. #2
    invite1d577638

    Re : Arduino & Capteur de pression MPL115A1

    Salut,

    Donne nous la datasheet histoire qu'on t'explique. (le code aussi !)

    Selon le type de protocole d'échange entre le capteur et la arduino (ou un autre µc) tu utilises les bibliothèques qui vont bien. Ensuite, la datasheet du capteur va t'aider à savoir quelles sont les données envoyées, dans quel ordre, s'il y a des bits de contrôle... SPI, I2c, et j'en passe...

  3. #3
    invitead51e543

    Re : Arduino & Capteur de pression MPL115A1

    Datasheet du capteur et code en pièce jointe.
    Fichiers attachés Fichiers attachés

  4. #4
    invitead51e543

    Re : Arduino & Capteur de pression MPL115A1

    Le protocole utilisé est le SPI, ce que je ne comprend pas trop, c'est les #define des registres, les valeurs ne correspondent pas avec ceux qu'il y a dans la datasheet du composant. Comment configurer ces registres?

  5. A voir en vidéo sur Futura
  6. #5
    JPL
    Responsable des forums

    Re : Arduino & Capteur de pression MPL115A1

    Cela aurait été mieux si tu avais intégré le programme dans le message avec la balise Code (# dans la barre d'outils du mode avancé).
    Rien ne sert de penser, il faut réfléchir avant - Pierre Dac

  7. #6
    invitead51e543

    Re : Arduino & Capteur de pression MPL115A1

    Pas de soucis

    Code:
    /*
     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 8
    #define MPL115A1_SELECT_PIN 9
    
    // 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(NWS_BARO, 2);
        Serial.println("Mesure de temperature et de pression atmospherique");
    }
    
    
    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(1000);
    }
    
    
    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);
    }

  8. #7
    invite1d577638

    Re : Arduino & Capteur de pression MPL115A1

    Quels sont les registres qui te posent problème ? Ceux-là semblent nickel :

    Code:
    // 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

  9. #8
    invitead51e543

    Re : Arduino & Capteur de pression MPL115A1

    Justement entre ces registres et ceux présents dans la datasheet :

    Code:
    0x00 Padc_MSB 10-bit Pressure ADC output value MSB
    0x01 Padc_LSB 10-bit Pressure ADC output value LSB
    0x02 Tadc_MSB 10-bit Temperature ADC output value MSB
    0x03 Tacd_LSB 10-bit Temperature ADC output value LSB
    0x04 a0_MSB a0 coefficient MSB 
    0x05 a0_LSB a0 coefficient LSB
    0x06 b1_MSB b1 coefficient MSB
    0x07 b1_LSB b1 coefficient LSB
    0x08 b2_MSB b2 coefficient MSB
    0x09 b2_LSB b2 coefficient LSB
    0x0A c12_MSB c12 coefficient MSB
    0x0B c12_LSB c12 coefficient LSB
    0x0C Reserved* —
    0x0D Reserved* —
    0x0E Reserved* —
    0x0F Reserved* —
    0x10 Reserved —
    0x11 Reserved —
    0x12 CONVERT Start Pressure and Temperature Conversion
    Pourquoi ce ne sont pas les mêmes valeurs?

  10. #9
    invite1d577638

    Re : Arduino & Capteur de pression MPL115A1

    Effectivement, je n'avais pas regardé les adresses.... Étrange !

    Le code fonctionne ?

  11. #10
    invitead51e543

    Re : Arduino & Capteur de pression MPL115A1

    Oui, c'est bien ça le problème!!!

  12. #11
    invite1d577638

    Re : Arduino & Capteur de pression MPL115A1

    Bin désolé, là pour le coup je ne vois pas....

  13. #12
    invitead51e543

    Re : Arduino & Capteur de pression MPL115A1

    Re,
    Effectivement, ce point me pose un problème.

    Après au niveau du setup et du loop, pas de problème.

    Ensuite, je ne n'ai pas tout compris dans la fonction qui permet de calculer la pression ; ou aller chercher toutes ces infos (décalage de bits, ...)?

    Bonne journée à tous!!!

Discussions similaires

  1. Capteur PIR + arduino
    Par invitef1ca4b7e dans le forum Électronique
    Réponses: 5
    Dernier message: 29/04/2014, 09h14
  2. capteur et arduino
    Par invite1c27b92a dans le forum Technologies
    Réponses: 3
    Dernier message: 04/03/2014, 10h22
  3. arduino et matrice de capteur de pression
    Par art17 dans le forum Électronique
    Réponses: 7
    Dernier message: 16/05/2013, 07h42
  4. Capteur de distance sur Arduino UNO
    Par kincurt dans le forum Technologies
    Réponses: 6
    Dernier message: 14/10/2012, 18h55
  5. Capteur à ultrasons + Arduino ADC
    Par inviteacc86bf5 dans le forum Électronique
    Réponses: 8
    Dernier message: 17/02/2011, 18h53
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...