No Code AI(肉寇)AI自動化兩日精通|實體6小時+線上6小時
|

【7688】用Python寫CGI傳輸即時影像並控制GPIO

   

作者:賴桑

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

LinkIt Smart 7688

LinkIt Smart 7688

2. Logitech C170 USB Camera

Logitech C170 USB Camera

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位址與埠號就可以了。比如:

加上img標籤

加上img標籤

編輯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輸出的即時影像了!

賴建宏

訂閱MakerPRO知識充電報

與40000位開發者一同掌握科技創新的技術資訊!

Author: 賴建宏

社群稱號為「賴桑」的他,以電子電機的背景,熱衷於OSHW的應用開發與實作。取得台北科技大學電子所博士學位,目前主推「農林漁牧大業」計畫的迷你型魚菜共生系統開發。

Share This Post On
468 ad

1 Comment

  1. DIRECT 的變數要轉字串

    你有試過嗎

    Post a Reply

Submit a Comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *