采集大气压力和温度也是核算大气标准状况下的各种数据的必须参数,为此我们必须知道压力和温度才能计算标准状况下的各种参数,于此我们需要一个既能检测压力也能检测温度的元件。

1、硬件概述

MS5837压力传感器是一种可用于电路板上,适用于检测10-1200mbar压力范围的传感器,灵敏度非常高,理论上能够检测到0.01mbar的压力变化,实际使用过程中测试并无明显的变化。

(1)硬件连接

MS5837采用I2C总线通讯,与STM32的MCU可以实现I2C通讯。硬件连接方式如下:

我们发现OneNET麒麟座的I2C引到了J3的第4和5引脚,但是我们发现在OLED的接口也是这个,所以我们直接用这个,因为电源也正好合适,具体位置如下图红框处:

(3)寄存器分配

MS5837只有5个基本命令:复位、读取出厂校准值、数据1转换(压力值数据)、数据2转换(温度值数据)和读取ADC的转换结果。具体分配如下:

2、软件设计

因为MS5837的地址是固定的,所以一个I2C总线只能挂1个MS5837模块。为了让程序具有较好的可移植性,我们在便写程序时不使用对硬件的直接操作,而采用函数指针来操作,所以我们定义了:

/*向MS5837下发指令,指令格式均为1个字节*/

typedef void (*WriteCommandToMs5837Type)(uint8_t deviceAddress,uint8_t command);

/*从MS5837读取多个字节数据的值*/

typedef void (*ReadBytesFromMs5837Type)(uint8_t deviceAddress,uint8_t *pData,uint16_t bytesNum);

以上两个函数指针来实现针对硬件的读写操作。接下来我们开始编写代码。

(1)复位操作

复位操作的数据流如下图所示,只需要发送一条命令就可完成:

/*复位MS5837操作*/

void ResetForMs5837(uint8_t deviceAddress,WriteCommandToMs5837Type WriteCommandToMs5837)

{

uint8_t command=COMMAND_RESET;

/*下发复位命令*/

WriteCommandToMs5837(deviceAddress,command);

}

(2)读取校准值

校准值是出厂时厂家校准的各种系数,每台设备都有差异,是固定不变的,只需要一次读取就可以了,共有6个系数,均为16为整数。首先发送读系数的命令,然后读取就可以了,每次读取1个,分6次读取。过程数据流如下图所示:

/*从MS5837的PROM中读取校准数据*/

void GetCalibrationData(uint8_t deviceAddress,uint16_t *caliPara,WriteCommandToMs5837Type WriteCommandToMs5837,ReadBytesFromMs5837Type ReadBytesFromMs5837)

{

/*C1压力灵敏度*/

caliPara[0]=ReadPromFromMs5837(deviceAddress,COMMAND_PROM_READ_C1,WriteCommandToMs5837,ReadBytesFromMs5837);

/*C2压力补偿值*/

caliPara[1]=ReadPromFromMs5837(deviceAddress,COMMAND_PROM_READ_C2,WriteCommandToMs5837,ReadBytesFromMs5837);

/*C3压力灵敏度温度系数*/

caliPara[2]=ReadPromFromMs5837(deviceAddress,COMMAND_PROM_READ_C3,WriteCommandToMs5837,ReadBytesFromMs5837);

/*C4压力补偿温度系数*/

caliPara[3]=ReadPromFromMs5837(deviceAddress,COMMAND_PROM_READ_C4,WriteCommandToMs5837,ReadBytesFromMs5837);

/*C5参考温度*/

caliPara[4]=ReadPromFromMs5837(deviceAddress,COMMAND_PROM_READ_C5,WriteCommandToMs5837,ReadBytesFromMs5837);

/*C6温度传感器温度系数*/

caliPara[5]=ReadPromFromMs5837(deviceAddress,COMMAND_PROM_READ_C6,WriteCommandToMs5837,ReadBytesFromMs5837);

}

(3)读取转换值

读取转换结果值是我们的目的,可以读取温度和压力两个量,不过一次只能读一个。首先发送命令设定采集压力还是温度,并设定精度。然后发送读取的命令,最后读取对应的值。再使用校准系数计算出最终的物理值。

/*获取转换值,包括温度和压力*/

void GetConversionValue(uint8_t deviceAddress,float *pPres,float *pTemp,uint16_t *caliPara,uint16_t *semaphore,WriteCommandToMs5837Type WriteCommandToMs5837,ReadBytesFromMs5837Type ReadBytesFromMs5837)

