first commit

This commit is contained in:
zhbaor 2021-10-30 23:20:58 +08:00
commit 71af632d64
20 changed files with 1964 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
__pycache__
.vscode
node_modules

275
caller.py Normal file
View file

@ -0,0 +1,275 @@
#!/usr/bin/env python3
'''
用RESTful API控制电机运动
'''
import subprocess
from flask import Flask
import RPi.GPIO as GPIO
from worker import *
from time import sleep
APP = Flask(__name__)
@APP.route('/carousel/clockwise')
def carousel_clockwise():
carousel.start(GPIO.HIGH)
return 'Done'
@APP.route('/carousel/counter-clockwise')
def carousel_counter_clockwise():
carousel.start(GPIO.LOW)
return 'Done'
@APP.route('/carousel/stop')
def carousel_stop():
carousel.stop()
return 'Done'
@APP.route('/carousel/presets/clockwise-90')
def carousel_preset_clockwise_90():
carousel.forward_degree(90)
return 'Done'
@APP.route('/carousel/presets/counter-clockwise-90')
def carousel_preset_counter_clockwise_90():
carousel.backward_degree(90)
return 'Done'
@APP.route('/elevator/down')
def elevator_down():
elevator.start(GPIO.HIGH)
return 'Done'
@APP.route('/elevator/up')
def elevator_up():
elevator.start(GPIO.LOW)
return 'Done'
@APP.route('/elevator/stop')
def elevator_stop():
elevator.stop()
return 'Done'
@APP.route('/elevator/presets/down-2-7')
def elevator_preset_down_2_7():
elevator.forward_degree(7200 * 2.7)
return 'Done'
@APP.route('/elevator/presets/up-2-7')
def elevator_preset_up_2_7():
elevator.backward_degree(7200 * 2.7)
return 'Done'
@APP.route('/conveyor/output')
def conveyor_output():
conveyor.start(GPIO.LOW)
return 'Done'
@APP.route('/conveyor/recycle')
def conveyor_recycle():
conveyor.start(GPIO.HIGH)
return 'Done'
@APP.route('/conveyor/stop')
def conveyor_stop():
conveyor.stop()
return 'Done'
@APP.route('/conveyor/presets/output')
def conveyor_preset_output():
conveyor.backward_degree(360 * 2)
return 'Done'
@APP.route('/conveyor/presets/recycle')
def conveyor_preset_recycle():
conveyor.forward_degree(360 * 2)
return 'Done'
@APP.route('/watchdog/open')
def watchdog_open():
watchdog.start(GPIO.HIGH)
return 'Done'
@APP.route('/watchdog/close')
def watchdog_close():
watchdog.start(GPIO.LOW)
return 'Done'
@APP.route('/watchdog/stop')
def watchdog_stop():
watchdog.stop()
return 'Done'
@APP.route('/watchdog/presets/open')
def watchdog_preset_open():
watchdog.backward_degree(360 * 2)
return 'Done'
@APP.route('/watchdog/presets/close')
def watchdog_preset_close():
watchdog.forward_degree(360 * 2)
return 'Done'
@APP.route('/recycleh/moveout')
def recycleh_moveout():
recycleh.start(GPIO.LOW)
return 'Done'
@APP.route('/recycleh/movein')
def recycleh_movein():
recycleh.start(GPIO.HIGH)
return 'Done'
@APP.route('/recycleh/stop')
def recycleh_stop():
recycleh.stop()
return 'Done'
@APP.route('/recycleh/presets/moveout')
def recycleh_preset_moveout():
recycleh.forward_degree(360 * 2)
return 'Done'
@APP.route('/recycleh/presets/movein')
def recycleh_preset_movein():
recycleh.backward_degree(360 * 2)
return 'Done'
@APP.route('/recyclev/rise')
def recyclev_rise():
recyclev.start(GPIO.HIGH)
return 'Done'
@APP.route('/recyclev/fall')
def recyclev_fall():
recyclev.start(GPIO.LOW)
return 'Done'
@APP.route('/recyclev/stop')
def recyclev_stop():
recyclev.stop()
return 'Done'
@APP.route('/recyclev/presets/rise')
def recyclev_preset_rise():
recyclev.backward_degree(360 * 2)
return 'Done'
@APP.route('/recyclev/presets/fall')
def recyclev_preset_fall():
recyclev.forward_degree(360 * 2)
return 'Done'
@APP.route('/bag-pusher/push')
def bag_pusher_push():
bag_pusher.start(GPIO.HIGH)
return 'Done'
@APP.route('/bag-pusher/loose')
def bag_pusher_loose():
bag_pusher.start(GPIO.LOW)
return 'Done'
@APP.route('/bag-pusher/stop')
def bag_pusher_stop():
bag_pusher.stop()
return 'Done'
@APP.route('/bag-pusher/presets/push')
def bag_pusher_preset_push():
bag_pusher.backward_degree(360)
return 'Done'
@APP.route('/bag-pusher/presets/loose')
def bag_pusher_preset_loose():
bag_pusher.forward_degree(360)
return 'Done'
@APP.route('/scissors-pusher/close')
def scissors_pusher_close():
scissors_pusher.start(GPIO.HIGH)
return 'Done'
@APP.route('/scissors-pusher/far')
def scissors_pusher_far():
scissors_pusher.start(GPIO.LOW)
return 'Done'
@APP.route('/scissors-pusher/stop')
def scissors_pusher_stop():
scissors_pusher.stop()
return 'Done'
@APP.route('/scissors-pusher/presets/close')
def scissors_pusher_preset_close():
scissors_pusher.backward_degree(360)
return 'Done'
@APP.route('/scissors-pusher/presets/far')
def scissors_pusher_preset_far():
scissors_pusher.forward_degree(360)
return 'Done'
@APP.route('/scissors/cut')
def scissors_cut():
scissors.degree(150)
return 'Done'
@APP.route('/scissors/loose')
def scissors_loose():
scissors.degree(10)
return 'Done'
@APP.route('/spigot/open')
def spigot_open():
spigot.enable()
return 'Done'
@APP.route('/spigot/close')
def spigot_close():
spigot.disable()
return 'Done'

