Category Archives: 物聯網

[Micro:bit ] I/O腳位控制

本文要介紹BBC Micro:bit上的I/O腳位,讀取類比輸入腳位的變化之後來控制開發板上的LED matrix。做出類似長條圖的效果。

作者/攝影  曾吉弘
時間  3小時
成本
難度  * *
材料表
  • 個人電腦
  • BBC Micro:bit開發板
  • LED x1
  • 麵包板 x1
  • 跳線 x2

Micro:bit I/O腳位介紹

Microbit除了明顯的五個腳位(原廠稱為pad)之外,另外還有十多隻腳位,功能定義如下圖。在使用上就如同Arduino或其他的開發板一樣,數位I/O,類比I/O(PWM)、I2C與SPI功能,該有的都有。

在使用上,我們可以用鱷魚夾去夾住pad (0, 1 ,2, 3V GND這五個大的pad),但比較小的腳位在操作上就不是很方便,因為Microbit端建議使用DFRobot BOSON kit for Micro:bit,或是Seeed StudioGrove Inventor kit for micro:bit。如下圖是DFRobot BOSON kit for Micro:bit,您可以看到常用的腳位都做好防呆接頭,其他的腳位也有母座,直接接杜邦線就可以使用了。如果想要用Micro:bit來輸出音效的朋友,左下角的音源接頭,您一定會喜歡的啦。

硬體接線