{

uint16_t senst1;        //C1压力灵敏度

uint16_t offt1;         //C2压力补偿值

uint16_t tcs;           //C3压力灵敏度温度系数

uint16_t tco;           //C4压力补偿温度系数

uint16_t tref;          //C5参考温度

uint16_t tempsens;      //C6温度传感器温度系数

/*从MS5837的PROM中读取校准数据*/

if(*semaphore>0)

{

GetCalibrationData(deviceAddress,caliPara,WriteCommandToMs5837,ReadBytesFromMs5837);

*semaphore=*semaphore-1;

}

senst1=caliPara[0];

offt1=caliPara[1];

tcs=caliPara[2];

tco=caliPara[3];

tref=caliPara[4];

tempsens=caliPara[5];

uint32_t digitalPressureValue;

uint32_t digitalTemperatureValue;

/*读取压力数据*/

digitalPressureValue=ReadConversionFromMs5837(deviceAddress,COMMAND_CONVERTD1OSR4096,WriteCommandToMs5837,ReadBytesFromMs5837);

Delayms(20);

/*读取温度数据*/

digitalTemperatureValue=ReadConversionFromMs5837(deviceAddress,COMMAND_CONVERTD2OSR4096,WriteCommandToMs5837,ReadBytesFromMs5837);

/*对温度进行一阶修正*/

int32_t dT;

int32_t temp;

dT=digitalTemperatureValue-tref*256;

temp=(int32_t)(2000+dT*tempsens/pow(2,23));

/*对压力进行一阶修正*/

int64_t off;

int64_t sens;

int32_t pres;

off=(int64_t)(offt1*pow(2,17)+(tco*dT)/pow(2,6));

sens=(int64_t)(senst1*pow(2,16)+(tcs*dT)/pow(2,7));

pres=(int32_t)((digitalPressureValue*sens/pow(2,21)-off)/pow(2,15));

/*对温度和压力进行二阶修正*/

int64_t ti=0;

int64_t offi=0;

int64_t sensi=0;

int64_t off2=0;

int64_t sens2=0;

if(temp<2000)

{

ti=(int64_t)(11*dT*dT/pow(2,35));

offi=(int64_t)(31*(temp-2000)*(temp-2000)/pow(2,3));

sensi=(int64_t)(63*(temp-2000)*(temp-2000)/pow(2,5));

off2=off-offi;

sens2=sens-sensi;

temp=temp-(int32_t)ti;

pres=(int32_t)((digitalPressureValue*sens2/pow(2,21)-off2)/pow(2,15));

}

if((-4000<=temp)&&(temp<=8500))

{

*pTemp=(float)temp/100.0;

}

if((1000<=pres)&&(pres<=120000))

{

*pPres=(float)pres/100.0;

}

}

最终在STM32的I2C接口实现通讯时,实现2个WriteCommandToMs5837Type(uint8_t deviceAddress,uint8_t command);和ReadBytesFromMs5837Type(uint8_t deviceAddress,uint8_t *pData,uint16_t bytesNum);函数并调用就可以了,更换平台也只需要重写这两个函数就能实现移植。

3、结果展示

完成上述开发后,编译下载。我们也将数据结果上传到OneNET,具体显示结果如下:

上图分别显示了,大气压力,温度以及湿度等参数。

