2015年3月2日 星期一

Raspberry Pi 藍牙4.0應用之iBeacon 發射器

藍牙在4.0版本中定義了「高速藍牙」、「傳統藍牙」和「低功耗藍牙」三種模式。高速藍牙主攻資料交換與傳輸;傳統藍牙則以資訊溝通、裝置連線為重點;藍牙低功耗顧名思義,以不需佔用太多頻寬的裝置連線為主。


而採用低功耗藍牙(BLE或藍牙4.0)的發射定位訊號的技術稱為Beacon,Apple公司在2013 WWDC(全球軟體開發者年會)中發佈了一項技術稱為 iBeacon (唸"矮嗶肯"),
iBeacon這項技術在Apple主要應用是想取代部分的 NFC (近場感應及支付)功能,另一個最常見的應用就是室內定位。目前常見室內定位技術大致分為Wifi、Zigbee及BLE三種,這三種技術大致上的共同點都是使用無線傳輸中RSSI( Received Signal Strength Indication,接收信號強度指示 )的dB值強弱來判斷距離。
而Beacon與iBeacon的差別於廣播訊號頻率。
也就是說 iBeacon 其實是基於BLE的訊號廣播設備,在基本的架構中通常會有一個 iBeacon 發射器,而這個發射器有一個唯一的ID號碼其主要的內容包括內容 UUID(16 byte)、Major (2 byte)、 Minor (2 byte)及 Tx Power等資訊。目前常見的發射器只有單向發射訊號的功能,除非客製化成Dual-Mode iBeacon的服務不然發射器並沒有接收功能。

因此在室內定位技術部分,前面提到過iBeacon的信號強度採用RSSI值表示。隨著距離的遠近,RSSI值會產生變化透過校準發射功率 (txPower)就可以算出與發射器的距離,這部分可以參考 iBeacon計算距離說明

當iBeacon接收器(手機或硬體裝置)接收到這組資料,就可以判斷所在位置。
由於上述訊號會因為一些物理或空間上的影響而改變,因此Apple定義了四種範值:
Immediate 很近,小於1公尺。
Near           附近,約1-3公尺。
Far              較遠。(或離開範圍)
Unknown   未知,一般出現在啟動階段,或者因為某些原因無法判斷。
至於定位方案則可以透過單點定位、兩點定位及多點定位方式以 iBeacon 發射器的數量多寡來完成定位的精準。詳見 iBeacon如何定位 說明

至此,或許會有個疑惑就是上述說過一般iBeacon只有單向發射訊號的功能,並沒有接收功能。要如何達到所謂的支付功能呢?
這個部分,通常還是需要依靠一個系統後臺服務或者雲端服務來完成,以下面的架構圖來看就很明白運作原理。

或者參考YouTube上的詳細介紹:



實作:
環境說明:
Raspberry Pi
EDIMAX 訊舟 EW-7822Uan 300M USB無線網路
SanDisk 16G microSDHC card
嘻哈佈落科技 CSR V4.0藍牙傳輸器

作業系統:
RASPBIAN
gcc version 4.6.3

步驟:
1.由於目前RASPBIAN作業系統中的Kernel已經將藍牙設備預設啟動,因此在Kernel部分我們就不需要修改內容。

2.安裝所需要的套件
sudo apt-get -y install libglib2.0-dev libudev-dev libical-dev libreadline-dev libdbus-1-dev

3.安裝 BlueZ 藍牙工具套件
這裡有兩種方式,一種是從 Raspbian 套件庫安裝,但BlueZ版本會比較舊。
另一種方式是直接到BlueZ官網下載 User Space BlueZ Package 來安裝。本文採用這個安裝方式來進行,目前官網上最新版本為5.28版。

wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.28.tar.xz


4.解壓縮下載檔案。
unxz bluez-5.28.tar.xz && tar xvf bluez-5.28.tar

5.編譯及安裝
cd bluez-5.28
LDFLAGS=-lrt ./configure --disable-systemd
make  (註:如果使用的是Raspberry Pi 2 可以使用 make -j4 指令進行編譯速度會比較快!!)
sudo make install

如果再make過程中出現 collect2: ld returned 1 exit status 錯誤的話,請在 ./configure --disable-systemd 前面加入 LDFLAGS=-lrt 參數既可完成編譯。


以上步驟已經完成BlueZ 藍牙工具套件安裝,接著開始啟動藍牙:

6.確認作業系統是否有抓到藍牙裝置。
lsusb


7.確認藍牙裝置接收器已被啟動。
hciconfig

由上圖所示,可以看到系統已經啟動藍牙裝置,並且命名為hci0