請將可變電阻先插上麵包板,接著將中間腳位接到Micro:bit0號腳位(#0 pad),接著一側接地(GND)一側接電。

 

請注意Miro:bitGND腳位相當多,但在此使用比較好接的GND pad

Micro:bit程式

寫一個簡單的程式,按下A按鈕之後,會不斷讀取P0類比腳位的狀態(0~1023),如果P0<300的話,亮起 LED matrx 第一列,反之亮起1~4列。您可以自由修改這個判斷值與呈現的效果。

Javascript code

 

有興趣的朋友也可以轉成JavaScript來比較看看,慢慢就會進步喔

input.onButtonPressed(Button.A, () => {
   while (true) {
       if (pins.analogReadPin(AnalogPin.P0) < 300) {
           basic.showLeds(`
               . . . . .
               . . . . .
               . . . . .
               . . . . .
               # # # # #
               `)
       } else {
           basic.showLeds(`
               . . . . .
               # # # # #
               # # # # #
               # # # # #
               # # # # #
               `)
       }
       basic.pause(100)
   }
})

完工了!來試試看吧。確認腳位都沒接錯之後,請慢慢轉動可變電阻,看看LED matrix有沒有變化吧。

 

相關文章:

 

[App Inventor+Microbit小專題 ] 按鈕控制畫面小球

作者/攝影  曾吉弘
時間  3小時
成本
難度  * * * *
材料表
  • 個人電腦
  • App Inventor開發環境
  • 支援BLE的Android手機
  • BBC Micro:bit開發板

本文要介紹如何透過BBC Micro:bit開發板上的按鈕來控制App Inventor畫面上的小球左右移動,碰到畫面邊緣還會在Micro:bit LED matrix 上顯示對應的字樣。

 

範例 aia檔下載請按我

 

藍牙配對

 

Micro:bit端設定:

  1. 同時按住Microbit 正面A、B按鍵,不要放掉
  2. 按住A、B鍵時,把背面的Reset 鍵按下後再放開。
  3. 這時應該可以看到 “PAIRING MODE!” 以跑馬燈方式出現在Microbit LED 螢幕上,若看到這訊息,便可以放開A、B鍵。
  4. PAIRING MODE! 結束後,會看到一個圖形出現在Microbit LED 螢幕上,不同的Microbit 出現的圖案也不同,這是Microbit 不同裝置獨特的”簽名” (Signature) 。

  1. 這時候的Microbit 已經準備好跟其他裝置配對,請看以下影片教學

 

 

 

Android手機端設定:

  1. 進入Android手機的設定–>藍牙
  2. 確認Micro:bit 已進入配對模式
  3. 當Micro:bit上的‘PAIRING MODE!’ 顯示完,搜尋(每隻Android手機這個選項的文字不一定相同,但意思差不多),應該會看到類似 micro:bit [XXXXX]的選項,其中XXXXX 會根據每片micro:bit而不同。點選該裝置來配對。

4.micro:bit 會出現向左的箭頭,然後Android裝置上會跳出畫面要求輸入配對PIN碼的視窗。

5.按住Micro:bit 的按鍵A ,這時microbit 會連續出現六個數字,這就是配對碼。

6.回到Android裝置上,輸入這六個數字。如果Microbit 出現[V],代表配對成功。如果是[X]代表沒成功,請再試一次

 

編寫程式

匯入BLE 與 micro:bit extension

 

請登入MIT App Inventor官方網站,建立新專案,在Designer頁面中點選Palette左下角的Extension,再點選”Import extension“與”URL:

  1. 貼入以下兩個 extension link:

 

2. 請加入 Microbit_LedMicrobit_Button這兩個Microbit元件。兩者的BluetoothDevice 屬性設為 “BluetoothLE1″。這步驟很容易忘記,別漏掉了

  1. 加入四個按鈕放入 horizontalArrangement元件中,分別用於掃描、停止掃描連線與斷線

 

  1. 新增Canvas畫布元件(寬高各為320像素,底色隨意),再放入一個Ball元件。完成後Designer頁面如下圖(可以不用一模一樣)

Blocks頁面

 

本範例的基本概念是按下Micro:bit板子上的兩個按鈕可以控制小球左右移動,碰到Canvas邊緣會在LED矩陣上顯示對應的文字。開始吧:

STEP1: BLE連線成功後啟動Clockl元件

在BluetoothLE1.Connected事件中,首先啟動Clock.Timer(timer Interval 設為100),並顯示相關訊息,最後要求Micro:bit開始更新兩個按鈕的狀態。

STEP2:按下Micro:bit左側A按鈕

Microbit_Button1.ButtonAStateReceived事件中:

○如果按下了左側的A按鈕(Button_State_Value為true),則讓ball_X 變數值累減10。

○讓Ball1元件移動到(ball_X, 100),也就是左移10像素。

STEP3:按下Micro:bit右側B按鈕

現在看到右側的B按鈕,所做的事情幾乎一模一樣但是Ball1元件的移動方向是相反的。

Microbit_Button1.ButtonBStateReceived事件:

○如果按下了右側的B按鈕(Button_State_Value為true),則讓ball_X 變數值累加10。

○讓Ball1元件移動到(ball_X, 100),也就是右移10像素。

STEP4 Ball reached canvas’ edge

當小球碰到Canvas畫面四邊時,我們希望在Micro:bit的LED矩陣上顯示對應的文字。

Ball1.EdgeReached事件中,使用 if / else if 來檢查到底碰到了哪一邊,根據App Inventor的文件,1是北方,所以要透過Microbit_Led1.WriteLEDText指令來顯示’N’。其餘類推,請看下圖:

完工了!來試試看吧。請確認您的Micro:bit與Android已經配對好了。按下Microbit板子上的按鈕應該讓畫面上的小球左右移動,試試看讓小球去撞牆吧,看看有沒有顯示對應的文字。試試看用 Micro:bit LED 搭配 App Inventor 做出更多功能吧

 

 

相關文章:

[ Micro:bit開箱文] 手勢辨識Grove也有Micro:bit的擴充板套件了Grove Inventor Kit

Micro:bit 為英國廣播公司(BBC) 為推廣學齡兒童程式邏輯教育給所推出的簡潔版卡式開發硬體;外形小巧便於攜帶,在程式教學上的特點有著簡單好上手的介面,硬體上有內含幾款感測器可供單獨使用,以及其可擴充性接腳的設計可將其教育應用的觸角更加延伸。

作者/攝影  林德昀
時間  拆開包裝紙的時間
成本 約NT:1,900
難度  * * *
材料表
  • Grove Inventor Kit

本套件由創客界知名的 Seeed 為 Micro:bit 所推出符合 Grove 標準的模組化套件,一般在物聯網的學習上通常使用的麵包板及杜邦線會有較多接線上的出錯機會,而對於硬體較不熟悉的軟體初學者若使用此套件學習可事先排除很多上述的問題而可更直接專注於程式學習上。

本套件包含:

  1. 擴充母板
  2. 迷你喇叭模組
  3. 角度感測模組
  4. 超音波感測器模組
  5. 光感測器模組
  6. 防水三色發光二極體條
  7. 手勢感應器模組 (筆者認為最有可玩性的模組)
  8. 4 位數字顯示器
  9. 紅光 LED 模組
  10. micro USB 線
  11. 五色鱷魚夾線各2條 (黑、白、紅、綠、黃)
  12. 使用手冊

 

手勢辨識

Micro:bit 上 5×5 LEDs 顯示手勢方向

 

以手勢控制彩虹燈走向

(程式實作部分請期待另篇應用教學文)

 

1.擴充母板

將Micro:bit 的擴充腳位拉出,有給 Grove 4-pin 接頭×4, 以及可供鱷魚夾或香焦棒使用的接點:P0,P1,P2,P8,P12,P13,及3.3V和GND,左方還有PWR的電源指示LED,及僅使用於供電使用的Micro USB接頭 (無法寫入程式);右方中間有廷伸用的接頭目前尚未有其資料,待有新資訊後補充。

 

下圖為Micro:bit 放入後週邊使用其他配線的示意圖

  1. 迷你喇叭模組

可由此喇叭發出汽車,門鈴⋯⋯等,經由不同的頻率的輪入訊號,可得出多樣變化的聲音;此模組中有可供調整輪出音量的可變電阻。

 

  1. 角度感測模組

由10k 歐姆可變電阻組成的角度感測模組,變化角度可由0~300度。可在學習專案中控制音量或馬達轉速⋯⋯等。

 

4.超音波感測器模組

可由此模組以非接觸的方式測量距離,可學習依據不同的距離變化將變量經由Micro:bit轉化為光或聲音的不同變化。

 

5.光感測器模組

可檢測出光度的變化而輸出相對應的訊號,可學習依照訊號強弱的不同而控制LED閃爍⋯⋯等應用。

 

  1. 防水三色發光二極體條

由30顆3色LED 所組成1公尺長的LED 條,每一LED 可由程式獨立控制顯示不同色彩,其封裝具有防水性,可使用於戶外而無需擔心下雨淋溼的影響。

 

7.手勢感應器模組

具有識別 上、下、左、右、前、後、順時鐘、反時鐘及揮手共9種手勢的感測模組。其感測範圍於前方5~15公分,視角60度內的區域內。由於未有詳細資料,筆者猜其工作原理可能為以紅外光加上脈波調變及都卜勒效應所作的感測器。可由本模組實作手勢操作各項目應用,如切換音樂,調整音量,開關燈⋯⋯等。

 

脈波調變:以脈波的形態將訊號改變為所需要的波形,創客界常用的PWM即為一種工作時間寬度上的脈波調變;在實際生活中,各遙控器不相互干擾也是一種脈波調變的應用。

 

都卜勒效應:當接近或遠離時,會對觀察者造成測量頻率的變化;如火車接近時的鳴笛聲會較尖銳,而遠離時會較低沉。

 

  1. 四位數字顯示器

可於學習專案中用作顯示時間或實驗數值。

 

  1. 紅光 LED 模組

需注意LED腳位,若不亮時請檢查是否接反。

  1. 使用手冊

內含12種對於以上模組的基礎程式應用

 

相關文章:

[LattePanda] 使用Google Assistant玩互動語音助理

作者/攝影  袁佑緣
時間  1小時
成本
難度  * * * * *
材料表
  • LattePanda
  • 螢幕
  • 鍵盤
  • 滑鼠
  • 喇叭
  • 麥克風

本文說明如何使用 LattePanda搭配Google推出的Google Assistant服務,來打造一個智慧助手,一起來看看是如何完成的吧!

 

STEP0. 事前準備

為了要能夠使用語音服務,除了我們的小電腦LattePanda外,請額外再準備USB麥克風以及喇叭,另外本次的範例會需要連到Google 雲端的服務,所以請確認LattePanda能夠連到網路。

 

STEP1. 首先我們要到先設定一個Google Developer Project

請點選以下的網址到Google Cloud Platform,如下圖。

https://console.cloud.google.com/project

接著請點選”CREATE PROJECT”,建立一個新的專案,如下圖,建立一個新專案名稱為my-google-assistant。

初始設定完成後,要等幾分鐘才會建立完成,回到Platform的右上角可以看到正在建立新專案。

 

STEP2. 接著我們要完成Google Assistant API的設定

首先,請連到Google API的設定網頁(https://console.developers.google.com/apis/api/embeddedassistant.googleapis.com/overview),並把Google Assistant API設定為”ENABLE”。

接著,為了要取用Google雲端的API,我們必須先有一個認證的client端,所以請連到以下的網址來建立一組oauth client ID。

https://console.developers.google.com/apis/credentials/oauthclient

而如果還沒有設定過Consent Screen的話,系統會提示您填上必要的設定,請點選”Configure consent screen”,設定如下圖。

最後回到”Create client ID”這一步,在Application Type填上Other即可。

到這裡,我們就已經完成了Client ID的設定囉!

最後,請把這個Client ID資訊下載到電腦上(請點選右方的下載箭頭),待會在進行Google Assistant認證的時候會用到。

STEP3.設定Google Acitvity

 

在進到安裝Google Assistant 的程式之前,我們要先設定一下這個Google帳號的

Activity,請連到以下的網址進行設定。

 

https://myaccount.google.com/activitycontrols

 

至於什麼是Activity呢?簡單說就是允許Google能否取用某些個人資訊,例如聲音、App資訊等,為了要能夠讓Google助手能正常運作,請將以下三個Activity設為Enabled。

 

Web & App Activity

Device Information

Voice & Audio Activity

STEP4.安裝Google Assistant SDK Python函式庫

我們使用的Google Assistant SDK是基於Python這個程式語言下去實做的,所以必須先在電腦上安裝Python的執行環境。

請到Python的官網(https://www.python.org/downloads/windows/)下載最新版的安裝檔。

接下來執行下載的Python安裝檔,並記得將勾選”Add Python to PATH”的選項,讓Python的執行位址加到Windows的系統變數中。

再來,請按下Windows的快捷鍵<Win>+R,啟動Windows快速開啟,並打上cmd呼叫Windows Command Prompt。

請在開啟的Command Prompt中輸入以下指令

 

pip install –upgrade setuptools

 

呼叫Python的套件管理員更新setuptools這個套件。

接著再輸入以下指令

 

pip install –upgrade google-auth-oauthlib[tool]

 

把Google認證oauth client的工具安裝到系統中。

還記得我們在STEP2中下載的Client ID JSON檔嗎?請將下載的JSON檔的位址複製起來,並改到以下指令中的”path/to/client_secret_XXXXX.json”

 

在Command Prompt中輸入以下指令以完成認證。

 

google-oauthlib-tool –client-secrets path/to/client_secret_XXXXX.json –scope https://www.googleapis.com/auth/assistant-sdk-prototype –save

 

Google會自動提示您在瀏覽器中完成認證,認證完成如下圖。

認證完的credential.json會自動存在電腦的系統上,Windows環境中預設會存在AppData中,使用者以後在啟動Google Assistant時不用擔心需要再次認證。

最後我們看到Google Assistant SDK的source,前面有說過這個SDK是基於Python這款程式語言去實做的,使用上非常容易上手,而官方的github網址在這邊(https://github.com/googlesamples/assistant-sdk-python)。

裡面有紀錄如何安裝SDK,以及如何去使用提供的函式庫功能,另外還有一些現成的範例可以讓入門的使用者去做體驗,如果讀者想要擴充、修改自己的Google Assistant的功能,可以下載(Download ZIP)整個專案來去修改,有興趣的朋友不妨去嘗試看看!

 

而本文章為了快速的demo,在這邊直接使用包好的assistant-sdk範例套件,讓使用者可以省去下載、手動安裝的過程,所以請在Command Prompt中輸入以下指令

 

pip install google-assistant-sdk[samples]

 

最後我們輸入以下的指令來執行一個簡單的範例pushtotalk。

 

googlesamples-assistant-pushtotalk

 

這支pushtotalk會提示使用者按下Enter鍵並開啟Google Assistant的語音對談功能,請確定您的麥克風與喇叭都有接到LattePanda上,並確認前面的步驟都設定正確,接下來就可以來玩玩看Google Assistant有什麼功能吧!

 

 

相關文章:

 

 

 

[App Inventor+Microbit小專題 ] LED控制

作者/攝影  曾吉弘
時間  3小時
成本
難度  * * *
材料表
  • 個人電腦
  • App Inventor開發環境
  • 支援BLE的Android手機
  • BBC Micro:bit開發板

本文要介紹如何讓App Inventor 透過 BLE 來與最近非常熱門的BBC Micro:bit開發板互動。Micro:bit板子上已經具備了BLE藍牙通訊功能,搭配app Inventor寫好的micro:bit extesion,就能有更多互動的效果。本範例修改自 MIT App Inventor IoT網站之 Micro:bit範例

範例 aia檔下載請按我

藍牙配對

 

Micro:bit端設定:

  1. 同時按住Microbit 正面A、B按鍵,不要放掉
  2. 按住A、B鍵時,把背面的Reset 鍵按下後再放開。
  3. 這時應該可以看到 “PAIRING MODE!” 以跑馬燈方式出現在Microbit LED 螢幕上,若看到這訊息,便可以放開A、B鍵。
  4. PAIRING MODE! 結束後,會看到一個圖形出現在Microbit LED 螢幕上,不同的Microbit 出現的圖案也不同,這是Microbit 不同裝置獨特的”簽名” (Signature) 。

  1. 這時候的Microbit 已經準備好跟其他裝置配對,請看以下影片教學

 

 

 

Android手機端設定:

1.進入Android手機的設定–>藍牙

2.確認Micro:bit 已進入配對模式

3.當Micro:bit上的‘PAIRING MODE!’ 顯示完,搜尋(每隻Android手機這個選項的文字不一定相同,但意思差不多),應該會看到類似 micro:bit [XXXXX]的選項,其中XXXXX 會根據每片micro:bit而不同。點選該裝置來配對。

4.micro:bit 會出現向左的箭頭,然後Android裝置上會跳出畫面要求輸入配對PIN碼的視窗。

5.按住Micro:bit 的按鍵A ,這時microbit 會連續出現六個數字,這就是配對碼。

6.回到Android裝置上,輸入這六個數字。如果Microbit 出現[V],代表配對成功。如果是[X]代表沒成功,請再試一次

編寫程式來控制Micro:bit LED matrix

匯入BLE 與 micro:bit extension

 

請登入MIT App Inventor官方網站,建立新專案,在Designer葉面中點選Palette左下角的Extension,再點選”Import extension“與”URL:

  1. 貼入以下兩個 extension link:

 

2. 請加入 Microbit_Led 這個元件,這是一個非可視元件。並把它的 BluetoothDevice 屬性設為 “BluetoothLE1″。這步驟很容易忘記,別漏掉了

  1. 加入四個按鈕放入 horizontalArrangement元件中,分別用於掃描、停止掃描連線與斷線
  2. 加入一個說明訊息用的 label
  3. 加入一個 ListVeiw,當掃描到鄰近的BLE裝置時會顯示在這裡
  4. 新增一個 TextBox,在此輸入我們希望 micro:bit呈現的英文字(中文不行喔)
  5. 新增兩個按鈕,一個是 [Write to LED] 把 Textbox 內容丟給 micro:bit ,一個是[DrawSmiley],讓 Micro:bit 呈現我們所指定的點陣圖案。

Blocks頁面

  1. 掃描與連線

  1. 畫笑臉副程式

在此用一個副程式 DrawSmiley 來代表,我們會用一個 5 x 5 的數字陣列發給 Micro:bit,就能藉此顯示我們想要的圖形。

在此用到的是 Microbit_Led1.WriteLEDMatrixState指令搭配 binary to base 10 指令組合起來的 0101 陣列,1代表 LED亮起,0則是熄滅。仔細看看,這樣就是一個笑臉呢

0 1 0 1 0

0 1 0 1 0

0 0 0 0 0

1 0 0 0 1

0 1 1 1 0

  1. 發送Textbox內容到 Micro:bit

沒錯,就這麼簡單,直接把 Textbox內容透過 Microbit_Led1.WriteLEDText指令發送出去就好,但不能打中文喔

斷線

斷線時會呼叫 bluetoothLE元件來中斷藍牙連線,確認斷線之後則顯示相關訊息。

完工了!來試試看吧。請確認您的Micro:bit與Android已經配對好了。按下按鈕應該可以看到您在 Textbox 中輸入的文字(中文不行喔)以跑馬燈的形式出現在micro:bit 的 LED matrix 上。按下 smilley 按鈕應該也能看到笑臉圖案, 試試看用 Micro:bit LED 搭配 App Inventor 做出更多功能吧

 

相關文章:

 

完成如下圖:

[Micro:bit] 使用MicroPython與Boson套件設計智慧風扇

本篇文章將帶領讀者使用Microbit輕鬆打造一台小型的智慧風扇,有興趣的朋友不妨參考一下本文,一起來動手DIY吧!

作者/攝影  袁佑緣
時間  3小時
成本
難度  * * *
材料表
  • Micro:bit
  • 樂高積木
  • Micro:bit Boson 擴充版

 

介紹

本篇文章的主角是BBC推出的微型電腦micro:bit,有興趣的朋友不妨參考一下micro:bit的官方網站(http://microbit.org/),裡面有許多適合入門又豐富有趣的應用喔!

而為了要打造一台電動風扇,我們需要加裝額外的擴充版跟電子元件,本文所使用的是DFRobot推出的Boson擴充版,Boson是DFRobot 所推出的一系列電子套件,外型就像積木一樣,除了相容於LEGO之外,還可以用金屬羅絲固定,並且附有磁吸式的底座,容易組裝也容易拆卸,且電路的接口都有經過特別的設計,隨插及用,非常適合沒有電路基礎的小朋友們入門電子實做的世界!

 

想了解更多boson kit相關資訊的朋友,不妨去參考一下DFRobot的官方網站說明喔(https://www.dfrobot.com/blog-630.html)!

準備

經過前面的介紹,接下來我們就要來正式進入我們的實做部份了,首先我們在軟體以及硬體上做一些準備。

 

組裝擴充版

準備我們的micro:bit以及Boson擴充板,組裝圖如下,記得micro:bit的logo朝下面,有LED陣列的那面朝上喔,如果說到時候燒錄程式失敗的話,就會用LED陣列顯示出錯誤訊息。

micro:bit控制板

組裝micro:bit boson擴充板

組裝完成!

 

風扇製作

本範例的硬體主要是用LEGO來做,請參考下方的圖片,零件上用LEGO動力機械的基本套件就能完成囉,當然有興趣的朋友也可以自己DIY設計一個獨特風格的電風扇底座,只要記得上面要有四個boson的座,在待會的實做部份我們會慢慢放入感測器以及馬達、風扇。

軟體安裝

Micro:bit 預設的程式撰寫環境有兩種,一種是圖形化的JavaScript Blocks Editor,另外一種則是我們接下來用的MicroPython Editor。

Microbit let’s code 網站:http://microbit.org/code/

MicroPython 線上編輯器

 

 

MicroPython是將原本就容易學習的程式語言Python實做到為微控制板的架構上,好比說是micro:bit,以下是micro:bit MicroPython的詳細說明文件(http://microbit-micropython.readthedocs.io/en/latest/tutorials/introduction.html),裡面有詳細敘述許多的功能,以及API取用的方法,比起圖形化的Block Editor 來說雖然難度上升了一點,但是彈性也增加了,可以讓我們程式撰寫的功能範圍變得更廣!

MicroPython for micro:bit文件

 

除了使用剛剛在官網看到的線上版,也可以下載MicroPython文件中推薦的Mu Editor(https://codewith.mu/#download),這款編輯器主打簡單、易學,初學者只要專心在學習如何撰寫MicroPython上就好。

Mu 編輯器

 

除此之外,這個編輯器還是跨平台的,不只Windows平台上可以執行,macOS或者是Linux也可以,請讀者依照自己的作業系統環境來下載。

下載Mu Editor

 

下載完成後,打開來之後就會有如下圖的編輯器,當我們要上傳程式碼的時後,請先將micro:bit用usb線接到電腦上,再按下flash的按鈕就行囉!

實做

STEP1:控制馬達 

首先我們先加入Boson套件中的馬達,請裝在基座的正中間,組裝如下圖。

裝完馬達跟風扇之後,接下來請把Boson的訊號線接到micro:bit Boson擴充板的8號腳位上,也就是右上角的那個插座,如下圖。

再來請打開我們的Mu Editor,並打上以下的範例程式碼。

from microbit import *

mode = [700, 900, 1023]
while True:
    for speed in mode:
        print(speed)
        pin8.write_analog(speed)
        sleep(1000)

 

程式碼解說

首先從microbit這個Python函式庫中引入所有的函式,也就是把我們所需要的工具都加進這支程式當中。

接下來再宣告一個變數mode,為三個數字的串列(list),其實就是建造一個三段變速的電風扇,而裡面的數字大小代表的則是馬達的輸出馬力,數字越大就會越強,風力也越大,注意到1023是最高的馬力,而最低馬力700則是個建議的數值,太低的話有可能馬達會轉不到風扇,這點要特別注意喔!

最後我們有一個大大的while迴圈,裡面在包著一個for迴圈,所謂的迴圈就是會在某種條件下一直執行動作的意思,好比說while True就是一直迴圈,for speed in mode就是在三段變速中各執行一次的意思。

至於for迴圈裡面的所執行的動作,就是很直接的把我們的馬達設成三段變速中的速度囉!其中要注意的是,我們所使用是函式(function)是write_analog,意思就是用類比(analog)電壓去驅動我們風扇的馬達,因為用數位的模式就只有開跟關的模式,為了要做到變速的模式,才需要用到類比控制喔!

 

 

 

STEP2:開關控制 

有了馬達之後,我們學會了撰寫程式碼來控制電風扇,但是這樣在使用上可能還不夠直接,如果說我們要像生活中的電風扇一樣,可以有個按鈕來開關電風扇呢?這時候就需要加裝感測器(sensor)啦,請依照下方的組裝圖加上一個Boson套件的按鈕,並把它接到擴充版上的腳位12上。

以下是這個範例的程式碼。

from microbit import *

fan_switch = False
while True:
    if pin12.read_digital():
        fan_switch = not fan_switch
        print('ON' if fan_switch else 'OFF')
        pin8.write_digital(int(fan_switch))
        while pin12.read_digital():
            sleep(100)

 

程式碼解說

在這個範例中,我們把重點放在風扇的開關上,所以在控制轉動風扇的馬達時,我們使用的就不是像前面變速式的類比(analog)方式,而是開跟關兩種模式互相切換的數位(digital)方式,所以用的函式是用write_digital。

在程式中,我們有宣告一個變數fan_switch,用來儲存現在使用者控制風扇的按鈕狀態(第12號腳位),每當使用者按下開關又放開之後,就會改變一次fan_switch的狀態,有可能是從開的狀態轉成關(ON->OFF),或者是相反,只要我們把這個fan_switch變數轉成數字後丟到控制馬達的函式上,就能夠達到開關風扇的功能囉!

請參考下面的示範影片,讀者是否能能順利做到開關風扇呢?

https://youtu.be/QeR3TxfTs5g)

 

STEP3:風量調整

 

接下來我們來整合一下前面兩步的範例,除了要能夠開關之外,還要加入一個旋鈕來調整風力大小,讓這個風扇更加的貼近使用者!

請按照下圖,加裝一個Boson 旋鈕套件到風扇的基座上,並把訊號線接到擴充板的0號腳位上,也就是板子的左上角。

以下是這個範例的程式碼。

from microbit import *

fan_switch = False
fan_mode = ["slow", "medium","fast"]
fan_power = [700, 900, 1023]

def fan_mode_switch(value):
    interval = int(1023/3)
    for i in range(3):
        if value >= i * interval and value < (i+1)*interval:
            break
    return fan_mode[i], fan_power[i]

previous_mode, power = fan_mode_switch(pin0.read_analog())

while True:
    if pin12.read_digital():
        fan_switch = not fan_switch
        print('Fan status: ' + ('ON' if fan_switch else 'OFF'))
        while pin12.read_digital():
            sleep(100)
    if fan_switch:
        mode, power = fan_mode_switch(pin0.read_analog())
        if mode is not previous_mode:
            previous_mode = mode
            print("Fan mode: ", mode)
            pin8.write_analog(power)
    else:
        previous_mode = 'OFF'
        pin8.write_analog(0)
    sleep(300)

程式碼解說

程式好像比起前面兩個程式碼加起來多了不少,就讓我們慢慢來拆解看看是怎麼實作的吧!

首先我們比起STEP1中的三段變速又更明確的定義了馬力(fan_power)跟風速模式(fan_mode)了,並且我們用def定義了一個自己的函式出來,這個fan_mode_switch函式主要會從吃進來的value值,也就是我們旋鈕轉到的數值,來決定我們現在風扇的模式,並輸出對應的馬力值。

而我們是如何判斷風扇馬力的模式呢?其實就是把我們的旋鈕數值(0到1023)分成三等份,然後看看當下使用者轉到的數值是落那一個區間上,就把它對應到三種不同的風力模式(slow, medium, fast)。

最後,這隻範例程式碼還有一個小細節是值得初學者去注意的,當我們在切換模式的時候,我們都必須要注意只有當前一刻風力模式跟此刻轉到的風力模式時才需要去改變我們馬達的轉速,同時顯示的馬力大小才需要去更新,所以我們會用一個previous_mode變數來儲存上一刻的模式喔!

以下是我們的示範影片。

 

STEP4:智慧風扇

最後,我們還想要加入一些常見的風扇沒有的功能,來讓我們的小風扇更加的智慧化,並貼近使用者的使用環境。請依照下面的組裝圖加上一個Boson套件的motion 感測器,並把訊號線接到1號腳位上。

而什麼是motion sensor呢?其實就是所謂的PIR(Passive Infrared Sensor),常見的用途就是用來偵測人體的接近(靠著生物體的紅外線),有時候我們在逃生梯上下樓時,電燈自動會開啟其實就是因為有這種感測器,它會自動偵測有人在走動來自動打光。

而我們想要實做的功能就是除了STEP3中有的功能以外,還要加入一個情境,如果偵測到有人的話,例如說偵測到人的手,就會自動開啟電風扇,而不需要特地去壓按鈕還開電風扇,一起來看是如何實做的吧!

以下是這個範例的程式碼。

from microbit import *

fan_switch = False
fan_mode = ["slow", "medium","fast"]
fan_power = [700, 900, 1023]

def fan_mode_switch(value):
    interval = int(1023/3)
    for i in range(3):
        if value >= i * interval and value < (i+1)*interval:
            break
    return fan_mode[i], fan_power[i]

previous_mode, power = fan_mode_switch(pin0.read_analog())

while True:
    if pin12.read_digital():
        fan_switch = not fan_switch
        print('Fan status: ' + ('ON' if fan_switch else 'OFF'))
        while pin12.read_digital():
            sleep(100)
    if fan_switch:
        mode, power = fan_mode_switch(pin0.read_analog())
        if mode is not previous_mode:
            previous_mode = mode
            print("Fan mode: ", mode)
            pin8.write_analog(power)
    elif pin1.read_digital():
        fan_switch = True
        print('Fan status: ' + 'ON')
    else:
        previous_mode = 'OFF'
        pin8.write_analog(0)
    sleep(300)

程式碼解說

比起STEP3的程式碼,我們延伸了主結構中的if…else…,將fan_switch的狀態以外,再新增(elif)了一個motion sensor的狀態(pin1.read_digital),注意到motion sensor只能偵測是否有人靠近,所以使用的是數位的訊號(digital),它無法偵測距離多寡,而且如果身體靜止一段時間的話,也不會觸發motion sensor喔!

以下是我們最後完成的智慧風扇影片,可以用按鈕開關風扇,還可以用旋鈕調整轉速,並且還能用motion sensor在有人的時候自動開啟風扇!

 

相關文章:

 

 

 

 

[LattePanda] 作品發表:中文手指閱讀器

這次跟各位讀者分享的作品,是淡江大學電機系CILAB實驗室朱永龍同學發表的專題,CILAB在互動式學習、人機互動、嵌入式系統、影像分析與辨識 、模式識別是主要研究方向,近年在小朋友學習、弱勢族群、MAKE領域發表相當多作品,更多作品可以到這裡

作者/攝影 徐豐智/朱永龍

本次作品為中文手指閱讀器,希望提供視障者一個輕巧且易於攜帶的閱讀器;將閱讀器穿戴在視障者的食指上,協助他們閱讀紙本書籍上的中文文字。視障者使用手指閱讀器時,系統首先會利用震動提示的方式,來引導視障者將食指移動到適當的閱讀位置(觸覺回饋)。系統辨識書籍上的中文文字完成後,透過朗讀文字提供視障者聽覺上的回饋。

 

來認識一下視障者的相關資訊吧

一般日常生活中閱讀文字是不可或缺的事情,除了閱讀書籍外,包括閱讀藥物罐上的說明,操作家電(例如微波爐)上的按鈕,閱讀車站內看板上相關訊息(例如位置、樓層)時,都需要辨識這些文字訊息。對視障者來說,理解這些文字訊息是一件困難的任務。對「中途失明者」來說更是如此,所謂的「中途失明者」是指年齡為15歲以上之視障者,他們原本擁有正常的視力,後來因為疾病或意外傷害導致失明。這些視障者未曾接受過特殊教育,他們普遍呈現摸讀速度緩慢、連續性不足、缺乏效率等問題。(*註解[1]-[5])

 

為了協助視障者閱讀文字,近年來國內外許多研究者提出許多研究成果。主要可分為穿戴式裝備或是手持式裝置兩大類型的輔具。(*註解[6]-[13])

  • 穿戴式輔具:

將身體當為攝影機或相機的載具,並在攝影機擷取影像後,搜尋影像中可能存在的文字區塊加以辨識。學者Yi與Tain將小型攝影機架設在眼鏡上,並透過影像分析與文字辨識技術,辨識出書寫在物品上的文字。Hanif與Prevost 同樣將小型攝影機架設在眼鏡上的方式,來辨識招牌上的文字,並提供一個震動回饋來與視障者互動。Mattar等人[8]設計一個頭戴式攝影機,來辨識招牌上的文字。Ezaki等人將攝影機架設在肩膀上,來辨識招牌上的文字。

  • 手持式輔具:

手持式裝置的特色就是視障者透過PDA或智慧型手機作為影像擷取裝置。學者Peters 等人[10]以PDA的相機擷取影像來辨識鈔票、條碼與商品上的標籤。Shen等人[11]使用智慧型手機辨識門牌或路標,並提供震動回饋來與視障者互動。

 

現在技術上常遇到的問題

  • 在擷取影像時,影像品質容易受到光源、焦距、反光等影響。
  • 在複雜背景中尋找文字區域也不容易。
  • 需要耗費大量的運算資源(處理時間可能需要數秒至數十秒)。
  • 很難辨別出哪些文字資訊才是視障者真正關心的資訊。

由MIT多媒體實驗室Shilkrot等人在2014與2015年所提出的穿戴式手指閱讀器。協助視障者閱讀紙本書籍上的英文文字。當系統辨識書籍上的英文文字後,利用語音朗讀文字的方式,讓視障者得知書籍上的文字內容為何。

這次主題以辨識繁體中文為主,將閱讀器套在食指上並指向書籍,閱讀器將透過震動提示引導視障者閱讀書中文字,閱讀器也將透過攝影機逐一朗讀出書籍上的文字內容,閱讀器也可以幫助外籍人士學習中文字。

View post on imgur.com

裡面的硬體裝置包含(1)小型攝影機、(2)震動馬達、(3)電容式觸控開關,(4)控制馬達的微控制系統。我們利用小型攝影機擷取影像資訊來判斷手指與書本文字的相對位置,並進一步擷取文字字元的影像。

 

我們來看看硬體

閱讀器裡面安置一個(5)電容式觸控開關,手指可藉由觸摸開關來切換閱讀器的中文閱讀模式、閱讀器內部也安置四個具震動功能之微型馬達,電腦端的控制系統可以即時控制馬達震動,並透過震動的提示資訊,引導食指移動到適當的閱讀位置。(6)LattePanda做我們文字辨識的後端處理系統,配合閱讀器可以隨時做文字處理,並隨時提供給使用者語音回饋。

View post on imgur.com

View post on imgur.com

情景一 單字閱讀模式

閱讀器擁有中文單字閱讀模式,使用者手指指向文字時,閱讀器將只偵測手指上方所指到的中文單字,單字閱讀模式不使用振動馬達,並且關閉其它跳行偵測和引導換行等震動提示功能。

View post on imgur.com

單一字閱讀

 

情景二 文章閱讀書籍文字

視障者在閱讀文章時並無法順利的將手指指在適當的文字位置上,文章閱讀模式在閱讀書籍時,閱讀器會透過震動馬達的震動來提示視障者,並引導食指移動到適當的文字位置,方便閱讀器做文字辨識。

我們在手指閱讀器內部安置了四個具震動功能之微型馬達。電腦端依據不同的使用情景設計了三種主要的引導機制(A)引導使用者到距離手指最接近的文字段落,並引導手指移至該行文字的開頭位置(圖4(a))。(B) 當手指出現跳行或偏移到其他橫行文字的情況時,閱讀器透過震動提示的方式,引導手指移回原本的閱讀的位置(圖(b))。(C) 當手指移動到此橫行文字段落的結尾邊界時,將提示回到行頭並到達下一行從頭開始閱讀(圖(c))。

View post on imgur.com

(a) 引導至開頭

View post on imgur.com

(b) 跳行提醒

View post on imgur.com

 

(c) 閱讀至結尾邊界時(震動引導機制

 

中文字元切割

當手指閱讀器將指尖前方的影像資訊傳送至電腦端後,CILAB開發一套中文字元擷取與辨識演算法來辨識影像中的文字。下圖是系統流程圖,這個系統利用影像前處理(灰階、Otsu、Opening、Closing)等演算法,找出指尖位置與傾斜角度,再偵測出行高等相關資訊來做文字擷取切割出單一的文字圖,透過中文字元辨識以及文字轉語音讓閱讀器念出中文。

View post on imgur.com

系統流程圖

 

若是針對整張影像做二色化處理,其二色化結果非常容易受到光源以及其他因素影像,經常出現文字破損的情況,也進一步影響文字切割以及中文字元辨識(OCR)的準確性。設計者採用區域式(local-based)的二色化處理擷取出完整度較好的文字影像,並提升文字切割以及中文字元辨識(OCR)的準確性。

另外採用投影掃描線法來偵測橫行,圖的灰色區域代表掃描線經過文字區塊(圖6a)。當系統偵測橫行並計算出行高後,我們會根據指尖位置,往上方延伸兩倍行高的高度,以及四倍行高的寬度,進行區域影像的切割(如圖(a)之紅色矩形區域),並針對此矩形區域使用Otsu threshold再次進行二色化處理,圖7(b)為此矩形區域進行二色化處理後之結果。

View post on imgur.com

橫向投影掃描線法

View post on imgur.com

View post on imgur.com

 

 

接著使用垂直投影的方式來切割中文字元(圖(a)),此種方式相較於切割英文字元會有較為複雜的問題,對於某些中文字來說(例如:化、川),以垂直投影進行文字切割時,一個完整的中文字元會被分割成兩個或三個獨立的文字區塊。

我們發現中文字的外觀都非常接近方正型,我們根據中文字的行高資訊,在做文字切割時,將部分寬度較小的且鄰近的中文字元合併成一個中文字元,圖 (b)為成功切割出一中文字元。

View post on imgur.com

圖(a)垂直投影掃描線

View post on imgur.com

(b)切割獨立元

 

註解

[1] 柯明期, 中途失明者適應與重建之研究。師範大學特殊教育所碩士論文, 2004。

[2] 李佳玲, 中高齡視障者電腦使用動機及對圖書館電子化資源服務需求之研究。臺灣大學圖書資訊學研究所碩士論文, 2013。

[3] W. Jeong, “Emotions in information seeking of blind people,” in Diane Nahl and Dania Bilal (Eds.), Information and Emotion: The Emergent Affective Paradigm in Information Behavior Research and Theory pp. 267-278, 2007.

[4] 陳怡佩。視覺障礙兒童及青少年的資訊需求。臺灣圖書館管理季刊, 2(3), pp. 32-43, 2006.

[5] K. Carey, “The opportunities and challenges of the digital age: a blind user’s perspective,” Library Trends 55(4): 767-784, 2007.

[6] C. Yi, and Y. Tian, “Assistive text reading from complex background for blind persons,” in Camera-Based Document Analysis and Recognition. Springer, 15–28, 2012.

[7] S. M. Hanif, and L. Prevost, “Texture based text detection in natural scene images-a help to blind and visually impaired persons,” In CVHI, 2007.

[8] M. Mattar, A. Hanson, and E. Learned-Miller, “Sign classification using local and meta-features,” in IEEE CVPR Workshops, pp. 26–26, 2005.

[9] N. Ezaki, M. Bulacu, and L. Schomaker, “Text detection from natural scene images: towards a system for visually impaired persons,” in Proc. of ICPR, vol. 2, pp. 683–686, 2004.

[10] J.-P. Peters, C. Thillou, and S. Ferreira, “Embedded reading device for blind people: a user-centered design.” in Proc. of IEEE ISIT, pp. 217–222, 2004.

[11] H. Shen, and J. M. Coughlan, “Towards a real-time system for finding and reading signs for visually impaired users,” In Proc. of ICCHP, pp. 41–47, 2012.

[12] R. Shilkrot, J. Huber, C. Liu, P. Maes, and S. C. Nanayakkara, “Fingerreader: A wearable device to support text reading on the go,” in CHI EA, ACM, pp. 2359–2364, 2014.

[13] R. Shilkrot, J. Huber, M. E. Wong, P. Maes, and S. C. Nanayakkara, “Fingerreader: A wearable device to explore printed text on the go,” in ACM CHI 2015, pp. 2363–2372, 2015.

 

相關文章:

 

 

 

 

 

 

 

 

 

 

 

[LinkIt 7697開發板教學]MCS雲端RGB LED類比控制-Blocklyduino圖形化開發環境

作者/攝影  曾吉弘
時間  3小時
成本
  • LinkIt 7697開發板
  • RGB LED
  • 麵包板
  • 線材
難度  * * *
材料表
  • 個人電腦
  • LinkIt 7697開發板
  • RGB LED
  • 麵包板
  • 線材

本文要介紹如何使用Mediatek Cloud Sandbox (聯發科技實驗室推出的雲服務)來控制LinkIt 7697上的 RGB LED 的個別顏色亮度。程式使用Blocklyduino圖形化開發環境開發板製作的小型電路專題。您可由此比較與一般Arduino IDE的類C語法的異同。請參考我們上課的投影片(超過100頁喔)!:

 


 

MCS端設定

        請登入MCS雲服務,建立新的原型,其下有三個整數(integer)型態的控制器,channel id 分別是 red, green, blue,下限0上限255,這是對應於Arduino的 analogWrite語法的參數。詳細建立資料通道畫面如下:

View post on imgur.com

建立好三個資料通道之後,請為這個原型建立一個測試裝置,完成如下圖:

View post on imgur.com

硬體線路

請將Linkit 7697插上麵包板,並根據下圖將RGB LED負極(最長腳)接到GND腳位。左到右分別代表R G B三個顏色的腳位,請分別接到LinkIt 7697的P10、P8與P6腳位。

View post on imgur.com

Blocklyduino程式碼

初始化/setup():在此會先連上指定的Wi-Fi AP、MCS伺服器並新增所指定的通道id。請注意相關資訊不要打錯

View post on imgur.com

重複執行/loop()

在此會持續與MCS保持同步,如果任一通道有更新(使用者在MCS輸入新的數值)的話,就會根據新的數值來控決定對應的RGB LED顏色強度。最後則是把MCS的數值顯示於Serial Monitor

View post on imgur.com

7697程式碼

上述BlocklyDuino轉出來的Arduino程式碼如下,請直接上傳到7697之後就可以執行,重要的指令都以註解方式寫在程式碼中。

 

操作

請先檢查相關資料是否都正確,執行7697端程式。確認7697已連上MCS之後,請在各個控制器通道輸入0~255之間的數值,即可看到RGB LED顏色產生變化,也會把相關數值顯示於Serial Monitor

 

由於BlocklyDuino目前尚未提供MCS的PWM控制器資料通道的指令,但您可以自行在轉為Arduino code之後將 MCSControllerInteger red(“red”);     改為 MCSControllerPWM red(“red”);   這樣就能在MCS端使用PWM控制器資料通道的拉桿來控制LED亮度。

#include <LWiFi.h>
#include "MCS.h"

char _lwifi_ssid[] = "";     //Wi-Fi 帳號
char _lwifi_pass[] = "";   //Wi-Fi 密碼
MCSDevice mcs("", ""); //MCS測試裝置的 deviceId, deviceKey

MCSControllerInteger red("red");            //新增 channelId 為 red 的整數型控制資料通道
MCSControllerInteger green("green");  // green
MCSControllerInteger blue("blue");       // blue

void setup()
{
  mcs.addChannel(red);                             //將這三個channel 加入測試裝置
  mcs.addChannel(green);
  mcs.addChannel(blue);
  while (WiFi.begin(_lwifi_ssid, _lwifi_pass) != WL_CONNECTED) {
    delay(1000);                                            //每隔1秒試著去連上指定的 Wi-Fi AP
  }
  while (!mcs.connected()) {                    //持續與MCS保持連線
    mcs.connect();
  }
  Serial.begin(9600);
  pinMode(10, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(6, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  while (!mcs.connected()) {                         //檢查與MCS的連線狀態,如果斷線會在此重連
    mcs.connect();
    if (mcs.connected()) {
      Serial.println("MCS Reconnected.");
    }
  }
  mcs.process(100);
  if (red.updated()) {                                       //如果各控制資料通道更新
    analogWrite(10, red.value());                 //根據該值來控制LED亮度
  } else if (green.updated()) {
    analogWrite(8, green.value());
  } else if (blue.updated()) {
    analogWrite(6, blue.value());
  }

  Serial.print(red.value());
  Serial.print(", ");
  Serial.print(green.value());
  Serial.print(", ");
  Serial.println(blue.value());                      //顯示各資料通道數值於Serial monitor
}

 

 

相關文章:

 

 

 

 

 

[Raspberry Pi]自製縮時攝影機

最近常常用到3D印表機做些小玩具,通常都是今天開始印,隔天成品才做好,如果用樹莓派做個縮時攝影機,把3D列印的過程拍下來一定很有趣,讓我們來動手做吧!

作者/攝影  郭曜銘
時間  30 分鐘
成本
  • Raspberry Pi 2 or 3
  • Webcam
  • SD card
難度 * *
材料表
  • Raspberry Pi 2 or 3
  • Webcam
  • SD card

升旗縮時:這部影片拍攝三十分鐘,大約五秒一張。

3D列印縮時:這部影片拍攝七小時,大約十五秒一張

 

—-事前準備—-

  • 將Raspberry Pi安裝好作業系統(RASPBIAN JESSIE)https://www.raspberrypi.org/downloads/raspbian/
  • 接上電源和webcam。
  • 確認已連上網路。
  • 在樹梅派開啟終端機或用電腦連線至終端機畫面。

 

—-正文開始—–

一、更新系統及套件

1.輸入指令”sudo apt-get update”來更新你的系統

2.輸入指令”sudo apt-get upgrade”來升級已安裝的套件包

 

二、安裝拍照軟體”motion”

1.輸入指令”sudo apt-get install motion”來安裝motion

 

三、設定拍照軟體”motion”

1.輸入指令”sudo nano /etc/motion/motion.conf”,這裡使用”nano”編輯器來更改motion 的設定檔(你也可以使用你慣用的編輯器來編輯設定檔)。

2.在”nano”中你可以使用組合鍵”Ctrl+W”在文件中快速查詢關鍵字。

3.將下表中的值修改成對應的數值

名稱數值附註
daemonON3.png
framerate10004.png
Stream_quality1005.png
Stream_localhostOFF6.png
webcontrol_localhostOFF7.png
quality1008.png
width12809.png 此數值為webcam解析度的寬
height72010.png此數值為webcam解析度的高
Snapshot_interval1011.png 每隔10秒拍一張
target_dir/home/pi12.png 照片存檔的位置

4.使用組合鍵”ctrl+X”離開nano,輸入”y”跟”enter”以保存檔案

5.輸入指令”sudo nano /etc/default/motion”編輯另一個設定檔

6.將名稱”start_motion_daemon”的值改成”yes”,並儲存離開

 

四、啟動攝影機

1.將你的攝影機擺放好

2.輸入指令”sudo service motion restart”重新啟動motion程式

3.輸入指令”sudo motion”執行程式

 

五、取得照片製作成影片

1.輸入指令”sudo motion stop”停止拍照

2.用隨身碟或SFTP將拍到的照片傳輸回電腦,照片會存在你剛剛設定的路徑。

 

3.利用影片製作軟體將所拍攝的照片製作成縮時攝影

我之前是用windows7內建的movie maker,你也可以使用更專業的剪輯軟體來製作影片。

 

相關文章:

[LinkIt 7697 iOS 方案] 寫出 Arduino code自動生成手機介面!

作者/攝影  曾吉弘
時間  3小時
成本
  • LinkIt 7697開發板
難度  * * *
材料表
  • 個人電腦
  • LinkIt 7697 開發板
  • iphone

本文要介紹聯發科技實驗室推出的LinkIt Remote iOS小程式,透過BLE來與 7697開發板互動,特色在於可以輕鬆設計各種簡易的控制界面喔!

 

LinkIt Remote iOS app

LinkIt Remote 是一個用來產生app介面的iOS小程式,是以 BLE 與 LinkIt 7697開發板搭配使用。只要在7697端設定好,就可以在兩者連線之後產生對應的介面。您需要做兩件事:

  • Arduino IDE 的 7697 SDK需要升級到9.5,才可使用最新LRemote 函式庫與本文的範例。

View post on imgur.com

  • 找一隻 iphone 安裝 LinkIt Remote iOS app,可用於掃描鄰近的 7697 開發板(需執行類似於本文的程式),並彼此溝通。

重點就是這一句:

寫Arduino code 可以自動生成 app 介面!

1.請開啟 File > Examples > LRemote > RemoteControl 範例,並上傳至您的 7697開發板。

2.下載 LinkIt Remote 到您的 iphone上,目前版本需要 iOS 10。

3.啟動 LinkIt Remote app,會看到 中的 7697 顯示在畫面的裝置清單中。

View post on imgur.com

4.點選這個 LinkIt 7697。item, the app connects to LinkIt 7697 and display the following remote UI control: (如果範圍裡有多台的話,就會看到多個項目,後續程式碼中的#25 LRemote.setName(“LinkIt 7697”); 可以修改開發板所顯示的名稱)

 

View post on imgur.com

5.請點選畫面中的 USR LED 搖頭開關,就會觸發 7697 的 USR LED (P7腳位)亮起。

6.請開啟 Arduino 的Serial Monitor,並拖拉畫面中的 Value Slider 滑桿,就可以在Serial Monitor中看到數值的變化,我們後續可以拿這個數值來控制LED亮度(analogWrite)、伺服機角度等等都可以喔。

View post on imgur.com

完工了,開始玩吧~

 

7697程式碼

 

最後是7697的程式碼,路徑是 File/Exmaples/LRemote/RemoteControl

由此可以看到如何編寫Arduino code 去定義畫面上的元件

  //設定 app 端介面 UI canvas
  LRemote.setName("LinkIt 7697");
  LRemote.setOrientation(RC_PORTRAIT);
  LRemote.setGrid(3, 5);         //設定螢幕棋盤格數 3行5列

  //加入按鈕
  button.setText("Press Me");   //加入文字
  button.setPos(1, 1);               //設定位置
  button.setSize(2, 1);              //設定元件尺寸
  button.setColor(RC_PINK);   //設定位置
  LRemote.addControl(button); //加入按鈕

  //加入大型圓形按鈕
  bigButton.setText("!BIG!");
  bigButton.setPos(0, 3);
  bigButton.setSize(3, 2);
  bigButton.setColor(RC_GREEN);
  LRemote.addControl(bigButton);

  //加入滑桿
  slider.setText("Value Slider(-100 ~ 1024)");    
  slider.setPos(0, 2);
  slider.setSize(3, 1);
  slider.setColor(RC_ORANGE);
  slider.setValueRange(-100, 1024, 0);   //設定滑桿範圍
  LRemote.addControl(slider);

  //加入文字標籤
  label.setText("Remote Test");
  label.setPos(0, 0);
  label.setSize(3, 1);
  label.setColor(RC_GREY);
  LRemote.addControl(label);

  //加入on/off搖頭開關
  switchButton.setText("USR LED");
  switchButton.setPos(0, 1);
  switchButton.setSize(1, 1);
  switchButton.setColor(RC_BLUE);
  LRemote.addControl(switchButton);

 

完整程式碼如下:

/*
  This example configures LinkIt 7697 to a reciver of the iOS LinkIt Remote App

  created Aug 2017
*/
#include <LRemote.h>

LRemoteButton button;
LRemoteSlider slider;
LRemoteLabel label;
LRemoteSwitch switchButton;
LRemoteCircleButton bigButton;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);

  Serial.println("Start configuring remote");

  // Initialize GPIO
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, 0);

  // Setup the Remote Control's UI canvas
  LRemote.setName("LinkIt 7697");
  LRemote.setOrientation(RC_PORTRAIT);
  LRemote.setGrid(3, 5);

  // Add a push button
  button.setText("Press Me");
  button.setPos(1, 1);
  button.setSize(2, 1);
  button.setColor(RC_PINK);
  LRemote.addControl(button);

  // Add a big, round button
  bigButton.setText("!BIG!");
  bigButton.setPos(0, 3);
  bigButton.setSize(3, 2);
  bigButton.setColor(RC_GREEN);
  LRemote.addControl(bigButton);

  // Add a slider
  slider.setText("Value Slider(-100 ~ 1024)");
  slider.setPos(0, 2);
  slider.setSize(3, 1);
  slider.setColor(RC_ORANGE);
  slider.setValueRange(-100, 1024, 0);
  LRemote.addControl(slider);

  // Add a simple text label
  label.setText("Remote Test");
  label.setPos(0, 0);
  label.setSize(3, 1);
  label.setColor(RC_GREY);
  LRemote.addControl(label);

  // Add an on/off switch
  switchButton.setText("USR LED");
  switchButton.setPos(0, 1);
  switchButton.setSize(1, 1);
  switchButton.setColor(RC_BLUE);
  LRemote.addControl(switchButton);

  // Start broadcasting our remote contoller
  // This method implicitly initialized underlying BLE subsystem
  // to create a BLE peripheral, and then start advertisement on it.
  LRemote.begin();
  Serial.println("begin() returned");
}

void loop() {

  // check if we are connect by some BLE central device, e.g. an mobile app
  if(!LRemote.connected()) {
    Serial.println("waiting for connection");
    delay(1000);
  } else {
    delay(100);
  }
  
  // Process the incoming BLE write request
  // and translate them to control events
  LRemote.process();

  // Now we poll each control's status
  
  if(button.isValueChanged()){
    Serial.print("button new value =");
    Serial.println(button.getValue());
  }

  if(bigButton.isValueChanged()){
    Serial.print("big button new value =");
    Serial.println(bigButton.getValue());
  }

  if(switchButton.isValueChanged()){
    digitalWrite(LED_BUILTIN, switchButton.getValue());
  }

  if(slider.isValueChanged()){
    Serial.print("slider to new value = ");
    Serial.println(slider.getValue());
    analogWrite(7, map(slider.getValue(),-100, 1024, 0 , 255)); 
    //將slider的數值轉換之後用來控制LED
  }
}

 

相關文章:

[教學投影片] LINE bot 聊天機器人結合 LinkIt 7697

 

作者/攝影  曾吉弘
時間  4小時
成本
  • LinkIt 7697開發板
  • LED (或用板子上的LED也可以)
難度 * * * * *
材料表
  • 個人電腦
  • LinkIt 7697開發板 LED (或用板子上的LED也可以)
  • Arduino IDE

本文先上架CAVEDU版本的LINE chatbot (Messageing API) 結合 LinkIt 7697 開發板,可以控制腳位狀態也可以回傳感測器狀態。製作過程參考了劉正吉老師的個人網站,獲益良多,在此感謝。

 

做法分為兩種:

 

  1. 使用ngrok讓7697直接能與LINE指定帳號溝通
  2. 7697透過 Mediatek Cloud Sandbox 雲服務,LINE再去讀取指定的資料通道。

 

請先看看投影片,後續的教學文章會先從 LINE 發訊息來控制 7697 的腳位狀態開始。


[contact-form][contact-field label=”名稱” type=”name” required=”true” /][contact-field label=”電子郵件” type=”email” required=”true” /][contact-field label=”網站” type=”url” /][contact-field label=”訊息” type=”textarea” /][/contact-form]

 

程式碼下載請點我

[ 課程紀錄文 ] 2017.08.07 LattePanda勉強會@東京21Cafe

8/5、8/6參觀完MakerFaire Tokyo,吸收完滿滿的能量CAVEDU東京遠征隊移動到涉谷,應DFrobot與日本在地工程師Hirokazu桑邀約下,我們在日本舉辦兩小時研習營,雖然研習當天還有颱風登陸,還是有不少人參加,真的很感謝。

作者/攝影 徐豐智/郭皇甫
課程時間 2017 年 8 月 7日 (月) 19:00 (開場 18:30) ~ 21:30
課程講師 徐豐智
課程場地 東京都渋谷区-21Cafe

 

這次是在東京澀谷的21Cafe舉辦研習營,主題是製作天氣預報的機器人,截取livedoor提供的日本各區天氣預報資料JSON資料,判斷明日的天氣氣溫是否讓人熱得滿頭大汗。

 

這次分享主題(1)認識LattePanda。(2)使用Python擷取JSON資料。(3)在LattePanda上使用Python控制Arduino。

 

日本の温度取得のチュートリアル (JSON)

http://weather.livedoor.com/weather_hacks/webservice

 

東京の温度のデータ取得のAPI

http://weather.livedoor.com/forecast/webservice/json/v1?city=130010

 

這次的講義,日本限定,感謝Hirokazu桑大力幫忙

 

首先由21Cafe的管理人-寶島春菜小姐致詞,21Cafe是一個工程師與設計師的免費活動空間,可以容納約30人,大家可以使用這個空間進行主題討論、學習課程。

View post on imgur.com

DFrobot本部的工程師-李暘也到現場,向大家介紹DFrobot團隊製作LattePanda的理想,希望在不久的將來,每個家庭都能擁有一個屬於自己的機器人,提供給”不是Linux”開發者”一塊開發板。

View post on imgur.com

隨後附上課程中的照片,目標是做出

View post on imgur.com

 

View post on imgur.com

View post on imgur.com

View post on imgur.com

 

 

相關文章:

[LattePanda] OpenCV視覺辨識人臉追蹤

本文說明如何使用 LattePanda搭配OpenCV視覺辨識函式庫來打造人臉辨識機器人。

作者/攝影 袁佑緣
時間  1小時
成本
  • LattePanda
  • 螢幕
  • 鍵盤
  • 滑鼠
  • 喇叭
  • webcam
難度 * *
材料表
  • LattePanda
  • 螢幕
  • 鍵盤
  • 滑鼠
  • Webcam

 

本文說明如何使用 LattePanda搭配 python語言去使用OpenCV機器視覺函式庫來打造一個人臉辨識機器人,本範例的操作環境將以LattePanda的Windows10為主。

 

1. 軟體準備

安裝Python與相關套件

首先請到Python的網站下載最新版的安裝檔,在這邊要提醒一下Python目前有兩種版本,一個是2.7x版,另一個3.x版。Python 2.7x版是比較舊的版本,同時官方也有發出聲明將不會在繼續更新了,而本篇的範例使用的是新版3.x的Python,所以請注意一下不要選錯囉,以本文為例,最新的版本是3.6.1,如下圖。接著請按照以下步驟進行。

 

請在安裝Python時,將下方Add Python 3.6 to PATH勾選起來,意思是要把Python加入windows作業系統的環境變數內。

 

安裝完成後,為了測試我們的電腦是否能正常呼叫Python,請呼叫您電腦的終端機,windows的使用者請按下快捷鍵win+R便會在左下角顯示執行視窗,接著輸入cmd,這樣一來就會叫出windows的命令提示字元。

 

 

接下來請在上面輸入Python,呼叫Python的互動界面,如果能成功看到>>>的符號,那就代表已經成功叫起Python的界面了,而使用者可以直接在上面輸入Python的相關指令,如果沒有正確顯示這個界面的話,可能是您前面的安裝過程有問題,請重新回到前面的安裝步驟,有可能是您沒有勾選系統變數那個選項,所以windows無從呼叫Python。

接下來請輸入exit()跳出這個Python互動界面,回到windows的命令提示字元。

接下來請輸入pip install numpy,使用Python的套件管理員pip來安裝numpy這個套件。

裝完numpy之後,一樣使用pip來安裝OpenCV套件,請輸入pip install opencv-python

最後請輸入pip install pyserial,安裝在python中用來做Serial溝通的pyserial套件。

準備Python IDE

撰寫Python的程式除了要打code之外,還需要執行的環境,所以筆者在這邊推薦一款非常容易上手的Python IDE,請到以下的網站(http://thonny.org/)下載並安裝Thonny。

 

裝完必要的Python套件之後,我們就要來把Thonny的程式路徑設定成我們電腦系統中預設的Python執行程式。請點選Tools然後再點選Options,進入Thonny的偏好設定。如下圖。

接下來選擇interpreter,也就是Python的直譯器為系統預設的路徑,如下圖。

2.硬體架設

 本範例使用羅技C170的webcam作為辨識人臉的攝影鏡頭,另外為了要能夠追蹤人臉的位置,我們還需要架設一個旋轉平台,如下圖,由底下的小型伺服馬達(MG90)來控制鏡頭對到的方位。且注意到下方的小馬達控制訊號線是接到LattePanda左邊的3Pin接頭,記得靠外側是要接深色的地線喔!

 

 

3.軟體實作

Arduino 程式碼

為了要控制旋轉平台的伺服馬達,我們需要使用LattePanda上的Arduino Leonardo晶片,請打開Arduino IDE並打上以下的程式碼,並上傳到LattePanda上的Arduino端(請記得選對COM port)。

Arduino端的控制動作其實很簡單,它會聽取Serial傳來的字元命令,如果是小寫的字母a或b就會分別左右旋轉一度,進而達到轉動鏡頭的效果,而伺服馬達的控制訊號腳位在本範例中用的是9號腳位,接法如上圖,如果想接其他腳位請記得要改一下Arduino程式碼裡的腳位定義(s.attach(9))。

#include <Servo.h>

Servo s;
int degree = 90;

void setup()
{
    Serial.begin(115200);
    s.attach(9);
}

void loop()
{
    if(Serial.available())
    {
        int cmd = Serial.read();
        if(cmd == 'a')
        {
            degree++;
            if(degree >= 180)
                degree = 180;
            s.write(degree);
        }
        else if(cmd == 'b')
        {
            degree--;
            if(degree <= 0)
                degree = 0;
            s.write(degree);
        }
        else
            Serial.println("Press a/b to turn the camrea!");
    }
}

 

Python 程式碼

前面已經準備好Python會需要用到的函式庫跟IDE了,接下來我們就要來實作最後關鍵的人臉辨識以及追蹤,因為需要用到辨識人臉的模型,請去OpenCV的github網站(https://github.com/opencv/opencv/tree/master/data/haarcascades)下載 haarcascade_frontalface_default.xml與 haarcascade_eye.xml這兩個.xml檔,分別是用來辨識人的臉部與以及眼睛。

程式碼的實做可以拆解成幾個重要的部份,以下就讓我們一步一步的來了解吧!

首先我們會由cv2.VideoCapture(0)來讀取Webcam的影像資訊,並且設定初始的解析度是640×480,接下來在連接埠COM5建立一個Serial通道,用來下指令給Arduino端,以控制鏡頭的方向。

而while迴圈裡面則包含了主要的辨識程式,辨識的方法其實很簡單,就是先把鏡頭每一幀的照片先灰階化,再透過前面下載的臉部及眼部辨識模組套進去(face_cascde和eye_cascade)去做最可能的人臉偵測(這裡使用的方法是取最大/近的臉部面積)。

最後為了要追蹤人臉,我們需要計算出人臉的中心位置(position = x + w/2.0),x是標示人臉方框的 角落x座標,w則是寬度,所以取一半的寬度就會得到人中的x座標位置,接下來我們只要跟我們取的影像中線做比較,然後左右旋轉鏡頭去做追蹤即可,而這調中線的位置則可以從前面設定的解析度640×480來算出,取寬的一半就能得到範例程式中的320了,如果說讀者想要嘗試其他的解析度,請記得也要修改鏡頭追蹤的中線喔!

import cv2
import numpy as np
import serial

face_cascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('./haarcascade_eye.xml')

cap = cv2.VideoCapture(0)
cap.set(3, 640)
cap.set(4, 480)
ser = serial.Serial('COM5', 115200)

while True:
    _, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 2, 5)
    if len(faces):
        (x, y, w, h) = max(faces, key=lambda face: face[2]*face[3])
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]
        eyes = eye_cascade.detectMultiScale(roi_gray)
        for (ex,ey,ew,eh) in eyes:
            cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
        position = x + w/2.0
        print(position)
        if position < 320:
            ser.write(b'a')
        else:
            ser.write(b'b')
        
    cv2.imshow('face', img)
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break
cv2.destroyAllWindows()

 

示範影片

 

相關文章:

[Linklt7697系列] 八校國中小夏令營不藏私大公開-Linklt7697搶答器

前情提要:LinkIt 7697開發板教學]BlocklyDuino圖形化介面 – 環境建置與介面

作者/攝影 趙偉伶
時間  1小時
成本 $1500
難度 * *
材料表
  • Linklt7697
  • 麵包版
  • 公母杜邦線
  • 10 mmLED燈
  • 大型按鈕
  • Mico USB線
  • 連接器
  • 極限開關

透過前篇   [LinkIt 7697開發板教學]BlocklyDuino圖形化介面 – 環境建置與介面   了解了BlocklyDuino圖形化介面後,接著要認識電腦程式是如何運作的。想問問大家,覺得電腦跟人類的思考方式有什麼不同呢?

電腦其實需要我們人類給他非常明確指令去控制,才會順利做事情,例如:媽媽請你拿桌上的水,人類會直接走到水杯前面後拿起來,在這之前如何移動、如何伸出手、張開手指、握住水杯等等幾乎都是身體自發性完成的。而電腦就不一樣了,他需要明確的指令才行。例如:走到座標XYZ哪個位置,機械手臂向下移動到哪個位置,先張開手指再闔上手指等等,一個都不能錯!寫程式就是我們與電腦的溝通方式,你會更了解電腦的思考模式。

 

動動手

要做搶答器,要先將按鈕組裝起來,就跟著圖一起來做吧!

 第一步:組裝連接器與極限開關

第二步:組裝按鈕

第三步:接上LED

接著,將7697開發板插上麵包板,拿出兩顆LED及四條公母杜邦線,將兩顆LED的正極(比較長的腳)分別接到7697開發板的P7與P8腳位,負極(比較短的腳)則接到開發板的GND腳位,完成如下圖:

第四步:接上按鈕

先了解按鈕的電路原理,再將接好的兩顆按鈕拿出來,並依下列圖示接在P3、P4及GND的位置。

動動腦,寫程式

BlocklyDuino圖形化程式有很多不同的抽屜,而每個抽屜都代表了不同功能的程式指令。今天的搶答器會用到〝程式流程抽屜〞、〝邏輯抽屜〞跟〝數位I/O抽屜〞,讓我們一邊認識程式積木一邊完成搶答器的程式吧!

第一步:搶答器動作分解

先了解程式的思考邏輯,再去認識所需積木,一步步將搶答器程式構築出來。

試試看,在了解這些邏輯後,是否可以完成搶答器的程式呢??

 

第二步:認識搶答器所需的程式積木

每個Blocklyduino程式都會有"初始化"跟"重複執行"兩個積木,如果沒有,可以從"程式流程抽屜"找到,就跟小豬一起來認識這兩個積木吧!

 

要如何知道誰先按下按鈕來搶答呢?這時登場的是邏輯抽屜的"如果(if)",它可用來檢查某個條件是否發生了,以搶答器來說就是按鈕被按下了。本次搶答器有三個條件,讓我們來看如何形成三個條件判斷吧!

條件判斷,電腦的邏輯有所不同,請看下圖。

Linklt Smart 7697這塊開發板背面有一根根的針腳,可以用來連接各種不同的電子元件。在程式中會用Pin X代表不同的元件,例如把按鈕接在Pin3的話,在程式鐘就能用Pin3來得知按鈕的狀態。

電腦傳輸資料,有分成兩種訊號:數位訊號跟類比訊號,讓小豬告訴大家這兩種訊號的差別。

搶答器會根據哪一個按鈕被壓下來決定LED要亮或暗,就是先前介紹的數位訊號,所以會使用到數位I/O抽屜的程式積木。

讓LED燈亮跟暗,代表要讓7697開發板對某一支針腳提供高電位或低電位。在此,如同按鈕,可用腳位編號來表示LED。

認識了這些積木,應該可以寫出搶答器的程式了吧?

還沒還沒~因為程式的速度跑很快,如果只用LED亮燈指令的話,實際上是看不清楚地,所以要加入"時間抽屜"的"延遲積木"來決定LED到底要亮或暗多久時間。

知道這些積木作用之後,將這些積木阻合起來就是搶答器的程式了吧!!

完整的程式,如下:

 

可以找同學一起玩可愛搶答器囉!

相關文章:

 

[微笑偵測器] 微軟辨識服務搭配Arduino

本文要介紹微軟辨識服務的Face API,可以偵測照片中的臉孔以及相關參數,包含年齡、性別、情緒、眼鏡、鬍子以及五官座標等。

作者/攝影 曾吉弘
時間  3小時
成本
難度 * * * * *
材料表
  • 個人電腦
  • Arduino Uno 或其他可執行 StandFirmata 之 Arduino相容板
  • LED x 3
  • 線材
  • 麵包板

本範例修改自微軟辨識服務Face API教學而來,您也可以在該頁面找到其他程式語言的教學。

微軟辨識服務

根據官方網站說法:Microsoft 辨識服務具備多種程式語言的API,可以透過自然的溝通方式看、聽、說,以及理解和解讀各種媒體素材,包然文字、語音、照片、影片與搜尋建議等等。分成五大類,每項又各自分成不同細項,本範例將使用辨識下的臉部API:

  1. 辨識
  2. 語音
  3. 語言
  4. 知識
  5. 搜尋

 

註冊Face API

註冊一個新的帳號,需要手機號碼認證與信用卡認證…

  • 這些步驟完成之後選擇您要的API,即可取得金鑰(subscription key),每一個API各自會有自己的流量與次數限制,請注意。
  • 下圖是 Face API 的兩組金鑰,使用任何一組都可以

 

在其頁面就可以看到效果,有一些範例圖片或者您可以自行上傳照片,右側就是偵測結果,格式是JSON,各主要程式語言對於JSON都有現成的函式庫來爬取。

範例程式

本範例是修改自 Face API python 範例程式而來,使用 python 2.7。本範例會使用一張網路圖片(#37)送到 Face API之後取得其辨識結果。

程式#33可指定我們所要偵測的臉孔參數,包含以下:

  • age:年齡
  • gender:性別
  • headPose:頭部姿態,回傳XYZ軸傾斜狀態
  • smile:微笑(0~1之間小數,數字愈高代表微笑愈明顯)
  • facialHair:臉部髮型,例如山羊鬍、八字鬍、鬢角
  • glasses:偵測有無戴眼鏡
  • emotion:情緒,包含生氣、滿足、害怕、驚訝與悲傷等等
  • hair:髮型,包含禿頭、髮色等等
  • makeup:偵測是否化妝
  • occlusion:偵測是否閉合,例如眼睛、嘴巴
  • accessories:配件
  • blur:偵測圖片是否模糊,以及模糊程度參數
  • exposure:偵測圖片曝光程度與曝光程參數
  • noise:偵測圖片中雜訊與雜訊程度參數

 

在此用到的圖片是這位可愛的女生,您可以換成其他的圖片來測試

import httplib, urllib, base64, json

###############################################
#### Update or verify the following values. ###
###############################################

# Replace the subscription_key string value with your valid subscription key.
subscription_key = 'XXXX'   #填入Face API金鑰,任一組都可以

# Replace or verify the region.
#
# You must use the same region in your REST API call as you used to obtain your subscription keys.
# For example, if you obtained your subscription keys from the westus region, replace 
# "westcentralus" in the URI below with "westus".
#
# NOTE: Free trial subscription keys are generated in the westcentralus region, so if you are using
# a free trial subscription key, you should not need to change this region.
uri_base = 'westcentralus.api.cognitive.microsoft.com'

# Request headers.
headers = {
    'Content-Type': 'application/json',
    'Ocp-Apim-Subscription-Key': subscription_key,
}

# Request parameters.
params = urllib.urlencode({
    'returnFaceId': 'true',
    'returnFaceLandmarks': 'false',
    'returnFaceAttributes': 'age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise',
})

# The URL of a JPEG image to analyze.
body = "{'url':'https://how-old.net/Images/faces2/main0011.jpg'}"

try:
    # Execute the REST API call and get the response.
    conn = httplib.HTTPSConnection('westcentralus.api.cognitive.microsoft.com')
    conn.request("POST", "/face/v1.0/detect?%s" % params, body, headers)
    response = conn.getresponse()
    data = response.read()

    # 'data' contains the JSON data. The following formats the JSON data for display.
    parsed = json.loads(data)
    print ("Response:")
    print (json.dumps(parsed, sort_keys=True, indent=2))
    print parsed[0]["faceAttributes"]["smile"]   #第一張臉的 smile 強度
    conn.close()

except Exception as e:
    print("[Errno {0}] {1}".format(e.errno, e.strerror))

 

根據Face API,一張照片最多可以辨識到64張臉,但這樣真的太多了… 在基礎練習最好使用單一臉孔來測試。熟悉之後可以加入更多臉孔甚至連續偵測

參考:[微軟認知服務] 串流影像之臉孔與年齡辨識

執行結果如下,本範例就是把所有JSON結果顯示出來(#50),但為了後續微笑偵測,我們在#51獨立把smile的強度抓出來了,如下圖的 1.0

print parsed[0][“faceAttributes”][“smile”] #取得第一張臉的 smile 強度

上圖可愛小妹妹的完整偵測JSON結果如下,您可以慢慢檢視:

[
  {
    "faceAttributes": {
      "accessories": [], 
      "age": 21.6, 
      "blur": {
        "blurLevel": "low", 
        "value": 0.1
      }, 
      "emotion": {
        "anger": 0.0, 
        "contempt": 0.0, 
        "disgust": 0.0, 
        "fear": 0.0, 
        "happiness": 1.0, 
        "neutral": 0.0, 
        "sadness": 0.0, 
        "surprise": 0.0
      }, 
      "exposure": {
        "exposureLevel": "goodExposure", 
        "value": 0.73
      }, 
      "facialHair": {
        "beard": 0.0, 
        "moustache": 0.0, 
        "sideburns": 0.0
      }, 
      "gender": "female", 
      "glasses": "NoGlasses", 
      "hair": {
        "bald": 0.03, 
        "hairColor": [
          {
            "color": "brown", 
            "confidence": 1.0
          }, 
          {
            "color": "black", 
            "confidence": 0.77
          }, 
          {
            "color": "other", 
            "confidence": 0.46
          }, 
          {
            "color": "red", 
            "confidence": 0.2
          }, 
          {
            "color": "blond", 
            "confidence": 0.06
          }, 
          {
            "color": "gray", 
            "confidence": 0.02
          }
        ], 
        "invisible": false
      }, 
      "headPose": {
        "pitch": 0.0, 
        "roll": -11.5, 
        "yaw": -5.6
      }, 
      "makeup": {
        "eyeMakeup": true, 
        "lipMakeup": true
      }, 
      "noise": {
        "noiseLevel": "low", 
        "value": 0.08
      }, 
      "occlusion": {
        "eyeOccluded": false, 
        "foreheadOccluded": false, 
        "mouthOccluded": false
      }, 
      "smile": 1.0
    }, 
    "faceId": "d87447bd-a4b3-4c87-b92d-736871e8e6d9", 
    "faceRectangle": {
      "height": 166, 
      "left": 175, 
      "top": 197, 
      "width": 166
    }
  }
]
1.0   #獨立抓出來的 smile 強度

您可以使用 jsoneditoronline.org 來檢視 json 結構,會比直接看原始資料來的清楚明暸。

 

pyfirmata

取得臉孔資訊之後就有很多東西可以玩了,例如本範例的微笑偵測器。或是找找看畫面中誰有戴眼鏡。如果是連續偵測的話,還能做到讓攝影鏡頭跟著你的臉孔中心移動(PTZ平台),總之太多應用啦!

pyfirmata 是python透過序列埠來與Arduino溝通的模組,Arduino端只要上傳(請先確認)StandardFirmata 這個程式就可以了,安裝完成請關閉Arduino IDE,後續用不到了~

 

請在 terminal 中使用以下指令來安裝 pyfirmata

pip install pyfirmata

 

Arduino端設定

python透過序列埠控制Arduino LED

 

本範例就是 python 版的 LED 閃爍,您可以比較一下兩者的差異,您只要確定COM port 邊與您電腦上的一致即可。如果是 MAC/ Linux,應該是 /dev/ttyUSB0 這樣的東西。如果是 Raspberry Pi 則應該是 /dev/ttyACM0

#!/usr/bin/python
 
import pyfirmata
import time
pin = 13
port = 'COM5'
board = pyfirmata.Arduino(port)   #對指定序列埠開啟通訊
while True:
    	board.digital[pin].write(1)  #設定指定腳位高電位
    	time.sleep(1)                    #等候1秒
    	print "ON : %s" % time.ctime()  #顯示相關訊息與時間
    	board.digital[pin].write(0)
    	time.sleep(1)
    	print "OFF : %s" % time.ctime()

執行畫面如下圖,除了Arduino D13 會亮暗之外,在console上也有對應的訊息

Python結合Arduino微笑偵測應用

來看一下綜合運用吧!本範例會根據畫面中臉孔的微笑程度來決定LED亮起的數目。

import httplib, urllib, base64, json, pyfirmata
from time import sleep
port = 'COM5'

# Replace the subscription_key string value with your valid subscription key.
subscription_key = 'XXX'   #填入Face API金鑰,任一組都可以

# NOTE: Free trial subscription keys are generated in the westcentralus region, so if you are using
# a free trial subscription key, you should not need to change this region.
uri_base = 'westcentralus.api.cognitive.microsoft.com'

# Request headers.
headers = {
    'Content-Type': 'application/json',
    'Ocp-Apim-Subscription-Key': subscription_key,
}

# Request parameters.
params = urllib.urlencode({
    'returnFaceId': 'true',
    'returnFaceLandmarks': 'false',
    'returnFaceAttributes': 'age,gender,smile,emotion,occlusion,accessories,exposure,noise',
    #'returnFaceAttributes': 'age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise',
})

# The URL of a JPEG image to analyze.
body = "{'url':'https://how-old.net/Images/faces2/main002.jpg'}"

#connect Arduino
board = pyfirmata.Arduino(port)    #對指定序列埠開啟連線
sleep(3)      #等候3秒來開啟序列連線

try:
    # Execute the REST API call and get the response.
    conn = httplib.HTTPSConnection('westcentralus.api.cognitive.microsoft.com')
    conn.request("POST", "/face/v1.0/detect?%s" % params, body, headers)
    response = conn.getresponse()
    data = response.read()
    # 'data' contains the JSON data. The following formats the JSON data for display.
    parsed = json.loads(data)
    print ("Response:")
    print (json.dumps(parsed, sort_keys=True, indent=2))  #顯示所有資料
    a = parsed[0]["faceAttributes"]["smile"]   #顯示微笑程度
    conn.close()

except Exception as e:
    print("[Errno {0}] {1}".format(e.errno, e.strerror))

print "smile value is"
print a                                #顯示微笑程度
if a > 0.75:                         #以下分成三個區間來控制LED,您可以自行修改
    board.digital[9].write(1)
    board.digital[10].write(1)
    board.digital[11].write(1)
    print 111
elif a < 0.25:
    board.digital[9].write(1)
    board.digital[10].write(0)
    board.digital[11].write(0)
    print 100
else:
    board.digital[9].write(1)
    board.digital[10].write(1)
    board.digital[11].write(0)
    print 110

 

執行!

執行時,Moto GP 傳奇車手 Valentino Rossi~ https://moto7.tw/imgs/valentino-rossi-2015.jpg,也可以看到100代表只會亮起一個LED代表 Rossi 現在只有微笑或是沒表情。您可以切分更多條件或是修改Arduino端的呈現效果,一起來微笑吧!

延伸

 

請改用以下語法來將本機端圖檔上傳到FACE API來做辨識,請注意這個圖檔需要與 .py 放在同一個資料夾中,不然就需要指定絕對路徑。為了程式精簡,我們把 Arduino 端拿掉,您可以根據上續範例修改即可。

 

f = open(‘7688.jpg’, ‘rb’)

jpgdata = f.read()

f.close()

 

完整程式如下:

import httplib, urllib, base64
import json

f = open('a006.jpg', 'rb')
jpgdata = f.read()
f.close()

# Request header
headers = {
# Request headers
'Content-Type': 'application/octet-stream',
'Ocp-Apim-Subscription-Key': 'd3d138ceb1f4470286dcaba79f7d2de9',
}

params = urllib.urlencode({
# Request parameters
'returnFaceId': 'true',
'returnFaceLandmarks': 'false',
'returnFaceAttributes': 'age,gender,smile,emotion,glasses',
})   #只需要上述五個參數


body = {
}

try:
    conn = httplib.HTTPSConnection('api.projectoxford.ai')
    #conn.request("POST", "/face/v1.0/detect?%s" % params, json.dumps(body), headers)
    conn.request("POST", "/face/v1.0/detect?%s" % params, jpgdata, headers)
    response = conn.getresponse()
    data = json.loads(response.read())
    print(json.dumps(data, indent=2))   #顯示所有資料
    print data[0]["faceAttributes"]["smile"]   #顯示微笑程度
    conn.close()
except Exception as e:
    print("[Errno {0}] {1}".format(e.errno, e.strerror))

 

相關文章: