//Logo Image
作者:黃于珍,楊哲彰(2009-04-23);推薦:徐業良(2009-04-23)

人體紅外線與溫溼度無線感測裝置之設計

本文敘述之人體紅外線與溫溼度無線感測裝置,可感測人員於空間內之活動以及環境溫溼度,並將感測資料以無線方式傳送至分散式資料伺服器(Distributed, Data Server, DDS)。以下將對於該裝置之電路與微處理器程式設計進行說明。

1.         硬體設計

人體紅外線與溫溼度無線感測裝置(以下簡稱本裝置)主要包含單晶片處理器(PIC18LF6722, Microchip Co.,)、紅外線開關模組(KC7783R益眾科技)、溫溼度感測器(SHT75, Sesirion Co.)Zigbee無線傳輸模組(XBee Series 2, MaxStream/Digi International),以及電源等週邊被動元件。系統概要圖如圖1所示,溫溼度感測器與紅外線開關模組透過DI/O與單晶片處理器連接,無線傳輸模組則透過UART(serial TX/RX)與單晶片處理器連接;電壓調節器(LM3940, National Semiconductor)提供DC+3.3V電源至溫溼度感測器、單晶片處理器、以及無線傳輸模組,紅外線開關模組則直接由輸入電源驅動。

1. 本裝置系統概要圖

2為本裝置電路圖。本裝置可使用外部DC+5V電源輸入(最大+7.5V),若不使用紅外線開關模組,而僅使用溫溼度感測器並搭配節電模式時,本裝置可使用21.5V電池作為電源(3V),電源不經過電壓調節器,直接連接至各主動元件。

溫濕度感測器採用瑞士Sensirion SHT75數位式溫濕度感測器,尺寸僅3.7×3.1×13.5(mm),此感測器可同時擷取溫度與濕度,於常溫常濕狀況下具備14bit(溫度)與12bit(溼度)解析度,以及±0.3oC±1.8%RH之量測準確度,可透過I2C(SCK, DATA)2個數位通道與外部微處理器連結通訊。人體紅外線開關模組內含KC778B焦電型紅外線感測器(PIR)控制晶片,外部控制器可透過D I/OA/DC讀取其輸出腳位。本裝置內人體紅外線開關模組之輸出至單晶片處理器RB4腳位(圖2D處),溫溼度感測器(圖2E處)則連接至單晶片處理器RB1RB2腳位。

2. PIR示意圖

無線傳輸模組採用MaxStream (Digi) XBee Series 2模組,使用ISM 2.4GHz,並相容IEEE 802.15.4 ZigBee規範,支援“point-to-point”“point-to-multipoint”“peer-to-peer”之無線感測網路通訊架構(wireless sensor network topology),該模組可透過UART界面與單晶片處理器TX1(RC6)RX1(RC7)連結通訊。

本裝置內部電路板與外觀如圖3所示,裝置外觀尺寸為120×70×25(mm),側面開孔處可連接外部AC-DC電源供應器插頭,並可視需求於無線傳輸模組加裝增益天線(SMA接頭)。附錄A為本裝置之零件表。

3. 本裝置外觀與內部電路板佈局

2.         程式設計

2.1 溫溼度感測器訊號擷取

附錄B為溫溼度感測器訊號擷取之主程式,主要使用ReadTempture()ReadHumidity()執行動作。本程式包含傳送起始化(TrasnsmitStart)、指令傳送(SendCommand)、讀值(ReadValue)、以及溫度或溼度之轉換(CalcTempValue, CalcHumiValue)四部分,不包含SHT75CRC-8偵錯、重設(connection reset)、以及睡眠(sleep)動作。當感測器供電後,首先須進行與感測器通訊之起始化動作。圖4說明初始化指令,當SCK為高位時,將DATA拉至低位(S1),接著將SCK產生一個脈波(pulse, S2),然後當SCK為高位時,再將DATA提升為高位,最後再將SCK拉為低位,完成一個初始化的動作。其中高位與低位須分別高於VDD電壓之90%與低於其10%。本階段程式指令對應於下表TransmitStart()內。

4. 起始化控制

接下來則由SendCommand()副程式對SHT75下指令,指令表如表1所示。表中所列之指令前皆須再加上「000」,成為8位元長度。例如若要擷取溫度,則命令為「000 00011」(即0x03),擷取溼度則為「000 00101」(即0x05)。SendCommand()副程式中,從命令的第8位元至第1位元執行動作,當該位元為“1”時,DATA提升為高位,若該位元為“0”時,則DATA為低位,且不論DATA之準位高低,SCK則需要將準位做拉高-降低的脈波動作,此程序重複至第1位元止。完成發送令後,將DATA設為輸入狀態後,再將SCK產生一個脈波,作為確認程序完成(ACK)的動作。