8.關閉掃瞄 Host 端功能,只用來發射訊號。
sudo hciconfig hci0 up
sudo hciconfig hci0 noscan

註:執行中如果出現 Can't set scan mode on hci0: Network is down (100) 訊息,代表藍牙裝置尚未啟動必須用sudo hciconfig hci0 up指令啟動它。

9.啟動 BLE 訊息廣播功能。
sudo hciconfig hci0 leadv

10.測試發送 iBeacon 的資料封包。
sudo hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 E2 C5 6D B5 DF FB 48 D2 B0 60 D0 F5 A7 10 96 E0 00 00 00 00 C8 00

此時你可以拿出iPhone/iPad或是Android來接收看看訊號。
這個時候需要注意的地方是所測試的硬體裝置必須要支援藍牙4.0 BLE的功能,因此比較舊款的裝置必須要確認一下是否有支援;
Apple 相關裝置部分,作業系統必須是 iOS 7 硬體則為:
iPhone 4s or later
iPad (3rd generation) or later
iPad mini or later
iPod touch (5th generation) or later

Android部分則必須是Android 4.3版以上,硬體部分由於太多請上相關官網查詢,本文測試所採用的是 Samsung Galaxy Note 3

軟體部分:
iPhone/iPad部分請安裝 Locate Beacon
https://itunes.apple.com/us/app/locate-beacon/id738709014?mt=8

Android部分請安裝Locate Beacon
https://play.google.com/store/apps/details?id=com.radiusnetworks.locate&hl=zh-TW

以下是Locate Beacon相關測試畫面:

經過上述的方法測試,確認沒有問題的話接著我們可以將 iBeacon 發送資訊的功能把它設定成一開機就執行,步驟如下:

11.在pi使用者家目錄下建立一個存放iBeacon服務相關檔案的目錄。
mkdir /home/pi/ibeacon

12.建立ibeacon.conf參數檔:
vi /home/pi/ibeacon/ibeacon.conf
其內容為:
export BLE_DEVICE=hci0
export UUID="e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0"
export MAJOR="00 01"
export MINOR="00 00"
export POWER="c8"

(註:相關設定參數參考文章後記說明)


13.建立名稱為start的啟動script檔。
vi /home/pi/ibeacon/start
其內容為:
#!/bin/sh
. ./ibeacon.conf
echo
echo "Enable iBeacon singal Advertising ..."
sudo hciconfig $BLE_DEVICE up
sudo hciconfig $BLE_DEVICE noleadv
sudo hciconfig $BLE_DEVICE noscan
sudo hciconfig $BLE_DEVICE leadv
sudo hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 $UUID $MAJOR $MINOR $POWER 00
echo "Complete"


14.建立名稱為stop的啟動script檔。
vi /home/pi/ibeacon/stop
其內容為:
#!/bin/sh
. ./ibeacon.conf
echo
echo "Disable iBeacon Advertising ..."
sudo hciconfig $BLE_DEVICE noleadv
echo "Complete"

15.將start及stop兩個檔案加入可執行的權限。
chmod +x /home/pi/ibeacon/start /home/pi/ibeacon/stop

16.建立一個名為ibeacon系統服務設定檔。
sudo vi /etc/init.d/ibeacon
其內容如下:
#!/bin/bash

### BEGIN INIT INFO
# Provides:             ibeacon
# Required-Start:       $local_fs $syslog
# Required-Stop:        $local_fs $syslog
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description:    iBeacon Emmiter
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:$PATH

DESC="iBeacon Service"
PIDFILE=/var/run/ibeacon.pid
SCRIPTNAME=/etc/init.d/ibeacon

case "$1" in
start)
        printf "%-50s" "Starting ibeacon..."
        cd /home/pi/ibeacon
        ./start
;;
stop)
        printf "%-50s" "Stopping ibeacon..."
        cd /home/pi/ibeacon
        ./stop
;;
restart)
        $0 stop
        $0 start
;;
*)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac


17.將編輯好的ibeacon檔案加入可執行權限。
sudo chmod +x /etc/init.d/ibeacon
設定開機時自動啟動 。
sudo update-rc.d ibeacon defaults

18.測試上述script 使否正確重新啟動服務。
service ibeacon restart

看到上述訊息代表設定成功,接著重新啟動確認開機後系統會自動戴起iBeacon 服務。



後記:
1. 本文實作在PC上如果使用的是Ubuntu同樣也可以實作出,不一定用在Raspberry Pi上面。

