Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 47

Thread: i2c Pressure Sensor Reading Help?

  1. #1

    i2c Pressure Sensor Reading Help?

    I have a pressure sensor by model, MS5525DSO made by TE. The datasheet can be found on https://www.te.com/usa-en/product-CA...p-tabs-content. Can someone please give me a step in the right direction, so I can start reading the sensor. I've tried digitalRead of the SDA pin and that just gives a returned 0. My i2c address is 0x76 HIGH or 0x77 LOW. Any advice is very useful and is much appreciated!

  2. #2
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    701
    You'll want to use the Wire library:
    https://www.arduino.cc/en/Reference/Wire

    If you search by the sensor name and "github arduino" you'll find some arduino drivers for the sensor. I've never used that sensor and I haven't reviewed the libraries, so I can't say whether they are good or not, but that's a general strategy for finding open-source sensor libraries.

  3. #3
    I've only found one library and the link is here: https://px4.github.io/Firmware-Doxyg...5525_8hpp.html I've never done this sort of thing. Do you think you could walk me through it once, so I and anyone else having problems learning about this can have a resource? I've looked up and down and I'm seriously struggling to understand all of this. Thanks for the info provided!

  4. #4
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    701
    I can't help with a walk through - I don't have the sensor to test a driver against and my work is very busy at the moment. Maybe someone else on the forum can help?

    I wouldn't use the library you found, that's for the PX4, rather then the Arduino. Here's what looks like an Arduino compatible library that came up when I searched:
    https://github.com/yubox-node-org/MS5525DSO-Arduino

    I would read through the code, read through the datasheet, and read the Arduino Wire API documentation to see if you can understand what's going on. Specific questions (i.e. why is XX line of code used?) are generally easier for people on the forum to answer.

  5. #5
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,721
    Which Teensy are you using?
    For most Teensys, you would normally connect SDA to pin 18 and SCL to pin 19. You will also need 3.3k pullup resistors on both SDA and SCL. Plus power and ground of course.
    Then run an I2c scanner to make sure that the Teensy can "see" the device. There is a scanner in the IDE at File|Examples|Wire|Scanner
    This should find and print the I2C address of your device.

    Pete

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,782
    First, run File > Examples > Wire > Scanner. This will test whether your device is responding and you can easily confirm what I2C address it uses. If the scanner doesn't detect your sensor, there is no point going any further. Get it working with the scanner first.


    Do you think you could walk me through it once, so I and anyone else having problems learning about this can have a resource?
    I'm going to make a quick attempt to walk you though using the Wire library, but first I want to be absolutely clear that many examples and projects and libraries use Wire to access devices very similar to this sensor. Plenty of resources already exist. I want to help you, but I also want to dis-spell any notion that resources are somehow lacking, so I'm going to show how a couple of the examples are modified to work...


    On the PJRC site, you can find this page for the Wire library.

    https://www.pjrc.com/teensy/td_libs_Wire.html

    Scroll down to "Example Program". The code I'm about to explain is from that page, so please if you haven't read the example on that page, do so now.


    Now, to apply that EEPROM example to this sensor, here the info from page 12 of the datasheet.

    Click image for larger version. 

Name:	screenshot.png 
Views:	20 
Size:	170.5 KB 
ID:	25215

    To send this sensor a command like Figure 13, you would use the same code as the EERPOM example, but you would transmit only 1 byte.

    Here is the EEPROM example code:

    Code:
      // set the 24C256 eeprom address to 0
      Wire.beginTransmission(80);
      Wire.write(0);  // address high byte
      Wire.write(0);  // address low byte
      Wire.endTransmission();
    To adapt this for your sensor, just replace the address with whatever address the Scanner example found (I'm going to guess it's 118 for the sake of this message). Then change the transmitted byte for the command you want to send, and delete the second write line since this sensor expects a 1 byte command rather than 2 bytes for the address of a 24C256 EEPROM. Also update the comments....

    Code:
      // send "initiate a pressure conversion" command
      Wire.beginTransmission(118);
      Wire.write(0x48);  // page 12 says "0 1 0 0 1 0 0 0"
      Wire.endTransmission();
    Hopefully you can see this is the same as the 24C256 EEPROM, only with the address and data byte changed.



    Likewise to read data from this sensor, you would use basically the same code as the example, but you want to read 3 bytes. Since the EEPROM example reads only 1 byte, I'm going to instead copy from File > Examples > Wire > master_reader. This example reads 8 bytes. Here is the example code:

    Code:
      Wire.requestFrom(8, 6);   // request 6 bytes from slave device #8
    
      while(Wire.available()) { // slave may send less than requested
        char c = Wire.read();   // receive a byte as character
        Serial.print(c);        // print the character
      }
    
      Serial.println();
    To adapt this for your sensor, change the address and request only 3 bytes. Also change the variable to "int" type, so the results print to the Arduino Serial Monitor as numbers rather than characters.

    Code:
      Wire.requestFrom(118, 3);   // request 3 bytes from pressure sensor
    
      while(Wire.available()) { // slave may send less than requested
        int n = Wire.read();   // receive a byte an integer
        Serial.print(n);        // print the number
      }
    
      Serial.println();

    Hopefully with this you can see how the examples for the Wire library and code on the web page are meant to help you.

  7. #7
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,426
    In addition to the walk through that @PaulStoffregen provided on using the wire library it becomes easier when you use a Arduino library for the sensor. As @brtaylor mention if you download and open the zip file from the link provided:
    https://github.com/yubox-node-org/MS5525DSO-Arduino

    There are three ways to install the library that you just downloaded:
    1. Using the Arduino IDE's library manager
    2. Installing from a zip file
    3. Manual install.

    A good resource is provided by DigiKey at https://www.digikey.com/en/maker/blo...uino-libraries that walks you through the process of installing a library. In your case I would use method 2, Installing from a zip file.

    To use the example file from the library next open the Arduino IDE, go to FILE->EXAMPLES and scroll down to the library that you just installed - in this case MS5525DSO-Arduino, select it and you should see the example. Select the example and the IDE will load the example. Then compile and upload to the your Teensy and try it out.

  8. #8
    Thanks guys for all of the advice! When I get to work on Monday I will attempt to try out the advice I've received THX!

  9. #9
    I tried using your requestFrom method to read the pressure, but I wasn't receiving anything. I decided to use that library mjs513 posted, but it's giving me a pressure of 140 and a temp of over 20k Celsius which obviously isn't right. How do I calibrate it?

  10. #10
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,426
    Quote Originally Posted by ATORTeensyMan View Post
    I tried using your requestFrom method to read the pressure, but I wasn't receiving anything. I decided to use that library mjs513 posted, but it's giving me a pressure of 140 and a temp of over 20k Celsius which obviously isn't right. How do I calibrate it?
    Unfortunately I don't have one of those press/temp sensors so not sure I can be of much more help. At this point you are probably going to have read the RM (https://www.te.com/commerce/Document...7FCAT-BLPS0003) and bounce it against the library or write your own using the methods that @Paul described

  11. #11
    Hmm. Man this shit is complicated. Looking at the library and datasheet would you be able to guide me on how to calibrate it? It's hard for me to understand reading it in c.

  12. #12
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,721
    Copy and paste all the output from the example code including the list of coefficients that are printed before it gets the temperature and pressure.

    Pete

  13. #13
    Quote Originally Posted by el_supremo View Post
    Copy and paste all the output from the example code including the list of coefficients that are printed before it gets the temperature and pressure.

    Pete
    INFO: pressure 141.1734 psi temperature 20341.150391 C
    C1 - Pressure Sensitivity : 15753
    C2 - Pressure Offset : 10568
    C3 - Temperature Coefficient of Pressure Sensitivity : 3763
    C4 - Temperature Coefficient of Pressure Offset : 2198
    C5 - Reference Temperature : 30081
    C6 - Temperature Coefficient of Temperature : 8434

    I've tried two other sensors and all three show different values for psi. I'm honestly completely lost at this point. I'm checking all of his equations in his library and I don't see the problem.

  14. #14
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,721
    Do you have pullups on SDA and SCL? If so, what value are they?
    It might help if you post a photo of the device and its connections to the Teensy.

    Pete

  15. #15

    Yes.

    Quote Originally Posted by el_supremo View Post
    Do you have pullups on SDA and SCL? If so, what value are they?
    It might help if you post a photo of the device and its connections to the Teensy.

    Pete
    Yes I have pull ups and i2c for the device works perfectly. I have no problem with the connectivity. I was just struggling to create the code

  16. #16
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,721
    I tested the library's calculation of temperature with the example values given in the PDF and it gets the correct answer. So, I suspect that your code must be getting incorrect values from the sensor (rather than the library getting it wrong). I note that the library does not do the CRC check described in the PDF and it would also be useful to know what PROM values have been read from the sensor.
    Can you add the code, below, to the MS5525DSO::_begin_common function in MS5525DSO.cpp immediately after the reset() statement:
    Code:
    #define MS5525_TEST
    #ifdef MS5525_TEST
      uint16_t temporary;
      Serial.printf("uint16_t nprom[8] = {");
      for (uint8_t i = 0; i <= 7; i++) {
        if(!_read_prom(i,&temporary)) success = false;
        Serial.printf("0x%04X\n, ",temporary);
      }
      Serial.println("};");
    #endif
    Then recompile and upload the example sketch again and copy and paste the entire output here.

    Pete

  17. #17
    Yes i will tomorrow. what exactly does this do?

  18. #18
    Quote Originally Posted by el_supremo View Post
    I tested the library's calculation of temperature with the example values given in the PDF and it gets the correct answer. So, I suspect that your code must be getting incorrect values from the sensor (rather than the library getting it wrong). I note that the library does not do the CRC check described in the PDF and it would also be useful to know what PROM values have been read from the sensor.
    Can you add the code, below, to the MS5525DSO::_begin_common function in MS5525DSO.cpp immediately after the reset() statement:
    Code:
    #define MS5525_TEST
    #ifdef MS5525_TEST
      uint16_t temporary;
      Serial.printf("uint16_t nprom[8] = {");
      for (uint8_t i = 0; i <= 7; i++) {
        if(!_read_prom(i,&temporary)) success = false;
        Serial.printf("0x%04X\n, ",temporary);
      }
      Serial.println("};");
    #endif
    Then recompile and upload the example sketch again and copy and paste the entire output here.

    Pete
    uint16_t nprom[8] = {0x0001
    , 0x3D89
    , 0x2948
    , 0x0EB3
    , 0x0896
    , 0x7581
    , 0x20F2
    , 0x0004
    , };
    INFO: sensor inicializado, volcando coeficientes...
    C1 - Pressure Sensitivity : 15753
    C2 - Pressure Offset : 10568
    C3 - Temperature Coefficient of Pressure Sensitivity : 3763
    C4 - Temperature Coefficient of Pressure Offset : 2198
    C5 - Reference Temperature : 30081
    C6 - Temperature Coefficient of Temperature : 8434

  19. #19
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,721
    It prints all 8 values in the PROM. The library only reads 6 of them and ignores the CRC. The data above show that the CRC is correct.
    But you didn't include the line which has the calculated pressure and temperature and I forgot to add code to print the raw ADC values.
    I'll get back to this later today.

    Pete

  20. #20
    Quote Originally Posted by el_supremo View Post
    It prints all 8 values in the PROM. The library only reads 6 of them and ignores the CRC. The data above show that the CRC is correct.
    But you didn't include the line which has the calculated pressure and temperature and I forgot to add code to print the raw ADC values.
    I'll get back to this later today.

    Pete
    uint16_t nprom[8] = {0x0001
    , 0x3B71
    , 0x2847
    , 0x0F12
    , 0x0908
    , 0x7E93
    , 0x2045
    , 0x0003
    , };
    INFO: sensor inicializado, volcando coeficientes...
    C1 - Pressure Sensitivity : 15217
    C2 - Pressure Offset : 10311
    C3 - Temperature Coefficient of Pressure Sensitivity : 3858
    C4 - Temperature Coefficient of Pressure Offset : 2312
    C5 - Reference Temperature : 32403
    C6 - Temperature Coefficient of Temperature : 8261
    INFO: Pressure 0.005300 psi, Temperature 26.230000 C

    INFO: Pressure 0.006700 psi, Temperature 26.209999 C

    INFO: Pressure 0.005900 psi, Temperature 26.510000 C

  21. #21
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,721
    The CRC of both nprom arrays is correct, so that gives some confidence that the library is using valid values. Also, those temperatures don't look as wildly improbable as you mentioned in #9.
    Next is to print the raw ADC. In the readPressureAndTemperature function (MS5525DSO.cpp), immediately before the statement which starts with " int64_t dT", insert:
    Code:
    Serial.printf("raw = %d, %d\n",raw[0],raw[1]);
    And again, post all the output.
    The sample code prints output every 200ms. You can stop it after a second or so and copy the results.

    Pete

  22. #22
    Quote Originally Posted by el_supremo View Post
    The CRC of both nprom arrays is correct, so that gives some confidence that the library is using valid values. Also, those temperatures don't look as wildly improbable as you mentioned in #9.
    Next is to print the raw ADC. In the readPressureAndTemperature function (MS5525DSO.cpp), immediately before the statement which starts with " int64_t dT", insert:
    Code:
    Serial.printf("raw = %d, %d\n",raw[0],raw[1]);
    And again, post all the output.
    The sample code prints output every 200ms. You can stop it after a second or so and copy the results.

    Pete
    So, the reason the temperature looks fine is, because I changed the source code to go to only 2 digits, the original library made the temp sit at closer to 26000.00 so, I forced it to multiply to get more decimal places. I believe it's accurate too, because I checked it against a lab thermometer we have. My psi was also closer to 140 before I made a simple change to the formula in the source code.

    New:
    Code:
    int64_t dT = raw[1] - (((int64_t)T_REF) << Q5);
    Old:
    Code:
    int64_t dT = raw[1] - ((int64_t)T_REF) << Q5;
    Now it seems to give a much closer output, but I can still tell that the sensor isn't calibrated, because sometimes it will throw a random -4.3psi or something of that nature. Here is the output of what you asked. I'm sorry for not telling you what I've updated as that is important for you to see a problem.

    Code:
    uint16_t nprom[8] = {0x0001
    , 0x3CDE
    , 0x2EC0
    , 0x0EE5
    , 0x0A85
    , 0x7A4D
    , 0x20B6
    , 0x0003
    , };
    INFO: sensor inicializado, volcando coeficientes...
    C1 - Pressure Sensitivity                            : 15582
    C2 - Pressure Offset                                 : 11968
    C3 - Temperature Coefficient of Pressure Sensitivity : 3813
    C4 - Temperature Coefficient of Pressure Offset      : 2693
    C5 - Reference Temperature                           : 31309
    C6 - Temperature Coefficient of Temperature          : 8374
    raw = 6431130, 4159132
    INFO: Sensor 1 Pressure -0.005500 psi, Temperature 26.049999 C
    
    raw = 6431150, 4159148
    INFO: Sensor 1 Pressure -0.005500 psi, Temperature 26.049999 C
    
    raw = 6431144, 4158912
    INFO: Sensor 1 Pressure -0.005500 psi, Temperature 26.039999 C

  23. #23
    I've been toying with the library to see how I can add a second sensor. I want to run one high and the other low. Hopefully it works XD

  24. #24
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,721
    int64_t dT = raw[1] - ((int64_t)T_REF) << Q5;
    Where did you get this from? This is completely wrong and is why you were seeing temperatures in the region of 26000 instead of 20.
    The original code that I have is:
    Code:
    int64_t dT = raw[1] - (((int64_t)T_REF) << Q5);
    and this gives the correct results.

    I've done some testing of the original code with the raw numbers and PROM values that you've posted and they produce reasonable values. Therefore, the code is correct as it is.
    If you've changed the calculations, I suggest that you go back to the original code.

    Pete

  25. #25
    What? No the one you just said was your original code was not what I had originally. I had
    Code:
    raw[1] - ((int64_t)T_REF) << Q5;
    somehow and I changed it to
    Code:
    int64_t dT = raw[1] - (((int64_t)T_REF) << Q5);

Posting Permissions

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