天天看點

基于單片機stm32的人體健康監護系統 - 單片機 嵌入式 物聯網

作者:嵌入式xff

基于stm32的人體健康監護系統

  • 難度系數:4分
  • 工作量:4分
  • 創新點:3分

1 簡介

基于STM32F103C8T6單片機開發的勞工監測系統,該系統可以實時的監測溫濕度、煙霧濃度、心率、環衛勞工位置,并可以将這些資料在上位機端進行顯示,将手指放置在心率檢測傳感器上,上位機端有心率顯示,煙雨霧濃度超過門檻值會進行報警并顯示勞工位置。

2 主要器件

  • STM32F103C8T6
  • 心率傳感器
  • 溫室度傳感器
  • 煙霧濃度傳感器

3 實作效果

基于單片機stm32的人體健康監護系統 - 單片機 嵌入式 物聯網

4 設計原理

4.1 ATGM332D定位子產品

簡介

ATGM332D-5N 系列子產品是12X16 尺寸的高性能BDS/GNSS 全星座定位導航子產品系列的總稱。該系列子產品産品都是基于中科微第四代低功耗 GNSS SOC單晶片—AT6558,支援美國的 GPS、中國的 BDS(北鬥衛星導航系統)

ATGM332D-5N 系列子產品具有高靈敏度、低功耗、低成本等優勢,适用車載導航、手持定位、可穿戴裝置,可以直接替換 NEO-M8N,封裝尺寸和引腳定義完全相容。

子產品預設波特率為9600,所有封包全開,不能直接使用

9600且所有封包全開,會造成資料堵塞,發生時間整秒延遲,大約在1,2,3,4秒整秒跳動。

必須調高波特率到115200;或關閉多餘封包,僅留RMC。

經緯資料說明

基于單片機stm32的人體健康監護系統 - 單片機 嵌入式 物聯網

4.2 MAX30102心率傳感器

MAX30102是一個內建的脈搏血氧儀和心率監測儀生物傳感器的子產品。它內建了一個紅光LED和一個紅外光LED、光電檢測器、光器件,以及帶環境光抑制的低噪聲電子電路。MAX30102采用一個1.8V電源和一個獨立的5.0V用于内部LED的電源,應用于可穿戴裝置進行心率和血氧采集檢測,佩戴于手指、耳垂和手腕等處。标準的2C相容的通信接口可以将采集到的數值傳輸給Arduino、KL25Z等單片機進行心率和血氧計算。此外,該晶片還可通過軟體關斷子產品,待機電流接近為零,實作電源始終維持供電狀态。正因為其優異的性能,該晶片被大量應用在了三星 Galaxy S7 手機。與前代産品 MAX30100 相比 (MAX30100 目前已經停産淘汰 ) , MAX30102 內建了玻璃蓋可以有效排除外界和内部光幹擾,擁有最優可靠的性能。

傳統的脈搏測量方法主要有三種:

  • 一是從心電信号中提取;
  • 二是從測量血壓時壓力傳感器測到的波動來計算脈率;
  • 三是光電容積法。

前兩種方法提取信号都會限制病人的活動,如果長時間使用會增加病人生理和心理上的不舒适感。而光電容積法脈搏測量作為監護測量中最普遍的方法之一,其具有方法簡單、佩戴友善、可靠性高等特點。 光電容積法的基本原理是利用人體組織在血管搏動時造成透光率不同來進行脈搏和血 氧飽和度測量的。其使用的傳感器由光源和光電變換器兩部分組成,通過綁帶或夾子固定 在病人的手指、手腕或耳垂上。光源一般采用對動脈血中氧合血紅蛋白( HbO2 )和血紅蛋 白( Hb )有選擇性的特定波長的發光二極管(一般選用 660nm 附近的紅光和 900nm 附近的 紅外光)。當光束透過人體外周血管,由于動脈搏動充血容積變化導緻這束光的透光率發 生改變,此時由光電變換器接收經人體組織反射的光線,轉變為電信号并将其放大和輸 出。由于脈搏是随心髒的搏動而周期性變化的信号,動脈血管容積也周期性變化,是以光 電變換器的電信号變化周期就是脈搏率。同時根據血氧飽和度的定義,其表示為:

基于單片機stm32的人體健康監護系統 - 單片機 嵌入式 物聯網

MAX30102 本身內建了完整的發光 LED 及驅動部分,光感應和 AD 轉換部分,環境光幹 擾消除及數字濾波部分,隻将數字接口留給使用者,極大地減輕了使用者的設計負擔。使用者隻 需要使用單片機通過硬體 I2C或者模拟I2C接口來讀取 MAX30102 本身的FIFO ,就可以得到轉換後的光強度數值,通過編寫相應算法就可以得到心率值和血氧飽和度。

基于單片機stm32的人體健康監護系統 - 單片機 嵌入式 物聯網

4.3 DHT11溫濕度傳感器

簡介

基于單片機stm32的人體健康監護系統 - 單片機 嵌入式 物聯網

DHT11數字溫濕度傳感器是一款含有已校準數字信号輸出的溫濕度複合傳感器。它應用專用的數字子產品采集技術和溫濕度傳感技術,確定産品具有極高的可靠性與卓越的長期穩定性。傳感器包括一個電阻式感濕元件和一個NTC測溫元件,并與一個高性能8位單片機相連接配接。是以該産品具有品質卓越、超快響應、抗幹擾能力強、成本效益極高等優點。每個DHT11傳感器都在極為精确的濕度校驗室中進行校準。校準系數以程式的形式儲存在OTP記憶體中,傳感器内部在檢測信号的處理過程中要調用這些校準系數。單線制串行接口,使系統內建變得簡易快捷。超小的體積、極低的功耗,信号傳輸距離可達20米以上,使其成為各類應用甚至最為苛刻的應用場合的最佳選則。産品為 4 針單排引腳封裝。連接配接友善,特殊封裝形式可根據使用者需求而提供。

接線

基于單片機stm32的人體健康監護系統 - 單片機 嵌入式 物聯網

DHT11編碼步驟

  1. 單片機上點後1s内不讀取(不重要)
  2. 主機(單片機)發送起始信号:主機先拉高data拉低data延遲18ms拉高data(通過此操作将單片機引腳設定為輸入)。
  3. 從機(DHT11)收到起始信号後進行應答:從機拉低data,主機讀取到data線被拉低持續80us後從機拉高data線, 持續80us,直到高電平結束,意味着主機可以開始接受資料。
  4. 主機開始接收資料:主機先把data線拉高(io設定為輸入)從機把data線拉低,主機讀取data線電平,直到低電平結束(大約50us)從機拉高data線後,延遲40us左右(28~70us之間)主機再次讀取data線電平,如果為低電平,則為“0”,如果為高電平,則為“1”。繼續重複上述1,2步驟累計40次。

4.4 MQ-2煙霧傳感器

簡介

MQ-2常用于家庭和工廠的氣體洩漏監測裝置,适宜于液化氣、苯、烷、酒精、氫氣、煙霧等的探測。故是以,MQ-2可以準确來說是一個多種氣體探測器。

MQ-2的探測範圍極其的廣泛。它的優點:靈敏度高、響應快、穩定性好、壽命長、驅動電路簡單。

基于單片機stm32的人體健康監護系統 - 單片機 嵌入式 物聯網

二、MQ-2的工作原理

MQ-2型煙霧傳感器屬于二氧化錫半導體氣敏材料,屬于表面離子式N型半導體。處于200~300攝氏度時,二氧化錫吸附空氣中的氧,形成氧的負離子吸附,使半導體中的電子密度減少,進而使其電阻值增加。當與煙霧接觸時,如果晶粒間界處的勢壘收到煙霧的調至而變化,就會引起表面導電率的變化。利用這一點就可以獲得這種煙霧存在的資訊,煙霧的濃度越大,導電率越大,輸出電阻越低,則輸出的模拟信号就越大。

基于單片機stm32的人體健康監護系統 - 單片機 嵌入式 物聯網

5 部分核心代碼

/** \file max30102.cpp ******************************************************
*
* Project: MAXREFDES117#
* Filename: max30102.cpp
* Description: This module is an embedded controller driver for the MAX30102
*
* Revision History:
*\n 1-18-2016 Rev 01.00 GL Initial release.
*\n
*/

