文章類型
開發平台
解決方案
關注主題
文章類型
開發平台
解決方案
關注主題

[Tutorial]運用 Arduino Yún實現家庭防盜系統

作者:章國俊

上週末(4/25)參加了MakerPRO舉辦的「用 Arduino Yún 自造智慧家電」工作坊,終於有機會實際用到它。Arduino Yún 本身所擁有的網路功能使得它可以直上「雲端」!但如何讓它接上網際網路這朵大雲呢?如何運用現有的資源製作出一個有用的東西呢?

那麼來試試,用 Arduino Yún 加上一個攝影機來實現家庭防盜系統 — 「當家門打開時,在手機上會出現通知,並且能夠看到是誰打開門的」。

透過 Temboo 這個服務,再結合 Dropbox 以及IFTTT,運用 Arduino Yún 做到這些功能其實並不難!

1

先看一下!可以發現 Temboo 直接支援 Arduino Yún,只要按照網頁上面指引的程序,一步一步進行,最後就會幫我們產生程式,我們只需要依照實際的需要修改就可以了。

開始動手做吧!

大致的運作流程如下:

1. 在 Arduino Yún 裝上 USB 攝影機,並且使用一個微動開關。當門打開時,微動開關會被觸發,並啟動攝影機拍一張照片。
2. 透過 Temboo,將照片傳到 Dropbox。
3. 透過 IFTTT,當 Dropbox 有新的照片時,會在手機上出現通知,而且可以看到照片。
4. 透過 Temboo,在 Google Drive 的 spreadsheets 上面增加一筆紀錄。

第一步:設定 Arduino Yún

Arduino Yún 簡介和基本的操作及設定,可以參考 Cave 教育團隊的教學文件
設定部份請參考:http://www.slideshare.net/NissinAllelujahnissin/141125-42552501

當用瀏覽器看到這個畫面時,就可以進行下一個步驟了。

2

第二步:在 Arduino Yún 安裝 USB Camera 以及所需的軟體

先用 ssh 連上 Yún 的 Linux 部份(root 密碼就登入上面那頁時所用的密碼)

3

執行以下的指令,以安裝攝影機所需的軟體。

opkg update
opkg install kmod-video-uvc
opkg install python-openssl
opkg install fswebcam

完成之後將攝影機接上

4

並且插上 MicroSD 卡

執行
cd /mnt/sda1
fswebcam -r960x720 test001.jpg
ls -l test001.jpg

確認一下照片是否成功地存在記憶卡上面,如果成功了就繼續下一步。

第三步:設定 Temboo 帳號

可以參考 http://www.slideshare.net/NissinAllelujahnissin/141125-42552501
從第 15 頁開始有註冊的方式和基本的設定。

第四步:建立將照片傳到 Dropbox 的程式

其實這個程式是由 Temboo 幫我們產生的,自己只需要做一些修改。

在 Temboo 註冊並且建立了一個 Application 之後,到:
https://www.temboo.com/library/Library/Dropbox/FilesAndMetadata/UploadFile/

5

在右上角的 IoT Mode 設為 off,點選藍色字的 Get OAuth Tokens,按照網頁上的指示一步一步作。雖然要花一點時間,但這個操作的過程的介面非常友善,很容易成功的!

6

建立 Dropbox APP 與認証的步驟都完成之後,會進入下面這個畫面。然後自己在 FileContents 這個欄位裡填上「SGVsbG8=」;FileName 欄位填入 test.txt。

註:
如下圖

1. FileContents 欄位填入的值 “SGVsbG8=" 是 “Hello" 這個字經過 base64 編碼後的結果。這是因為實際上傳檔是透過 Web Service 進行的,像圖片這類的二進位格式的檔案都必須先經過編碼成文字再傳送。
上面那些被自動填進去,沒有規則字元的組合都是不可以洩漏的,圖片裏面的都是我自己亂敲的。

2. 按下RUN 如果成功的話,去看看Dropbox裏面是不是已經收到檔案了,如果檔案的內容是Hello結果就是正確了。

7

第五步:試著在 Arduino Yún 上面執行上傳檔案的程式

