1、簡單介紹樹莓派的GPIO口javascript
上圖是樹莓派2代的接口(不一樣型號接口會有差別),咱們就以此爲例來講下這些接口。css
一、GPIO介紹html
GPIO 英文全稱是:General-purpose input/output
通用型之輸入輸出的簡稱,其接腳能夠供使用者由程控自由使用,PIN腳依現實考量可做爲通用輸入(GPI)或通用輸出(GPO)或通用輸入與輸出(GPIO)。經過這些GPIO口,咱們能夠控制不少第三方的寄存器設備,簡單來講咱們能夠經過這些I/O口控制一些芯片的電路、讀取傳感器的數值等。java
二、所需材料python
材料名稱 | 數量 |
---|---|
樹莓派2代板子(包含電源、數據線、存儲卡) | 1 |
智能小車底盤(包含四個直流電機) | 1 |
移動電源 | 1 |
L298N電機驅動板 | 1 |
杜邦線母對公 | 10 |
杜邦線母對母 | 10 |
無線網卡 | 1 |
4孔或6孔電池盒 | 1 |
三、安裝所需軟件jquery
樹莓派官方有兩套GPIO的python庫,分別是RPi.GPIO
和RPIO
。如今網絡上許多關於樹莓派GPIO文檔的教程多數是RPi.GPIO
,這個是老版本的庫。而RPIO
是用來替代前者的新版本。後面的課程我將使用RPIO
這個庫,來給你們演示。下面安裝RPIO
:android
1
2
|
sudo apt
-
get install python
-
dev python
-
pip
sudo pip install RPIO
|
2、 樹莓派與L298N線路鏈接git
一、第一步組裝小車github
組裝底盤 分別用銅線鏈接兩側電機,而且保證同側轉向一致。以下圖:web
鏈接電機與L298N 將兩側側的電機分別接入L298N的輸出A和輸出B,見下圖:
鏈接L298N與樹莓派 見上圖邏輯輸入部分有4個針腳(IN一、IN二、IN三、IN4),按照順序分別鏈接到樹莓派接口的十一、十二、1六、18 四個口。見下圖藍色部分:
除了上面這些,還要將L298N的供電GND
和樹莓派的GPIO的6號Ground
鏈接,造成供電迴路。
鏈接電池盒與移動電源 將電池盒的正極鏈接到L298N的12V供電
口,負極鏈接到L298N的供電GND
口。完成鏈接後,L298N的供電GND
口鏈接了兩個線,分別是電池盒的負極和樹莓派的6號Ground口。
二、測試小車
登陸樹莓派,vim robot.py
文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
import
RPIO as GPIO
import
time
IN1
=
11
IN2
=
12
IN3
=
16
IN4
=
18
def
init():
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
forward():
GPIO.output(IN1,GPIO.HIGH)
GPIO.output(IN2,GPIO.LOW)
GPIO.output(IN3,GPIO.HIGH)
GPIO.output(IN4,GPIO.LOW)
if
__name__
=
=
'__main__'
:
init()
forward()
time.sleep(
5
)
GPIO.cleanup()
|
保存退出後,用sudo python robot.py
執行命令,小車將會向前進5秒。
備註:一、要避免靜電和短路。二、接線要當心,尤爲是正負極接線。
3、使用Python控制小車
一、Tornado介紹
Tornado是使用Python編寫的一個強大的、可擴展的Web服務器。它在處理嚴峻的網絡流量時表現得足夠強健,但卻在建立和編寫時有着足夠的輕量級,並可以被用在大量的應用和工具中。
二、Tornado安裝
1
2
3
4
5
|
$ curl
-
L
-
O https:
/
/
github.com
/
facebook
/
tornado
/
archive
/
v3.
1.0
.tar.gz
$ tar xvzf v3.
1.0
.tar.gz
$ cd tornado
-
3.1
.
0
$ python setup.py build
$ sudo python setup.py install
|
Tornado官方並不支持Windows,但你能夠經過ActivePython的PyPM包管理器進行安裝,相似以下所示:
1
|
C:\> pypm install tornado
|
二、robot.py
文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
#!/usr/bin/python
#coding: utf8
import
RPIO as GPIO
import
time
import
sys
import
threading
import
tornado.ioloop
import
tornado.web
import
tornado.httpserver
import
tornado.options
import
json
tornado.options.define(
"port"
,default
=
8000
,
type
=
int
)
IN1
=
11
IN2
=
12
IN3
=
16
IN4
=
18
stop_status
=
0
last_key
=
""
last_request_time
=
0
def
init():
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
forward():
global
stop_status
GPIO.output(IN1,GPIO.HIGH)
GPIO.output(IN2,GPIO.LOW)
GPIO.output(IN3,GPIO.HIGH)
GPIO.output(IN4,GPIO.LOW)
# print "forward"
# time.sleep(0.1)
# 後退
def
reverse():
global
stop_status
GPIO.output(IN1,GPIO.LOW)
GPIO.output(IN2,GPIO.HIGH)
GPIO.output(IN3,GPIO.LOW)
GPIO.output(IN4,GPIO.HIGH)
# 左轉彎
def
left():
global
stop_status
GPIO.output(IN1,GPIO.LOW)
GPIO.output(IN2,GPIO.HIGH)
GPIO.output(IN3,GPIO.HIGH)
GPIO.output(IN4,GPIO.LOW)
# 右轉彎
def
right():
global
stop_status
GPIO.output(IN1,GPIO.HIGH)
GPIO.output(IN2,GPIO.LOW)
GPIO.output(IN3,GPIO.LOW)
GPIO.output(IN4,GPIO.HIGH)
#中止
def
stop_car():
GPIO.output(IN1,
False
)
GPIO.output(IN2,
False
)
GPIO.output(IN3,
False
)
GPIO.output(IN4,
False
)
global
stop_status
stop_status
=
1
#關閉GPIO接口
def
close_car():
global
stop_status
stop_status
=
1
GPIO.cleanup()
class
IndexHandler(tornado.web.RequestHandler):
def
set_default_headers(
self
):
self
.set_header(
'Access-Control-Allow-Origin'
,
'*'
)
self
.set_header(
'Access-Control-Allow-Methods'
,
'POST, GET, OPTIONS'
)
self
.set_header(
'Access-Control-Allow-Headers'
,
'*'
)
def
get(
self
):
self
.render(
"index.html"
)
def
post(
self
):
global
stop_status
global
last_key
global
last_request_time
old_request_time
=
last_request_time
init()
sleep_time
=
0.1
try
:
arg
=
self
.get_argument(
'k'
)
new_request_time
=
self
.get_argument(
'time'
)
print
'get last time'
,new_request_time
except
Exception, e:
arg
=
json.loads(
self
.request.body)[
'k'
]
new_request_time
=
json.loads(
self
.request.body)[
'time'
]
print
'json last time'
, new_request_time
print
"==new time =="
, new_request_time
print
"==old time =="
, old_request_time
if
(arg
=
=
'w'
and
last_key!
=
'w'
and
new_request_time >
=
old_request_time):
print
"forward"
stop_status
=
0
autoThread
=
threading.Thread(target
=
forward)
autoThread.start()
last_key
=
'w'
elif
(arg
=
=
's'
and
last_key!
=
's'
and
new_request_time >
=
old_request_time):
print
"reverse"
stop_status
=
0
autoThread
=
threading.Thread(target
=
reverse)
autoThread.start()
last_key
=
's'
elif
(arg
=
=
'a'
and
last_key!
=
'a'
and
new_request_time >
=
old_request_time):
print
"left"
stop_status
=
0
autoThread
=
threading.Thread(target
=
left)
autoThread.start()
last_key
=
'a'
elif
(arg
=
=
'd'
and
last_key!
=
'd'
and
new_request_time >
=
old_request_time):
print
"right"
stop_status
=
0
autoThread
=
threading.Thread(target
=
right)
autoThread.start()
last_key
=
'd'
elif
(arg
=
=
'stop'
and
new_request_time >
=
old_request_time):
print
"stop"
last_key
=
"stop"
time.sleep(
0.3
)
stop_car()
else
:
print
"error"
last_request_time
=
new_request_time
self
.write(arg)
def
options(
self
):
pass
if
__name__
=
=
'__main__'
:
tornado.options.parse_command_line()
app
=
tornado.web.Application(handlers
=
[(r
"/"
,IndexHandler)])
http_server
=
tornado.httpserver.HTTPServer(app)
http_server.listen(tornado.options.options.port)
tornado.ioloop.IOLoop.instance().start()
|
三、index.html
文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
<!DOCTYPE html>
<html>
<head>
<meta charset
=
"utf-8"
/
>
<title>WIFI小車客戶端<
/
title>
<script src
=
"http://libs.baidu.com/jquery/1.9.0/jquery.js"
><
/
script>
<
/
head>
<body>
<script
type
=
"text/javascript"
>
function go(k){
var requestTime
=
new Date().getTime();
$.post(
'/'
,{k:k,time:requestTime},function(){},
"json"
);
}
$(function(){
var i
=
null;
window.document.onkeydown
=
keyDown;
function keyDown(env){
env
=
(env) ? env : window.event;
if
(env.keyCode
=
=
'87'
){
go(
'w'
);
}
if
(env.keyCode
=
=
'83'
){
go(
's'
);
}
if
(env.keyCode
=
=
'65'
){
go(
'a'
);
}
if
(env.keyCode
=
=
'68'
){
go(
'd'
);
}
};
window.document.onkeyup
=
keyUp;
function keyUp(env){
env
=
(env) ? env : window.event;
if
(env.keyCode
=
=
'87'
){
go(
'stop'
);
}
if
(env.keyCode
=
=
'83'
){
go(
'stop'
);
}
if
(env.keyCode
=
=
'65'
){
go(
'stop'
);
}
if
(env.keyCode
=
=
'68'
){
go(
'stop'
);
}
}
$(
'.before'
).mousedown(function(){
i
=
setInterval(function(){
go(
'w'
);
},
100
);
});
$(
'.left'
).mousedown(function(){
i
=
setInterval(function(){
go(
'a'
);
},
100
);
});
$(
'.right'
).mousedown(function(){
i
=
setInterval(function(){
go(
'd'
);
},
100
);
});
$(
'.cabk'
).mousedown(function(){
i
=
setInterval(function(){
go(
's'
);
},
100
);
});
$(
'#main span'
).mouseup(function(){
clearInterval(i);
go(
'stop'
);
});
});
<
/
script>
<style
type
=
"text/css"
>
#main{width: 150px;height: 150px;background: #ccc;}
#main span{width: 50px;height: 50px;float: left;z-index: 999;}
#main span.on2{background: #ff00ff;}
<
/
style>
<div
id
=
"main"
>
<span><
/
span>
<span
class
=
"on2 before"
><
/
span>
<span><
/
span>
<span
class
=
"on2 left"
><
/
span>
<span><
/
span>
<span
class
=
"on2 right"
><
/
span>
<span><
/
span>
<span
class
=
"on2 cabk"
><
/
span>
<span><
/
span>
<
/
div>
<
/
body>
<
/
html>
|
在命令行裏嘗試運行這個程序以測試輸出:
1
|
$ sudo python robot.py
|
在本地瀏覽器中打開http://localhost:8000,或者其餘計算機使用瀏覽器中打開http://PI的IP:8000/
4、遠程控制小車
ionic環境搭建
安裝ionic
1
|
npm install
-
g cordova ionic
|
克隆小車客戶端代碼
1
|
git clone https:
/
/
github.com
/
jingzhaoyang
/
AutoClient.git
|
編譯代碼
1
2
3
4
5
6
|
#添加平臺
ionic platform add android
#編譯android的apk安裝包
ionic build android
#啓動android模擬器
ionic emulate android
|
在build目錄有編譯好的apk文件,能夠直接在Android平臺直接使用。而且經過終端控制小車。