520
controller.html Normal file
View file

@ -0,0 +1,520 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Bootstrap CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
crossorigin="anonymous"
/>
<!-- FontAwesone Icons -->
<link
href="node_modules/@fortawesome/fontawesome-free/css/all.min.css"
rel="stylesheet"
/>
<title>Controller</title>
</head>
<body>
<table class="table">
<thead>
<tr>
<th scope="col">名称</th>
<th scope="col">手动控制</th>
<th scope="col">预设</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" class="align-middle">旋转木马</th>
<td>
<button
id="carousel-clockwise"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-redo"></i> 顺时针旋转
</button>
<button
id="carousel-counter-clockwise"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-undo"></i> 逆时针旋转
</button>
<button
id="carousel-stop"
type="button"
class="btn btn-outline-danger"
>
<i class="fas fa-stop-circle"></i> 停止旋转
</button>
</td>
<td>
<button
id="carousel-preset-clockwise-90"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-redo"></i> 顺时针旋转90°
</button>
<button
id="carousel-preset-counter-clockwise-90"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-undo"></i> 逆时针旋转90°
</button>
</td>
</tr>
<tr>
<th scope="row" class="align-middle">观光电梯</th>
<td>
<button
id="elevator-down"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-arrow-down"></i> 下降
</button>
<button
id="elevator-up"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-arrow-up"></i> 上升
</button>
<button
id="elevator-stop"
type="button"
class="btn btn-outline-danger"
>
<i class="fas fa-stop-circle"></i> 停止
</button>
</td>
<td>
<button
id="elevator-preset-down-2-7"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-arrow-down"></i> 下降2.7CM
</button>
<button
id="elevator-preset-up-2-7"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-arrow-up"></i> 上升2.7CM
</button>
</td>
</tr>
<tr>
<th scope="row" class="align-middle">传送履带</th>
<td>
<button
id="conveyor-output"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-sign-out-alt"></i> 出药
</button>
<button
id="conveyor-recycle"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-recycle"></i> 回收
</button>
<button
id="conveyor-stop"
type="button"
class="btn btn-outline-danger"
>
<i class="fas fa-stop-circle"></i> 停止
</button>
</td>
<td>
<button
id="conveyor-preset-output"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-sign-out-alt"></i> 出药
</button>
<button
id="conveyor-preset-recycle"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-recycle"></i> 回收
</button>
</td>
</tr>
<tr>
<th scope="row" class="align-middle">看门狗</th>
<td>
<button
id="watchdog-open"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-expand-arrows-alt"></i> 打开
</button>
<button
id="watchdog-close"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-compress-arrows-alt"></i> 关闭
</button>
<button
id="watchdog-stop"
type="button"
class="btn btn-outline-danger"
>
<i class="fas fa-stop-circle"></i> 停止
</button>
</td>
<td>
<button
id="watchdog-preset-open"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-expand-arrows-alt"></i> 打开
</button>
<button
id="watchdog-preset-close"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-compress-arrows-alt"></i> 关闭
</button>
</td>
</tr>
<tr>
<th scope="row" class="align-middle">水平回收</th>
<td>
<button
id="recycleh-moveout"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-sign-out-alt"></i> 移出
</button>
<button
id="recycleh-movein"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-sign-in-alt"></i> 移入
</button>
<button
id="recycleh-stop"
type="button"
class="btn btn-outline-danger"
>
<i class="fas fa-stop-circle"></i> 停止
</button>
</td>
<td>
<button
id="recycleh-preset-moveout"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-sign-out-alt"></i> 移出
</button>
<button
id="recycleh-preset-movein"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-sign-in-alt"></i> 移入
</button>
</td>
</tr>
<tr>
<th scope="row" class="align-middle">垂直回收</th>
<td>
<button
id="recyclev-rise"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-upload"></i> 上升
</button>
<button
id="recyclev-fall"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-download"></i> 下降
</button>
<button
id="recyclev-stop"
type="button"
class="btn btn-outline-danger"
>
<i class="fas fa-stop-circle"></i> 停止
</button>
</td>
<td>
<button
id="recyclev-preset-rise"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-upload"></i> 上升
</button>
<button
id="recyclev-preset-fall"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-download"></i> 下降
</button>
</td>
</tr>
<tr>
<th scope="row" class="align-middle">推药袋</th>
<td>
<button
id="bag-pusher-push"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-compress-alt"></i> 推药袋
</button>
<button
id="bag-pusher-loose"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-expand-alt"></i> 松开
</button>
<button
id="bag-pusher-stop"
type="button"
class="btn btn-outline-danger"
>
<i class="fas fa-stop-circle"></i> 停止
</button>
</td>
<td>
<button
id="bag-pusher-preset-push"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-compress-alt"></i> 推药袋
</button>
<button
id="bag-pusher-preset-loose"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-expand-alt"></i> 松开
</button>
</td>
</tr>
<tr>
<th scope="row" class="align-middle">剪刀移动</th>
<td>
<button
id="scissors-pusher-close"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-compress-alt"></i> 靠近
</button>
<button
id="scissors-pusher-far"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-expand-alt"></i> 远离
</button>
<button
id="scissors-pusher-stop"
type="button"
class="btn btn-outline-danger"
>
<i class="fas fa-stop-circle"></i> 停止
</button>
</td>
<td>
<button
id="scissors-pusher-preset-close"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-compress-alt"></i> 靠近
</button>
<button
id="scissors-pusher-preset-far"
type="button"
class="btn btn-outline-success"
>
<i class="fas fa-expand-alt"></i> 远离
</button>
</td>
</tr>
<tr>
<th scope="row" class="align-middle">剪切药袋</th>
<td>
<button
id="scissors-cut"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-cut"></i> 剪切
</button>
<button
id="scissors-loose"
type="button"
class="btn btn-outline-danger"
>
<i class="fas fa-stop-circle"></i> 松开
</button>
</td>
<td></td>
</tr>
<tr>
<th scope="row" class="align-middle">水箱</th>
<td>
<button
id="spigot-open"
type="button"
class="btn btn-outline-primary"
>
<i class="fas fa-faucet"></i> 打开阀门
</button>
<button
id="spigot-close"
type="button"
class="btn btn-outline-danger"
>
<i class="fas fa-stop-circle"></i> 关闭阀门
</button>
</td>
<td></td>
</tr>
</tbody>
</table>
<!-- Optional JavaScript; choose one of the two! -->
<!-- Option 1: Bootstrap Bundle with Popper -->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
crossorigin="anonymous"
></script>
<!-- Option 2: Separate Popper and Bootstrap JS -->
<!--
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js" integrity="sha384-q2kxQ16AaE6UbzuKqyBE9/u/KzioAlnx2maXQHiDX9d4/zp8Ok3f+M7DPm+Ib6IU" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.min.js" integrity="sha384-pQQkAEnwaBkjpqZ8RU1fF1AKtTcHJwFl3pblpTlHXybJjHpMYo79HY3hIi4NKxyj" crossorigin="anonymous"></script>
-->
<!-- jQuery -->
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("#carousel-clockwise").click(() => $.get("/api/carousel/clockwise"));
$("#carousel-counter-clockwise").click(() =>
$.get("/api/carousel/counter-clockwise")
);
$("#carousel-stop").click(() => $.get("/api/carousel/stop"));
$("#carousel-preset-clockwise-90").click(() =>
$.get("/api/carousel/presets/clockwise-90")
);
$("#carousel-preset-counter-clockwise-90").click(() =>
$.get("/api/carousel/presets/counter-clockwise-90")
);
$("#elevator-down").click(() => $.get("/api/elevator/down"));
$("#elevator-up").click(() => $.get("/api/elevator/up"));
$("#elevator-stop").click(() => $.get("/api/elevator/stop"));
$("#elevator-preset-down-2-7").click(() =>
$.get("/api/elevator/presets/down-2-7")
);
$("#elevator-preset-up-2-7").click(() =>
$.get("/api/elevator/presets/up-2-7")
);
$("#conveyor-output").click(() => $.get("/api/conveyor/output"));
$("#conveyor-recycle").click(() => $.get("/api/conveyor/recycle"));
$("#conveyor-stop").click(() => $.get("/api/conveyor/stop"));
$("#conveyor-preset-output").click(() =>
$.get("/api/conveyor/presets/output")
);
$("#conveyor-preset-recycle").click(() =>
$.get("/api/conveyor/presets/recycle")
);
$("#watchdog-open").click(() => $.get("/api/watchdog/open"));
$("#watchdog-close").click(() => $.get("/api/watchdog/close"));
$("#watchdog-stop").click(() => $.get("/api/watchdog/stop"));
$("#watchdog-preset-open").click(() =>
$.get("/api/watchdog/presets/open")
);
$("#watchdog-preset-close").click(() =>
$.get("/api/watchdog/presets/close")
);
$("#recycleh-moveout").click(() => $.get("/api/recycleh/moveout"));
$("#recycleh-movein").click(() => $.get("/api/recycleh/movein"));
$("#recycleh-stop").click(() => $.get("/api/recycleh/stop"));
$("#recycleh-preset-moveout").click(() =>
$.get("/api/recycleh/presets/moveout")
);
$("#recycleh-preset-movein").click(() =>
$.get("/api/recycleh/presets/movein")
);
$("#recyclev-rise").click(() => $.get("/api/recyclev/rise"));
$("#recyclev-fall").click(() => $.get("/api/recyclev/fall"));
$("#recyclev-stop").click(() => $.get("/api/recyclev/stop"));
$("#recyclev-preset-rise").click(() =>
$.get("/api/recyclev/presets/rise")
);
$("#recyclev-preset-fall").click(() =>
$.get("/api/recyclev/presets/fall")
);
$("#bag-pusher-push").click(() => $.get("/api/bag-pusher/push"));
$("#bag-pusher-loose").click(() => $.get("/api/bag-pusher/loose"));
$("#bag-pusher-stop").click(() => $.get("/api/bag-pusher/stop"));
$("#bag-pusher-preset-push").click(() =>
$.get("/api/bag-pusher/presets/push")
);
$("#bag-pusher-preset-loose").click(() =>
$.get("/api/bag-pusher/presets/loose")
);
$("#scissors-pusher-close").click(() =>
$.get("/api/scissors-pusher/close")
);
$("#scissors-pusher-far").click(() =>
$.get("/api/scissors-pusher/far")
);
$("#scissors-pusher-stop").click(() =>
$.get("/api/scissors-pusher/stop")
);
$("#scissors-pusher-preset-close").click(() =>
$.get("/api/scissors-pusher/presets/close")
);
$("#scissors-pusher-preset-far").click(() =>
$.get("/api/scissors-pusher/presets/far")
);
$("#scissors-cut").click(() => $.get("/api/scissors/cut"));
$("#scissors-loose").click(() => $.get("/api/scissors/loose"));
$("#spigot-open").click(() => $.get("/api/spigot/open"));
$("#spigot-close").click(() => $.get("/api/spigot/close"));
});
</script>
</body>
</html>

