毕设树莓派小车
當初是這樣選中課設這樣一個題目的,看到有關于Python這樣的題目(基于Python的數據采集器),就很想報,剛好同學找的我,想和我一起組個隊一起搞畢設,所以我就說要不我們一起報這個(基于Python的數據采集器)題目,后來一拍而成,就妥妥的報了這個課題。所以才有了后來一系列的學習的文章,還有現在這篇文章,基本上在這個項目當中,我是一個技術指導者吧(也沒那么牛逼啦,只是我可能比他們早接觸編程吧,比我隊友懂多了一點吧,我實在是很垃圾啦)。
首先我們決定使用的是一個小車搭載一個攝像頭進行識別,最后添加了溫濕度提取顯示在頁面上。
我們使用的是樹莓派這款片上系統編程,驅動小車運動,攝像頭識別,溫度傳感器dht22提取溫濕度。
首先我們使用Python這樣的一個bottle框架來搭建我們的后臺服務器,接下來我們來看看他們的基本用法
第一步當然是安裝
當然如果有安裝Python 直接推薦如下安裝方法
$ sudo pip install bottle # recommended $ sudo easy_install bottle # alternative without pip $ sudo apt-get install python-bottle # works for debian, ubuntu, ...windows安裝
無論哪種方式, 您都需要安裝好 2.5以上 (包含3.x)來運行 bottle 應用. 如果您沒有權限在整個系統中安裝這些包或者根本不想這么做,那可以先創建 virtualenv :
如果您沒有安裝virtualenv ,可以通過以下方式安裝:
$ wget https://raw.github.com/pypa/virtualenv/master/virtualenv.py $ python virtualenv.py develop # Create virtual environment $ source develop/bin/activate # Change default python to virtual one (develop)$ pip install -U bottle # Install bottle to virtual environment快速入門: “HELLO WORLD”
from bottle import route, run@route('/hello') def hello():return "Hello World!"run(host='localhost', port=8080, debug=True)
代碼很簡單,運行這個腳本,訪問 http://localhost:8080/hello 您可以在瀏覽器中看到 “Hello World!” 。 它的運行原理如下:
route() 裝飾器為URL地址綁定了一段代碼,在這個例子中,我們關聯了/hello 地址到 hello() 函數上。 這個叫route的(裝飾器的名字) 是Bottle框架的最重要的概念。您可以定義任意多個 route。當瀏覽器請求一個URL地址,它所關聯的函數就會被調用并返回相應的值給瀏覽器,原理比較簡單。
最后一行調用 run() 方法啟動一個內置的開發環境用的服務器,運行在 localhost 8080 端口來為請求提供服務,可以按 Control-c來關閉它。以后你切換使用其他服務器,不過目前使用這個內置服務器就夠用了,它不需要任何配置,并且以難以置信的無侵害方式使您的應用運行并且用于本地測試。
默認應用
為了簡單起見,本教程中的例子都使用module-level route()裝飾器來定義route. 它會將這些routes添加到一個全局的 “默認應用”,它是一個Bottle 的實例,當第一次調用 route()時候會自動創建。有很多其他的 module-level 裝飾器和函數與默認應用相關,但是如果您喜歡更面向對象的方法和不介意額外的輸入,您可以創建一個單獨的應用程序對象,而不是使用全局的默認應用:
請求路由
route() 裝飾器關聯了一個URL 地址到一個回調函數,并添加了一個新的 route 到默認應用( default application),一個應用只有一個路由太單調了,因此,我們增加一些 (不要忘記 from bottle import template):
@route('/') @route('/hello/<name>') def greet(name='Stranger'):return template('Hello {{name}}, how are you?', name=name)動態路由
包含通配符的Route稱為動態路由 (對比于靜態路由) ,可以同時匹配不止一個 URL地址。一個簡單的通配符由一個名稱和一對中括號組成 (例如 ) ,接受下一個斜杠(/)前一個多多個字母。例如 路由/hello/ 接受請求/hello/alice和 /hello/bob,但不接受 /hello, /hello/ 或者/hello/mr/smith.
每一個通配符將覆蓋URL的一部分作為一個關鍵字參數,用于請求的回調函數。您可以使用它們輕松地實現基于RESTful的、代碼整潔友好的、有意義的url。這里有一些其他的例子,展示他們匹配的url:
@route('/wiki/<pagename>') # matches /wiki/Learning_Python def show_wiki_page(pagename):...@route('/<action>/<user>') # matches /follow/defnull def user_api(action, user):...0.10 版本后的新特性.
使用過濾器是用來定義更具體的通配符,并且/或者 在傳遞給回調函數之前對參數進行轉換。一個過濾通配符聲明為name:filter orname:filter:config。可選配置部分的語法取決于所使用的過濾器。
以下是默認實現的過濾器,以后可能會增加更多:
:int matches (signed) digits only and converts the value to integer. :float similar to :int but for decimal numbers. :path matches all characters including the slash character in a non-greedy way and can be used to match more than one path segment. :re allows you to specify a custom regular expression in the config field. The matched value is not modified.讓我們來看看一些實際的例子:
@route('/object/<id:int>') def callback(id):assert isinstance(id, int)@route('/show/<name:re:[a-z]+>') def callback(name):assert name.isalpha()@route('/static/<path:path>') def callback(path):return static_file(path, ...)您可以實現定制的過濾器,細節請參考 Request Routing .
0.10版本更新.
Bottle 0.10中引入的新規則語法,用來簡化一些常見的用例,但是老語法仍然有效,你可以找到很多示例代碼還使用它。下面例子描述了他們的差異:
Old Syntax New Syntax :name <name> :name#regexp# <name:re:regexp> :#regexp# <:re:regexp> :## <:re>在未來的項目中盡量避免使用舊語法,它目前還能使用,但最終會被棄用。
HTTP請求方法
HTTP協議定義了多種請求方法(request methods ,有時被稱作“verbs”) 來實現不同的任務。當沒有指定方法時,所有的routes路由都默認使用GET方法,這些路由只能匹配GET請求。如果要處理其他的請求如 POST, PUT, DELETE 或者 PATCH, 給route() 增加一個 method 關鍵字參數,或者使用四個替代裝飾器: get(), post(), put(), delete() 或patch().
POST方法通常用于 HTML 表單的提交,下面例子展示了如何使用POST處理一個登錄表單:
from bottle import get, post, request # or route@get('/login') # or @route('/login') def login():return '''<form action="/login" method="post">Username: <input name="username" type="text" />Password: <input name="password" type="password" /><input value="Login" type="submit" /></form>'''@post('/login') # or @route('/login', method='POST') def do_login():username = request.forms.get('username')password = request.forms.get('password')if check_login(username, password):return "<p>Your login information was correct.</p>"else:return "<p>Login failed.</p>"ok,這個小車大概就用到這樣的一些用法吧,其他可以訪問下面這個博客的鏈接
bottle 博客教程
1 小車行動的程序
主要界面分為前進,后退,左轉,右轉,停止,五大功能
前臺界面使用 bootstrap 布局簡單的界面
前臺主要代碼如下:
車子的的電機驅動模塊是L298N這個模塊,
1 他的主電源正極為 12 V 電壓
2 他主要有四個引腳分別為 IN1,IN2,IN3,IN4,這里我們鏈接在樹莓派的11,12,13,15號引腳。
3 5V 輸入我是從 2 號引腳拉出來的
4 通道A,B 用于連接電機的,有一個是正極輸出,一個是負極輸出。
接下來就是我們給小車的驅動代碼
#!/usr/bin/env python3 # _*_ coding: utf-8 _*_ from bottle import get,post,run,request,template #導入gpio的模塊 import RPi.GPIO as GPIO import time#定義小車驅動引腳號 IN1 = 11 IN2 = 12 IN3 = 13 IN4 = 15 #定義引腳號 ServoPinlr = 23 ServoPinud = 26#設置GPIO口為BOARD編碼方式 GPIO.setmode(GPIO.BOARD)#忽略警告信息 GPIO.setwarnings(False)# 初始化攝像頭的PWM波 def inits():global pwm_servo1global pwm_servo2GPIO.setmode(GPIO.BOARD)GPIO.setup(ServoPinlr, GPIO.OUT)GPIO.setup(ServoPinud, GPIO.OUT)#設置pwm引腳和頻率為50hzpwm_servo1 = GPIO.PWM(ServoPinud, 50)pwm_servo2 = GPIO.PWM(ServoPinlr, 50)pwm_servo1.start(0)pwm_servo2.start(0)inits() # 控制攝像頭左右轉動 def servo_control1(pos):# 設置PWM 波的占空比pwm_servo1.ChangeDutyCycle(2.5 + 10 * pos/180) # 控制攝像頭上下轉動 def servo_control2(pos):# 設置PWM波的占空比pwm_servo2.ChangeDutyCycle(2.5 + 10 * pos/180) #設置GPIO口的輸出方式 def init():#設置gpio口的模式 注意GPIO.setmode(GPIO.BOARD)GPIO.setup(IN1,GPIO.OUT)GPIO.setup(IN2,GPIO.OUT)GPIO.setup(IN3,GPIO.OUT)GPIO.setup(IN4,GPIO.OUT)# 左轉函數 def left():GPIO.output(IN1,False)GPIO.output(IN2,False)GPIO.output(IN3,GPIO.HIGH)GPIO.output(IN4,GPIO.LOW)# 右轉 def right():GPIO.output(IN1,GPIO.HIGH)GPIO.output(IN2,GPIO.LOW)GPIO.output(IN3,False)GPIO.output(IN4,False)# 前進 def go():GPIO.output(IN1,GPIO.HIGH)GPIO.output(IN2,GPIO.LOW)GPIO.output(IN3,GPIO.HIGH)GPIO.output(IN4,GPIO.LOW)# 后退 def back():GPIO.output(IN1,GPIO.LOW)GPIO.output(IN2,GPIO.HIGH)GPIO.output(IN3,GPIO.LOW)GPIO.output(IN4,GPIO.HIGH)#GPIO.cleanup()#釋放GPIO口# 停止 def stop():GPIO.output(IN1,GPIO.LOW)GPIO.output(IN2,GPIO.LOW)GPIO.output(IN3,GPIO.LOW)GPIO.output(IN4,GPIO.LOW)#GPIO.cleanup()#釋放GPIO口@get("/") def index():return template("index") @post("/cmd") def cmd():# 在這里判斷要判斷前臺的按鍵按下了那個按鍵# 根據按鍵來響應哪些事件# 獲取前臺按下按鈕傳過來的this.id# 根據this.id判斷執行那個函數# 我猜測request對象應該有一個實例化方法可以查詢前臺post過來的字段的# print("按下了按鈕: "+request.body.read().decode())init() # 初始化板和引腳param = request.body.read().decode();print(param)if param == 'go':go()if param == 'back':back()if param == 'left':left()if param == 'right':right()if param == 'stop':stop()return "OK" @post("/ser") def ser():try:#舵機left/right#pos = request.body.read().decode();pos = int(request.forms.get('val'))flag = int(request.forms.get('flag'))if not flag:pwm_servo1.start(0)servo_control1(pos)print(pos)else:pwm_servo1.stop()pwm_servo1.start(0) except KeyboardInterrupt:pass#GPIO.cleanup() @post("/serud") def serud():try:pos = int(request.forms.get('val'))flag = int(request.forms.get('flag'))if not flag:pwm_servo2.start(0)servo_control2(pos)print(pos)else:pwm_servo2.stop()pwm_servo2.start(0) except KeyboardInterrupt:pass#GPIO.cleanup() run(host="0.0.0.0",port="1025")小車完成驅動源碼已經上傳到git
樹莓派小車源碼
今天把dht22傳感器 提取溫濕度也完成了
DHT22 溫濕度傳感器盡管不是使用效率最高的溫濕度傳感器,但價格便宜被廣泛應用。下面我們介紹另一種基于Adafruit DHT 庫讀取 DHT22 數據的方法。
DHT22 規格
DHT22 有四個引腳,但是其中一個沒有被使用到。所有有的模塊會簡化成3個引腳。
濕度檢測范圍 : 20-80% (5% 精度)
溫度檢測范圍 : 0-50°C (±2°C 精度)
該廠商不建議讀取頻率小于2秒,如果這么做數據可能會有誤。
硬件連接
需要在電源和數據腳之間串聯一個上拉電阻(4.7K-10K),通常情況下,購買DHT11模塊的話都自帶了這個電阻。不同的模塊型號引腳位置略有不同,下面以圖上模塊為說明:
DHT Pin Signal Pi Pin
1 3.3V 1
2 Data/Out 11 (GPIO17)
3 not used –
4 Ground 6 or 9
數據引腳可以根據你的需要自行修改。
Python 庫
D
DHT22 的讀取需要遵循特定的信號協議完成,為了方便我們使用Adafruit DHT 庫。
軟件安裝
開始之前需要更新軟件包:
從 GitHub 獲取 Adafruit 庫:
sudo git clone https://github.com/adafruit/Adafruit_Python_DHT.git cd Adafruit_Python_DHT給 Python 2 和 Python 3 安裝該庫:
sudo python setup.py install sudo python3 setup.py installAdafruit 提供了示例程序,運行下面的命令測試。
cd ~ cd Adafruit_Python_DHT cd examples python AdafruitDHT.py 11 17這兩個參數分別表示 DHT22 和數據引腳所接的樹莓派 GPIO 編號。成功的話會輸出:
Temp=22.0* Humidity=68.0%如何在其他 Python 程序中使用這個庫
參照下面的方法引入 Adafruit 庫,然后就可以使用 “read_retry” 方法來讀取 DHT11 的數據了:
最終溫濕度檢測源碼如下
dht22源碼
最終的界面如下,界面暫時樣式還沒有調整好,所以丑
總結
- 上一篇: 初中信息学c语言组竞赛ppt,论C语言在
- 下一篇: 思维导图制作软件/网站