2013年4月8日 星期一

[AlaMode][PIR] AlaMode 與人體紅外線感應 (PIR) 模組


AlaMode + Raspberry Pi + PIR + Relay + Buzzer

還記得我們在 "使用人體紅外線感應 (PIR) 模組,製作家中安全防護及警報系統" 使用樹莓派控制 PIR 模組與繼電器,並發送電子郵件嗎 ?

這次樹莓派除了負責接收從 AlaMode 發送過來的訊息,並由訊息中確認是否開始發送電子郵件之外,所有週邊的控制都是由 AlaMode 負責。

或許有人會問,這不是都一樣嗎 ? no! No! NO! 同款隔不同師傅!

AlaMode 只要有電,裡面的程式會一直執行,當你想要在 PIR 模組被觸發時發送電子郵件再把樹莓派裡的接收程式開啟就可以了。

使用此程式,樹莓派裡的 UART 功能必須已經被打開了。如果您不是一開始就依照 "AlaMode: Get Started (中文入門說明)" 作設定,那設定的方法請參考 "使用樹莓派模擬 HT12E 遙控器編碼晶片的編碼格式" 網頁中關於 "樹莓派接收無線訊號" 這一段的說明,照著做再重開機就可以!

另外,也請在閱讀此網頁之前先瀏覽

下面這段影片就是整個動作情形,在 4.3 吋螢幕上所看到的時間,是由 AlaMode 取自 RTC 晶片 ( 設定方式請看 "AlaMode RTC 晶片使用說明" )。一旦 PIR 模組觸發,繼電器就會打開電燈,蜂鳴器就會作動,幾秒鐘的時間就可以收到預警電子郵件,非常快速且方便!


想要動手自己做,相關零組件可至露天賣場訂購:


硬體線路:

要製作上面的東西,下面是電路圖。不過在配線時要先說一下:PIR 模組一旦插上電源之後,會有 30 - 60 秒的穩定時間,這段時間內輸出接腳會有高高低低的訊號輸出,如果 AlaMode 裡又載入了本網頁的範例程式時,繼電器就會有斷斷續續的開關動作。請注意,這是正常的!
AlaMode 與 Raspberry Pi 做的家用安全系統
硬體線路部分,可以先接也可以在程式寫好之後再接。但是在寫程式之前請必須了解一下線路,這樣才知道所使用的接腳是哪一個 ?

而且在未成功載入 Arduino 程式,千萬不要使用 AlaMode 其他接腳,因為有可能在上傳程式時會失敗;等成功上傳之後,請大家再自己變換接腳試試,找找為什麼吧!

另外,線路圖中使用 ARDUINO UNO R3 板子,這是因為我沒有也沒特別去畫 AlaMode 的電路圖案,而且它與 AlaMode 的接腳是相同的 ( 除了 AlaMode 特殊功能接腳之外 ),因此只要照著上面的標示文字接就可以了。

為了一個蘿蔔一個坑,每個電子零件都有自己的電源供應與輸出入接腳,所以不需要額外使用麵包板,請對照上方電路圖或下面照片做接線
PIR 模組、繼電器模組和蜂鳴器與 AlaMode 的線路連接照片


近照圖 - PIR 模組、繼電器模組和蜂鳴器與 AlaMode 的線路連接照片


程式撰寫:

程式的撰寫分為兩個部分:AlaMode 和 Raspberry Pi,可使用下圖做表示

程式架構與控制方式

AlaMode 負責 PIR 模組、蜂鳴器和繼電器模組的控制與觸發訊號接收,而且一旦開始觸發,每個動作就會伴隨的時間將訊息輸出,並將資料經由 UART 傳送到樹莓派。樹莓派接收之後,就會原封不動的將訊息在螢幕上秀出,並在接收到包含 "sendemail" 訊息時開始發送電子郵件出去。

AlaMode 的程式可於樹莓派中使用 Arduino IDE 撰寫,或是在 PC 中叫出樹莓派裡的 Arduino IDE 撰寫,又或是使用 SublimeText  撰寫 ... 等,不管哪一種方式,最好的方法就是互相搭配使用並選擇一個你自己最喜歡的撰寫方式,而這些東西都在最下面的賣場部落格文章連結裡,請自行參考並安裝,本篇內文中就不再贅述!