首先確認在這個網頁的右上角的 IoT mode 是 Off 的,然後往下在 Code 的部份選擇 Python。
接著要做兩件事情:

從右邊的 Get Python SDK 下載,解壓縮後將 temboo 這個資料夾,放進 MicroSD 卡。
複製產生的 Python 程式碼,稍做修改後另存新檔 upload.py,一樣也是放進 MicroSD 卡。

8

程式略做修改

import base64
import sys
from temboo.Library.Dropbox.FilesAndMetadata import UploadFile
from temboo.core.session import TembooSession

file_name = str(sys.argv[1])
with open(file_name, “rb") as image_file:
encoded_string = base64.b64encode(image_file.read())

# Create a session with your Temboo account details
session = TembooSession(“your account", “your app name", “your app ID")

# Instantiate the Choreo
uploadFileChoreo = UploadFile(session)

# Get an InputSet object for the Choreo
uploadFileInputs = uploadFileChoreo.new_input_set()

# Set the Choreo inputs
uploadFileInputs.set_AppSecret(“xxxxxxxxxxxx")
uploadFileInputs.set_AccessToken(“xxxxxxxxxxx")
uploadFileInputs.set_FileName(file_name)
uploadFileInputs.set_AccessTokenSecret(“xxxxxxxxx")
uploadFileInputs.set_AppKey(“xxxxxxxxxxx")
uploadFileInputs.set_FileContents(encoded_string)

# Execute the Choreo
uploadFileResults = uploadFileChoreo.execute_with_results(uploadFileInputs)

# Print the Choreo outputs
print(“Response: " + uploadFileResults.get_Response())

ssh 到 Console 來執行看看,如圖:

9

經過了這個測試,如果前個步驟用來測試攝影機安裝的那張照片可以傳到 Dropbox,這表示離成功又近一步了!

第六步:將開關接到 Arduino Yún

我的微動開關因為是要裝在門上,所以關門時是保持被壓下的,而開門時則釋放開來。所以在接線的時候,要讓開關在釋放時接通。

10

線路的接法可以參考這篇 Arduino 練習:以開關切換 LED 明滅狀態

自己寫段 Sketch:當開關釋放時,通知攝影機拍下照片,然後執行上一個步驟的用來上傳照片的 Python 程式。

#include
#include

Process process;
boolean hasPictured = false;
int MILIS_TO_WAIT_DOOR_OPEN = 2000;
int switchPin = 2;
String path = “/mnt/sda1/";

void setup() {
pinMode(switchPin, INPUT);
Bridge.begin();
}

void loop() {
if (digitalRead(switchPin) == HIGH) {
if (!hasPictured) {
delay(MILIS_TO_WAIT_DOOR_OPEN);
String fileName = takePicture();
hasPictured = true;
uploadPicture(fileName);
logToGoogleDrive(fileName);
}
} else {
hasPictured = false;
}
}

String takePicture() {
String filename = getCurrentTimeString() + “.jpg";
String filePathName = path + filename;
process.runShellCommand(“fswebcam " + filePathName + " -r 800×600″);
while (process.running());
hasPictured = true;
return filePathName;
}

void uploadPicture(String filePathName) {
process.runShellCommand(“python " + path + “upload.py " + filePathName);
while (process.running());
}

String getCurrentTimeString() {
String currentTimeStr;
process.runShellCommand(“date +%Y-%m-%d-%H-%M-%S");
while (process.running());

while (process.available() > 0) {
char c = process.read();
currentTimeStr += c;
}
currentTimeStr.trim();
return currentTimeStr;
}

void logToGoogleDrive(String filePathName) {
}

目前 logToGoogleDrive() 這個函式先保持空的,先整合開關和攝影機以及上傳的程式。

將程式 upload 之後,試著按下開關再放鬆,照片會不會自動傳到 Dropbox。
當我放開開關後,10 秒內就可以在 Dropbox 看到照片了。

11

第七步:運用 IFTTT 透過手機來通知

首先需要將 IFTTT 的 APP 下載到手機,完成註冊之後可以直接在手機或是 IFTTT 的網頁上進行設定。

12

以網頁為例:按右上角的 Create a Recipt,接著:

This 選擇 Dropbox
Trigger 選擇 New phote in your folder
That 選擇 Android Notification

設定完成之後可以看到如下圖這樣。

13

這時只要再次讓按下開關然後放開,幾分鐘後在手機就會出現通知。

14

15

第八步:在 Google Drive 上面建立 Log

首先在自己的 Google Drive 上面建立一個新的 Google Sheets,我的檔名是 GateMonitorLog,記得一定要在第 1 列放上標題!

16

然後又要借助 Temboo 了。

先到 https://www.temboo.com/library/Library/Google/OAuth/ 處理 OAuth 相關的設定。
還是按照上面指引的步驟,一步一步進行。其中在 InitializeOAuth 的步驟中,Scope 請填 “https://spreadsheets.google.com/feeds"

在完成 FinalizeOAuth 這個步驟之後記下 RefreshToken 的值。

來到 https://www.temboo.com/library/Library/Google/Spreadsheets/AppendRow/
填好相關欄位之後,一樣試 RUN 看看會不會成功。

如果成功了,將右上角的 IoT Mode 打開,就可以看到下載 Arduino 程式的聯結。
下載完成之後解壓縮,有兩個檔案:

TembooAccount.h 複製到剛才我們自己寫的那個 Sketch 的資料夾裏面。
appendrow_sketch.ino 則提取部份的程式,加到自己寫的那個 Sketch 的 logToGoogleDrive() 裏面。

程式再修改一下,這是最後版本了。(最後面與自己的 Google Account 和 OAuth 相關的部份要改成實際的值)。

#include
#include
#include
#include “TembooAccount.h" // contains Temboo account information, as described below

Process process;
boolean hasPictured = false;
int MILIS_TO_WAIT_DOOR_OPEN = 2000;
int switchPin = 2;
String path = “/mnt/sda1/";

void setup() {
pinMode(switchPin, INPUT);
Bridge.begin();
}

void loop() {
if (digitalRead(switchPin) == HIGH) {
if (!hasPictured) {
delay(MILIS_TO_WAIT_DOOR_OPEN);
String fileName = takePicture();
uploadPicture(path + fileName);
logToGoogleDrive(fileName);
}
} else {
hasPictured = false;
}
}

String takePicture() {
String filename = getCurrentTimeString(“+%Y-%m-%d-%H-%M-%S") + “.jpg";
String filePathName = path + filename;
process.runShellCommand(“fswebcam " + filePathName + " -r 800×600″);
while (process.running());
hasPictured = true;
return filename;
}

void uploadPicture(String filePathName) {
process.runShellCommand(“python " + path + “upload.py " + filePathName);
while (process.running());
}

String getCurrentTimeString(String format) {
String currentTimeStr;
process.runShellCommand(“date " + format);
while (process.running());

while (process.available() > 0) {
char c = process.read();
currentTimeStr += c;
}
currentTimeStr.trim();
return currentTimeStr;
}

void logToGoogleDrive(String fileName) {
TembooChoreo AppendRowChoreo;
// Invoke the Temboo client
AppendRowChoreo.begin();

// Set Temboo account credentials
AppendRowChoreo.setAccountName(TEMBOO_ACCOUNT);
AppendRowChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME);
AppendRowChoreo.setAppKey(TEMBOO_APP_KEY);

// Set Choreo inputs
String dateString = getCurrentTimeString(“");
String rowString = dateString +"," + fileName;
Serial.println(rowString);
AppendRowChoreo.addInput(“ClientSecret", “xxxxxxxxxx");
AppendRowChoreo.addInput(“RefreshToken", “xxxxxxxx");
AppendRowChoreo.addInput(“RowData", rowString);
AppendRowChoreo.addInput(“SpreadsheetTitle", “GateMonitorLog");
AppendRowChoreo.addInput(“ClientID", “xxxxxxxxxx");

// Identify the Choreo to run
AppendRowChoreo.setChoreo(“/Library/Google/Spreadsheets/AppendRow");
// Run the Choreo; when results are available, print them to serial
AppendRowChoreo.run();

while(AppendRowChoreo.available()) {
char c = AppendRowChoreo.read();
Serial.print(c);
}
AppendRowChoreo.close();
}

upload 之後,再次按下開關然後放開,就可以看到剛剛建立的試算表出現資料了。

17

好,完成了!

只要準備好材料,這可以當作是一個週末的專案,自己動手完成!無論是好玩,還是作一個雛型的實驗,用 Arduino Yún 加上 Temboo 都是個不錯的方案。

章國俊

章國俊

平時為忙碌的軟體工程師,但閒暇時就搖身一變成為Maker,目前想做的專案是:一隻能捏爆鐵罐的手!
章國俊

上一篇: | 下一篇:

14 Comments

  1. 第五步的錯誤如下,請幫我看看,謝謝。
    root@Arduino:/mnt/sda1# python upload_picture_edward.py test.png
    File “upload_picture_edward.py", line 2
    import sys
    ^
    IndentationError: unexpected indent

    Post a Reply
    • 執行時發生問題的程式碼應該是直接從網頁剪貼下來吧?
      這是縮排造成的問題,可以再檢查一下!

      Post a Reply
  2. 你好!
    第五步的錯誤如下,請幫我看看,謝謝。

    Disabling the the banner.
    Writing JPEG image to ‘test001.jpg’.
    root@Group3:~# ls
    test001.jpg
    root@Group3:~# python upload.py test001.jpg
    python: can’t open file ‘upload.py’: [Errno 2] No such file or directory
    root@Group3:~#

    而且我有點不明白如何複製產生的 Python 程式碼,稍做修改後另存新檔 upload.py,一樣也是放進 MicroSD 卡。

    Post a Reply
  3. 你好!有一些問想問一下

    我有點不明白如何複製產生的 Python 程式碼,稍做修改後另存新檔 upload.py,一樣也是放進 MicroSD 卡。

    而且在第五步有點問題
    Disabling the the banner.
    Writing JPEG image to ‘test001.jpg’.
    root@Group3:~# ls
    test001.jpg
    root@Group3:~# python upload.py test001.jpg
    python: can’t open file ‘upload.py’: [Errno 2] No such file or directory
    root@Group3:~#

    Post a Reply
    • 從錯誤訊息來看,upload.py 並不在當前的目錄裡面。
      最簡單的方法就是把upload.py 和 test001.jpg 放在同一個目錄,這樣就能執行了。

      Post a Reply
  4. root@Arduino:/mnt/sda1# python upload.py test001.jpg
    File “upload.py", line 6
    with open(file_name, “rb”) as image_file:
    ^
    SyntaxError: invalid syntax

    Post a Reply
  5. 可以問一下 我拍的照片時間都是少八小時 UTC的時區
    請問怎麼改時區 如果直接設+8是可以 可是從新啟動就reset了
    感謝

    Post a Reply
    • 只需要到 /etc/TZ 將值改為 CST-8 就會立刻生效。

      Post a Reply
      • 可不可以詳細一點改時區的指令
        我困惑好久了

        Post a Reply
      • 不好意思 可以指令詳細一點嗎? 我搞了好久 拜託

        Post a Reply
        • 其實就是直接去編輯這個檔案 /etc/TZ
          可以先ssh進入系統,然後 vi /etc/TZ
          檔案內容改為 CST-8 就完成了!

          Post a Reply
  6. 哈囉,因為我家裡基於安全考量,需要做一個監控系統,但本人除了放假都在外地,希望透過電腦遠端查看家中狀況

    請問若要透過 wifi 將 arduino yun sense 到的資料傳輸到不同網域的遠端電腦,可以怎麼做呢?

    Post a Reply
    • 比較簡單的方法,還是可以如這篇的方式先將各種傳感器的資料集中傳到到某個地方(如Dropbox, MCS)。
      不同的Client端,再依需要取得資料。

      Post a Reply

我想回應

你的電子郵件位址並不會被公開。 必要欄位標記為 *

成城共創股份有限公司版權所有、轉載必究.Copyright(c) 2017 MakerPRO