#include "max30102.h"
#include "myiic.h"

#define max30102_WR_address 0xAE
bool maxim_max30102_write_reg(uint8_t uch_addr, uint8_t uch_data)
/**
* \brief        Write a value to a MAX30102 register
* \par          Details
*               This function writes a value to a MAX30102 register
*
* \param[in]    uch_addr    - register address
* \param[in]    uch_data    - register data
*
* \retval       true on success
*/
{
    /* 第1步:發起I2C總線啟動信号 */
    i2c_Start();

    /* 第2步:發起控制位元組,高7bit是位址,bit0是讀寫控制位,0表示寫,1表示讀 */
    i2c_SendByte(max30102_WR_address | I2C_WR);	/* 此處是寫指令 */

    /* 第3步:發送ACK */
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;	/* EEPROM器件無應答 */
    }

    /* 第4步:發送位元組位址 */
    i2c_SendByte(uch_addr);
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;	/* EEPROM器件無應答 */
    }

    /* 第5步:開始寫入資料 */
    i2c_SendByte(uch_data);

    /* 第6步:發送ACK */
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;	/* EEPROM器件無應答 */
    }

    /* 發送I2C總線停止信号 */
    i2c_Stop();
    return true;	/* 執行成功 */

cmd_fail: /* 指令執行失敗後,切記發送停止信号,避免影響I2C總線上其他裝置 */
    /* 發送I2C總線停止信号 */
    i2c_Stop();
    return false;
}

bool maxim_max30102_read_reg(uint8_t uch_addr, uint8_t *puch_data)
/**
* \brief        Read a MAX30102 register
* \par          Details
*               This function reads a MAX30102 register
*
* \param[in]    uch_addr    - register address
* \param[out]   puch_data    - pointer that stores the register data
*
* \retval       true on success
*/
{
    /* 第1步:發起I2C總線啟動信号 */
    i2c_Start();

    /* 第2步:發起控制位元組,高7bit是位址,bit0是讀寫控制位,0表示寫,1表示讀 */
    i2c_SendByte(max30102_WR_address | I2C_WR);	/* 此處是寫指令 */

    /* 第3步:發送ACK */
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;	/* EEPROM器件無應答 */
    }

    /* 第4步:發送位元組位址, */
    i2c_SendByte((uint8_t)uch_addr);
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;	/* EEPROM器件無應答 */
    }


    /* 第6步:重新啟動I2C總線。下面開始讀取資料 */
    i2c_Start();

    /* 第7步:發起控制位元組,高7bit是位址,bit0是讀寫控制位,0表示寫,1表示讀 */
    i2c_SendByte(max30102_WR_address | I2C_RD);	/* 此處是讀指令 */

    /* 第8步:發送ACK */
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;	/* EEPROM器件無應答 */
    }

    /* 第9步:讀取資料 */
    {
        *puch_data = i2c_ReadByte();	/* 讀1個位元組 */

        i2c_NAck();	/* 最後1個位元組讀完後,CPU産生NACK信号(驅動SDA = 1) */
    }
    /* 發送I2C總線停止信号 */
    i2c_Stop();
    return true;	/* 執行成功 傳回data值 */

cmd_fail: /* 指令執行失敗後,切記發送停止信号,避免影響I2C總線上其他裝置 */
    /* 發送I2C總線停止信号 */
    i2c_Stop();
    return false;
}