我使用的方法是使用 Sublime Text 2 連線遠端資料夾,修改後同步上傳至樹莓派;再使用 MobaXterm 開啟樹莓派的 Arduino IDE,載入撰寫的程式並上傳至 AlaMode。看倌們可以參考一下。

現在我們就開始吧!


AlaMode - 安裝 RTClib 函式庫:

RTC 晶片的讀取使用 I2C 通訊,因此我們下載 RTClib 函式庫並解壓縮到 Arduino libraries 目錄來作使用,請輸入下面指令:
pi@raspberrypi ~ $ cd /usr/share/arduino/libraries/
pi@raspberrypi /usr/share/arduino/libraries $ ls -l
總計 40
drwxr-xr-x 3 root root 4096  3月 25 16:07 EEPROM
drwxr-xr-x 4 root root 4096  3月 25 16:07 Ethernet
drwxr-xr-x 3 root root 4096  3月 25 16:07 Firmata
drwxr-xr-x 3 root root 4096  3月 25 16:07 LiquidCrystal
drwxr-xr-x 4 root root 4096  3月 25 16:07 SD
drwxr-xr-x 3 root root 4096  3月 25 16:07 Servo
drwxr-xr-x 3 root root 4096  3月 25 16:07 SoftwareSerial
drwxr-xr-x 3 root root 4096  3月 25 16:07 SPI
drwxr-xr-x 3 root root 4096  3月 25 16:07 Stepper
drwxr-xr-x 4 root root 4096  3月 25 16:07 Wire
pi@raspberrypi /usr/share/arduino/libraries $ mkdir RTClib
pi@raspberrypi /usr/share/arduino/libraries $ cd RTClib
pi@raspberrypi /usr/share/arduino/libraries/RTClib $ ls -l
總計 0
pi@raspberrypi /usr/share/arduino/libraries/RTClib $ wget -O - http://goo.gl/X55uz | tar xvf -
--2013-04-04 00:21:38--  http://goo.gl/X55uz
正在查找主機 goo.gl (goo.gl)... 173.194.72.139, 173.194.72.100, 173.194.72.101, ...
正在連接 goo.gl (goo.gl)|173.194.72.139|:80... 連上了。
已送出 HTTP 要求,正在等候回應... 301 Moved Permanently
位置: http://dl.dropbox.com/s/bocxn2lldu83zsl/RTCLib.tar [跟隨至新的 URL]
--2013-04-04 00:21:38--  http://dl.dropbox.com/s/bocxn2lldu83zsl/RTCLib.tar
正在查找主機 dl.dropbox.com (dl.dropbox.com)... 23.23.128.5
正在連接 dl.dropbox.com (dl.dropbox.com)|23.23.128.5|:80... 連上了。
已送出 HTTP 要求,正在等候回應... 200 OK
長度: 22016 (22K) [application/x-tar]
Saving to: `STDOUT'

 0% [                                              ] 0           --.-K/s              examples/
examples/datecalc/
examples/datecalc/datecalc.pde
examples/ds1307/
examples/ds1307/ds1307.pde
examples/softrtc/
examples/softrtc/softrtc.pde
keywords.txt
100%[=============================================>] 22,016      98.2K/s   in 0.2s

2013-04-04 00:21:39 (98.2 KB/s) - written to stdout [22016/22016]

RTCLib-installation.log
RTClib.cpp
RTClib.h
pi@raspberrypi /usr/share/arduino/libraries/RTClib $ ls -l
總計 24
drwxr-xr-x 5 pi pi 4096  3月 29 12:56 examples
-rwxr-xr-x 1 pi pi  704  3月 29 12:56 keywords.txt
-rwxr-xr-x 1 pi pi 6643  3月 29 12:56 RTClib.cpp
-rwxr-xr-x 1 pi pi 1515  3月 29 12:56 RTClib.h
-rwxr-xr-x 1 pi pi  624  3月 29 12:51 RTCLib-installation.log

安裝好 RTClib 函式庫後,如果此時有開啟 Arduino IDE 的話,記得關閉 Arduino IDE 再重新開啟,讓軟體重新讀取新的函式庫與範例程式。如下圖,就會多出 RTClib 的範例程式資料夾,需要使用的時候可以拿來做參考。
安裝 RTClib 函式庫後的 Arduino IDE 
如果想要在 PC 環境下開啟遠端軟體並如同 PC 裡的軟體一樣,請先參照網頁中最下面的部落格連結 "把 Windows 桌面當作是 Raspberry Pi (樹莓派) 的螢幕",安裝與設置 MobaXterm;接著開啟 MobaXterm 連線至樹莓派,連線成功後,輸入下面指令就可以開啟樹莓派的 Arduino IDE 在 PC 桌面環境中了
### 開啟 Arduino IDE
$ arduino&

### 開啟 Midori 瀏覽器
$ midori&

後面的 是表示將程式丟到背景執行,這樣才可以繼續輸入其他指令。


AlaMode - 下載原始碼:

輸入下面指令下載此部份的原始碼
pi@raspberrypi ~ $ cd sketchbook
pi@raspberrypi ~/sketchbook $ ls -l
總計 0
pi@raspberrypi ~/sketchbook $ cd
pi@raspberrypi ~/sketchbook $ wget -O - http://goo.gl/irDsj | tar xvf -
--2013-04-06 14:08:58--  http://goo.gl/irDsj
正在查找主機 goo.gl (goo.gl)... 74.125.31.101, 74.125.31.102, 74.125.31.113, ...
正在連接 goo.gl (goo.gl)|74.125.31.101|:80... 連上了。
已送出 HTTP 要求,正在等候回應... 301 Moved Permanently
位置: http://dl.dropbox.com/s/z9tutxm06ud7kaw/alamode_arduinoCode.tar [跟隨至新的 URL]
--2013-04-06 14:08:58--  http://dl.dropbox.com/s/z9tutxm06ud7kaw/alamode_arduinoCode.tar
正在查找主機 dl.dropbox.com (dl.dropbox.com)... 23.21.146.171
正在連接 dl.dropbox.com (dl.dropbox.com)|23.21.146.171|:80... 連上了。
已送出 HTTP 要求,正在等候回應... 200 OK
長度: 10752 (10K) [application/x-tar]
Saving to: `STDOUT'

 0% [                                              ] 0           --.-K/s              PIR_EINT/