2. iBeacon 有UUID(16 byte)、Major (2 byte)、 Minor (2 byte)及 Tx Power等參數,其說明如下:
UUID 服務識別碼: 這裡用來區別不同公司不同的系統。例如:
Apple在它們自家的iBeacon服務中定義了 Apple AirLocate 其UUID開頭為 E2C56DB5 、5A4BCFCE 及 74278BDA。
本文的UUID就是採用 E2C56DB5 開頭的一組  Apple AirLocate UUID : E2C56DB5-DFFB-48D2-B060-D0F5A71096E0 。

另外常見的UUID還有:
Radius Networks 的 2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6 及 52414449-5553-4E45-5457-4F524B53434F
RedBear Labs 的 5AFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF
TwoCanoes 的 92AB49BE-4127-42F4-B532-90FAF1E26491
Estimote 的 B9407F30-F5F8-466E-AFF9-25556B57FE6D
UUID不一定要符合上述、以目前來看,尚未有一個組織在管理各家所定義的UUID,所以你可以定義一組UUID,這時你只要確定你的接收端Client能解析出你所定義的 UUID 就可以了。上述的UUID在iPhone/iPad/Android所安裝的 Locate Beacon 軟體均可解出。

Major ID: 在同樣 UUID 的一群 iBeacon 發射器中為了區隔不同分類可以定以此Major Number (2 byte),例如商場 1F 就定義為0001、以此類推;又或者電器商場中電視就定義為0001、冰箱為0002、洗衣機.....

Minor ID: 則是在更細的分類、例如商場某層樓為3C販賣此時你就可以把 ACER的Major Number為001,ASUS定義為002,....以此類推。

TX power:則是用來判斷使用者與beacon之間的距離遠近。


3. iPhone/iPad 的  iBeacon 接收軟體,請參考 GitHub 上的原始碼: https://github.com/relevante/ibeacon-tutorial
教學網站在這裡: http://ibeaconmodules.us/blogs/news/14279747-tutorial-getting-started-with-ibeacon-app-development

4. Android 的 iBeacon 接收軟體,請參考 GitHub 上的原始碼: https://github.com/Vinayrraj/Android-iBeacon-Demo
我試過執行畫面如下:


5.下圖為一般市售的 iBeacon 發射器,大約為50元硬幣大小規格上說可以發射訊號持續一年。

這類產品如果要該參數通常會使用藍牙配對後透過 AT command 來進行,例如
UUID: 0XFFB1 用來改 Major&Minor ID
UUID: 0XFFB2 用來改 iBeacon UUID
......
在iPhone/iPad 中可以透過 LightBlue - Bluetooth Low Energy 這個APP來更改。
https://itunes.apple.com/tw/app/lightblue-bluetooth-low-energy/id557428110?mt=8



參考:
Raspberry Pi 的應用 - iBeacon 發射器
http://blog.itist.tw/2014/05/ibeacon.html

Raspberry Pi 和 USB 藍牙自製 iBeacon 發射器
http://www.arthurtoday.com/2014/12/raspberry-pi-ibeacon-transmitter.html#ixzz3T7BSaQuB

piBeacon - DIY Beacon with a Raspberry Pi
https://learn.adafruit.com/downloads/pdf/pibeacon-ibeacon-with-a-raspberry-pi.pdf
https://learn.adafruit.com/pibeacon-ibeacon-with-a-raspberry-pi/overview

What is iBeacon?
http://www.ibeacon.com/what-is-ibeacon-a-guide-to-beacons/

INTRODUCTION TO ELVISTEK’S IBEACON SOLUTION
http://www.elvistek.com/docs/Introduction_to_ElvisTek%27s_Ibeacon_solution_for_Customer.pdf

iBeacon應用



==============延伸閱讀=====================
1. Raspberry Pi 第一次接觸
http://cheng-min-i-taiwan.blogspot.tw/2013/02/raspberry-pi.html

2.Raspberry Pi 網路設定
http://cheng-min-i-taiwan.blogspot.tw/2013/02/raspberry-pi_23.html

3.Raspberry Pi 應用之Windows檔案伺服器
http://cheng-min-i-taiwan.blogspot.tw/2013/02/raspberry-pi-windows.html

4.Raspberry Pi 應用之DLNA影音伺服器
http://cheng-min-i-taiwan.blogspot.tw/2013/02/raspberry-pi-dlna.html

5.Raspberry Pi 硬體控制-- Python 語言篇
http://cheng-min-i-taiwan.blogspot.tw/2013/04/raspberry-pi-python.html

6.Raspberry Pi 硬體控制-- C 語言篇
http://cheng-min-i-taiwan.blogspot.tw/2013/04/raspberry-pi-c.html

7.Raspberry Pi 2 Model B 使用心得
http://www.cheng-min-i-taiwan.blogspot.tw/2015/02/raspberry-pi-2-model-b.html

