commit 71af632d64d823fc62d8b96c0e5b3312fb3c9918 Author: Zhao Zuohong <1040110848@qq.com> Date: Sat Oct 30 23:20:58 2021 +0800 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..64d17fb --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +__pycache__ +.vscode +node_modules \ No newline at end of file diff --git a/caller.py b/caller.py new file mode 100644 index 0000000..7e4e9dd --- /dev/null +++ b/caller.py @@ -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' diff --git a/controller.html b/controller.html new file mode 100644 index 0000000..ff93317 --- /dev/null +++ b/controller.html @@ -0,0 +1,520 @@ + + + + + + + + + + + + + + Controller + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称手动控制预设
旋转木马 + + + + + + +
观光电梯 + + + + + + +
传送履带 + + + + + + +
看门狗 + + + + + + +
水平回收 + + + + + + +
垂直回收 + + + + + + +
推药袋 + + + + + + +
剪刀移动 + + + + + + +
剪切药袋 + + +
水箱 + + +
+ + + + + + + + + + + + + + + diff --git a/demo.html b/demo.html new file mode 100644 index 0000000..9d03677 --- /dev/null +++ b/demo.html @@ -0,0 +1,114 @@ + + + + + + + + + PiApp + + +
正在加载
+
正在加载
+
正在加载
+
正在加载
+ + + + + + diff --git a/images/homepage.png b/images/homepage.png new file mode 100644 index 0000000..2a935c4 Binary files /dev/null and b/images/homepage.png differ diff --git a/images/select-bg.png b/images/select-bg.png new file mode 100644 index 0000000..b5a8389 Binary files /dev/null and b/images/select-bg.png differ diff --git a/images/settings-bg.png b/images/settings-bg.png new file mode 100644 index 0000000..775140b Binary files /dev/null and b/images/settings-bg.png differ diff --git a/images/settings-item.png b/images/settings-item.png new file mode 100644 index 0000000..2293c5e Binary files /dev/null and b/images/settings-item.png differ diff --git a/images/settings-new.png b/images/settings-new.png new file mode 100644 index 0000000..76f0d87 Binary files /dev/null and b/images/settings-new.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..0666f5d --- /dev/null +++ b/index.html @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + 遥控器 + + +
+

转盘遥控器

+ + + +
+ + + + + + + + + + + + + + + diff --git a/launch_uwsgi.sh b/launch_uwsgi.sh new file mode 100755 index 0000000..a32d3d4 --- /dev/null +++ b/launch_uwsgi.sh @@ -0,0 +1,2 @@ +#!/bin/bash +uwsgi -s /tmp/piapp.sock --chmod-socket=666 --manage-script-name --mount /api=caller:APP --plugin python3 diff --git a/old_controller.html b/old_controller.html new file mode 100644 index 0000000..7450d12 --- /dev/null +++ b/old_controller.html @@ -0,0 +1,272 @@ + + + + + + + + + + + + + + + 遥控器 + + + + +
+ 旋转木马: + + +
+
+ 观光电梯: + + +
+
+ 滑梯: + + + + +
+
+ 回收装置: + + + + +
+
+ 震动马达: + + +
+
+ 机械爪 + +
+
+ 继电器 + + +
+
+ 端口测试 + + + +
+
+ 爪子 + + +
+
+ 药袋 + + +
+
+ 上面的传感器 + 未知 + +
+
+ 其它: + + +
+ + + + + + + + + + + + diff --git a/old_worker.py b/old_worker.py new file mode 100644 index 0000000..3204ad6 --- /dev/null +++ b/old_worker.py @@ -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) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..f0f33c2 --- /dev/null +++ b/package-lock.json @@ -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=" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..aa829ac --- /dev/null +++ b/package.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "@fortawesome/fontawesome-free": "^5.15.1", + "jquery": "^3.5.1", + "moment": "^2.29.1" + } +} diff --git a/scheduler.py b/scheduler.py new file mode 100644 index 0000000..5d64281 --- /dev/null +++ b/scheduler.py @@ -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() diff --git a/select.html b/select.html new file mode 100644 index 0000000..e0b0e83 --- /dev/null +++ b/select.html @@ -0,0 +1,54 @@ + + + + + + + + + PiApp + + + + + + + + diff --git a/settings.html b/settings.html new file mode 100644 index 0000000..76c7f12 --- /dev/null +++ b/settings.html @@ -0,0 +1,156 @@ + + + + + + + + + PiApp + + + + + +
07
+
12
+
17
+
00
+
30
+
00
+
:
+
:
+
:
+
3
+
3
+
3
+ + + diff --git a/test.http b/test.http new file mode 100644 index 0000000..7de5e08 --- /dev/null +++ b/test.http @@ -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 \ No newline at end of file diff --git a/worker.py b/worker.py new file mode 100644 index 0000000..0849f2f --- /dev/null +++ b/worker.py @@ -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)