作者:賴桑
LinkIt Smart 7688所支援的OpenWRT,原本就已經安裝有uHTTPd的網頁伺服器,讓使用者可以透過網頁互動,目前最常見的方法就是用Web Form搭配CGI。
所謂CGI其實全名是「Common Gateway Interface」,不論用甚麼語言、工具開發,uHTTPd會透過stdio、重導向,或者環境參數設定的方式,把使用者在Web Form上面填寫的內容轉傳給你的CGI程式進行後續處理。
本文將介紹的這個方法好處在於,不論7688是在「AP」還是「Station」模式下,只要能夠連上uHTTPd,就可以進行Web Form資料的輸出入處理,相當方便而且自由度比較高!
不過,7688的CPU執行效率並不高,千萬不要處理太過複雜的Web Form否則使用者反應效能會很低。
所需材料
1. LinkIt Smart 7688
2. Logitech C170 USB Camera
3.一個220Ω固定電阻跟一個LED
基本架構
設定uHTTPd可以執行Python
uHTTPd目前定義CGI是Lua為基準,所以要對於uHTTPd的設定檔案進行修改,好讓Python寫的CGI知道是要誰去執行這個Python,就是載入哪個Interpreter才能執行你的CGI程式,這樣而已啦~
uHTTPd的設定檔案就是 /etc/config/uhttpd 這個,打開以後如下圖,再來加上對於Python當CGI解譯器的定義吧!
Python的解譯器鏈結,就是7688的OpenWRT中的 /usr/bin/python ,以後你的CGI檔案尾巴就用 .py 字樣結尾,就會讓uHTTPd認出來是要去呼叫Python的解譯器來執行它。設定編輯完成後除了儲存外,更重要的是要uHTTPd將新的設定載入,所以在OpenWRT下要輸入以下指令:
/etc/init.d/uhttpd restart
網頁上的即時影像
在7688的OpenWRT中已經安裝有 mjpg_streamer ,所以我們可以直接套用,例如:
mjpg_streamer -i "input_uvc.so -f 30 -r 320*240" -o "output_http.so -p 8080"
這樣會找 /dev 目錄下名為 video0 的Linux UVC Camera,也就是本文的LogiTech C170,當作視訊來源,每秒30張畫面,解析度為320 x 240,而串流的埠號則是8080;有關 mjpg_streamer 的使用說明與範例,可以輸入:
mjpg_streamer --help
就會有各項使用參數的說明。一旦 mjpg_streamer 啟動成功後,只要網頁中加上img標籤就可以看到即時影像,src屬性就指向串流提供的IP位址與埠號就可以了。比如:
編輯Web Form以及CGI程式
7688下的網頁存在 /www 目錄下,而CGI程式就在 /www/cgi-bin 目錄下;我們這裡的範例就用一個Web Form和一個Python寫的CGI程式來當作範例。Web Form的部分:
<html>
<head>
<title>Control GPIO by Web</title>
</head>
<body>
<form action="/cgi-bin/motorcgi.py" method="post">
Relay :<br>
<input type="radio" name="LED" value="U">ON<br>
<input type="radio" name="LED" value="OFF">OFF<br>
<input type="submit" value="Submit" />
</form>
<img src="http://192.168.100.1:8080/?action=stream">
</body>
</html>
而Python寫CGI,除了GPIO本文是用libmraa以外,就還要用到package名為cgi、cgitb這兩個了!做法上就是把Web Form當成物件取得後,再由Web Form的物件中,依據欄位的名稱,比如網頁中的LED,取出欄位的值之後進行判斷。
如果有要回應的網頁內容,那就用Python本來就有的print指令就行了,非常簡單。本文用Python寫的CGI範例,記住,要放到 /www/cgi-bin 中,而且檔案名稱還要跟上面網頁中form標籤後面的action所指向的位置、檔案名稱相符,不然就呼叫失敗了。
import mraa
import cgi
import cgitb
WAY = mraa.Gpio(43) #GPIO43 on 7688
WAY.dir(mraa.DIR_OUT)
cgitb.enable()
form = cgi.FieldStorage() #Get the form instance
DIRECT = form.getvalue('LED') #Get the value from posted web form
print "Content-type: text/html\n\n"
print ""
print ""
print "LED :" + DIRECT + "\n
"
print ""
print ""
if DIRECT == "U": #Decide the LED is on or off
WAY.write(1)
else:
WAY.write(0)
然後打開瀏覽器,連線到7688;例如本文撰寫時7688是處於AP模式,所以網址就是 http://192.168.100.1/motor.html
然後,試著操作Radio buttons並按下Submit按鈕,看看你的LED燈是不是會跟著點亮或熄滅,想再操作一次可以直接叫瀏覽器的回上一頁,再重複按下你要的Radio buttons並且按下Submit按鈕。注意!7688的CPU執行CGI需要數秒鐘,所以按下Submit按鈕後請稍等待一下。
小結
如果你的LED會跟著Web Form的Radio buttons決定點亮或熄滅,恭喜!可以藉由這個方法,隨時透過網頁控制任何一台7688的GPIO,並且也可以隨時透過網頁擷取到任何一個7688上的USB Camera輸出的即時影像了!
- 【開箱評測】用Mbed上手開發DSI 2599開發板 - 2020/08/03
- 【OpenVINO™教學】自製麵包影像辨識POS機的應用 - 2019/12/24
- 【邊緣運算】OpenVINO好夥伴 — athena A1 Kit x86單板 - 2019/11/18
訂閱MakerPRO知識充電報
與40000位開發者一同掌握科技創新的技術資訊!
2016/12/26
DIRECT 的變數要轉字串
你有試過嗎