[嵌入式开发模块]SHT30/20 温湿度传感器 驱动模块
文章目录
- 前言
- SHT30简介
- 概述
- 通信协议
- 驱动文件
- SHT30Driver.h
- SHT30Recver.c
- SHT30Cmder.c
- 依赖
- 使用示例
- 更新历史
前言
干活中用到了SHT30,其实是对应的转串口板子,写了相应的驱动程序,放出来。
好像SHT20和30几乎是一样的,所以不用纠结这个。
这个模块本身的协议比较简单,所以模块的驱动也很小巧。
驱动被设计为拥有指令器和接收机两个部分,完全被动方式运行,与具体的平台解耦。
SHT30简介
概述
SHT20是由瑞士推出的数字温湿度传感器,基于领先世界的CMOSens数字传感技术,具有极高的可靠性和卓越的长期稳定性。全量程标定,两线数字接口,可与单片机直接相连,大大缩短研发时间、简化外围电路并降低费用。此外,体积微小、响应迅速、低能耗、可浸没、抗干扰能力强、温湿一体,兼有露点测量,性价比高,使该产品能够适于多种场合的应用。
通信协议
(1) 串口通信参数
电平:TTL
波特率:115200
停止位:1
校验位:0
(2)输出格式
输出字符串格式: Temp = XX.XXX Hum = XX.XXX\r\n
(3)控制指令:下面指令需要发送两次,第一次使模块由工作模式进入到配置模式,第二次发送才是设置模块。
设置回传速度:
设置报警值(这个驱动没有实现):
驱动文件
SHT30Driver.h
/*
*******************************************************************************************
*
* SHT30 DRIVER MODULE
* SHT30驱动模块
*
* File : SHT30Driver.h
* By : Lin Shijun(https://blog.csdn.net/lin_strong)
* Date : 2020/06/17
* version: V1.1
* History: 2020/04/29 V1.0 the prototype
* 2020/06/17 V1.1 find that SHT30's data is "XXXX Hum = XXXX"
* but not "XXXX Humi = XXXX" in SHT20, so fix it.
* Note : The SHT30 driver is divided into two part, i.e. cmder and recver. The cmder is for
* sending the SHT30 command. The recver is for resolving data from the SHT30.
********************************************************************************************
*/#ifndef SHT30DRIVER_H
#define SHT30DRIVER_H/*
******************************************************************************************
* INCLUDE
******************************************************************************************
*/#include <stdint.h>/*
******************************************************************************************
* DEBUG CONFIGURATION
******************************************************************************************
*/// to enable debug messages in this module
// #define SHT30_DEBUG/*
******************************************************************************************
* TYPE DEFINE
******************************************************************************************
*/typedef struct SHT30STRUCT_DATA{float temp; // °Cfloat humi; // percent
} SHT30Data;typedef void (* SHT30FUNC_DATA)(SHT30Data data);typedef enum {SHT30SR_10Hz ,SHT30SR_5Hz ,SHT30SR_2Hz ,SHT30SR_1Hz ,SHT30SR_0d5Hz, // 0.5HzSHT30SR_0d2Hz, // 0.2HzSHT30SR_0d1Hz, // 0.1Hz
}SHT30SampleRate;
/*
************************************************************************************
* INTERFACES
************************************************************************************
*/void SHT30Cmder_Init(void (* outChannel)(uint8_t *buf, uint16_t len));
void SHT30Cmder_Destroy(void);
void SHT30Cmder_setSampleRate(SHT30SampleRate value);void SHT30Recver_Init(SHT30FUNC_DATA onRecvData);
// Call it to modify the call-back function.
void SHT30Recver_RegisterCallback(SHT30FUNC_DATA onRecvData);
void SHT30Recver_CleanupBuffer(void);
// Feed the receiver every byte received so that receiver can notify user
// the resolved data for each frame.
void SHT30Recver_Feed(uint8_t nextByte);
void SHT30Recver_Destroy(void);#endif // of SHT30DRIVER_H
SHT30Recver.c
/*
*******************************************************************************************
*
* SHT30 RECEIVER MODULE
* SHT30驱动模块 - 接收机
*
* File : SHT30Recver.c
* By : Lin Shijun(https://blog.csdn.net/lin_strong)
* Date : 2020/06/17
* version: V1.1
* History: 2020/06/17
* Note :
********************************************************************************************
*//*
*********************************************************************************************
* INCLUDES
*********************************************************************************************
*/#include <string.h>
#include <ctype.h>
#include "SHT30Driver.h"
#include "RxMac.h"#ifndef SHT30_DEBUG
#undef _DEBUG
#endif#include "DebugMsg.h"/*
*********************************************************************************************
* LOCAL FUNCTION
*********************************************************************************************
*/#define ARRAYSIZE(arr) (sizeof(arr)/ sizeof(arr[0]))
static void _onFlushed(RxMac sender,RxMacPtr buf,uint16_t len,RxState state,RxFlag HorU,RxFlag Ender);/*
*********************************************************************************************
* LOCAL VARIABLE
*********************************************************************************************
*/static const char * _str_SHT30Recver = "SHT30Recver";static SHT30FUNC_DATA _onRecvData;
static const uint8_t _flag_header[] = {(uint8_t)'T', (uint8_t)'e', (uint8_t)'m', (uint8_t)'p', (uint8_t)' ', (uint8_t)'=', (uint8_t)' '};
static const uint8_t _flag_ender[] = {(uint8_t)'\r', (uint8_t)'\n'};
static const RXFLAG_STRUCT _flags[] = {{_flag_header, sizeof(_flag_header), RXFLAG_OPTION_STRONG_HEADER},{_flag_ender , sizeof(_flag_ender) , RXFLAG_OPTION_STRONG_ENDER }
};
static RxMac _mac;
static uint8_t _macBuf[36];/*
*********************************************************************************************
* INTERFACE IMPLEMENTATION
*********************************************************************************************
*/void SHT30Recver_Init(SHT30FUNC_DATA onRecvData){_onRecvData = onRecvData;_mac = RxMac_Create(_flags, ARRAYSIZE(_flags), _macBuf, sizeof(_macBuf) - 1,NULL, NULL, _onFlushed);if(_mac == NULL)for(;;);
}void SHT30Recver_Destroy(){_onRecvData = NULL;RxMac_Destroy(_mac);
}void SHT30Recver_RegisterCallback(SHT30FUNC_DATA onRecvData){_onRecvData = onRecvData;
}void SHT30Recver_CleanupBuffer(void){RxMac_ResetState(_mac);
}void SHT30Recver_Feed(uint8_t nextByte){RxMac_FeedData(_mac, nextByte);
}/*
*********************************************************************************************
* LOCAL FUNCTION IMPLEMENTATION
*********************************************************************************************
*/
static int _FloatFormatRight(const char *beg, const char *end){const char *p;if(end - beg <= 0)return 0;for(p = beg; end - p > 0; p++)if(!isdigit(*p) && *p != '-' && *p != '.')return 0;return 1;
}static void _onFlushed(RxMac sender,RxMacPtr buf,uint16_t len,RxState state,RxFlag HorU,RxFlag Ender){const char *p;SHT30Data data;if(_onRecvData == NULL || !state.headerFound || !state.enderFound)return;buf[len] = '\0';p = strstr((const char *)buf, " Hum = ");if(p == NULL || !_FloatFormatRight((const char *)&buf[7], p) || !_FloatFormatRight((const char *)&p[9], (const char *)buf + len - 2)){_dbg_printf2("%s: got corrupt frame-%s", _str_SHT30Recver, (const char *)buf);return;}data.temp = (float)atof((const char *)&buf[7]);data.humi = (float)atof((const char *)&p[9]);_dbg_printf3("%s: got data-temp(%.3f),humi(%.3f)\r\n", _str_SHT30Recver, data.temp, data.humi);_onRecvData(data);
}
SHT30Cmder.c
/*
*******************************************************************************************
*
* SHT30 COMMANDER MODULE
* SHT30驱动模块 - 指令器
*
* File : SHT30Cmder.c
* By : Lin Shijun(https://blog.csdn.net/lin_strong)
* Date : 2020/06/17
* version: V1.1
* History: 2020/06/17
* Note : Only implement the set sample rate command for now.
********************************************************************************************
*//*
*********************************************************************************************
* INCLUDES
*********************************************************************************************
*/#include <stdio.h>
#include "SHT30Driver.h"/*
*********************************************************************************************
* LOCAL VARIABLE
*********************************************************************************************
*/
static void (* _out)(uint8_t *buf, uint16_t len) = NULL;/*
*********************************************************************************************
* INTERFACE IMPLEMENTATION
*********************************************************************************************
*/void SHT30Cmder_Init(void (* outChannel)(uint8_t *buf, uint16_t len)){_out = outChannel;
}void SHT30Cmder_Destroy(){_out = NULL;
}void SHT30Cmder_setSampleRate(SHT30SampleRate value){uint8_t buf[] = {0xFF, 0xAA, 0x09, 0x00, 0x00};buf[3] = (uint8_t)value;if(_out != NULL)_out(buf, sizeof(buf));
}
依赖
接收器的实现依赖于我写的通用接收机:
通用接收状态机模块
至于DebugMsg.h则是我自己使用的调试信息的模块:
#ifndef _DEBUG_MSG_H
#define _DEBUG_MSG_H
#include <stdio.h>
#ifdef _DEBUG#define _dbg_printf0(format) ((void)printf(format))#define _dbg_printf1(format,p1) ((void)printf(format,p1))#define _dbg_printf2(format,p1,p2) ((void)printf(format,p1,p2))#define _dbg_printf3(format,p1,p2,p3) ((void)printf(format,p1,p2,p3))#define _dbg_printf4(format,p1,p2,p3,p4) ((void)printf(format,p1,p2,p3,p4))#define _dbg_printf5(format,p1,p2,p3,p4,p5) ((void)printf(format,p1,p2,p3,p4,p5))#define _dbg_printf6(format,p1,p2,p3,p4,p5,p6) ((void)printf(format,p1,p2,p3,p4,p5,p6))#define _dbg_printf7(format,p1,p2,p3,p4,p5,p6,p7) \((void)printf(format,p1,p2,p3,p4,p5,p6,p7))#define _dbg_printf8(format,p1,p2,p3,p4,p5,p6,p7,p8) \((void)printf(format,p1,p2,p3,p4,p5,p6,p7,p8))#define _dbg_printf9(format,p1,p2,p3,p4,p5,p6,p7,p8,p9) \((void)printf(format,p1,p2,p3,p4,p5,p6,p7,p8,p9))
#else#define _dbg_printf0(format)#define _dbg_printf1(format,p1)#define _dbg_printf2(format,p1,p2)#define _dbg_printf3(format,p1,p2,p3)#define _dbg_printf4(format,p1,p2,p3,p4)#define _dbg_printf5(format,p1,p2,p3,p4,p5)#define _dbg_printf6(format,p1,p2,p3,p4,p5,p6)#define _dbg_printf7(format,p1,p2,p3,p4,p5,p6,p7)#define _dbg_printf8(format,p1,p2,p3,p4,p5,p6,p7,p8)#define _dbg_printf9(format,p1,p2,p3,p4,p5,p6,p7,p8,p9)
#endifint dummyprintf(const char *format, ...);#endif
这样在项目中同时宏定义 _DEBUG 和 SHT30_DEBUG 时才会打印调试信息。不需要的话删除相关语句就好。
想要了解相关技巧的话详见:
C语言宏配置的各种奇淫技巧
使用示例
使用此模块基本分几步:
- 初始化模块
- 如需要发送指令则实现并注册信道给指令器;注册回调函数给接收器,这样接收器在发现完整的数据帧时就会通过回调函数进行通知。
- 不断接收数据,并喂(Feed)给接收器;如需要发指令,随时调用指令器的接口。
以下代码示例了在上电后不断读取数据并进行解析(假设使用标准输入输出上的串口和SHT30通信):
#include "SHT30Driver.h"
#include <stdio.h>
#include <stdint.h>
……
// 收到数据的回调函数
static void onDataResolved(SHT30Data data);
// 发送信道
static void sendChannel(uint8_t *buf, uint16_t len);void main(){uint8_t b;……SHT30Recver_Init(onDataResolved);SHT30Cmder_Init(sendChannel);// 如果需要调整采样率的话发送对应指令,注意要先发一次指令使进入配置模式的问题// SHT30Cmder_setSampleRate(SHT30SR_1Hz);for(;;){// 不断得到下一个字节并喂给接收机// 接收机会通过回调函数实时传递解析出来的值b = (uint8_t)getchar();SHT30Recver_Feed(b);}
}static void onDataResolved(SHT30Data data){// data中就是实时解析到的数据,具体怎么使用是你的事
}static void sendChannel(uint8_t *buf, uint16_t len){// 往标准输出输出这个字节while(len-- > 0)putchar((char)*buf++);
}
更新历史
2020/06/07 放出V1.0
2020/06/17 发现了SHT30和SHT20在数据输出格式上一个是Humi,一个是Hum,所以修正为了SHT30的Hum。如果是SHT20。则将Recver中的onFlush函数按如下修改即可。
static void _onFlushed(RxMac sender,RxMacPtr buf,uint16_t len,RxState state,RxFlag HorU,RxFlag Ender){const char *p;SHT30Data data;if(_onRecvData == NULL || !state.headerFound || !state.enderFound)return;buf[len] = '\0';p = strstr((const char *)buf, " Humi = ");if(p == NULL || !_FloatFormatRight((const char *)&buf[7], p) || !_FloatFormatRight((const char *)&p[10], (const char *)buf + len - 2)){_dbg_printf2("%s: got corrupt frame-%s", _str_SHT30Recver, (const char *)buf);return;}data.temp = (float)atof((const char *)&buf[7]);data.humi = (float)atof((const char *)&p[10]);_dbg_printf3("%s: got data-temp(%.3f),humi(%.3f)\r\n", _str_SHT30Recver, data.temp, data.humi);_onRecvData(data);
}
[嵌入式开发模块]SHT30/20 温湿度传感器 驱动模块相关推荐
- 嵌入式开发在过去20年中是如何演变的
嵌入式开发在过去20年中是如何演变的 How embedded development has evolved over the past two decades 与任何开发领域一样,嵌入式系统开发就 ...
- Arduino开发板使用DHT11温湿度传感器的方法
在本篇文章中,我们将DHT11温湿度传感器与Arduino开发板和LCD显示屏连接,设计一种能够测量室温和环境湿度的设备.简单地说,我们将使用Arduino和DHT11传感器设计数字湿度和温度计,并将 ...
- c语言数组实现环形缓冲区,[嵌入式开发模块]环形缓冲区/循环队列 C语言实现
忙着毕设,很久没有写文章了,终于答辩完了,得了个校优秀毕业设计.毕设做的是个智能接口模块,用一周时间入门了,MC9S12XEP100的开发,又用一周时间入门了uC/OS-II嵌入式操作系统,在做毕设的 ...
- [嵌入式开发模块]JY61姿态角度传感器 驱动模块
文章目录 前言 JY61简介 概述 通信协议 驱动文件 JY61Driver.h JY61Recver.c JY61Cmder.c 依赖 使用示例 更新历史 前言 干活中用到了JY61姿态角度传感器, ...
- [嵌入式开发模块]GY25倾斜角度传感器 驱动模块
文章目录 前言 GY25简介 概述 通信协议 驱动文件 GY25Driver.h GY25Recver.c GY25Cmder.c 依赖 使用示例 更新历史 前言 干活中用到了GY25传感器模块,写了 ...
- [嵌入式开发模块]AD转换芯片ADS8344驱动模块
文章目录 芯片简介 代码 头文件 源文件 使用及示例代码 芯片简介 ADS8344是一个8通道16位模数转换器,使用SPI接口. 其可以使用单端或差分输入,单端模式时,每个CHX独立作为采样输入,测其 ...
- 嵌入式开发模块]AD转换芯片ADS8344驱动模块16位分辨率,程序实例
文章目录 芯片简介 代码 头文件 源文件 使用及示例代码 芯片简介 ADS8344是一个8通道16位模数转换器,使用SPI接口. 其可以使用单端或差分输入,单端模式时,每个CHX独立作为采样输入,测其 ...
- MSP430 单片机 SHT30 SHT31 温湿度传感器 MSP430F5529 MSP430G2553 程序
SHT30和SHT31程序是一样的 手册是一样的 寄存器是一样的 操作都是一样的. 唯一 不同点是:SHT31的湿度波动小,测量较准确. 推荐打开SHT3X的周期测量模式,然后一直循环读取寄存器即可, ...
- [嵌入式开发模块]通用接收状态机模块
文章目录 前言 模块相关概念和逻辑 接收机状态 标志字符序列 flush 接收机类 过滤器 onGetHeader事件 接收机运行逻辑 边际条件 相关代码 接收机代码 RxMac.h RxMacPri ...
最新文章
- mybatis-plus对datetime返回去掉.0_华为AI认证-TensorFlow2.0编程基础
- C#_Math函数总结
- 查看linux4222端口,linux 内核 ALIGN 含义
- python3.6安装教程-Python 3.6.6安装教程(附安装包) | 我爱分享网
- UA MATH524 复变函数13 补充:留数计算的例题
- git cherry-pick简介
- 基于用例点来度量软件规模并管理进度 之结束语
- EasyUI表单验证,自定义插件验证,自定义js插件验证,远程验证,常见手机号,中英文,qq等验证规则验证
- 卷积神经网络——池化层学习——最大池化
- spark中使用categoricalFeaturesInfo来标记分类型变量
- oracle 10g安装需注意细节
- 网络管理与维护作业5
- 下载安装tomcat和jdk,配置运行环境,与Intellij idea 2017关联
- [Google Guava]学习--新集合类型BiMap
- idea svn回退版本_mac下使用svn通过终端回退版本到某个版本号 - 博客频道 - CSDN.NET...
- 吴伯凡-认知方法论-知行合一-建立神经元之间的高带宽连接
- Python 给图片上加文字
- World Locking Tools for Unity (一)指南部分
- 11.0、C语言数据结构——栈
- mysql加密函数password