bool maxim_max30102_init(void)
/**
* \brief        Initialize the MAX30102
* \par          Details
*               This function initializes the MAX30102
*
* \param        None
*
* \retval       true on success
*/
{
    if(!maxim_max30102_write_reg(REG_INTR_ENABLE_1, 0xc0)) // INTR setting
        return false;
    if(!maxim_max30102_write_reg(REG_INTR_ENABLE_2, 0x00))
        return false;
    if(!maxim_max30102_write_reg(REG_FIFO_WR_PTR, 0x00)) //FIFO_WR_PTR[4:0]
        return false;
    if(!maxim_max30102_write_reg(REG_OVF_COUNTER, 0x00)) //OVF_COUNTER[4:0]
        return false;
    if(!maxim_max30102_write_reg(REG_FIFO_RD_PTR, 0x00)) //FIFO_RD_PTR[4:0]
        return false;
    if(!maxim_max30102_write_reg(REG_FIFO_CONFIG, 0x6f)) //sample avg = 8, fifo rollover=false, fifo almost full = 17
        return false;
    if(!maxim_max30102_write_reg(REG_MODE_CONFIG, 0x03))  //0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED
        return false;
    if(!maxim_max30102_write_reg(REG_SPO2_CONFIG, 0x2F)) // SPO2_ADC range = 4096nA, SPO2 sample rate (400 Hz), LED pulseWidth (411uS)
        return false;

    if(!maxim_max30102_write_reg(REG_LED1_PA, 0x17))  //Choose value for ~ 4.5mA for LED1
        return false;
    if(!maxim_max30102_write_reg(REG_LED2_PA, 0x17))  // Choose value for ~ 4.5mA for LED2
        return false;
    if(!maxim_max30102_write_reg(REG_PILOT_PA, 0x7f))  // Choose value for ~ 25mA for Pilot LED
        return false;
    return true;
}

bool maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led)

/**
* \brief        Read a set of samples from the MAX30102 FIFO register
* \par          Details
*               This function reads a set of samples from the MAX30102 FIFO register
*
* \param[out]   *pun_red_led   - pointer that stores the red LED reading data
* \param[out]   *pun_ir_led    - pointer that stores the IR LED reading data
*
* \retval       true on success
*/
{
    uint32_t un_temp;
    uint8_t uch_temp;
    *pun_ir_led = 0;
    *pun_red_led = 0;
    maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
    maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);



    /* 第1步:發起I2C總線啟動信号 */
    i2c_Start();

    /* 第2步:發起控制位元組,高7bit是位址,bit0是讀寫控制位,0表示寫,1表示讀 */
    i2c_SendByte(max30102_WR_address | I2C_WR);	/* 此處是寫指令 */

    /* 第3步:發送ACK */
    if (i2c_WaitAck() != 0)
    {
        printf("read fifo failed");
        goto cmd_fail;	/* EEPROM器件無應答 */
    }

    /* 第4步:發送位元組位址, */
    i2c_SendByte((uint8_t)REG_FIFO_DATA);
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;	/* EEPROM器件無應答 */
    }


    /* 第6步:重新啟動I2C總線。下面開始讀取資料 */
    i2c_Start();

    /* 第7步:發起控制位元組,高7bit是位址,bit0是讀寫控制位,0表示寫,1表示讀 */
    i2c_SendByte(max30102_WR_address | I2C_RD);	/* 此處是讀指令 */

    /* 第8步:發送ACK */
    if (i2c_WaitAck() != 0)
    {
        goto cmd_fail;	/* EEPROM器件無應答 */
    }

    un_temp = i2c_ReadByte();
    i2c_Ack();
    un_temp <<= 16;
    *pun_red_led += un_temp;
    un_temp = i2c_ReadByte();
    i2c_Ack();
    un_temp <<= 8;
    *pun_red_led += un_temp;
    un_temp = i2c_ReadByte();
    i2c_Ack();
    *pun_red_led += un_temp;

    un_temp = i2c_ReadByte();
    i2c_Ack();
    un_temp <<= 16;
    *pun_ir_led += un_temp;
    un_temp = i2c_ReadByte();
    i2c_Ack();
    un_temp <<= 8;
    *pun_ir_led += un_temp;
    un_temp = i2c_ReadByte();
    i2c_Ack();
    *pun_ir_led += un_temp;
    *pun_red_led &= 0x03FFFF; //Mask MSB [23:18]
    *pun_ir_led &= 0x03FFFF; //Mask MSB [23:18]

    /* 發送I2C總線停止信号 */
    i2c_Stop();
    return true;
cmd_fail: /* 指令執行失敗後,切記發送停止信号,避免影響I2C總線上其他裝置 */
    /* 發送I2C總線停止信号 */
    i2c_Stop();
    return false;
}

bool maxim_max30102_reset()
/**
* \brief        Reset the MAX30102
* \par          Details
*               This function resets the MAX30102
*
* \param        None
*
* \retval       true on success
*/
{
    if(!maxim_max30102_write_reg(REG_MODE_CONFIG, 0x40))
        return false;
    else
        return true;
}


           
//DHT11溫濕度傳感器部分
#include "reg52.h"
#include "LCD1602.h"
#include "intrins.h"

//typedef unsigned char uchar;
//typedef unsigned int uint;
	
//定義變量
sbit Data=P3^6;
uchar rec_dat[13];//用于儲存接收到的資料組

void DHT11_delay_us(uchar n)
{
    while(--n);
}

void DHT11_delay_ms(uint z)
{
   uint i,j;
   for(i=z;i>0;i--)
      for(j=110;j>0;j--);
}

void DHT11_start()
{
   Data=1;
   DHT11_delay_us(2);
   Data=0;
   DHT11_delay_ms(20);   //延時18ms以上
   Data=1;
   DHT11_delay_us(30);
}

uchar DHT11_rec_byte()      //接收一個位元組
{
   uchar i,dat=0;
  for(i=0;i<8;i++)    //從高到低依次接收8位資料
   {          
      while(!Data);   //等待50us低電平過去
      DHT11_delay_us(8);     //延時60us,如果還為高則資料為1,否則為0 
      dat<<=1;           //移位使正确接收8位資料,資料為0時直接移位
      if(Data==1)    //資料為1時,使dat加1來接收資料1
         dat+=1;
      while(Data);  //等待資料線拉低    
    }  
    return dat;
}

void DHT11_receive()      //接收40位的資料
{
    uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise; 
    DHT11_start();
    if(Data==0)
    {
        while(Data==0);   //等待拉高     
        DHT11_delay_us(40);  //拉高後延時80us
        R_H=DHT11_rec_byte();    //接收濕度高八位  
        R_L=DHT11_rec_byte();    //接收濕度低八位  
        T_H=DHT11_rec_byte();    //接收溫度高八位  
        T_L=DHT11_rec_byte();    //接收溫度低八位
        revise=DHT11_rec_byte(); //接收校正位

        DHT11_delay_us(25);    //結束

        if((R_H+R_L+T_H+T_L)==revise)      //校正
        {
            RH=R_H;
            RL=R_L;
            TH=T_H;
            TL=T_L;
        } 
		
	
        /*資料處理,友善顯示*/
        rec_dat[0]=RH/10+'0';
        rec_dat[1]=(RH%10)+'0';
		rec_dat[2]='%';
        rec_dat[3]='R';
        rec_dat[4]='H';
        rec_dat[5]=' ';
		rec_dat[6]=' ';
        rec_dat[7]=(TH/10)+'0';
        rec_dat[8]=(TH%10)+'0';
		rec_dat[9]='^';
        rec_dat[10]='C';
    }
}

void main()
{
	//使用lcd1602顯示資料
	DHT11_receive();
	lcd1602(rec_dat);
}
           
// MQ-2煙霧傳感器

unsigned char GetYanWuValue(void)
{
		unsigned int sum=0;
		unsigned char m,value=0;
		for(m=0;m<20;m++)			//讀50次AD值
			sum = adc0832(0)+sum;		//讀到的AD值,将讀到的資料累加到sum
		value=(unsigned char)(sum/20);				//跳出上面的for循環後,将累加的總數除以50得到平均值value
	
		if(value > ADC_Zero) 
				value = value - ADC_Zero;              //首先減去零點漂移
			else
				value = 0;
	
		return value;

}


           

完整代碼可進群免費領取。

嵌入式物聯網的學習之路非常漫長,不少人因為學習路線不對或者學習内容不夠專業而錯失高薪offer。不過别擔心,我為大家整理了一份150多G的學習資源,基本上涵蓋了嵌入式物聯網學習的所有内容。點選下方連結,0元領取學習資源,讓你的學習之路更加順暢!記得點贊、關注、收藏、轉發哦!

點選這裡找小助理0元領取:掃碼進群領資料

基于單片機stm32的人體健康監護系統 - 單片機 嵌入式 物聯網
基于單片機stm32的人體健康監護系統 - 單片機 嵌入式 物聯網

繼續閱讀