原理图资料
模块说明
数字温湿度传感 DHT11
►相对湿度和温度测量
►全部校准,数字输出
►卓越的长期稳定性
►无需额外部件
►超长的信号传输距离
►超低能耗
►4 引脚安装
►完全互换
DHT11产品概述
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传
感器。 它应用专用的数字模块采集技术和温湿度传感技术, 确保产品具有极高
的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测
温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快
响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的
湿度校验室中进行校准。校准系数以程序的形式储存在OTP内存中,传感器内
部在检测信号的处理过程中要调用这些校准系数。 单线制串行接口, 使系统集
成变得简易快捷。超小的体积、极低的功耗, 信号传输距离可达20米以上, 使
其成为各类应用甚至最为苛刻的应用场合的最佳选则。产品为 4 针单排引脚
封装。 连接方便, 特殊封装形式可根据用户需求而提供。
接口说明
建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使
用合适的上拉电阻
电源引脚
DHT11的供电电压为 3-5.5V。 传感器上电后, 要等待 1s 以越过不稳定状态在此期间无需发送任何指令。 电源引脚( VDD, GND) 之间可增加一个100nF 的电容, 用以去耦滤波。
串行接口 (单线双向)
DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次
通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数
部分用于以后扩展,现读出为零.操作流程如下:
一次完整的数据传输为40bit,高位先出。
总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必
须大于18毫秒,保证DHT11能检测到起始信号。 DHT11接收到主机的开始信号后,
等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束
后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换
到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。
MAX30100 的说明
原理简介:
MAX30100 如何测量脉率? 该设备有两个 LED, 一个发射红光, 另一个发射红外光。 红光和红外光都用来测量血液中的氧含量。 当心脏泵血时, 由于有更多血液, 含氧血液增加。随着心脏放松, 含氧血液的体积也减少。 通过知道氧合血液增加和减少之间的时间, 确定脉搏率。 事实证明, 含氧血吸收更多的红外光并传递更多的红光, 而脱氧血吸收红光并传递更多的红外光。 这就是 MAX30100 的主要功能原理: 它读取两个光源的吸收电平, 并将它们存储在可通过 I2C 读取的缓冲区中。 但是, 它并不像听起来那么简单, 中间会涉及到很多数据过滤以及处理过程。
0.96寸OLED显示屏模块
OLED模块
4针链接OLED iic接口 网盘下载
提取码:869m
测试数据处理图
部分代码展示
void max10300_init()
{
max10300_Bus_Write(0x06, 0x0b); //mode configuration : temp_en[3] MODE[2:0]=010 HR only enabled 011 SP02 enabled
//max10300_Bus_Write(0x06, 0x0a); //MODE[2:0]=010 HR only enabled when used is mode ,the red led is not used.
max10300_Bus_Write(0x01, 0xF0); //open all of interrupt
max10300_Bus_Write(INTERRUPT_REG, 0x00); //all interrupt clear
max10300_Bus_Write(0x09, 0x33); //r_pa=3,ir_pa=3
#ifdef SAMPLE_50
max10300_Bus_Write(0x07, 0x43); //SPO2_SR[4:2]=000 50 per second LED_PW[1:0]=11 16BITS
#else
max10300_Bus_Write(0x07, 0x47); //SPO2_SR[4:2]=001 100 per second LED_PW[1:0]=11 16BITS
#endif
max10300_Bus_Write(0x02, 0x00); //set FIFO write Pointer reg = 0x00 for clear it
max10300_Bus_Write(0x03, 0x00); //set Over Flow Counter reg = 0x00 for clear it
max10300_Bus_Write(0x04, 0x0f); //set FIFO Read Pointer reg = 0x0f for
//waitting write pointer eq read pointer to interrupts INTERRUPT_REG_A_FULL
}
double my_floor(double x)
{
double y=x;
if( (*( ( (int *) &y)+1) & 0x80000000) != 0) //或者if(x<0)
return (float)((int)x)-1;
else
return (float)((int)x);
}
double my_fmod(double x, double y)
{
double temp, ret;
if (y == 0.0)
return 0.0;
temp = my_floor(x/y);
ret = x - temp * y;
if ((x < 0.0) != (y < 0.0))
ret = ret - y;
return ret;
}
#define XPI (3.1415926535897932384626433832795)
#define XENTRY (100)
#define XINCL (XPI/2/XENTRY)
static const double XSinTbl[] = {
0.00000000000000000 , 0.015707317311820675 , 0.031410759078128292 , 0.047106450709642665 , 0.062790519529313374 ,
0.078459095727844944 , 0.094108313318514325 , 0.10973431109104528 , 0.12533323356430426 , 0.14090123193758267 ,
0.15643446504023087 , 0.17192910027940955 , 0.18738131458572463 , 0.20278729535651249 , 0.21814324139654256 ,
0.23344536385590542 , 0.24868988716485479 , 0.26387304996537292 , 0.27899110603922928 , 0.29404032523230400 ,
0.30901699437494740 , 0.32391741819814940 , 0.33873792024529142 , 0.35347484377925714 , 0.36812455268467797 ,
0.38268343236508978 , 0.39714789063478062 , 0.41151435860510882 , 0.42577929156507272 , 0.43993916985591514 ,
0.45399049973954680 , 0.46792981426057340 , 0.48175367410171532 , 0.49545866843240760 , 0.50904141575037132 ,
0.52249856471594880 , 0.53582679497899666 , 0.54902281799813180 , 0.56208337785213058 , 0.57500525204327857 ,
0.58778525229247314 , 0.60042022532588402 , 0.61290705365297649 , 0.62524265633570519 , 0.63742398974868975 ,
0.64944804833018377 , 0.66131186532365183 , 0.67301251350977331 , 0.68454710592868873 , 0.69591279659231442 ,
0.70710678118654757 , 0.71812629776318881 , 0.72896862742141155 , 0.73963109497860968 , 0.75011106963045959 ,
0.76040596560003104 , 0.77051324277578925 , 0.78043040733832969 , 0.79015501237569041 , 0.79968465848709058 ,
0.80901699437494745 , 0.81814971742502351 , 0.82708057427456183 , 0.83580736136827027 , 0.84432792550201508 ,
0.85264016435409218 , 0.86074202700394364 , 0.86863151443819120 , 0.87630668004386369 , 0.88376563008869347 ,
0.89100652418836779 , 0.89802757576061565 , 0.90482705246601958 , 0.91140327663544529 , 0.91775462568398114 ,
0.92387953251128674 , 0.92977648588825146 , 0.93544403082986738 , 0.94088076895422557 , 0.94608535882754530 ,
0.95105651629515353 , 0.95579301479833012 , 0.96029368567694307 , 0.96455741845779808 , 0.96858316112863108 ,
0.97236992039767667 , 0.97591676193874743 , 0.97922281062176575 , 0.98228725072868872 , 0.98510932615477398 ,
0.98768834059513777 , 0.99002365771655754 , 0.99211470131447788 , 0.99396095545517971 , 0.99556196460308000 ,
0.99691733373312796 , 0.99802672842827156 , 0.99888987496197001 , 0.99950656036573160 , 0.99987663248166059 ,
1.00000000000000000 };
double XSin( double x )
{
int s = 0 , n;
double dx , sx , cx;
if( x < 0 )
s = 1 , x = -x;
x = my_fmod( x , 2 * XPI );
if( x > XPI )
s = !s , x -= XPI;
if( x > XPI / 2 )
x = XPI - x;
n = (int)( x / XINCL );
dx = x - n * XINCL;
if( dx > XINCL / 2 )
++n , dx -= XINCL;
sx = XSinTbl[n];
cx = XSinTbl[XENTRY-n];
x = sx + dx*cx - (dx*dx)*sx/2
- (dx*dx*dx)*cx/6
+ (dx*dx*dx*dx)*sx/24
;
return s ? -x : x;
}
double XCos( double x )
{
return XSin( x + XPI/2 );
}
```c
void test_max30100_fun(void)
{
u16 temp_num=0;
u16 fifo_word_buff[15][2];
u16 Heart_Rate=0;
u16 s1_max_index=0;
u16 s2_max_index=0;
delayl_init(); //延时函数初始化
OLED_Init(); //初始化OLED
while(1)
{
temp_num = max10300_Bus_Read(INTERRUPT_REG);
//if( (INTERRUPT_REG_HR_RDY&temp_num) && (INTERRUPT_REG_SPO2_RDY&temp_num) )
if( INTERRUPT_REG_A_FULL&temp_num )
{
max10300_FIFO_Read(0x05,fifo_word_buff,15); //read the hr and spo2 data form fifo in reg=0x05
{
u16 i=0;
for(i=0;i<15;i++)
{
if(g_fft_index < FFT_N)
{
s1[g_fft_index].real = fifo_word_buff[i][0];
s1[g_fft_index].imag= 0;
s2[g_fft_index].real = fifo_word_buff[i][1];
s2[g_fft_index].imag= 0;
g_fft_index++;
}
}
if(g_fft_index>=FFT_N)
{
{ //printf() fft data
u16 index=0;
for(index=0;index<40;index++)
{
//printf("s1[%3d]= %f\r\n",index,s1[index].real);
//printf("s2[%3d]= %f\r\n",index,s2[index].real);
}
}
FFT(s1);
FFT(s2);
for(i=0;i<FFT_N;i++)
{
s1[i].real=sqrtf(s1[i].real*s1[i].real+s1[i].imag*s1[i].imag);
s2[i].real=sqrtf(s2[i].real*s2[i].real+s2[i].imag*s2[i].imag);
}
{ //printf() fft data
u16 index=START_INDEX;
for( ;index<60;index++)
{
#ifdef SAMPLE_50
printf("f=%3.3f HZ,s1[%3d] = %f \r\n",50.0/FFT_N*index,index,s1[index].real);
printf("f=%3.3f HZ,s2[%3d] = %f \r\n",50.0/FFT_N*index,index,s2[index].real);
#else
printf("f=%3.3f HZ,s1[%3d] = %f \r\n",100.0/FFT_N*index,index,s1[index].real);
printf("f=%3.3f HZ,s2[%3d] = %f \r\n",100.0/FFT_N*index,index,s2[index].real);
#endif
}
}
s1_max_index = find_max_num_index(s1, 60);
s2_max_index = find_max_num_index(s2, 60);
if(s1_max_index == s2_max_index)
{
#ifdef SAMPLE_50
Heart_Rate = 60*50*((s1_max_index+s2_max_index )/2)/FFT_N;
#else
Heart_Rate = 60*100*((s1_max_index+s2_max_index )/2)/FFT_N;
#endif
printf("\r\n心率为: %d\r\n",Heart_Rate+52);
sp02_treated_fun(s1_max_index);
OLED_ShowString(0,0, "SpO2:",16);
OLED_ShowString(0,30,"Heart_Rate:",12);
OLED_ShowNum(70,30,Heart_Rate+52,4,16);
OLED_Refresh();//更新显示到OLED
}
else
{
printf("\r\n 测量失败, 请压好重新测量!\r\n");
OLED_ShowString(0,0, "SpO2:",16);
OLED_ShowString(0,30,"Heart_Rate:",12);
OLED_ShowString(70,30,"ERROR",16);
OLED_Refresh();//更新显示到OLED
}
g_fft_index = 0;
}
}
/* ic 自动管理FIFO指针 不用参与
max10300_Bus_Write(0x02, 0x00); //set FIFO write Pointer reg = 0x00 for clear it
max10300_Bus_Write(0x03, 0x00); //set Over Flow Counter reg = 0x00 for clear it
max10300_Bus_Write(0x04, 0x0f); //set FIFO Read Pointer reg = 0x0F
max10300_Bus_Write(INTERRUPT_REG, 0x00); // all interrupt clear
*/
}
}
}
`
资料包
心率模块资料分享
链接:https://pan.baidu.com/s/129VgzvSngC_rhLgqGAK2vg
提取码:8pyd