基于物联网技术的智慧病房管理系统
目錄
- 前言
- 一、功能設計
- 二、基本配置
- 1.選擇芯片型號
- 2.RCC配置
- 3.SYS配置
- 4.USART1 與 DMA 配置
- 5.I2C配置
- 6.TIME3配置
- 7.DMA配置
- 8.TIM2 與 PWM 配置
- 9.NVIC配置
- 10.GPIO配置
- 11.時鐘配置
- 12.引腳配置
- 三、RTOS 與模塊驅動、代碼配置
- RTOS 配置
- 四、RTOS、AHT20 與 按鈕功能實現
- 1.溫濕度獲取代碼設計
- 2.RTOS 進程設計
- 3.按鈕的使用與消抖
- 五、定時開關燈與信息獲取
- 1.定時開關燈
- 六、總結
前言
設計一個基于物聯網技術的智慧病房管理系統。假設醫院住院部的一層病房(走廊兩邊病房平行分布),病房數量最多60間,每間病房3個床位,編號從1~180號。每間病房可采用的設備如下:STM32F103開發板1塊,房間溫濕度采集模塊1套(I2C接口,AHT20模塊),房間自動燈光開關控制器(以PWM方式控制,每天早上7點漸亮,晚上22點漸滅),病人脈搏&血氧檢測儀3套(UART接口輸出脈搏+血氧的數字值),床頭緊急呼叫按鍵開關3個(按下呼叫)。
每間病房的STM32F103開發板通過UART轉485接口,以mobus組網方式,連接到護士監控室的PC電腦上(上位機)。PC電腦上可接收每間病房的溫濕度數據(周期為5分鐘)、床頭緊急呼叫信號、病人脈搏血氧數據(正常狀態下30分鐘一次采集;當脈搏超過120或血氧值低于90時切換到危重狀態下,實時采集),顯示在屏幕上并且保存到MySQL數據庫里。
一、功能設計
1.使用 I2C 讀取 AHT20 模塊
2.TIM 定時器與 PWM 呼吸燈
3.按鍵信息接收與消抖
4.UART 轉 485 接口與 modbus 通信
5.MAX30102 模塊心率與血氧測量
二、基本配置
1.選擇芯片型號
2.RCC配置
3.SYS配置
4.USART1 與 DMA 配置
5.I2C配置
6.TIME3配置
7.DMA配置
8.TIM2 與 PWM 配置
9.NVIC配置
10.GPIO配置
11.時鐘配置
12.引腳配置
三、RTOS 與模塊驅動、代碼配置
RTOS 配置
選擇引入 RT-Thread 輕量便捷 :
外部按鈕配置
四、RTOS、AHT20 與 按鈕功能實現
1.溫濕度獲取代碼設計
首先我們需要引入溫濕度驅動頭文件:
#include "AHT20.h"然后我們需要在進程中對溫濕度傳感器進行初始化,這里在初始化之后,不能立即獲取溫濕度,需要等待 2 秒或以上,確保數據正確性:
MX_GPIO_Init(); MX_I2C1_Init(); MX_USART1_UART_Init(); uint32_t CT_data[2]={0,0}; // 用于獲取溫濕度數據 volatile int c1,t1; rt_thread_delay(50); AHT20_Init(); rt_thread_delay(2500);然后我們需要獲取經過 CRC 驗證的溫濕度數據,這里直接調用驅動函數即可:
while(1){AHT20_Read_CTdata_crc(CT_data); //經過CRC校驗,讀取AHT20的溫度和濕度數據 推薦每隔大于1S讀一次c1 = CT_data[0]*1000/1024/1024; //計算得到濕度值c1(放大了10倍)t1 = CT_data[1]*2000/1024/1024-500;//計算得到溫度值t1(放大了10倍)printf("正在檢測");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");printf("\r\n");printf("溫度:%d%d.%d",t1/100,(t1/10)%10,t1%10); // 這里需要對溫度進行計算后才能得到我們需要的溫度值printf("濕度:%d%d.%d",c1/100,(c1/10)%10,c1%10); // 這里同樣需要對適度進行計算printf("\r\n");printf("等待");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");printf("\r\n");}2.RTOS 進程設計
首先新建 app_rt_thread.c 文件,然后引入頭文件:
#include "rtthread.h" #include "main.h" #include "i2c.h" #include "usart.h" #include "gpio.h" #include "stdio.h" #include "AHT20.h"然后我們需要設計進程,這里主進程先設置為串口發送,子進程設置兩個,一個是獲取溫度參數,另一個是控制 PC13 引腳上的板載 LED ,后續會根據系統進程對進行設計:
//初始化線程函數 void MX_RT_Thread_Init(void) {//初始化LED1線程rt_thread_init(&led1_thread,"led1",led1_task_entry,RT_NULL,&rt_led1_thread_stack[0],sizeof(rt_led1_thread_stack),3,20);//開啟線程調度rt_thread_startup(&led1_thread);//初始化USART1線程rt_thread_init(&usart1_thread,"usart1",usart1_task_entry,RT_NULL,&rt_usart1_thread_stack[0],sizeof(rt_usart1_thread_stack),3,20);//開啟線程調度rt_thread_startup(&usart1_thread); }//主任務 void MX_RT_Thread_Process(void) {printf("Hello RT_Thread!!!\r\n");rt_thread_delay(2000); }//LED1任務 void led1_task_entry(void *parameter) {while(1){HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13, GPIO_PIN_RESET);rt_thread_delay(500);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13, GPIO_PIN_SET);rt_thread_delay(500);} } //讀取溫度任務 void usart1_task_entry(void *parameter) {MX_GPIO_Init();MX_I2C1_Init();MX_USART1_UART_Init();uint32_t CT_data[2]={0,0}; //volatile int c1,t1;rt_thread_delay(50);AHT20_Init();rt_thread_delay(2500);while(1){AHT20_Read_CTdata_crc(CT_data); //經過CRC校驗,讀取AHT20的溫度和濕度數據 推薦每隔大于1S讀一次c1 = CT_data[0]*1000/1024/1024; //計算得到濕度值c1(放大了10倍)t1 = CT_data[1]*2000/1024/1024-500;//計算得到溫度值t1(放大了10倍)printf("正在檢測");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");printf("\r\n");printf("溫度:%d%d.%d",t1/100,(t1/10)%10,t1%10); // 這里需要對溫度進行計算后才能得到我們需要的溫度值printf("濕度:%d%d.%d",c1/100,(c1/10)%10,c1%10); // 這里同樣需要對適度進行計算printf("\r\n");printf("等待");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");rt_thread_delay(100);printf(".");printf("\r\n");} }點擊查看完整 app_rt_thread.c 代碼
然后我們在主函數中引入 RT-Thread 必要的頭文件并引用函數:
最后我們直接在主函數中對進程進行初始化,并運行即可,這里直接給出完整主函數:
int main(void) {/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_I2C1_Init();MX_TIM3_Init();MX_USART1_UART_Init();MX_TIM2_Init();/* USER CODE BEGIN 2 */MX_RT_Thread_Init(); // 初始化線程/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){MX_RT_Thread_Process(); // 執行主進程/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */ }3.按鈕的使用與消抖
首先我們設計按鈕在 PA3 引腳,然后在設置 PA4 引腳上外接一個 LED ,這里先令按鈕按下反轉 PA4 引腳電平,即按下小燈泡點亮,再次按下,小燈泡熄滅,這里直接設計為一個新進程:
struct rt_thread btnclick_thread; rt_uint8_t rt_btnclick_thread_stack[128]; void btnclick_task_entry(void *parameter);void btnclick_task_entry(void *parameter){while(1){switch(KEY_Scan(0)){ case KEY1_PRES: HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_4);break;default:break;}} }初始化線程:
//初始化線程 rt_thread_init(&btnclick_thread,"btnclick",btnclick_task_entry,RT_NULL,&rt_btnclick_thread_stack[0],sizeof(rt_btnclick_thread_stack),3,20); //開啟線程調度 rt_thread_startup(&btnclick_thread);但是我們不進行按鍵消抖,這里按鍵非常容易誤觸,所以這里進行按鍵消抖:
#define KEY1 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3) //讀取按鍵1 #define KEY1_PRES 1 //KEY1按下 uint8_t KEY_Scan(uint8_t mode) {static uint8_t key_up=1;//按鍵松開標志位if(key_up&&(KEY1==0)){HAL_Delay(10);//去抖動key_up=0;if(KEY1==0)return KEY1_PRES;}else if(KEY1==1)key_up=1;return 0;//無按鍵按下 }五、定時開關燈與信息獲取
這里我們主要實現能夠定時開關燈,并且能夠獲取如下信息:
病人按下緊急呼叫信號
定時獲取病人脈搏血氧數據
1.定時開關燈
這里要求我們能夠實現在早上 7 點開燈,晚上 22 點滅燈,所以我們就要設計 RTC 系統時間與日歷讀取,確定我們當前的時間與日期,然后判斷時間數,最終通過 PWM 實現燈的漸亮與漸滅
這里首先我們需要配置 RTC:
這里先設置兩個變量用于獲取時間和日期:
然后我們可以通過時間進行判斷從而實現開關燈的效果:
void ledauto_task_entry(void *parameter){HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);while(1){HAL_RTC_GetTime(&hrtc,&Time,RTC_FORMAT_BIN);if(Time.Hours == 7&&Time.Minutes == 0&&Time.Seconds == 0){printf("開燈!");for(uint16_t i=1;i<500;i++){htim2.Instance->CCR2 = i;rt_thread_delay(5);}}else if(Time.Hours == 22&&Time.Minutes == 0&&Time.Seconds == 0){printf("關燈!");for(uint16_t i=499;i>=1;i--){htim2.Instance->CCR2 = i;rt_thread_delay(5);}}} }前面在博客中已經介紹了如何通過 RTC 讀取日歷和時間:
RTC時間讀取(可查看我之前博客)
這里我們只需要照做就可以,但是,由于開發板掉電,時間會重置,所以這里設計時間掉電保存,如果使用外接 RTC 并有電池,則會在掉電后繼續計時,這里我設計將代碼直接寫道 RTC 初始化的函數中即可,完整初始化代碼如下:
然后我們需要在運行時,實時獲取一次時間:
void getRealTime(void) {HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);HAL_RTC_GetDate(&hrtc, &datebuff, RTC_FORMAT_BIN);HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, (uint16_t)datebuff.Year);HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR3, (uint16_t)datebuff.Month);HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR4, (uint16_t)datebuff.Date);HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR5, (uint16_t)datebuff.WeekDay); }void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc) {if(hrtc->Instance == RTC){getRealTime(); } }六、總結
智慧病房是以院內物聯網為基礎的輔助診療及智能護理一體化解決方案。以智能改造醫院病房,通過先進的物聯網技術,讓患者與醫務人員、智能醫療設備緊密聯接。
通過對臨床數據采集、篩選、整合,形成醫療大數據,為臨床診療、護理提供智能輔助決策。
提高醫療資源的利用率,更好地保障醫療安全,更好地以患者為中心,提供有品質的醫療服務。
總結
以上是生活随笔為你收集整理的基于物联网技术的智慧病房管理系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 幼儿园宝宝培训计划
- 下一篇: 计算机网络安全的脆弱性,网络安全及网络安