找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5679|回复: 3
收起左侧

用于arduino的MS5837-30BAR和02BAR的官方测试源程序与资料

[复制链接]
ID:413939 发表于 2018-10-23 11:56 | 显示全部楼层 |阅读模式
用于arduino的MS5837-30BAR和02BAR的官方测试程序可以在代码里面自由对MS5837的种类进行切换,非常的方便
MS5837是高精度的压力传感器,形状微小
在很多地方都有应用,比如潜水仪器等等
另上传关于MS5837的芯片手册,供大家使用

未命名_副本1.jpg

BlueRobotics_MS5837_Library-master

源程序如下:

  1. #include "MS5837.h"
  2. #include <Wire.h>

  3. #define MS5837_ADDR               0x76  
  4. #define MS5837_RESET              0x1E
  5. #define MS5837_ADC_READ           0x00
  6. #define MS5837_PROM_READ          0xA0
  7. #define MS5837_CONVERT_D1_8192    0x4A
  8. #define MS5837_CONVERT_D2_8192    0x5A

  9. const float MS5837::Pa = 100.0f;
  10. const float MS5837::bar = 0.001f;
  11. const float MS5837::mbar = 1.0f;

  12. const uint8_t MS5837::MS5837_30BA = 0;
  13. const uint8_t MS5837::MS5837_02BA = 1;

  14. MS5837::MS5837() {
  15.         fluidDensity = 1029;
  16. }

  17. bool MS5837::init() {
  18.         // Reset the MS5837, per datasheet
  19.         Wire.beginTransmission(MS5837_ADDR);
  20.         Wire.write(MS5837_RESET);
  21.         Wire.endTransmission();

  22.         // Wait for reset to complete
  23.         delay(10);

  24.         // Read calibration values and CRC
  25.         for ( uint8_t i = 0 ; i < 7 ; i++ ) {
  26.                 Wire.beginTransmission(MS5837_ADDR);
  27.                 Wire.write(MS5837_PROM_READ+i*2);
  28.                 Wire.endTransmission();

  29.                 Wire.requestFrom(MS5837_ADDR,2);
  30.                 C[i] = (Wire.read() << 8) | Wire.read();
  31.         }

  32.         // Verify that data is correct with CRC
  33.         uint8_t crcRead = C[0] >> 12;
  34.         uint8_t crcCalculated = crc4(C);

  35.         if ( crcCalculated == crcRead ) {
  36.                 return true; // Initialization success
  37.         }

  38.         return false; // CRC fail
  39. }

  40. void MS5837::setModel(uint8_t model) {
  41.         _model = model;
  42. }

  43. void MS5837::setFluidDensity(float density) {
  44.         fluidDensity = density;
  45. }

  46. void MS5837::read() {
  47.         // Request D1 conversion
  48.         Wire.beginTransmission(MS5837_ADDR);
  49.         Wire.write(MS5837_CONVERT_D1_8192);
  50.         Wire.endTransmission();

  51.         delay(20); // Max conversion time per datasheet
  52.         
  53.         Wire.beginTransmission(MS5837_ADDR);
  54.         Wire.write(MS5837_ADC_READ);
  55.         Wire.endTransmission();

  56.          Wire.requestFrom(MS5837_ADDR,3);
  57.         D1 = 0;
  58.         D1 = Wire.read();
  59.         D1 = (D1 << 8) | Wire.read();
  60.         D1 = (D1 << 8) | Wire.read();
  61.         
  62.         // Request D2 conversion
  63.         Wire.beginTransmission(MS5837_ADDR);
  64.         Wire.write(MS5837_CONVERT_D2_8192);
  65.         Wire.endTransmission();

  66.         delay(20); // Max conversion time per datasheet
  67.         
  68.         Wire.beginTransmission(MS5837_ADDR);
  69.         Wire.write(MS5837_ADC_READ);
  70.         Wire.endTransmission();

  71.         Wire.requestFrom(MS5837_ADDR,3);
  72.         D2 = 0;
  73.         D2 = Wire.read();
  74.         D2 = (D2 << 8) | Wire.read();
  75.         D2 = (D2 << 8) | Wire.read();

  76.         calculate();
  77. }

  78. void MS5837::calculate() {
  79.         // Given C1-C6 and D1, D2, calculated TEMP and P
  80.         // Do conversion first and then second order temp compensation
  81.         
  82.         int32_t dT = 0;
  83.         int64_t SENS = 0;
  84.         int64_t OFF = 0;
  85.         int32_t SENSi = 0;
  86.         int32_t OFFi = 0;  
  87.         int32_t Ti = 0;   
  88.         int64_t OFF2 = 0;
  89.         int64_t SENS2 = 0;
  90.         
  91.         // Terms called
  92.         dT = D2-uint32_t(C[5])*256l;
  93.         if ( _model == MS5837_02BA ) {
  94.                 SENS = int64_t(C[1])*65536l+(int64_t(C[3])*dT)/128l;
  95.                 OFF = int64_t(C[2])*131072l+(int64_t(C[4])*dT)/64l;
  96.                 P = (D1*SENS/(2097152l)-OFF)/(32768l);
  97.         } else {
  98.                 SENS = int64_t(C[1])*32768l+(int64_t(C[3])*dT)/256l;
  99.                 OFF = int64_t(C[2])*65536l+(int64_t(C[4])*dT)/128l;
  100.                 P = (D1*SENS/(2097152l)-OFF)/(8192l);
  101.         }
  102.         
  103.         // Temp conversion
  104.         TEMP = 2000l+int64_t(dT)*C[6]/8388608LL;
  105.         
  106.         //Second order compensation
  107.         if ( _model == MS5837_02BA ) {
  108.                 if((TEMP/100)<20){         //Low temp
  109.                         Serial.println("here");
  110.                         Ti = (11*int64_t(dT)*int64_t(dT))/(34359738368LL);
  111.                         OFFi = (31*(TEMP-2000)*(TEMP-2000))/8;
  112.                         SENSi = (63*(TEMP-2000)*(TEMP-2000))/32;
  113.                 }
  114.         } else {
  115.                 if((TEMP/100)<20){         //Low temp
  116.                         Ti = (3*int64_t(dT)*int64_t(dT))/(8589934592LL);
  117.                         OFFi = (3*(TEMP-2000)*(TEMP-2000))/2;
  118.                         SENSi = (5*(TEMP-2000)*(TEMP-2000))/8;
  119.                         if((TEMP/100)<-15){    //Very low temp
  120.                                 OFFi = OFFi+7*(TEMP+1500l)*(TEMP+1500l);
  121.                                 SENSi = SENSi+4*(TEMP+1500l)*(TEMP+1500l);
  122.                         }
  123.                 }
  124.                 else if((TEMP/100)>=20){    //High temp
  125.                         Ti = 2*(dT*dT)/(137438953472LL);
  126.                         OFFi = (1*(TEMP-2000)*(TEMP-2000))/16;
  127.                         SENSi = 0;
  128.                 }
  129.         }
  130.         
  131.         OFF2 = OFF-OFFi;           //Calculate pressure and temp second order
  132.         SENS2 = SENS-SENSi;
  133.         
  134.         if ( _model == MS5837_02BA ) {
  135.                 TEMP = (TEMP-Ti);
  136.                 P = (((D1*SENS2)/2097152l-OFF2)/32768l)/100;
  137.         } else {
  138.                 TEMP = (TEMP-Ti);
  139.                 P = (((D1*SENS2)/2097152l-OFF2)/8192l)/10;
  140.         }
  141. }

  142. float MS5837::pressure(float conversion) {
  143.         return P*conversion;
  144. }

  145. float MS5837::temperature() {
  146.         return TEMP/100.0f;
  147. }

  148. float MS5837::depth() {
  149.         return (pressure(MS5837::Pa)-101300)/(fluidDensity*9.80665);
  150. }

  151. float MS5837::altitude() {
  152.         return (1-pow((pressure()/1013.25),.190284))*145366.45*.3048;
  153. }


  154. uint8_t MS5837::crc4(uint16_t n_prom[]) {
  155.         uint16_t n_rem = 0;

  156.         n_prom[0] = ((n_prom[0]) & 0x0FFF);
  157.         n_prom[7] = 0;

  158.         for ( uint8_t i = 0 ; i < 16; i++ ) {
  159.                 if ( i%2 == 1 ) {
  160.                         n_rem ^= (uint16_t)((n_prom[i>>1]) & 0x00FF);
  161.                 } else {
  162.                         n_rem ^= (uint16_t)(n_prom[i>>1] >> 8);
  163.                 }
  164.                 for ( uint8_t n_bit = 8 ; n_bit > 0 ; n_bit-- ) {
  165.                         if ( n_rem & 0x8000 ) {
  166.                                 n_rem = (n_rem << 1) ^ 0x3000;
  167.                         } else {
  168.                                 n_rem = (n_rem << 1);
  169.                         }
  170.                 }
  171.         }
  172.         
  173.         n_rem = ((n_rem >> 12) & 0x000F);

  174.         return n_rem ^ 0x00;
  175. }

复制代码

所有资料51hei提供下载:
BlueRobotics_MS5837_Library-master.zip (8.31 KB, 下载次数: 51)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:565602 发表于 2019-10-25 19:20 | 显示全部楼层
有个客户在用,今天开始调试,先顶再读
回复

使用道具 举报

ID:683452 发表于 2020-1-8 11:30 | 显示全部楼层
蠻厲害的選擇
回复

使用道具 举报

ID:318415 发表于 2020-4-4 10:57 | 显示全部楼层
感谢楼主 !

我自己写了个ms5837 一直没找到问题 对着例子 改了改可以用  

再次感谢!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表