OneNET麒麟座应用开发之八:采集大气压力等环境参数
采集大气压力和温度也是核算大气标准状况下的各种数据的必须参数,为此我们必须知道压力和温度才能计算标准状况下的各种参数,于此我们需要一个既能检测压力也能检测温度的元件。
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麒麟座应用开发之八:采集大气压力等环境参数的更多相关文章
- OneNET麒麟座应用开发之四:数据上传测试
已经测试过OneNET麒麟座开发板了,这次来尝试与OneNET的连接和数据上传.这也是我们测试这块开发办的主要原因,因为在十几种我们有这种将分散的采集点数据上传到后台的需求. 先看看麒麟座这块开发板, ...
- OneNET麒麟座应用开发之六:与气体质量流量控制器通讯
气体质量流量控制器,简称MFC,通常用于在各种检测中,计量气体的流量.在我们的大气环境数据采集站中,要让气流保持稳定,这样才能准确的获取PM25的数据. 我们采用的气体质量流量控制器具备串口通讯功能, ...
- OneNET麒麟座应用开发之一:初识OneNET麒麟座
今天收到了OneNET麒麟座开发板.能得到使用的机会只能说是幸运的.首先上一张靓照: 板子使用的MCU是STM32F103RET6,带有GSM摸块和Wifi摸块可以联网.带有显示屏接口和I2C接口以及 ...
- OneNET麒麟座应用开发之七:控制采样电机
气体采样采用主动抽取气体的方式保证充足而平稳的气流,所以我们采用气泵抽取气体来完成. 1.设计概述 客户对这部分要求能够设定电机的速度,但并不需要动态调节.对电机的控制有很多方式,我们采用比较简单的方 ...
- OneNET麒麟座应用开发之三:获取温湿度数据
对于大气环境监测来说温湿度也是重要的指标.原本计划使用SHT15来采集温湿度数据,不过在OneNET麒麟开发板上,我们发现已经集成有SHT20温湿度传感器,于是我们就使用它了.如下图的红框处: 我们还 ...
- OneNET麒麟座应用开发之五:获取加速度传感器ADXL345数据
由于数据采集站基本都安装在野外或者楼顶,安装位置以及震动对检测数据的准确性有一定影响.所以想要有一个位置状态数据,正好发现麒麟作上有ADXL345,这样一个数字输出的加速度传感器.如图中红框所示: 1 ...
- OneNET麒麟座应用开发之十:空气质量数据监测站项目总结
大气质量数据监测站用于测试空气质量监测及数据采集,实现野外或者室内空气质量的检测. 1.项目概述 本项目是一个定制项目,要求采集大气的压力.温度.湿度.PM25.位置等数据并上传到指定的后台服务器.但 ...
- OneNET麒麟座应用开发之二:串口读取PM25传感器数据
作为环境数据监测站首先要获取大气中可吸入颗粒物的数据.为了检测PM25数据,我们采用北京海联信为的HLPM025K3型号传感器,该传感器使用激光法测量PM25和PM10的数据. 该型传感器的检测对象如 ...
- MVC5 网站开发之八 栏目功能 添加、修改和删除
本次实现栏目的浏览.添加.修改和删除. 栏目一共有三种类型. 常规栏目-可以添加子栏目,也可以添加内容模型.当不选择内容模型时,不能添加内容. 单页栏目-栏目只有一个页面,可以设置视图. 链接栏目-栏 ...
随机推荐
- 走进Java中的持有对象(容器类)【二】Collection
概述 通过前文的学习,我们对容器的分类及常用容器类的作用有了基本的认识.本文将针对Collection容器的功能与使用进行细致分析. 基本操作 Collection集合抽象出的目的是为存放独立元素的序 ...
- PHP依赖倒置和控制反转
判断代码的好坏,我们有自己的标准:高内聚,低耦合.为了解决这一问题,php中有许多优秀的设计模式,比如工厂模式,单例模式. 而在代码中体现出来的设计模式,就如依赖注入和控制反转. 那什么是依赖注入? ...
- GO语言的进阶之路-go的程序结构以及包简介
GO语言的进阶之路-go的程序结构以及包简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编辑,编译和运行 A,编辑 Go程序使用UTF-8编码的纯Unicode文本编写.大 ...
- mysql表备份的一种方式
前提: 最近测试环境shop表经常出现表损坏不能正常查询,通过mysql的修复方法,暂时有效.故做该表的迁移操作. 思路是: 停止数据库的操作 1.备份老表. 2.创建一个结构一样的表. 3.将老表 ...
- 在eclipse中启动项目报java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: PermGen space
在我们启动项目的时候经常会出现内存溢出这个错误 设置一下内存就ok 错误信息 java.util.concurrent.ExecutionException: java.lang.OutOfMemo ...
- mySQL数值类型的取值范围
如下图,int最大为2145483647,手机号码应该用bigint
- Lucene Query In Kibana
1. Terms 一个查询由词条与操作组成.词条可以是单词,或者短语. hello #单独项 "hello pzdn" #双引号引起来短语 2. Field Lucene 支持字段 ...
- Table Dragger - 简单的 JS 拖放排序表格插件
Table Dragger 是一个极简的实现拖放排序的表格插件,纯 JavaScript 库,不依赖 jQuery.用于构建操作方便的拖放排序功能,超级容易设置,有平滑的动画,支持触摸事件. 在线演示 ...
- Javaweb学习笔记——(八)——————常见系统体系结构,Tomcat,以及web的内部外部应用,http协议概述
·软件系统体系结构: 1.常见软件系统体系结构B/S.C/S C/S 1.C/S结构即客户端/服务器(Client/Server),列如QQ: 2.需要编写服务器端程序,以及客户端程序,列如我们安装的 ...
- Linux 4.10.8 根文件系统制作(三)---制作yaffs文件系统
这里直接用的是韦东山提供的工具. yaffs文件系统是专门用于nandflash的文件系统 我们前面已经下载了yaffs 的源码,也做了文件系统目录的构建. 在yaffs2的源码目录中有一个utils ...