8.Raspberry Pi 藍牙4.0應用之iBeacon 發射器
http://www.cheng-min-i-taiwan.blogspot.tw/2015/03/raspberry-pi-40ibeacon.html

9.Raspberry Pi安裝MQTT之應用 -- Android訊息推播
http://www.cheng-min-i-taiwan.blogspot.tw/2015/03/raspberry-pimqtt-android.html

10. Raspberry Pi安裝MQTT之IoT應用 -- Android示範
http://cheng-min-i-taiwan.blogspot.tw/2015/03/raspberry-pimqttiot-android.html#more

17 則留言:

  1. 你好,請問一下
    如果我想使用USB dongle透過Bluez傳送字串(英文字串)給遠端藍牙模組 我該如何實現?

    回覆刪除
    回覆
    1. 用藍牙的UART profile比較快,請參考http://goo.gl/lP5GHP ,如果你要簡單一點的話網路上有一些高手寫好的jar你可以拿來用。

      刪除
    2. 你好,由於想做到樹莓派與遠端藍牙4.0模組溝通之功能(不直接手機與模組溝通)
      若使用Bluez(或有其他方法)的話要如何實現?
      謝謝

      刪除
    3. 如果要透過藍牙有兩種方式,
      一種是買個藍芽模組接在IO腳上,你就可以跟預設的com port進行溝通,類似的作法你可以參考部落格裏面有一篇RPi與GPS方式,藍牙的接法則參考這篇:http://yehnan.blogspot.tw/2013/09/raspberry-pi.html

      另外一種方式,你可以試試看用BT USB dongle與你的終端裝置配對後,看看/dev/目錄下有沒有新增加一個USBxxx開頭的裝置,你得程式就直接跟/dev/USBttyXX進行溝通就可行了。

      刪除
    4. 補充一項,就是透過BLE的協定去溝通,這部分....不過~~有些些複雜!

      刪除
    5. 你好,我使用USB dongle透過hcitool lescan找到模組之位置
      並透過hcitool lescan與模組建立連線(這樣配對是否正確?)
      但在/dev/目錄中沒有版主你所說的裝置..
      (另外我有使用過sudo bluez-simple-agent hci0 xx:xx:xx:xx:xx:xx無法配對)
      不好意思 問題有點多 因為傳字串這個功能卡的有點久 再請版主解答一下 謝謝

      刪除
    6. 您試試看用Xwin的方式配對看看,參考:http://www.modmypi.com/blog/installing-the-raspberry-pi-nano-bluetooth-dongle

      刪除
  2. 作者已經移除這則留言。

    回覆刪除
  3. 你好,我發現我使用hcitool scan不到模組的位址(hcitool lescan可以搜尋的到)
    請問是不是因為這樣才無法使用版主所提供的方式配對?
    如果這樣的話有辦法解決嗎?

    回覆刪除
  4. 請問iBeacon 可以做到方位的判斷嗎?
    如果想要做精度1公尺內的室內定位有什麼建議的做法嗎?
    謝謝

    回覆刪除
    回覆
    1. 方位判斷建議由接收端或手機上的陀螺儀之類的去做比較精準。
      令外增加iBeacon數量然後寫個三角定位演算法是可以做到1M精準

      刪除
  5. 你好,小弟我是個初學者多多包涵,請教一下,到目前為止,步驟五以前都相當順利,可是藍芽就是讀不到,用Lsusb測好幾次都沒偵測到,沒辦法接下去進行,請問哪裡出了問題呢,另外步驟一是什麼意思?

    回覆刪除
    回覆
    1. lsusb沒有看到你插進去的 bluetooth USB dongle 代表預設的RPi 驅動程式沒有支援到,建議:
      1.找一隻有支援raspberry pi 的 bluetooth 4.x USB dongle
      2.或者....找驅動自己安裝

      刪除
  6. 你好,小弟我是個初學者多多包涵,請教一下,到目前為止,步驟五以前都相當順利,可是藍芽就是讀不到,用Lsusb測好幾次都沒偵測到,沒辦法接下去進行,請問哪裡出了問題呢,另外步驟一的Kernel是什麼?

    回覆刪除
  7. 你好~ 我發現一個問題,有些使用人(包括我)用vi 指令下,會有bug出現,一整行的波浪,無法輸入任何訊息

    解決的辦法是 "" vi改成nano "" 一樣可以設定開機啟動藍芽

    回覆刪除
  8. 請問出現這個錯誤該如何解決?
    can't set advertise mode on hci0 input/output error (5)

    回覆刪除
  9. 您好,請問有沒有辦法將樹莓派設定為server端,做為接收beacon訊號的模式呢
    若方便的話能否讓我用email跟您聯繫呢 dnex779@gmail.com

    回覆刪除