PIR_EINT/PIR_EINT.ino
PIR_EINT_RTC/
PIR_EINT_RTC/PIR_EINT_RTC.ino
100%[=============================================>] 10,752      --.-K/s   in 0.001s

2013-04-06 14:08:59 (13.2 MB/s) - written to stdout [10752/10752]

pi@raspberrypi ~/sketchbook $ ls -l
總計 8
drwxr-xr-x 2 pi pi 4096  3月 29 16:25 PIR_EINT
drwxr-xr-x 2 pi pi 4096  3月 29 17:39 PIR_EINT_RTC

目錄中會產生兩個目錄,沒有 RTC 結尾的表示,在通訊輸出時不包含 RTC 晶片時間,另一個有。請使用此網頁最下面所提供的連結中的方法,在 PC 開啟這幾個原始檔做為下面說明的對照。


AlaMode - 程式架構與說明 [ 接點與外部變數的設定 ]:

各接腳的定義與外部變數的宣告,如下:

AlaMode - 程式架構與說明 [ 外部中斷 ]:

AlaMode 所負責部分就是一般簡單的 IO 控制,不過若是一直使用輪詢的方式來偵測 PIR 模組的輸入訊號,那寫起來也不好玩!因此我們在 PIR 模組控制的部分,引入"中斷"的方式來負責偵測 PIR 模組是否被觸發的工作,通常使用時會搭配 "睡眠" 的功能,讓微控制器進入睡眠的狀態直到外部事件將其喚醒。不過我們在這裡不讓控制器進入到睡眠模式,而是單純使用中斷,這部分有興趣的話可以到 "Arduino Sleep Code" 或 Google 找一下。

還記得 AlaMode 除了外加的一些硬體與線路之外,核心晶片 ATMega328P 與 Arduino UNO R3 都是相同的,因此就是把 AlaMode 視為 Arduino UNO R3 板子來用就對了,千萬不要因為網頁中有時說 AlaMode 或是 Arduino 就搞混了!

關於 Arduino 中斷的說明,請參考 "Interrupts" 網頁中的說明,這邊不再贅述!!

Arduino UNO R3 有兩個外部中斷 INT0INT1,分別對應到 D2D3 這兩支接腳,而且觸發動作有下面五種方式:
  • LOW       :只要接腳狀態為低電位就產生中斷
  • CHANGE:只要接腳狀態有變化就產生中斷
  • RISING   :接腳狀態必須由低電位轉換為高電位才會產生中斷
  • FALLING:接腳狀態必須由高電位轉換為低電位才會產生中斷
  • HIGH       :只要接腳狀態為高電位就產生中斷
由於 PIR 模組在觸發時是高電位,平常時候是低電位,因此我們選用 RISING 方式產生中斷。

外部中斷在使用時要先宣告,方法是使用 attachInterrupt( 1, 2, 3 )函式:其中,1 指定所使用的外部中斷號碼、2 外部中斷觸發時所要呼叫的附程式是哪一個、3 最後就是該外部中斷使用哪一種方式觸發中斷。

外部中斷宣告之後,要使用的時候就是呼叫函式 interrupts() 告知晶片啟用中斷,不使用的時候呼叫函式 noInterrupts() 告知晶片關閉中斷;這兩個都是一次開啟或是一次關閉所有中斷的函式


中斷觸發時呼叫的程式 pir_trigger(),一進入時要先將中斷處理全部關掉,然後再將 pir_state 狀態變更為觸發 YES;這樣做的目的是在避免 PIR 重複觸發。pir_state 一旦設定為 YES 之後,由於中斷不會再重覆觸發,因此程式主控權會整個落在 loop() 迴圈裡,這是會一直重複執行的無窮迴圈。

AlaMode - 程式架構與說明 [ 抓取硬體時間 (RTC) ]:

我們在 AlaMode 第二篇文章 "RTC 晶片 (DS3231) 使用說明" 中已經介紹過,如何在樹莓派環境中設置以及使用 AlaMode 中的 RTC 晶片,但是我們並未在其中使用程式範例做說明。

RTC 是使用 I2C 通訊與 AlaMode 和樹莓派做通訊,由於我們所接的東西是在 AlaMode 上,因此時間應該是要以 AlaMode 所讀取到的時間為準而不是樹莓派上的時間,因此在這邊我們要來介紹如何使用 RTClib 函式庫讀取 RTC 晶片裡的時間。

使用 I2C 與 RTC 晶片通訊,我們必須先引入兩個標頭檔,並宣告一個實體

接著在 setup() 函式裡加入下面的程式碼

Line 54 - 55:WireRTC_AlaMode 初始化
Line 58 - 67:這一段主要是傳送 RTC 晶片沒有運行的訊息給通訊另一端的設備;但其實最只要的是 Line 66所能做的事情,這會在 Arduino IDE 執行編譯的時候,使用抓到的系統時間來設置 RTC 晶片的時間,這對於不能使用指令來設定時非常有用。

如何讀取 RTC 的時間呢 ?

下面是讀取 RTC 晶片並轉換為台灣時間的函式,讀取之後直接由 UART 傳送出去,函式直至最後都沒有多加換行字元 (LF),如果接收部分有使用這個字元,在傳送端撰寫時要記得加上去,使用時要特別注意!

AlaMode - 程式架構與說明 [ loop() ]:

介紹過上面 RTClib 與中斷程式後,接著就是主程式的部分。

一旦 PIR 模組觸發之後,電壓準位由低變高,外部中斷 ( INT0 ) 啟動,並呼叫中斷副程式 pir_trigger() 將 pir_state 設為 YES,然後主控權回到 loop() 做狀態的確認。

下面 loop() 程式被分割為三段:一旦狀態為真 (Line 93),就會傳送觸發時間與訊息字串到接收端 ( Line 95 - 99 ),再開啟繼電器以 ( Line 101 ) 及蜂鳴器 (Line 102 - 109:0.5 秒 ON,1.0 秒 OFF共執行三次),然後關閉繼電器 ( Line 122 ) 將 pir_state 狀態設定為 NO ( Line 128 ),最後別忘了再次將中斷打開 ( Line 130 )