114
demo.html Normal file
View file

@ -0,0 +1,114 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<style type="text/css">
body {
background-image: url("images/homepage.png");
overflow: hidden;
height: 100%;
}
#clock {
position: absolute;
top: 40px;
left: 40px;
font-family: "Noto Sans CJK SC";
font-weight: 700;
font-size: 100pt;
}
#calendar {
position: absolute;
top: 220px;
left: 42px;
font-family: "Noto Sans CJK SC";
font-weight: 700;
font-size: 38pt;
}
#weather {
position: absolute;
top: 100px;
left: 630px;
font-family: "Noto Sans CJK SC";
font-weight: 700;
font-size: 32pt;
}
#temperature {
position: absolute;
top: 150px;
left: 630px;
font-family: "Noto Sans CJK SC";
font-weight: 700;
font-size: 70pt;
}
#settings {
position: absolute;
top: 300px;
left: 0px;
width: 512px;
height: 300px;
}
#view {
position: absolute;
top: 300px;
left: 512px;
width: 512px;
height: 300px;
}
</style>
<title>PiApp</title>
</head>
<body>
<div id="clock">正在加载</div>
<div id="calendar">正在加载</div>
<div id="weather">正在加载</div>
<div id="temperature">正在加载</div>
<a href="select.html" id="settings"></a>
<a href="view.html" id="view"></a>
<script src="node_modules/moment/min/moment-with-locales.min.js"></script>
<script>
moment.locale("zh-cn");
displayTime();
function displayTime() {
document.getElementById("clock").textContent = moment().format("LTS");
}
document.getElementById("calendar").textContent = moment().format(
"LL dddd"
);
String.prototype.removeBlankLines = function () {
return this.replace(/(\n[\s\t]*\r*\n)/g, "\n").replace(
/^[\n\r\n\t]*|[\n\r\n\t]*$/g,
""
);
};
setInterval(displayTime, 1000);
var Http = new XMLHttpRequest();
var url =
"https://devapi.qweather.com/v7/weather/3d?location=101220109&key=cb36659932e04262904836976ac4e47a";
Http.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var weatherJson = Http.responseText;
var weatherObj = JSON.parse(weatherJson);
document.getElementById("weather").textContent =
weatherObj.daily[0].textDay +
" " +
weatherObj.daily[0].windDirDay +
weatherObj.daily[0].windScaleDay +
"级";
document.getElementById("temperature").textContent =
weatherObj.daily[0].tempMin +
"-" +
weatherObj.daily[0].tempMax +
"℃";
}
};
Http.open("GET", url);
Http.send();
</script>
</body>
</html>

BIN
images/homepage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

BIN
images/select-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
images/settings-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
images/settings-item.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
images/settings-new.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

87
index.html Normal file
View file

@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Bootstrap CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
crossorigin="anonymous"
/>
<!-- FontAwesone Icons -->
<link
href="node_modules/@fortawesome/fontawesome-free/css/all.min.css"
rel="stylesheet"
/>
<style>
@import url("https://fonts.googleapis.com/css2?family=Ma+Shan+Zheng&display=swap");
.mytitle {
font-family: "Ma Shan Zheng", cursive;
font-size: 48px;
text-align: center;
padding-top: 20px;
}
.root {
padding-top: 40px;
}
</style>
<title>遥控器</title>
</head>
<body>
<div class="d-grid gap-4 col-10 col-sm-8 col-lg-6 mx-auto">
<h1 class="mytitle">转盘遥控器</h1>
<button class="btn btn-primary btn-lg" type="button" id="clockwise">
<i class="fas fa-redo"></i> 顺时针转动
</button>
<button
class="btn btn-primary btn-lg"
type="button"
id="counter-clockwise"
>
<i class="fas fa-undo"></i> 逆时针转动
</button>
<button class="btn btn-danger btn-lg" type="button" id="stop">
<i class="fas fa-stop-circle"></i> 停止转动
</button>
</div>
<!-- jQuery -->
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<!-- Optional JavaScript; choose one of the two! -->
<!-- Option 1: Bootstrap Bundle with Popper -->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
crossorigin="anonymous"
></script>
<!-- Option 2: Separate Popper and Bootstrap JS -->
<!--
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js" integrity="sha384-q2kxQ16AaE6UbzuKqyBE9/u/KzioAlnx2maXQHiDX9d4/zp8Ok3f+M7DPm+Ib6IU" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.min.js" integrity="sha384-pQQkAEnwaBkjpqZ8RU1fF1AKtTcHJwFl3pblpTlHXybJjHpMYo79HY3hIi4NKxyj" crossorigin="anonymous"></script>
-->
<script type="text/javascript">
$(function () {
$("#clockwise").click(() => {
$.get("/api/carousel/clockwise");
});
$("#counter-clockwise").click(() => {
$.get("/api/carousel/counter-clockwise");
});
$("#stop").click(() => {
$.get("/api/carousel/stop");
});
});
</script>
</body>
</html>

2
launch_uwsgi.sh Executable file
View file

@ -0,0 +1,2 @@
#!/bin/bash
uwsgi -s /tmp/piapp.sock --chmod-socket=666 --manage-script-name --mount /api=caller:APP --plugin python3

272
old_controller.html Normal file
View file

@ -0,0 +1,272 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<!-- Bootstrap CSS -->
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="node_modules/bootstrap-slider/dist/css/bootstrap-slider.min.css"
/>
<style>
.label {
font-size: 22pt;
}
#demo-start {
font-size: 230pt;
}
</style>
<title>遥控器</title>
</head>
<body>
<!-- <button id="demo-start" type=" button" class="btn btn-success mt-5 mb-5">START</button> -->
<div class="label mt-5">
旋转木马:
<button id="carousel-clockwise" type="button" class="btn btn-primary">
顺时针旋转90度
</button>
<button
id="carousel-counter-clockwise"
type="button"
class="btn btn-primary"
>
逆时针旋转90度
</button>
</div>
<div class="label">
观光电梯:
<button id="elevator-up" type=" button" class="btn btn-primary">
上升2.7CM
</button>
<button id="elevator-down" type="button" class="btn btn-primary">
下降2.7CM
</button>
</div>
<div class="label">
滑梯:
<button id="slide-degree-rise" type=" button" class="btn btn-primary">
角度上升
</button>
<button id="slide-degree-fall" type="button" class="btn btn-primary">
角度下降
</button>
<button id="slide-width-increase" type=" button" class="btn btn-primary">
宽度增加
</button>
<button id="slide-width-decrease" type="button" class="btn btn-primary">
宽度减少
</button>
</div>
<div class="label">
回收装置:
<button id="recycleh-in" type=" button" class="btn btn-primary">
移入药箱
</button>
<button id="recycleh-out" type="button" class="btn btn-primary">
移出药箱
</button>
<button id="recyclev-up" type=" button" class="btn btn-primary">
竖直上升
</button>
<button id="recyclev-down" type="button" class="btn btn-primary">
竖直下降
</button>
</div>
<div class="label">
震动马达:
<button id="vibrator-enable" type="button" class="btn btn-primary">
开始震动
</button>
<button id="vibrator-disable" type="button" class="btn btn-primary">
停止震动
</button>
</div>
<div class="label">
机械爪 <input id="servo"></input>
<button id="set-servo"" type="button" class="btn btn-primary">
设置
</button>
</div>
<div class="label">
继电器
<button id="relay-enable" type="button" class="btn btn-primary">
</button>
<button id="relay-disable" type="button" class="btn btn-primary">
</button>
</div>
<div class="label">
端口测试
<input id="test-port"></input>
<button id="test-port-high" type="button" class="btn btn-primary">
</button>
<button id="test-port-low" type="button" class="btn btn-primary">
</button>
</div>
<div class="label">
爪子
<button id="paw-close" type="button" class="btn btn-primary">
靠近
</button>
<button id="paw-far" type="button" class="btn btn-primary">
远离
</button>
</div>
<div class="label">
药袋
<button id="bag-close" type="button" class="btn btn-primary">
靠近
</button>
<button id="bag-far" type="button" class="btn btn-primary">
远离
</button>
</div>
<div class="label">
上面的传感器
<span id="sensor-up-data">未知</span>
<button id="sensor-up" type="button" class="btn btn-primary">
获取
</button>
</div>
<div class="label">
其它:
<button id="init" type="button" class="btn btn-success">初始化</button>
<button id="cleanup" type="button" class="btn btn-danger">停止</button>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<!-- <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"></script> -->
<script src="https://cdn.staticfile.org/jquery/3.5.1/jquery.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
crossorigin="anonymous"
></script>
<script
src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"
integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV"
crossorigin="anonymous"
></script>
<script src="node_modules/bootstrap-slider/dist/bootstrap-slider.min.js"></script>
<script>
$(document).ready(function () {
$.ajax({ url: "api/init" });
$("#carousel-clockwise").click(function () {
$.ajax({ url: "api/carousel/clockwise" });
});
$("#carousel-counter-clockwise").click(function () {
$.ajax({ url: "api/carousel/counter-clockwise" });
});
$("#elevator-up").click(function () {
$.ajax({ url: "api/elevator/up" });
});
$("#elevator-down").click(function () {
$.ajax({ url: "api/elevator/down" });
});
$("#slide-degree-rise").click(function () {
$.ajax({ url: "api/slide/degree/rise" });
});
$("#slide-degree-fall").click(function () {
$.ajax({ url: "api/slide/degree/fall" });
});
$("#slide-width-increase").click(function () {
$.ajax({ url: "api/slide/width/increase" });
});
$("#slide-width-decrease").click(function () {
$.ajax({ url: "api/slide/width/decrease" });
});
$("#recycleh-in").click(function () {
$.ajax({ url: "api/recycle/horizonal/in" });
});
$("#recycleh-out").click(function () {
$.ajax({ url: "api/recycle/horizonal/out" });
});
$("#recyclev-up").click(function () {
$.ajax({ url: "api/recycle/vertical/up" });
});
$("#recyclev-down").click(function () {
$.ajax({ url: "api/recycle/vertical/down" });
});
$("#vibrator-enable").click(function () {
$.ajax({ url: "api/vibrator/enable" });
});
$("#vibrator-disable").click(function () {
$.ajax({ url: "api/vibrator/disable" });
});
$("#relay-enable").click(function () {
$.ajax({ url: "api/relay/enable" });
});
$("#relay-disable").click(function () {
$.ajax({ url: "api/relay/disable" });
});
$("#set-servo").click(function () {
$.ajax({
url:
"api/servo/" + document.getElementById("servo").value,
});
});
$("#paw-close").click(function () {
$.ajax({ url: "api/paw/close" });
});
$("#paw-far").click(function () {
$.ajax({ url: "api/paw/far" });
});
$("#bag-close").click(function () {
$.ajax({ url: "api/bag/close" });
});
$("#bag-far").click(function () {
$.ajax({ url: "api/bag/far" });
});
$("#sensor-up").click(function(){
$.ajax({ url: "api/sensor/up",success: function(result) {
document.getElementById("sensor-up-data").innerText = result;
} });
});
$("#init").click(function () {
$.ajax({ url: "api/init" });
});
$("#cleanup").click(function () {
$.ajax({ url: "api/cleanup" });
});
$("#demo-start").click(function () {
$.ajax({ url: "api/demo" });
});
$("#test-port-high").click(function () {
$.ajax({
url:
"api/sethigh/" + document.getElementById("test-port").value,
});
});
$("#test-port-low").click(function () {
$.ajax({
url:
"api/setlow/" + document.getElementById("test-port").value,
});
});
});
</script>
</body>
</html>

106
old_worker.py Normal file
View file

@ -0,0 +1,106 @@
'''
worker模块包含两个类Motor和port_enaMotor
前者就是普通的马达后者多了一个启用的端口
'''
from time import sleep
import RPi.GPIO as GPIO
class Motor():
'''
步进电机
'''
def __init__(self, port_dir, port_pul, degree_per_cycle, steps):
self.port_dir = port_dir
self.port_pul = port_pul
self.degree_per_cycle = degree_per_cycle
self.steps = steps
GPIO.setup(port_dir, GPIO.OUT, initial=GPIO.HIGH)
GPIO.setup(port_pul, GPIO.OUT, initial=GPIO.HIGH)
def turn_degree(self, degree, direction):
'''
转动角度
'''
GPIO.output(self.port_dir, direction)
cycle = int(degree / self.degree_per_cycle * self.steps)
for _ in range(cycle):
GPIO.output(self.port_pul, GPIO.LOW)
sleep(0.0001)
GPIO.output(self.port_pul, GPIO.HIGH)
sleep(0.0001)
class ENAMotor(Motor):
'''
带有port_ena信号的步进电机
'''
def __init__(self, port_dir, port_pul, degree_per_cycle, steps, port_ena):
super(ENAMotor, self).__init__(
port_dir, port_pul, degree_per_cycle, steps)
self.port_ena = port_ena
GPIO.setup(port_ena, GPIO.OUT, initial=GPIO.HIGH)
def enable(self):
'''
启用电机
'''
GPIO.output(self.port_ena, GPIO.LOW)
def disable(self):
'''
停用电机
'''
GPIO.output(self.port_ena, GPIO.HIGH)
class VibratorMotor:
'''震动马达'''
def __init__(self, port):
'''
初始化
'''
self.port = port
GPIO.setup(port, GPIO.OUT, initial=GPIO.LOW)
def enable(self):
'''开始震动'''
GPIO.output(self.port, GPIO.HIGH)
def disable(self):
'''停止震动'''
GPIO.output(self.port, GPIO.LOW)
class Servo:
'''舵机'''
def __init__(self, port):
'''初始化'''
self.port = port
GPIO.setup(port, GPIO.OUT, initial=GPIO.LOW)
def degree(self, degree):
'''转到某个角度'''
dc = (degree / 180 * 2 + 0.5) * 5
p = GPIO.PWM(self.port, 50)
p.start(dc)
sleep(1)
p.stop()
class Relay:
"继电器"
def __init__(self, port):
self.port = port
GPIO.setup(port, GPIO.OUT, initial=GPIO.LOW)
def enable(self):
GPIO.output(self.port, GPIO.HIGH)
def disable(self):
GPIO.output(self.port, GPIO.LOW)

21
package-lock.json generated Normal file
View file

@ -0,0 +1,21 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"@fortawesome/fontawesome-free": {
"version": "5.15.1",
"resolved": "https://registry.npm.taobao.org/@fortawesome/fontawesome-free/download/@fortawesome/fontawesome-free-5.15.1.tgz",
"integrity": "sha1-zP723b5Z+P6PaUeD4dPriJAtxes="
},
"jquery": {
"version": "3.5.1",
"resolved": "https://registry.npm.taobao.org/jquery/download/jquery-3.5.1.tgz",
"integrity": "sha1-17TQjhv9uGrS8aPQOeoXMEcXq7U="
},
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npm.taobao.org/moment/download/moment-2.29.1.tgz?cache=0&sync_timestamp=1601983320283&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmoment%2Fdownload%2Fmoment-2.29.1.tgz",
"integrity": "sha1-sr52n6MZQL6e7qZGnAdeNQBvo9M="
}
}
}

7
package.json Normal file
View file

@ -0,0 +1,7 @@
{
"dependencies": {
"@fortawesome/fontawesome-free": "^5.15.1",
"jquery": "^3.5.1",
"moment": "^2.29.1"
}
}

65
scheduler.py Normal file
View file

@ -0,0 +1,65 @@
#!/usr/bin/env python3
'''
电机调度器
'''
from RPi import GPIO
from worker import Motor, ENAMotor
from time import sleep
GPIO.setmode(GPIO.BCM)
# carousel = ENAMotor(20, 21, 1.8, 32, 26)
# elevator = Motor(19, 16, 18, 16)
# slide_degree = ENAMotor(12, 13, 1.8, 32, 6)
# slide_width = Motor(0, 5, 0.18, 16)
# recycleh = ENAMotor(7, 1, 1.8, 32, 8)
# recyclev = ENAMotor(9, 11, 1.8, 32, 10)
# '''旋转木马可能卡住,只转90度可能没有问题。'''
# '''旋转木马逆时针旋转90度'''
# carousel.turn_degree(90, GPIO.LOW)
# # '''旋转木马顺时针旋转90度'''
# # carousel.turn_degree(90, GPIO.HIGH)
# '''电梯:药片几乎下不去,下去之后下落速度特别快,直接弹飞了。'''
# '''电梯下降2.7CM'''
# elevator.turn_degree(7200 * 2.8, GPIO.HIGH)
# '''sleep'''
# sleep(1)
# '''电梯上升2.7CM'''
# elevator.turn_degree(7200 * 2.8, GPIO.LOW)
# '''宽度现在不能调,等电阻来了之后再弄。'''
# # slide_width.turn_degree(360, GPIO.HIGH)
# # sleep(1)
# # slide_width.turn_degree(360, GPIO.LOW)
# '''滑梯角度抬升'''
# slide_degree.turn_degree(360 * 2, GPIO.HIGH)
# sleep(2)
# # '''不考虑回收'''
# # slide_degree.turn_degree(360 * 2, GPIO.LOW)
# '''考虑回收'''
# slide_degree.turn_degree(360 * 4, GPIO.LOW)
# sleep(2)
# slide_degree.turn_degree(360 * 2, GPIO.HIGH)
# '''回收部分:废了'''
# # '''回收上升'''
# # recyclev.turn_degree(360 * 42, GPIO.HIGH)
# # '''回收伸入'''
# # recycleh.turn_degree(360 * 4.5, GPIO.HIGH)
# # sleep(2)
# # recycleh.turn_degree(360 * 4.5, GPIO.LOW)
# # '''回收下降'''
# # recyclev.turn_degree(360 * 42, GPIO.LOW)
GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.wait_for_edge(4, GPIO.FALLING)
print("catched falling pill.")
GPIO.cleanup()

54
select.html Normal file
View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<style type="text/css">
body {
background-image: url("images/select-bg.png");
overflow: hidden;
height: 100%;
}
#a {
position: absolute;
top: 0px;
left: 0px;
width: 512px;
height: 300px;
}
#b {
position: absolute;
top: 0px;
left: 512px;
width: 512px;
height: 300px;
}
#c {
position: absolute;
top: 300px;
left: 0px;
width: 512px;
height: 300px;
}
#d {
position: absolute;
top: 300px;
left: 512px;
width: 512px;
height: 300px;
}
</style>
<title>PiApp</title>
</head>
<body>
<a href="settings.html" id="a"></a>
<a href="settings.html" id="b"></a>
<a href="settings.html" id="c"></a>
<a href="settings.html" id="d"></a>
</body>
</html>

156
settings.html Normal file
View file

@ -0,0 +1,156 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<style type="text/css">
body {
background-image: url("images/settings-bg.png");
overflow: hidden;
height: 100%;
}
#new {
position: absolute;
top: 230px;
left: 160px;
}
#item1 {
position: absolute;
top: 420px;
left: 160px;
}
#item2 {
position: absolute;
top: 490px;
left: 160px;
}
#h1 {
position: absolute;
top: 282px;
left: 202px;
font-family: "Noto Sans Mono CJK SC";
font-weight: 700;
font-size: 36pt;
}
#h2 {
position: absolute;
top: 407px;
left: 202px;
font-family: "Noto Sans Mono CJK SC";
font-weight: 700;
font-size: 36pt;
}
#h3 {
position: absolute;
top: 477px;
left: 202px;
font-family: "Noto Sans Mono CJK SC";
font-weight: 700;
font-size: 36pt;
}
#s1 {
position: absolute;
top: 280px;
left: 267px;
font-family: "Noto Sans Mono CJK SC";
font-weight: 700;
font-size: 36pt;
}
#s2 {
position: absolute;
top: 405px;
left: 267px;
font-family: "Noto Sans Mono CJK SC";
font-weight: 700;
font-size: 36pt;
}
#s3 {
position: absolute;
top: 475px;
left: 267px;
font-family: "Noto Sans Mono CJK SC";
font-weight: 700;
font-size: 36pt;
}
#m1 {
position: absolute;
top: 282px;
left: 307px;
font-family: "Noto Sans Mono CJK SC";
font-weight: 700;
font-size: 36pt;
}
#m2 {
position: absolute;
top: 407px;
left: 307px;
font-family: "Noto Sans Mono CJK SC";
font-weight: 700;
font-size: 36pt;
}
#m3 {
position: absolute;
top: 477px;
left: 307px;
font-family: "Noto Sans Mono CJK SC";
font-weight: 700;
font-size: 36pt;
}
#p1 {
position: absolute;
top: 282px;
left: 427px;
font-family: "Noto Sans Mono CJK SC";
font-weight: 700;
font-size: 36pt;
}
#p2 {
position: absolute;
top: 407px;
left: 427px;
font-family: "Noto Sans Mono CJK SC";
font-weight: 700;
font-size: 36pt;
}
#p3 {
position: absolute;
top: 477px;
left: 427px;
font-family: "Noto Sans Mono CJK SC";
font-weight: 700;
font-size: 36pt;
}
#back {
position: absolute;
top: 300px;
left: 600px;
width: 424px;
height: 300px;
}
</style>
<title>PiApp</title>
</head>
<body>
<img src="images/settings-new.png" id="new" />
<img src="images/settings-item.png" id="item1" />
<img src="images/settings-item.png" id="item2" />
<div id="h1">07</div>
<div id="h2">12</div>
<div id="h3">17</div>
<div id="m1">00</div>
<div id="m2">30</div>
<div id="m3">00</div>
<div id="s1">:</div>
<div id="s2">:</div>
<div id="s3">:</div>
<div id="p1">3</div>
<div id="p2">3</div>
<div id="p3">3</div>
<a href="demo.html" id="back"></a>
</body>
</html>

29
test.http Normal file
View file

@ -0,0 +1,29 @@
### 初始化
GET http://127.0.0.1:5000/init
### 旋转木马顺时针旋转90度
GET http://127.0.0.1:5000/carousel/clockwise
### 旋转木马逆时针旋转90度
GET http://127.0.0.1:5000/carousel/counter-clockwise
### 观光电梯上升1CM
GET http://127.0.0.1:5000/elevator/up
### 观光电梯下降1CM
GET http://127.0.0.1:5000/elevator/down
### 滑梯角度抬升
GET http://127.0.0.1:5000/slide/degree/rise
### 滑梯角度下降
GET http://127.0.0.1:5000/slide/degree/fall
### 滑梯宽度增加
GET http://127.0.0.1:5000/slide/width/increase
### 滑梯宽度减少
GET http://127.0.0.1:5000/slide/width/decrease
### 停
GET http://127.0.0.1:5000/cleanup

253
worker.py Normal file
View file

@ -0,0 +1,253 @@
'''
经过重构后的船新代码
使用GPIO.PWM来生成PWM波
可以指定固定角度或时间也可以手动控制
'''
from time import sleep
import RPi.GPIO as GPIO
'''
端口的定义
'''
CAROUSEL_ENA = 19
CAROUSEL_DIR = 26
CAROUSEL_PUL = 21
ELEVATOR_DIR = 16
ELEVATOR_PUL = 20
CONVEYOR_ENA = 12
CONVEYOR_DIR = 6
CONVEYOR_PUL = 13
WATCHDOG_DIR = 9
WATCHDOG_PUL = 5
HORIZONAL_ENA = 14
HORIZONAL_DIR = 18
HORIZONAL_PUL = 15
VERTICAL_ENA = 11
VERTICAL_DIR = 7
VERTICAL_PUL = 1
BAG_PUSHER_ENA = 23
BAG_PUSHER_DIR = 22
BAG_PUSHER_PUL = 24
SCISSORS_PUSHER_ENA = 0
SCISSORS_PUSHER_DIR = 3
SCISSORS_PUSHER_PUL = 8
SPIGOT = 17
SCISSORS = 25
class Motor():
'''
小板控制的电机只有DIR和PUL引脚用于控制方向和速度
'''
def __init__(self, DIR, PUL, step_angle, subdivision, degree_per_second):
'''
初始化指定引脚步进角和细分
'''
self.__DIR = DIR
self.__PUL = PUL
self.__degree_per_cycle = step_angle / subdivision
self.__degree_per_second = degree_per_second
self.__half_cycle = self.__degree_per_cycle / self.__degree_per_second / 2
self.__frequency = degree_per_second / self.__degree_per_cycle
GPIO.setup(DIR, GPIO.OUT)
GPIO.setup(PUL, GPIO.OUT)
self.__pwm = GPIO.PWM(PUL, self.__frequency)
def __set_direction(self, output_DIR):
'''
设置转动的角度
'''
GPIO.output(self.__DIR, output_DIR)
def __pwm_start(self):
'''
开始产生PWM波
'''
self.__pwm.ChangeFrequency(self.__frequency)
self.__pwm.start(50)
def stop(self):
'''
停止产生PWM波
'''
self.__pwm.stop()
def start(self, direction):
'''
开始转动
'''
self.__set_direction(direction)
self.__pwm_start()
def __turn_time(self, second):
'''
转动指定时间
'''
self.__pwm_start()
sleep(second)
self.stop()
def __turn_degree(self, degree):
'''
转动指定角度
'''
cycle = int(degree / self.__degree_per_cycle)
for _ in range(cycle):
GPIO.output(self.__PUL, GPIO.LOW)
sleep(self.__half_cycle)
GPIO.output(self.__PUL, GPIO.HIGH)
sleep(self.__half_cycle)
def forward_time(self, second):
'''
设置时间正转
'''
self.__set_direction(GPIO.HIGH)
self.__turn_time(second)
def backward_time(self, second):
'''
设置时间反转
'''
self.__set_direction(GPIO.LOW)
self.__turn_time(second)
def forward_degree(self, degree):
'''
设置角度正转
'''
self.__set_direction(GPIO.HIGH)
self.__turn_degree(degree)
def backward_degree(self, degree):
'''
设置角度反转
'''
self.__set_direction(GPIO.LOW)
self.__turn_degree(degree)
class ENAMotor(Motor):
'''
带有ENA信号的步进电机
'''
def __init__(self, ENA, DIR, PUL, step_angle, subdivision, degree_per_second):
super(ENAMotor, self).__init__(DIR, PUL, step_angle,
subdivision, degree_per_second)
self.__ena = ENA
GPIO.setup(ENA, GPIO.OUT)
def enable(self):
'''
启用电机
'''
GPIO.output(self.__ena, GPIO.HIGH)
def disable(self):
'''
停用电机
'''
GPIO.output(self.__ena, GPIO.LOW)
def start(self, direction):
'''
开始转动
'''
self.enable()
super(ENAMotor, self).start(direction)
def stop(self):
'''
停止转动
'''
super(ENAMotor, self).stop()
self.disable()
def forward_degree(self, degree):
'''
设置角度正转
'''
self.enable()
super(ENAMotor, self).forward_degree(degree)
self.disable()
def backward_degree(self, degree):
'''
设置角度反转
'''
self.enable()
super(ENAMotor, self).backward_degree(degree)
self.disable()
def forward_time(self, second):
'''
设置时间正转
'''
self.enable()
super(ENAMotor, self).forward_time(second)
self.disable()
def backward_time(self, second):
'''
设置时间反转
'''
self.enable()
super(ENAMotor, self).backward_time(second)
self.disable()
class Servo:
'''
舵机
'''
def __init__(self, port):
'''初始化'''
self.port = port
GPIO.setup(port, GPIO.OUT)
self.__pwm = GPIO.PWM(self.port, 50)
def degree(self, degree):
'''转到某个角度'''
dc = (degree / 180 * 2 + 0.5) * 5
self.__pwm.ChangeFrequency(50)
self.__pwm.start(dc)
sleep(1)
self.__pwm.stop()
class Relay:
'''
继电器
'''
def __init__(self, port):
self.port = port
GPIO.setup(port, GPIO.OUT)
def enable(self):
GPIO.output(self.port, GPIO.HIGH)
def disable(self):
GPIO.output(self.port, GPIO.LOW)
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
carousel = ENAMotor(CAROUSEL_ENA, CAROUSEL_DIR, CAROUSEL_PUL, 1.8, 32, 30)
elevator = Motor(ELEVATOR_DIR, ELEVATOR_PUL, 18, 16, 1800)
conveyor = ENAMotor(CONVEYOR_ENA, CONVEYOR_DIR, CONVEYOR_PUL, 1.8, 32, 30)
watchdog = Motor(WATCHDOG_DIR, WATCHDOG_PUL, 18, 16, 3600)
recycleh = ENAMotor(
HORIZONAL_ENA, HORIZONAL_DIR, HORIZONAL_PUL, 1.8, 32, 360)
recyclev = ENAMotor(
VERTICAL_ENA, VERTICAL_DIR, VERTICAL_PUL, 1.8, 32, 360)
bag_pusher = ENAMotor(BAG_PUSHER_ENA, BAG_PUSHER_DIR,
BAG_PUSHER_PUL, 1.8, 32, 360)
scissors_pusher = ENAMotor(
SCISSORS_PUSHER_ENA, SCISSORS_PUSHER_DIR, SCISSORS_PUSHER_PUL, 1.8, 32, 360)
spigot = Relay(SPIGOT)
spigot.disable()
scissors = Servo(SCISSORS)