樹莓派Raspberry區域網視頻小車教程

  • 一、功能介紹

最近完成一個Raspberry區域網視頻小車項目,特此拿出來分享!

首先來介紹小車的情況,Raspberry首先擔任一個伺服器兼控制中心的角色,用戶通過區域網查看監控視頻以及髮指令給Raspberry,然後Raspberry通過串口通信髮指令給Arduino控制小車電機和舵機移動。

根據上述描述,我們可以把項目分為以下幾部分:

1.Raspberry搭建伺服器

2.搭建VNC遠程桌面

3.視頻流的傳輸

4.Raspberry-Arduino的串口通信

5.Arduino的電機與舵機控制

接下來,我會根據以上部分詳細介紹每一步!至於安裝系統,連接互聯網等一些基本步驟就不在這介紹了。

  • 二、搭建vnc遠程桌面

因為我們這個項目需要在python編程,為了方便,所以搭建一個vnc伺服器,在pc端遠程連接樹莓,以遠程操控樹莓。

首先,在樹莓上安裝vnctight:

sudo apt-get updatensudo apt-get install tightvncservern

安裝完後,運行命令開啟vnc伺服器:

vncserver :1n或者設定特定屏幕解析度:nvncserver :1 -geometry 1440x900n

首次使用會提示你設置密碼,那個是遠程登錄時要用到。

在樹莓端開啟vnc後,在pc端下載TightVnc Viewer遠程登錄,效果如圖:

相關資料可以參考:VNC簡明指南

  • 三、Raspberry搭建伺服器

首先,為什麼要搭建伺服器呢?因為我需要在區域網上控制小車的移動,所以就需要向Raspberry發送網路請求,Raspberry需要實時監控並接收網路請求,然後執行相對應的動作。

下面資料一切都是為了講明白如何在區域網中向Raspberry發送指令,不要亂了思路!

我這次搭建伺服器用了Python的Flask模板,這個模板簡單且易入手,不用深入理解TCP/IP等一大堆令人頭痛的協議也可操作。下面,介紹一下,怎麼使用:

3.1在使用該模板前,需要在樹莓上下載Python的Flask模板

sudo apt-get install python3-flaskn

3.2Flask搭建伺服器

#flask_hello.pynnfrom flask import Flasknnapp = Flask(__name__)nn@app.route(/)ndef index():n return Hello worldnnif __name__ == __main__:n app.run(debug=True, host=0.0.0.0port=5000)n

在以上常式中:

host=0.0.0.0:代表伺服器接收區域網一切對象的訪問 port=5000則代表埠值n

試著在Python上運行這一段代碼,你會看到輸出有:

* Running on http://0.0.0.0:5000/n* Restarting with reloadern

此時,你的電腦只要在區域網中訪問

http://樹莓ip:5000/n

就可以看到收到相對應的數據:

3.2.1路徑設置:

當你回顧剛才那段代碼時,你會發現有這麼一段程序:

@app.route(/)ndef index():n return Hello worldn

上面代碼是路徑設置,如果你想通過打開不同的路徑顯示不同的內容,你可以嘗試在該代碼下面加:

@app.route(/cakes)ndef cakes():n return Yummy cakes!n

訪問下面的網址:

所以我們可以知道@app.route(/XXX)裡面XXX是路徑名,當你訪問不同的路徑時,你可以通知Raspberyy執行不同的動作!

學到這裡,來拓展一下路徑參數,這個很重要,看下常式:

@app.route(/<name>)ndef cakes(name):n return name;n

以上常式把路徑名作為輸入參數,當路徑為XXX時,Raspberry就會返回對應的值,看結果:

3.2.2建立網頁

首先在程序模板的目錄下建立templates文件夾

mkdir templatesn

接著在該目錄下新建一個index.html格式的空文件,並用Text Editor編輯,在該文件下植入以下代碼:

<html>n<body>n<h1>Hello from a template!</h1>n</body>n</html>n

將主頁路徑觸發事件改為:

@app.route(/)ndef index():n return render_template(index.html)n

同時,也要記得引入render_template模板:

from flask import Flask,render_templaten

當你打開主頁時,你會看到:

說到這裡,之前我們學了flask模板的路徑設置以及網頁製作,我是在區域網中通過點擊網頁指令來控制小車移動的,下面來說明一下如何做到這一點?

First,構建指令鏈接:

在你的網頁.html文件中,嘗試加以下語句:

<!DOCTYPE html>n<head>n <title>Rotbot_Car</title>n</head>nn<body>n <br><a href="/forward">前進</a></br>n <br><a href="/back">後退</a></br>n <br><a href="/left">左轉</a></br>n <br><a href="/right">右轉</a></br>n n</body>n</html>n

對於上面的代碼只說一點關於href的,href用於指定超鏈接目標的URL,比如說

<br><a href="/forward">前進</a></br>n

