0%

[IOT] D1 mini智能小車

透過D1 mini的wifi功能或搭配紅外線遠端控制小車移動。

wifi功能實作

使用ESP8266WebServer模組,透過簡單的Python程式提供網站功能。

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
import network
import time
import ubinascii
import ESP8266WebServer
from machine import Pin


a1b = Pin(15, Pin.OUT) # A控制右輪
a1a = Pin(13, Pin.OUT)
b2a = Pin(12, Pin.OUT) # B控制左輪
b1a = Pin(14, Pin.OUT)

def handleAction(socket, args):
print(args)
if 'action' in args:
if args['action'] == 'stop':
stop()
elif args['action'] == 'forward':
forward()
elif args['action'] == 'backward':
backward()
elif args['action'] == 'turnLeft':
turnLeft()
elif args['action'] == 'turnRight':
turnRight()
ESP8266WebServer.ok(socket, '200', 'OK')
else:
ESP8266WebServer.err(socket, '400', 'ERR')

def stop():
a1a.value(0)
a1b.value(0)
b1a.value(0)
b2a.value(0)

def forward():
a1b.value(1)
a1a.value(0)
b2a.value(1)
b1a.value(0)

def backward():
a1b.value(0)
a1a.value(1)
b2a.value(0)
b1a.value(1)

def turnLeft():
a1b.value(1)
a1a.value(0)
b2a.value(0)
b1a.value(0)

def turnRight():
a1b.value(0)
a1a.value(0)
b2a.value(1)
b1a.value(0)

print('初始化', ubinascii.hexlify(network.WLAN().config('mac'), ':').decode())

sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect('無線網路名稱', '密碼')
print('連線中...')
while not sta_if.isconnected():
pass

ESP8266WebServer.begin(80)
ESP8266WebServer.onPath('/cmd', handleAction)
ESP8266WebServer.setDocPath("/car")
print('伺服器位置:', sta_if.ifconfig()[0])

stop()
# 測試用
# while True:
# forward()
# time.sleep(1)
# backward()
# time.sleep(1)
# turnLeft()
# time.sleep(1)
# turnRight()
# time.sleep(1)

while True:
ESP8266WebServer.handleClient()

遠端遙控網頁,使用ajax技術,讓使用者點選連結後留在原頁面繼續操作。

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
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>智能小車</title>
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
document.getElementById('status').innerHTML = xhttp.responseText;
}
};

function testGet(cmd) {
document.getElementById('status').innerHTML = '送出中...';
xhttp.open('GET', '/cmd?action=' + cmd, true);
xhttp.send();
}
</script>
</head>
<body>
<table>
<tr>
<td/>
<td><a href="#" onclick='testGet("forward")'>^</a></td>
<td/>
</tr>
<tr>
<td><a href="#" onclick='testGet("turnLeft")'><</a></td>
<td><a href="#" onclick='testGet("stop")'>x</a></td>
<td><a href="#" onclick='testGet("turnRight")'>></a></td>
<tr>
<td/>
<td><a href="#" onclick='testGet("backward")'>v</a></td>
<td/>
</tr>
</table>
<p id='status'></p>
</body>
</html>

紅外線實作

使用ir_rx紅外線模組。

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
import network
import time
import ubinascii
from machine import Pin
from ir_rx.nec import NEC_8


a1b = Pin(15, Pin.OUT) # A控制右輪
a1a = Pin(13, Pin.OUT)
b2a = Pin(12, Pin.OUT) # B控制左輪
b1a = Pin(14, Pin.OUT)

def callback(data, addr, ctrl):
if data < 0: # NEC protocol sends repeat codes.
print('Repeat code.')
return
print('Data {:02x} Addr {:04x}'.format(data, addr))
if data == 0x15:
stop()
elif data == 0x40:
forward()
elif data == 0x19:
backward()
elif data == 0x07:
turnLeft()
elif data == 0x09:
turnRight()

def stop():
a1a.value(0)
a1b.value(0)
b1a.value(0)
b2a.value(0)

def forward():
a1b.value(1)
a1a.value(0)
b2a.value(1)
b1a.value(0)

def backward():
a1b.value(0)
a1a.value(1)
b2a.value(0)
b1a.value(1)

def turnLeft():
a1b.value(1)
a1a.value(0)
b2a.value(0)
b1a.value(0)

def turnRight():
a1b.value(0)
a1a.value(0)
b2a.value(1)
b1a.value(0)

stop()
# 測試用
# while True:
# forward()
# time.sleep(1)
# backward()
# time.sleep(1)
# turnLeft()
# time.sleep(1)
# turnRight()
# time.sleep(1)

ir = NEC_8(Pin(2, Pin.IN), callback)