极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 44123|回复: 10

Arduino 调用GY-86模块上的MS5611芯片经验分享

[复制链接]
发表于 2013-11-30 00:32:43 | 显示全部楼层 |阅读模式
本帖最后由 1206527298 于 2013-11-30 00:36 编辑

最近刚开始研究IIC的一些东西,把研究得到的成果给各位遇到同样问题的网友分享一下~

硬件:
Arduino nano
GY-86  (MPU6050+5611+HMC5883)

软件:
Arduino IDE   1.0.5

资料:
MS5611中文资料:http://wenku.baidu.com/view/ccd4ef02c5da50e2524d7f9a.html

GY-86与NANO采用 IIC 总线连接,官方给出NANO的IIC总线针脚定义为: A4 为SDA,A5为SCL,根据官方给出的针脚定义连接GY-86即可。

在这里需要简述一下我所查到的IIC总线:
Arduino主从机之间的I2C通讯实验:http://www.eefocus.com/zhang700309/blog/12-01/236815_59f78.html
——————————————————————————————————————————————————————————
I2C总线定义I2C(‘intel’ -Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。在主从通信中,可以有多个I2C总线器件同时接到I2C总线上,通过地址来识别通信对象。
    I2C总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,最高传送速率100kbps。各种被控制电路均并联在这条总线上,但就像电话机一样只有拨通各自的号码才能工作,所以每个电路和模块都有唯一的地址,在信息的传输过程中,I2C总线上并接的每一模块电路既可以是主控器(或被控器),又可以是发送器(或接收器),这取决于它所要完成的功能。


——————————————————————————————————————————————————————————
根据简述可知GY-86上的各个芯片都有自己的地址(Address),主控与芯片通信必须了解地址才行。
而根据芯片资料所示:MS5611的IIC地址是:为二进制 111011Cx,其中C为芯片CSB引脚的补码值(取反)。化为十六进制就是0x77   或  0x76 两种。

这是GY-86上的MS5611电路图,(此图仅供参考)


这是单独的MS5611模块图片,由图片可看到CSB引脚定义IIC地址


我手里的这块GY-86板子,MS5611的地址就是0x76

下面是从国外论坛查到的调用MS5611的调试代码:可以在串口监视器以及其他串口接收工具上实时查看到温度、高度等数值

——————————————————————————————————————————————————————————
  1. #include <Wire.h>
  2. #define ADDRESS 0x77 //0x76   IIC Address

  3. uint32_t D1 = 0;
  4. uint32_t D2 = 0;
  5. int64_t dT = 0;
  6. int32_t TEMP = 0;
  7. int64_t OFF = 0;
  8. int64_t SENS = 0;
  9. int32_t P = 0;
  10. uint16_t C[7];

  11. float Temperature;
  12. float Pressure;
  13. const float sea_press = 1013.25;

  14. void setup() {
  15. // Disable internal pullups, 10Kohms are on the breakout
  16. PORTC |= (1 << 4);
  17. PORTC |= (1 << 5);

  18.   Wire.begin();
  19.   Serial.begin(9600); //9600 changed 'cos of timing?
  20.   delay(100);
  21.   initial(ADDRESS);

  22. }

  23. void loop()
  24. {
  25.   D1 = getVal(ADDRESS, 0x48); // Pressure raw
  26.   D2 = getVal(ADDRESS, 0x58);// Temperature raw

  27.   dT   = D2 - ((uint32_t)C[5] << 8);
  28.   OFF  = ((int64_t)C[2] << 16) + ((dT * C[4]) >> 7);
  29.   SENS = ((int32_t)C[1] << 15) + ((dT * C[3]) >> 8);

  30.   TEMP = (int64_t)dT * (int64_t)C[6] / 8388608 + 2000;

  31.   if(TEMP < 2000) // if temperature lower than 20 Celsius
  32.   {
  33.     int32_t T1    = 0;
  34.     int64_t OFF1  = 0;
  35.     int64_t SENS1 = 0;

  36.     T1    = pow(dT, 2) / 2147483648;
  37.     OFF1  = 5 * pow((TEMP - 2000), 2) / 2;
  38.     SENS1 = 5 * pow((TEMP - 2000), 2) / 4;
  39.    
  40.     if(TEMP < -1500) // if temperature lower than -15 Celsius
  41.     {
  42.       OFF1  = OFF1 + 7 * pow((TEMP + 1500), 2);
  43.       SENS1 = SENS1 + 11 * pow((TEMP + 1500), 2) / 2;
  44.     }
  45.    
  46.     TEMP -= T1;
  47.     OFF -= OFF1;
  48.     SENS -= SENS1;
  49.   }


  50.   Temperature = (float)TEMP / 100;
  51.   
  52.   P  = ((int64_t)D1 * SENS / 2097152 - OFF) / 32768;

  53.   Pressure = (float)P / 100;
  54.   
  55.   Serial.print("     Actual TEMP= ");
  56.   Serial.print(Temperature);
  57.   Serial.print("      Actual PRESSURE= ");
  58.   Serial.print(Pressure);
  59.   Serial.println();
  60.   Serial.println();
  61.   
  62.   Serial.print("     Actual ALTITUDE= ");
  63.   Serial.print(getAltitude(Pressure, Temperature));
  64.   Serial.println("m");
  65.   Serial.println();  
  66.   Serial.print(" RAW Temp D2=  ");
  67.   Serial.print(D2);
  68.   Serial.print(" RAW Pressure D1=  ");
  69.   Serial.println(D1);
  70.   Serial.println();

  71. //  Serial.print(" dT=  ");
  72. //  Serial.println(dT); can't print int64_t size values
  73.   Serial.println();
  74.   Serial.print(" C1 = ");
  75.   Serial.println(C[1]);
  76.   Serial.print(" C2 = ");
  77.   Serial.println(C[2]);
  78.   Serial.print(" C3 = ");
  79.   Serial.println(C[3]);
  80.   Serial.print(" C4 = ");
  81.   Serial.println(C[4]);
  82.   Serial.print(" C5 = ");
  83.   Serial.println(C[5]);
  84.   Serial.print(" C6 = ");
  85.   Serial.println(C[6]);
  86. //  Serial.print(" C7 = ");
  87. //  Serial.println(C[7]);
  88.   Serial.println();

  89.   delay(1000);
  90. }
  91. float getAltitude(float Pressure, float Temperature) {
  92.   return ((pow((sea_press / Pressure), 1/5.257) - 1.0) * (Temperature + 273.15)) / 0.0065;
  93. }
  94. long getVal(int address, byte code)
  95. {
  96.   unsigned long ret = 0;
  97.   Wire.beginTransmission(address);
  98.   Wire.write(code);
  99.   Wire.endTransmission();
  100.   delay(10);
  101.   // start read sequence
  102.   Wire.beginTransmission(address);
  103.   Wire.write((byte) 0x00);
  104.   Wire.endTransmission();
  105.   Wire.beginTransmission(address);
  106.   Wire.requestFrom(address, (int)3);
  107.   if (Wire.available() >= 3)
  108.   {
  109.     ret = Wire.read() * (unsigned long)65536 + Wire.read() * (unsigned long)256 + Wire.read();
  110.   }
  111.   else {
  112.     ret = -1;
  113.   }
  114.   Wire.endTransmission();
  115.   return ret;
  116. }

  117. void initial(uint8_t address)
  118. {

  119.   Serial.println();
  120.   Serial.println("PROM COEFFICIENTS ivan");

  121.   Wire.beginTransmission(address);
  122.   Wire.write(0x1E); // reset
  123.   Wire.endTransmission();
  124.   delay(10);


  125.   for (int i=0; i<6  ; i++) {

  126.     Wire.beginTransmission(address);
  127.     Wire.write(0xA2 + (i * 2));
  128.     Wire.endTransmission();

  129.     Wire.beginTransmission(address);
  130.     Wire.requestFrom(address, (uint8_t) 6);
  131.     delay(1);
  132.     if(Wire.available())
  133.     {
  134.        C[i+1] = Wire.read() << 8 | Wire.read();
  135.     }
  136.     else {
  137.       Serial.println("Error reading PROM 1"); // error reading the PROM or communicating with the device
  138.     }
  139.     Serial.println(C[i+1]);
  140.   }
  141.   Serial.println();
  142. }
复制代码


以上就是我所搜索资料研究得到的经验,希望能帮到遇到困难的各位。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2014-1-18 18:18:14 | 显示全部楼层
Thanks!图中的单片机用的是pro mini~
回复 支持 反对

使用道具 举报

发表于 2014-4-4 22:24:28 | 显示全部楼层
国外这个代码 不知道哪里有问题,实际压力为0,实际高度为inf
回复 支持 反对

使用道具 举报

发表于 2014-4-4 22:30:31 | 显示全部楼层
ok,这个代码是对的,重新打开串口以后,数据正常啦
回复 支持 反对

使用道具 举报

发表于 2014-4-4 23:17:38 | 显示全部楼层
刚好在弄这个东西,一直不对。看了代码后终于对了。谢谢
回复 支持 反对

使用道具 举报

发表于 2014-5-18 16:17:39 | 显示全部楼层
求注释~~英文不好的孩子~伤不起~
回复 支持 反对

使用道具 举报

发表于 2014-7-8 15:09:59 | 显示全部楼层
用 ardublock 如何表达这个程序
回复 支持 反对

使用道具 举报

发表于 2014-7-8 19:44:30 | 显示全部楼层
伊芙妤 发表于 2014-7-8 15:09
用 ardublock 如何表达这个程序

ardublock只适合逻辑很简单的东西。。。这种稍微复杂点的,就不用想了。还是用代码比较稳妥。
回复 支持 反对

使用道具 举报

发表于 2014-10-6 10:17:06 | 显示全部楼层
对新手真的很有用啊~~~给楼主赞一个~~~
回复 支持 反对

使用道具 举报

发表于 2016-2-5 11:19:49 | 显示全部楼层
学习了,非常感谢。
回复 支持 反对

使用道具 举报

发表于 2016-7-15 14:38:58 | 显示全部楼层
您好!请问你知道BA5803和MS5611的防水方式吗?急求!谢谢!
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-25 21:22 , Processed in 0.049323 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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