1. 指令清單

Command

Code

Reserved

0000x

Measure Temperature

00011

Measure Relative Humidity

00101

Read Status Register

00111

Write Status Register

00110

Reserved

0101x-1110x

Soft Reset

11110

接下來ReadValue()副程式由DATA腳位讀取SHT75之輸出數據,數據為2Byte長度(16bit);第1個輸出位元存於MSb(most significant bit),最後一個輸出則存於LSb(least significant bit)。此2Byte資料數據將存於Lx變數,再傳回至CalcHumiValue()副程式轉換成為可讀的溼度數值。CalcHumiValue()副程式中,Lx即可以式(1)以及表2所列之係數計算濕度:

                                                                             (1)

2. 溼度轉換係數表

SORH

c1

c2

c3

12bit

-4

0.0405

-2.8E-6

8bit

-4

0.6480

-7.2E-4

例如若Lx=0000100100110001=2353,則溼度之計算為

       

若為擷取溫度,則同樣在執行ReadValue()副程式後,以CalcTempValue()副程式執行轉換,該副程式以式(2)及表3所列之係數轉換為可讀的溫度值,須注意當不同的VDD電壓準位驅動SHT75時,其係數會稍有不同。

                                                                                               (2)

3. 溫度轉換係數表

VDD

d1()

5.0V

-40.1

4.0V

-39.8

3.5V

-39.7

3.0V

-39.6

2.5V

-39.4

2.2 紅外線開關訊號擷取與處理

當紅外線開關模組感應人體活動時,將於該元件OUT腳位輸出高位脈波訊號(如圖5“1”處),其輸出電壓等於該元件之電源電壓(V+);未感測到人體活動時,則該腳位無輸出(0V)。單晶片處理器以1Hz取樣頻率擷取輸出訊號,若該輸出訊號發生改變(0è11è0),或持續為高位輸出時(1è1),視為觸發狀態。

5. 紅外線開關模組之輸出訊號

附錄C為紅外線開關訊號擷取之主程式,宣告兩字元變數S1S2分別儲存這一秒與下一秒該元件OUT腳位輸出之脈波訊號。接著判斷S1S2,如此二脈波訊號發生改變(S1=0èS2=1S1=1èS2=0),或持續高位輸出(S1=1èS2=1),則視為觸發狀態,此時傳遞字元變數S=31視為觸發(字元碼為1hex碼為0x1F),反之則傳遞S=30視為無觸發(字元碼為0hex碼為0x1E)。最後,判斷如果從ZigBee收到之資料其hex碼為0x1F,則表示紅外線開關被觸發一次,在此處將紅外線開關被觸發的總次數增加1

2.3 無線傳輸模組控制

6說明本裝置程式執行流程,首先擷取溫溼度感測器之數值,接著判斷紅外線開關是否被觸發,若被觸發時,本裝置隨即將紅外線開關的觸發訊號以及當時的溫濕度數據透過無線傳輸模組發送至分散式資料伺服器;當擷取溫溼度數據後,若無紅外線開關觸發訊號達60秒,則裝置同樣會發送溫溼度數據。

6. 程式執行流程

傳送溫溼度數據前須以如下方式將資料型態由浮點數轉換成字元字串,方能透過UART由無線傳輸模組發送:

sprintf(溫度變數, “%2.0f”);

sprintf(溼度變數, “%2.0f”);

下圖7為資料的傳輸格式。第一字元與最後字元分別為0x7E0xFF,作為辨識有效資料之用。第二字元為感測器編號,由ASCII31代表第1號感測器(hex碼為0x1F)、32為第二號感測器(hex碼為0x20),依此類推;第三字元為紅外線開關之觸發狀態,1為觸發(ASCII碼為31hex碼為0x1F)、0為未觸發(ASCII碼為30hex碼為0x1E);第四至六字元為溫度數值,分別為溫度的十位數、個位數以及小數位數,同樣地,第七至九字元為濕度數值。將此數據格式依序送出後,即完成無線數據之發送。

7. 訊息字串所代表之意義

3.         系統測試