上面指定超鏈接目標的URL為:

http://主域名/forwardn

具體運行結果為:

當你點擊不同的選項時,便會跳轉到對應的URL中!

Second,獲取路徑名參數來指揮Raspberry工作:

在上面網頁程序的基礎上繼續操作,當點擊不同指令時,Raspberry會收到不同路徑名的跳轉請求,所以我們就用路徑設置的方法,根據路徑名的類別來判斷用戶指令是什麼,從而執行相對應的操作!

下面是程序的一個雛形!

from flask import Flask,render_templatennapp = Flask(__name__)nn@app.route(/)ndef index():n return render_template(index.html)nn@app.route(/<name>)ndef index(name):n if(name == forward):n %發送前進指令給Arduinon if(name == back):n %發送後退指令給Arduinonnn if(name == left):n %發送左轉指令給Arduinon if(name == right):n %發送右轉指令給Arduinon return render_template(index.html)nnif __name__ == __main__:n app.run(debug=True, host=0.0.0.0)n

到這裡,想必大家已經知道如何構建伺服器實時獲取用戶控制小車的指令了吧!

相關資料可以參考:python-web-server-with-flask

Raspberry-Pi-Flask

  • 四、視頻流的傳輸

說下我用到的攝像頭,Raspberry官方的攝像頭,是一魚眼攝像頭,額外買紅外燈的話,還會有夜視的功能,在京東淘寶都可以買到,在這我就不自行打廣告了。

為了能使用戶從區域網觀看小車攝像頭拍到的視頻,raspberry需要把視頻流傳輸到區域網上去,在這裡,我們採用mjpg-streamer的方案,它是github上一個開源項目,有關介紹,可以參考:mjpg-streamer介紹

首先,把開源代碼下載到樹莓上

pi@raspberrypi:~ $ wget https://github.com/jacksonliam/mjpg-streamer/archive/master.zipn

接著,在樹莓上編譯工具安裝好

pi@raspberrypi:~ $ sudo apt-get install cmake libjpeg8-devn

解壓下載好的壓縮文件

pi@raspberrypi:~ $ unzip master.zipn

修改視頻傳輸參數:

設置視頻傳輸參數的input_raspicam.c文件在以下目錄中,:

mjpg-streamer-master/mjpg-streamer-experimental/plugins/input_raspicamn

具體代碼如下:

為了保障視頻傳輸流暢,建議把fps調到30左右較好!

編譯程序:

pi@raspberrypi:~ $ cd mjpg-streamer-master/mjpg-streamer-experimental

pi@raspberrypi:~ $ make clean all

製作mjpg的啟動腳本

新建一個.sh格式文件xx.sh,並進行編輯。

pi@raspberrypi:~ $ nano xx.sh n

將以下內容複製到xx.sh文件中:

cd mjpg-streamer-master/mjpg-streamer-experimentaln./mjpg_streamer -i "./input_raspicam.so" -o "./output_http.so -w ./www"n

生成啟動腳本

chmod 744 xx.shn

以後只要執行上面生成的啟動腳本,就可以啟動mjpg很方便,啟動指令為:

sh xx.shn

觀看視頻:

啟動了mjpg後,在pc端訪問以下網址即可觀看視頻:

http://the ip of raspberry:8080n

總的來說很簡單,就是把源文件下載到樹莓上,解壓,修改視頻傳輸參數,然後編譯程序,最後弄一個啟動腳本方便以後運行。執行啟動腳本後,在pc端輸入指定網址即可觀看視頻!

相關教程可以參考:用樹莓派官方攝像頭做絲滑般流暢的監控!

  • 五、Raspberry-Arduino串口通信

我採用的方案是Raspberry通過USB轉TTL與Arduino的RX,TX管腳連接,USB轉TTL器件可以在淘寶選購,具體圖片為:

因為Arduino與Raspberry的電源值不同,為了安全起見,不要接USB-TTL的VCC,USB-TTL的RX端接Arduino的TX端,TX端接Arduino的RX端,當然GND肯定是要接的!

做好電路連接後,首先先查看哪個USB0亦或USB1埠被佔用了:

ls /dev/tty* n

* 為USB0或USB1,兩個都試一下,當某一個埠被佔用,是會有對應的文件生成!

Raspberry串口發送數據的簡單常式為:

import serialnimport timenndef Serial_open():n return serial.Serial("/dev/ttyUSB0", 115200) nn#"/dev/ttyUSB0"表示該埠被佔用nnif __name__ == "__main__":nn Ser = Serial_open()nn while True:n pl2303.write(『a』)n time.sleep(1)n

上面常式作用就是Raspberry隔一秒就發送一個數據『a』!

接下來到了Arduino的串口操作,這麼都非常簡單:

void setup() {n // put your setup code here, to run once:n Serial.begin(115200); #串口通信波特率為115200n}nnvoid loop() {n // put your main code here, to run repeatedly:n if (Serial.available() > 0) {nn if(Serial.read() == a){n #執行相對應的動作n }nn }n}n

上面常式就是首先對串口初始化,然後實時對Serial進行檢查,當串口收到數據時,Serial.available()會返回一個非0值,接著通過Serial.read()把串口收到的數據讀出來,再進行進一步的操作。

相關資料參考:使用串口連接Arduino與樹莓派開發板

RaspberryPi2樹莓派USB轉串口連接Arduino

  • 六、Arduino的電機與舵機控制

到最後一章,如果前面都看懂的話,再加上這一節,幾乎就可以做基於Raspberry與Arduino的區域網視頻小車。

Fisrt,首先說下電機控制,電機控制需要購買電機驅動模塊,如果直接GPIO驅動可能對板子來說很吃力,電機驅動模塊,我首推薦的是Arduino配套的L298P驅動模塊,如圖:

說下它的使用方法,該擴展板是可以直接插到Ardunio MEGA2560開發板上面使用,右上角的VIN是電源輸入端,一般電機需要高於5V的電壓驅動才會比較好玩,速度才會快些,建議上網買幾塊大電池,8~12V左右供電,而且它會自動輸出5V給Arduino供電,非常方便,同時它有光耦隔離電路,根本不用擔心電源電壓過高把開發板燒掉,所以還是建議多花點錢買這個拓展版比較好。

接著,右邊有A,B各兩個輸入口,每兩個連在一起的輸入口接電機兩根的線,板子上PWMA,PWMB的PWM占空比輸出是控制對應輸入端電機的速度,而DIRA,DIRB的高低電平是控制對應輸入端電機轉動的方向,具體方向取值因接線不同而不同,所以自己要親自去調試一遍才能知道。

下面給一段自己的小車電機控制子函數給大家做個參考,這部分都比較簡單就不做詳細解釋:

int Right_motor = 3;nint Left_motor = 11;nint Right_Dir = 12;nint Left_Dir = 13;nchar flag;nnvoid setup() { //初始化n // put your setup code here, to run once:n Serial.begin(115200);n pinMode(Right_motor,OUTPUT);n pinMode(Left_motor,OUTPUT);n pinMode(Right_Dir,OUTPUT);n pinMode(Left_Dir,OUTPUT);n}nnvoid Car_Control(int r_speed, int l_speed, int flag){n analogWrite(Right_motor,r_speed); //PWM輸出控制電機速度n analogWrite(Left_motor,l_speed);n n if(flag == 1){ //小車行動方向控制n digitalWrite(Right_Dir,HIGH);//FORWARDn digitalWrite(Left_Dir,LOW);//FORWARDn }n else if(flag == 0){n digitalWrite(Right_Dir,LOW);//FORWARDn digitalWrite(Left_Dir,HIGH);//FORWARDn }n }n

Second,說一下舵機的控制,舵機一般選購sg50舵機較適宜吧,價格不貴,佔用空間也不是很大,模塊如圖:

把攝像頭裝到舵機上也是個很煩惱的問題,建議上網買些合適的舵機雲台,然後用502或者熱熔膠這類的工具把攝像頭裝上去也可以,總之,自己衡量吧。

控制舵機可以用到Arduino的Servo庫,這個庫控制電機的程序很簡單,不過缺點在於該庫只能利用9、10介面,只能控制兩路舵機,不過在這已經夠用了,所以,下面展示下常式:

#include <Servo.h>nnServo myservo;nint pos;nnvoid setup() {n // put your setup code here, to run once:n myservo.attach(10); //初始化n}nnvoid loop() {n // put your main code here, to run repeatedly:n myservo.write(pos); //控制舵機轉動角度n}n

具體資料可參考:Arduino 入門到精通 常式18-舵機控制

  • 七、總結

整篇文章把視頻小車所需要實現功能的方法都介紹了一遍,可能文章較長,比較難把握結構,我在這總結一下文章的分支結構:

*********************************************分割線***************************************************

1.VNC伺服器搭建實現遠程桌面操控

2.發送網路請求給Raspberr: 2.1Flask模板

2.2Flask路徑設置

2.3Flask網頁模板創建與傳送

2.4發送網路請求給Raspberry

3.視頻流的傳輸

4.Raspberry與Arduino的串口通信

5.Arduino的電機與舵機控制

*********************************************分割線***************************************************

整篇文章結構已經歸納完畢,由於水平有限,文章深度自然不夠,如有錯漏之處,希望可以提出建議,望海涵,謝謝!


推薦閱讀:

Python從零開始系列連載(27)——Python特色數據類型(函數)(中)
Python數據分析之讀取文件
R語言中不能進行深度學習?
黃哥Python,從一個簡單問題說起

TAG:树莓派RaspberryPi | Arduino | Python |