下面這段是要增加動作執行的時間,因為除了 PIR 模組本身的動作延遲時間之外,接收端的電子郵件傳送也是需要時間的。因此在中斷再次開啟之前,所有的動作必須要完全結束,才能避免被二次觸發產生錯誤。

下段是 loop() 程式最後一部分

以上就是 AlaMode 程式的部分,完成之後請將其載入到 Arduino IDE 中,並按下上方按鈕 "Upload" 上傳程式到晶片中,接著開啟 "Serial Monitor" 再按下 AlaMode 板子上面的 "RESET" 按鈕,就會看到倒數計時的文字出現,這時你就可以開始觸發 PIR 模組,所顯示的文字就會跟下圖一樣 (除了時間),只要再將樹莓派中接收的程式寫好,就可以發送電子郵件了!
Arduino IDE 和 Serial Monitor

其它 AlaMode 程式碼的部分請自行參照所下載的程式內容。


Raspberry Pi - 下載原始碼:

輸入下面指令,下載程式碼:
pi@raspberrypi ~ $ cd codes
pi@raspberrypi ~/codes $ mkdir PIR_AlaMode
pi@raspberrypi ~/codes $ cd PIR_AlaMode/
pi@raspberrypi ~/codes/PIR_AlaMode $ wget -O - http://goo.gl/ywVRv | tar xvf -
--2013-04-06 18:31:51--  http://goo.gl/ywVRv
正在查找主機 goo.gl (goo.gl)... 74.125.31.100, 74.125.31.101, 74.125.31.102, ...
正在連接 goo.gl (goo.gl)|74.125.31.100|:80... 連上了。
已送出 HTTP 要求,正在等候回應... 301 Moved Permanently
位置: http://dl.dropbox.com/s/7yy36mfgsuf16um/rpi_code.tar [跟隨至新的 URL]
--2013-04-06 18:31:52--  http://dl.dropbox.com/s/7yy36mfgsuf16um/rpi_code.tar
正在查找主機 dl.dropbox.com (dl.dropbox.com)... 204.236.227.215
正在連接 dl.dropbox.com (dl.dropbox.com)|204.236.227.215|:80... 連上了。
已送出 HTTP 要求,正在等候回應... 200 OK
長度: 11776 (12K) [application/x-tar]
Saving to: `STDOUT'

 0% [                                              ] 0           --.-K/s              sendemail.c
sendemail.py
100%[=============================================>] 11,776      --.-K/s   in 0.001s

2013-04-06 18:31:52 (19.1 MB/s) - written to stdout [11776/11776]

pi@raspberrypi ~/codes/PIR_AlaMode $ ls -l
總計 12
-rwxr-xr-x 1 pi pi 7352  4月  6 03:22 sendemail.c
-rwxr-xr-x 1 pi pi 1768  4月  6 03:22 sendemail.py
pi@raspberrypi ~/codes/PIR_AlaMode $

下載的程式碼有 sendemail.csendemail.py 兩個,這兩個程式是由 "[PIR] 使用人體紅外線感應 (PIR) 模組,製作家中安全防護及警報系統" 網頁中的程式修改而來。程式的架構都一樣,就是加入了字串判斷與 UART 的功能而已,因此下面我們只說明增加的部分,其餘的請自行參考上面所提供的網頁中的說明。


Raspberry Pi [ Python ] - 下載與安裝函式庫 pySerial:

輸入下面指令,下載並安裝 pySerial 2.6
pi@raspberrypi ~ $ wget -O - http://goo.gl/ksw7e | tar xvf -
... << 中間省略 >> ...
pi@raspberrypi ~ $ ls -l
總計 28
drwxr-xr-x 2 pi pi 4096 10月  4 08:21 alamode-setup
drwxr-xr-x 2 pi pi 4096  3月 25 14:31 Desktop
-rw-r--r-- 1 pi pi 5781  2月  3 13:07 ocr_pi.png
drwxr-xr-x 6 pi pi 4096 11月  2  2011 pyserial-2.6
drwxrwxr-x 2 pi pi 4096  7月 21  2012 python_games
drwxr-xr-x 4 pi pi 4096  3月 29 17:32 sketchbook
pi@raspberrypi ~ $ cd pyserial-2.6/
pi@raspberrypi ~/pyserial-2.6 $ ls -l
總計 52
-rw-r--r-- 1 pi pi 13700 11月  2  2011 CHANGES.txt
drwxr-xr-x 2 pi pi  4096 11月  2  2011 documentation
drwxr-xr-x 2 pi pi  4096 11月  2  2011 examples
-rw-r--r-- 1 pi pi  2850  8月 10  2011 LICENSE.txt
-rw-r--r-- 1 pi pi   968  7月 22  2010 MANIFEST.in
-rw-r--r-- 1 pi pi  1399 11月  2  2011 PKG-INFO
-rw-r--r-- 1 pi pi  1237  8月 10  2011 README.txt
drwxr-xr-x 4 pi pi  4096 11月  2  2011 serial
-rw-r--r-- 1 pi pi  3215  8月 22  2011 setup.py
drwxr-xr-x 2 pi pi  4096 11月  2  2011 test
pi@raspberrypi ~/pyserial-2.6 $ sudo python setup.py install
... << 中間省略 >> ...
running install_scripts
copying build/scripts-2.7/miniterm.py -> /usr/local/bin
changing mode of /usr/local/bin/miniterm.py to 755
running install_egg_info
Writing /usr/local/lib/python2.7/dist-packages/pyserial-2.6.egg-info
pi@raspberrypi ~/pyserial-2.6 $

pySerial 2.6 說明文件和範例程式,可上來源官網。我們使用到的部分是其中的 serial.Serial.readline() ,裡面各函式的說明請參照 pySerial API


Raspberry Pi [ Python ] - 引入函式庫:

下面是所引入的函式庫,Line 15 是 pySerial 的函式庫
14 import sys              # for sys.stdout.flush()
15 import serial
16 import smtplib


Raspberry Pi [ Python ] - UART 初始化:

加入這一行,初始化 UART
28 rpi_ser = serial.Serial('/dev/ttyS0', 9600)


Raspberry Pi [ Python ] - 主程式:

下面是主程式的部分:每次從發送端讀取以 LF 結尾的一行 ( Line 49 ),並將收到的訊息原封不動輸出在螢幕上 ( Line 50 ),如果訊息中包含 sendemail 字串 ( Line 51 ),輸出 ... ( Line 52 ) 並開始傳送電子郵件 ( Line 54 ),當使用者按下 Ctrl + CLine 55 ) 離開程式。
46 try:    
47     # 按下 Ctrl + C 離開
48     while True:
49         message = rpi_ser.readline()
50         print message,
51         if message.find("sendemail") >= 0:
52             print "...",
53            sys.stdout.flush()
54            send_email()
55 except KeyboardInterrupt:    
56     print "  Quit!  \n"

上面就是使用 pySerial 函式庫接收 AlaMode 傳送過來的訊息,並確認訊息中使否包含傳送電子郵件的字串,最後傳送電子郵件的方法。

接下來,換成用 C 語言來做!


Raspberry Pi [ C ] - 安裝函式庫:

使用 C 語言傳送電子郵件與做 UART 通訊,需要安裝兩個函式庫:libcurl 和 wiringPi,安裝的方法與詳細說明可搜尋部落格網頁,或直接使用下面的指令
### 安裝 libcurl
pi@raspberrypi ~ $ sudo apt-get install libcurl4-openssl-dev
... << 中間省略 >> ...
### 安裝 wiringPi
pi@raspberrypi ~ $ git clone git://git.drogon.net/wiringPi
Cloning into 'wiringPi'...
remote: Counting objects: 321, done.
remote: Compressing objects: 100% (321/321), done.
remote: Total 321 (delta 219), reused 0 (delta 0)
Receiving objects: 100% (321/321), 117.28 KiB | 96 KiB/s, done.
Resolving deltas: 100% (219/219), done.
pi@raspberrypi ~ $ cd wiringPi/
pi@raspberrypi ~/wiringPi $ git pull origin
Already up-to-date.
pi@raspberrypi ~/wiringPi $ ls -l
總計 36
-rwxr-xr-x 1 pi pi 1462  3月 29 20:54 build
-rw-r--r-- 1 pi pi 7651  3月 29 20:54 COPYING.LESSER
drwxr-xr-x 2 pi pi 4096  3月 29 20:54 examples
drwxr-xr-x 2 pi pi 4096  3月 29 20:54 gpio
-rw-r--r-- 1 pi pi 1036  3月 29 20:54 INSTALL
-rw-r--r-- 1 pi pi  735  3月 29 20:54 People
-rw-r--r-- 1 pi pi  636  3月 29 20:54 README.TXT
drwxr-xr-x 2 pi pi 4096  3月 29 20:54 wiringPi
pi@raspberrypi ~/wiringPi $ ./build
wiringPi Build script
=====================

The wiringPi I2C helper libraries will not be built.

WiringPi library
[UnInstall]
[Compile] wiringPi.c
[Compile] wiringPiFace.c
[Compile] wiringSerial.c
[Compile] wiringShift.c
[Compile] gertboard.c
[Compile] piNes.c
[Compile] lcd.c
[Compile] piHiPri.c
[Compile] piThread.c
[Compile] wiringPiSPI.c
[Compile] softPwm.c
[Compile] softServo.c
[Compile] softTone.c
[Link (Dynamic)]
[Install]

GPIO Utility
[Compile] gpio.c
[Link]
[Install]

All Done.
pi@raspberrypi ~/wiringPi $


Raspberry Pi [ C ] - 宣告 UART 所使用到的函示庫與變數:

下面列出使用在 UART 通訊使用到的函示庫和變數的定義
20 #include <errno.h>
21 #include <unistd.h>     // Used for UART
22 
23 /* wiringSerial.h: a serial port handling library */
24 #include <wiringSerial.h>
25 // 變數宣告
26 int FD_UART;
27 // ex. /dev/ttyS0 for AlaMode, if use USV converter , try /dev/ttyUSB0
28 #define FD_TTY  "/dev/ttyS0"
29 // try 1200 bps first
30 #define FD_BAUD 9600
31 // 從串列步接收到的資料
32 unsigned char FD_BUFFER[256];


Raspberry Pi [ C ] - 宣告 UART 所使用到的函示庫與變數:

wiringPi 裡面 UART 的函式並沒有一次讀取一行的功能,因此另外寫了一個以 LF 結尾的副程式,讀取到的字串存放在 FD_BUFFER 裡面
150 int serialReadline(fd)
151 {
152     int i, rev_no;
153     static int index;
154     while(1)
155     {
156         rev_no = serialDataAvail(fd);
157         if(rev_no > 0)
158         {
159             for(i = 0; i < rev_no; i++)
160             {
161                 FD_BUFFER[index] = serialGetchar(fd);
162                 //printf("index = %d,", index);
163                 if( ( i == ( rev_no - 1 )) && ( FD_BUFFER[index] == '\n' ) ) // line feed
164                 {
165                     FD_BUFFER[index + 1] = '\0';
166                     index = 0;
167                     return 0; // 有讀到東西
168                 }
169                 else
170                 {
171                     index++;
172                 }
173             }
174         }
175         else { break; }
176     }
177     return 1; // 沒有讀到東西
178 }


Raspberry Pi [ C ] - 主程式 main()

main() 主程式一開頭就是初始化 UART,並確認使否可以正常開啟使用。接著如下程式碼,開始等待 UART 接收到一行的文字 ( Line 202 ) 再輸出到螢幕上 ( Line 204 ),並且比對是否是傳送電子郵件的字串 ( Line 205 ) ? Line 209 開始傳送電子郵件
199    // 開始讀取資料
200     while(1)
201     {
202         if(serialReadline(FD_UART) == 0)
203         {
204             printf("%s", FD_BUFFER);            
205             if(strstr(FD_BUFFER, "sendemail"))
206             {
207                 printf("...\n");
208                 fflush(stdout);
209                 send_email();
210             }
211         }
212     }

以上就是使用 C 語言的程式碼,編譯時請輸入產生執行檔
$ sudo gcc sendemail.c -l wiringPi -l curl -std=gnu99 -o sendemail


上面兩個程式在執行或是編譯前,請先設定好電子郵件相關的資料在程式裡面,這部分請自行參考 "[PIR] 使用人體紅外線感應 (PIR) 模組,製作家中安全防護及警報系統" 網頁的說明。

由於 AlaMode 裡已經上傳了程式,因此只要樹莓派這邊 sendemail 程式不開啟的話,它就只會開關電燈與發出警報聲。所以不管在樹莓派中使用哪個程式,主要的功能就是接收文字訊息,並且發送電子郵件,使用的方式如下:

Python
pi@raspberrypi ~/codes $ cd PIR_AlaMode/
pi@raspberrypi ~/codes/PIR_AlaMode $ sudo python sendemail.py
2013/3/31 14:9:33 MOVEMENT
sendemail
...

Sending Email
To:ruten.proteus@gmail.com
From: ruten.proteus
Subject:Intrusion!!

2013/3/31 14:9:38  Ready...

  Quit!

pi@raspberrypi ~/codes/PIR_AlaMode $


C
pi@raspberrypi ~/codes $ cd PIR_AlaMode/
pi@raspberrypi ~/codes/PIR_AlaMode $ sudo python sendemail.py
FD_TTY = /dev/ttyS0
FD_BAUD = 9600
Serial device /dev/ttyS0 (baud rate: 9600),open success!!!

2013/3/31 21:27:33 MOVEMENT
sendemail
...
* About to connect() to smtp.gmail.com port 587 (#0)
*   Trying 173.194.79.109...
* connected
* Connected to smtp.gmail.com (173.194.79.109) port 587 (#0)
... << 中間省略 >> ...
< 221 2.0.0 closing connection qs10sm10029341pbb.28 - gsmtp
* SMTP 0xffe218 state change from QUIT to STOP
* Closing connection #0


2013/3/31 21:27:38  Ready...

pi@raspberrypi ~/codes/PIR_AlaMode $


以上就是 AlaMode 與人體紅外線感應 (PIR) 模組和樹莓派之間的搭配應用,提供給大家做參考。


返回 "人體紅外線 (PIR) 感應模組系列文章" 或 "AlaMode: Get Started (中文入門說明)看其他單元


<<樹莓派編輯環境設置系列文章>>

2 則留言:

  1. 版大您好,

    或許有人會問,這不是都一樣嗎 ? no! No! NO! 同款隔不同師傅!
    AlaMode 只要有電,裡面的程式會一直執行,當你想要在 PIR 模組被觸發時發送電子郵件再把樹莓派裡的接收程式開啟就可以了。

    是的..

    想請教,
    跟只用rpi實作比較,用AlaMode 與 Raspberry Pi 做的家用安全系統,
    有什麼優缺點呢?(當你想要在 PIR 模組被觸發時發送電子郵件再把樹莓派裡的接收程式開啟就可以了。<-為何有此設計考量呢?)

    謝謝!

    回覆刪除
  2. 您好:

    其實這程式最主要是要說明在樹莓派中如何使用 AlaMode 並撰寫程式,這是之前 PIR 系列文章就要寫的,雖然效果與單純使用樹莓派實做一樣,但是多加了 Arduino 外部中斷使用的方法、以及 RTC 晶片的讀取方式和 UART 通訊。

    我想要說明的是,相同的效果可用不同的東西來完成,了解不同程式碼之間的轉換方式,就可以很容易自己做程式移植,網頁中就是範例,可互相做為比較。

    好處就是不需要浪費多餘的 CPU 時間在樹莓派中,將常規化的工作給 AlaMode 做。舉個例子,若您需要作量測,工件載入、工件傳送、量測...等工作若式都在同一台電腦完成,這負載會很大!因此我會將其分成模組化控制,每個模組負責單一工作,各模組之間由主電腦與其通訊並傳送命令,只要各模組之間的通訊格式定義好,主電腦就可以很方便監控與控制,不需要什麼事都自己做。

    因為我們的範例不困難,所以或許看不出其好處,但是當更多模組加進來的時候,是將其分開後設計比較方便還是全部放在一起設計較簡單就可以明顯感覺得出來了!

    以上是個人看法,歡迎再作討論!

    回覆刪除