本系統目前裝置於元智大學老人福祉科技研究中心內(睡眠品質實驗室、辦公室、洗手間、機房與實驗室5處)進行人體紅外線溫溼度無線感測裝置之監測。本系統硬體包含DDS5個人體紅外線溫溼度無線感測裝置,用以偵測環境溫濕度以及人員於空間內之活動。

本監測系統可供遠端電腦透過網際網路顯示即時溫溼度資料與人體紅外線感測開關被觸發之紀錄。使用者若欲瀏覽即時數據,僅需開啟網頁瀏覽器(如IE等)連結至DDS後,即可動態顯示目前所有監測器的即時數據(如圖8所示),無須安裝其他軟體。

8. 以網頁瀏覽器連結至DDS後動態顯示目前所有監測器的即時數據

附錄DDDS端網頁程式之主程式,此動態網頁畫面需要用兩個網頁程式才能實現,第一個是入口網頁index.htm。當HTTP client在網頁瀏覽器中鍵入DDS的網址(http://140.138.40.147/)並按下ENTER鍵之後,瀏覽器就會向該IP網址的DDS索取入口網頁檔案index.htm,當瀏覽器收到index.htm之後,就會繼續向DDS索取第3行的指令中所要求的網頁檔案main.egi,此為第二個網頁程式。

main.egi中並沒有儲存動態的即時數據,當DDS從它的唯讀記憶體中取出main.egi這個副檔名為EGI的動態網頁檔案傳送給HTTP用戶時,才會用當時的人體紅外線感測裝置觸發次數之數據取代檔案中的EGI碼(如@a@b@c@d@e

檢視index.htmmain.egi這兩個網頁程式的執行效果無誤之後,就可以把這兩個檔案製成ROM檔燒入DDS的唯讀記憶體中。

附錄A. 零件表

料號

件號

備註

C1

 

0.47μF

C2

 

33μF

C3

 

0.22μF

C4

 

0.01μF

C5

 

22pF

C6

 

22pF

C7

 

0.22μF

C8

 

0.22μF

D2

0805

 

D3

0805

 

D4

0805

 

D5

0805

 

J1

POWERJACK

DC 5V

J2

SHT75

 

J3

 

PIR

J4

 

CON5

J5

 

RS-232

J6

SIP10-2.0

ZigBee_L

J7

SIP10-2.0

ZigBee_R

R1

 

10k

R2

 

2.2k

R3

 

100k

R4

 

2.2k

R5

 

RESET

R6

 

1k

R7

 

1k

 

料號

件號

備註

R8

 

10k

R9

 

20k

R10

 

10k

S1

 

ICP

S2

SIP2

ICP

S3

SIP2

SW-SPST

U1

TO-263

3940

U2

PIC18F6622

 

Y1

SMD-HC4

10MHz

BT1

SIP2

AAA1.5V*2

 

附錄B. 溫溼度感測器訊號擷取之主程式

signed int16 ReadTemperature(); 

signed int16 ReadHumidity();    

 

// Define clock and data pins

#ifndef SHT7x_SCK

#define SHT7x_SCK    PIN_B6

#define SHT7x_DATA   PIN_B7

#endif

 

// ---------------------------------------------------------------------

// Command byte values     // adr cmd  r/w

#define RESET        0x1e  // 000 1111  0

#define MEASURE_TEMP 0x03  // 000 0001  1

#define MEASURE_HUMI 0x05  // 000 0010  1

#define WrSTATUS_REG 0x06  // 000 0011  0

#define RdSTATUS_REG 0x07  // 000 0011  1

 

#define SHT7x_ACK    0

 

// int1 Acknowledge, chkCRC, error; int8 TimeOut, err;

 

signed int16 CalcTempValue(int16 Lx) // [0.1 deg C], with 14 bit @ 5V

{

   return((signed int16)(-396.5 + 0.1*(float)Lx));

}

 

signed int16 CalcHumiValue(int16 Lx) // [0.1 %RH], with 12 bit @ 5V

{

   float Fx;

   Fx  = -40.0 + 0.405*(float)Lx - 2.8e-5*(float)Lx*(float)Lx;

   Fx += (float)(ReadTemperature()-250)*(0.01+8e-5*(float)Lx); // 溫度補償

   return((signed int16)Fx);

}

 

void TransmitStart()

{

   output_high(SHT7x_DATA);

   output_low (SHT7x_SCK);  delay_us(2);

   output_high(SHT7x_SCK);  delay_us(2);

   output_low (SHT7x_DATA); delay_us(2);

   output_low (SHT7x_SCK);  delay_us(6);

   output_high(SHT7x_SCK);  delay_us(2);

   output_high(SHT7x_DATA); delay_us(2);

   output_low (SHT7x_SCK);  delay_us(2);

}

 

void RST_Connection()

{

   int8 i;

   output_high(SHT7x_DATA);

   for(i=1;i<=10;++i)

   {

      output_high(SHT7x_SCK); delay_us(2);

      output_low (SHT7x_SCK); delay_us(2);

   }

   TransmitStart();

}

 

// void RST_Software(){}

// int8 WriteStatReg(int8 command){}

// int8 ReadStatReg (int8 command){}

 

int16 ReadValue()

{

   int8 i, ByteHigh=0, ByteLow=0; int16 Lx;

   for(i=1;i<=8;++i) // read high byte VALUE from SHT11

   {

      output_high(SHT7x_SCK); delay_us(2);

      shift_left (&ByteHigh, 1, input(SHT7x_DATA) );

      output_low (SHT7x_SCK); delay_us(2);

   }

   output_low  (SHT7x_DATA);  delay_us(2);

   output_high (SHT7x_SCK);   delay_us(2);

   output_low  (SHT7x_SCK);

   output_float(SHT7x_DATA);  delay_us(2);

 

   for(i=1;i<=8;++i) // read low byte VALUE from SHT11

   {

      output_high(SHT7x_SCK); delay_us(2);

      shift_left (&ByteLow, 1, input(SHT7x_DATA) );

      output_low (SHT7x_SCK); delay_us(2);

   }

   output_high (SHT7x_DATA);  delay_us(2);

   output_high (SHT7x_SCK);   delay_us(2);

   output_low  (SHT7x_SCK);

   output_float(SHT7x_DATA);  delay_us(2);

   Lx=make16(ByteHigh,ByteLow);

   return(Lx);

}

 

void SendCommand(int Command)

{

   int8 i;

   for(i=128;i>0;i/=2)

   {

      if(i & Command) output_high(SHT7x_DATA);

      else            output_low (SHT7x_DATA);  delay_us(2);

      output_high(SHT7x_SCK); delay_us(2);

      output_low (SHT7x_SCK);

   }

   output_float(SHT7x_DATA);  delay_us(2);

   output_high (SHT7x_SCK);   delay_us(2);

   output_low  (SHT7x_SCK);

}

 

signed int16 ReadTemperature()

{

   TransmitStart();           SendCommand(MEASURE_TEMP);

   while(input(SHT7x_DATA));  delay_us(2);

   return( CalcTempValue ( ReadValue() ) );

}

 

signed int16 ReadHumidity()

{

   TransmitStart();           SendCommand(MEASURE_HUMI);

   while(input(SHT7x_DATA));  delay_us(2);

   return( CalcHumiValue ( ReadValue() ) );

}

附錄C. 紅外線開關訊號擷取之主程式

S1=input(PIN_B4);       
delay_ms(500);       
S2=input(PIN_B4);
if (S1==0 && S2==1){
  S=31;
  delay_ms(1000);      
}else if (S1==1 && S2==1){
  S=31;
  delay_ms(1000);
}else if (S1==1 && S2==0){
  S=31;
  delay_ms(1000);
}else{
 S=30;
}

if (buffer[1]==0x1f){
block_sensor_data_IR[number_sensor-1]++;

}

附錄D. DDS端網頁程式之主程式

<!-- index.htm -->
  
 <HTML> 
    <TITLE>ADL
監測系統</TITLE>
    <FRAMESET>
    <FRAME src="main.egi">
    </FRAMESET>
    </HTML>

     <!-- main.eg i-->  

        <html>
        <meta http-equiv="refresh" content="10">

     <br />
         ADL
監測系統
         <br />
         <br />
          No.01_(
睡眠實驗室)_IR@a 溫度:@k___濕度:@I<br /><br /> 
          No.02_(
辦公室)_____IR@b 溫度:@l___濕度:@J<br /><br />   
          No.03_(
洗手間)_____IR@c 溫度:@A___濕度:@K<br /><br />   
          No.04_(
機房)_______IR@d 溫度:@B___濕度:@L<br /><br />
          No.05_(
實驗室)_____IR@e 溫度:@C___濕度:@M<br /><br />

      現在時間:@S<br />
          <a href="set.egi">DDS
網路資訊設定</a><br>
        </html>