OneNET麒麟座应用开发之八:采集大气压力等环境参数的更多相关文章

  1. OneNET麒麟座应用开发之四:数据上传测试

    已经测试过OneNET麒麟座开发板了,这次来尝试与OneNET的连接和数据上传.这也是我们测试这块开发办的主要原因,因为在十几种我们有这种将分散的采集点数据上传到后台的需求. 先看看麒麟座这块开发板, ...

  2. OneNET麒麟座应用开发之六:与气体质量流量控制器通讯

    气体质量流量控制器,简称MFC,通常用于在各种检测中,计量气体的流量.在我们的大气环境数据采集站中,要让气流保持稳定,这样才能准确的获取PM25的数据. 我们采用的气体质量流量控制器具备串口通讯功能, ...

  3. OneNET麒麟座应用开发之一:初识OneNET麒麟座

    今天收到了OneNET麒麟座开发板.能得到使用的机会只能说是幸运的.首先上一张靓照: 板子使用的MCU是STM32F103RET6,带有GSM摸块和Wifi摸块可以联网.带有显示屏接口和I2C接口以及 ...

  4. OneNET麒麟座应用开发之七:控制采样电机

    气体采样采用主动抽取气体的方式保证充足而平稳的气流,所以我们采用气泵抽取气体来完成. 1.设计概述 客户对这部分要求能够设定电机的速度,但并不需要动态调节.对电机的控制有很多方式,我们采用比较简单的方 ...

  5. OneNET麒麟座应用开发之三:获取温湿度数据

    对于大气环境监测来说温湿度也是重要的指标.原本计划使用SHT15来采集温湿度数据,不过在OneNET麒麟开发板上,我们发现已经集成有SHT20温湿度传感器,于是我们就使用它了.如下图的红框处: 我们还 ...

  6. OneNET麒麟座应用开发之五:获取加速度传感器ADXL345数据

    由于数据采集站基本都安装在野外或者楼顶,安装位置以及震动对检测数据的准确性有一定影响.所以想要有一个位置状态数据,正好发现麒麟作上有ADXL345,这样一个数字输出的加速度传感器.如图中红框所示: 1 ...

  7. OneNET麒麟座应用开发之十:空气质量数据监测站项目总结

    大气质量数据监测站用于测试空气质量监测及数据采集,实现野外或者室内空气质量的检测. 1.项目概述 本项目是一个定制项目,要求采集大气的压力.温度.湿度.PM25.位置等数据并上传到指定的后台服务器.但 ...

  8. OneNET麒麟座应用开发之二:串口读取PM25传感器数据

    作为环境数据监测站首先要获取大气中可吸入颗粒物的数据.为了检测PM25数据,我们采用北京海联信为的HLPM025K3型号传感器,该传感器使用激光法测量PM25和PM10的数据. 该型传感器的检测对象如 ...

  9. MVC5 网站开发之八 栏目功能 添加、修改和删除

    本次实现栏目的浏览.添加.修改和删除. 栏目一共有三种类型. 常规栏目-可以添加子栏目,也可以添加内容模型.当不选择内容模型时,不能添加内容. 单页栏目-栏目只有一个页面,可以设置视图. 链接栏目-栏 ...

随机推荐

  1. scala生态圈概览

    相信很多朋友都对 Scala 这个结合了面向对象编程范式和函数式编程范式的编程语言新宠有所耳闻吧?!那么一旦你所在的项目选择了 Scala 的技术栈,还有哪些工具,类库可以选择呢?各种类型的框架或者类 ...

  2. HTML格式化标签

    除了div.p.h1~h6.a.span这几个极常用的标签外,HTML还有一些不常见的标签(10个,5对:加粗.斜体.大小.上下标.特殊),默认效果如下: 当然,我们习惯用css编写效果来替代这些效果 ...

  3. Python基础【day01】:python介绍发展史(一)

    本节内容 Python介绍 发展史 Python 2 or 3? 一. Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏 ...

  4. javascript 字符串的连接和截取

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. mac下chrome快捷键

    打开开发者工具:alt + command + I: 打开“JavaScript 控制台”:⌘-Option-J: 打开当前网页的源代码:⌘-Option-U: 刷新页面:command + R: m ...

  6. C 编译过程浅析

    From where i stand, there are two programmig languages in the world, which is C lang and the other. ...

  7. VUE2.0 饿了吗视频学习笔记(二):新版本添加路由和显示Header

    https://gitee.com/1981633/vue_study.git 源码下载地址,随笔记动态更新中 webpack.dev.conf.js中添加两段代码 'use strict' cons ...

  8. 配置Arcengine10.1+java开发环境(Eclipse)

    以下开发环境配置是假定用户已经安装了Java开发的IDE(Eclipse) 软件准备 (一)ArcEngine 10.1 安装包 提取码:poa0 (二)ArcGIS License Manager ...

  9. ELF格式探析之三:sections

    前文链接: ELF格式探析之一:Segment和Section ELF格式探析之二:文件头ELF Header详解 今天我们讲对目标文件(可重定位文件)和可执行文件都很重要的section. 我们在讲 ...

  10. 液晶数字显示屏QLCDNumbe

    import sys from PyQt5.QtWidgets import QApplication, QWidget, QLCDNumber, QVBoxLayout class Demo(QWi ...