Skip to content

Commit

Permalink
Easyservo V1.0.1
Browse files Browse the repository at this point in the history
Here is the stable version of Easyservo.
Some improvements:
- Fine movements
- AutoHoming function
- Axis inversion
- Minor fixes
  • Loading branch information
iFrostizz authored Jun 30, 2020
1 parent 9eb050c commit 8e4b0aa
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 35 deletions.
131 changes: 99 additions & 32 deletions EasyServo/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# coding=utf-8
from __future__ import absolute_import
import time

import octoprint.plugin
import pigpio
Expand All @@ -11,15 +12,19 @@ class EasyservoPlugin(octoprint.plugin.SettingsPlugin,
octoprint.plugin.ShutdownPlugin):

def __init__(self):
self.current_angle_x = 90
self.current_angle_y = 90
self.pi = None

##~~ SettingsPlugin mixin
def get_settings_defaults(self):
return dict(
GPIOX="12",
GPIOY="13"
GPIOX=12,
GPIOY=13,
xAutoAngle=90,
yAutoAngle=90,
xInvert=False,
yInvert=False,
saved_angle_x=90,
saved_angle_y=90
)

def on_settings_save(self, data):
Expand All @@ -32,17 +37,15 @@ def on_settings_save(self, data):
newGPIOY = self._settings.get_int(["GPIOY"])

if oldGPIOX != newGPIOX:
self._logger.info("GPIO x changed, initilizing.")
self.current_angle_x = 90
self._logger.info("GPIO x changed, initializing.")
self.pi.set_servo_pulsewidth(newGPIOX, 0)
self._logger.info("moving GPIO %d to %d degrees" % (newGPIOX,self.current_angle_x))
self.pi.set_servo_pulsewidth(newGPIOX, self.angle_to_width(self.current_angle_x, "X"))
self._logger.info("moving GPIO %d to %d degrees" % (newGPIOX, self.current_angle_x))
self.current_angle_x = self.move_servo_by(GPIOX, self.current_angle_x)
if oldGPIOY != newGPIOY:
self._logger.info("GPIO y changed, initilizing.")
self.current_angle_y = 90
self._logger.info("GPIO y changed, initiliazing.")
self.pi.set_servo_pulsewidth(newGPIOY, 0)
self._logger.info("moving GPIO %d to %d degrees" % (newGPIOY,self.current_angle_y))
self.pi.set_servo_pulsewidth(newGPIOY, self.angle_to_width(self.current_angle_y, "Y"))
self._logger.info("moving GPIO %d to %d degrees" % (newGPIOY, self.current_angle_y))
self.current_angle_y = self.move_servo_by(GPIOY, self.current_angle_y)


##~~ AssetPlugin mixin
Expand All @@ -67,14 +70,35 @@ def on_after_startup(self):

GPIOX = self._settings.get_int(["GPIOX"])
GPIOY = self._settings.get_int(["GPIOY"])
xAutoAngle = self._settings.get_int(["xAutoAngle"])
yAutoAngle = self._settings.get_int(["yAutoAngle"])
saved_angle_x = xAutoAngle
saved_angle_y = yAutoAngle
#self._logger.info("xAutoAngle {} yAutoAngle {}.".format(xAutoAngle, yAutoAngle))


# initialize x axis
saved_angle_x = self._settings.get_int(["saved_angle_x"])
self.pi.set_servo_pulsewidth(GPIOX, 0)
self._logger.info("moving GPIO %d to %d degrees" % (GPIOX,self.current_angle_x))
self.pi.set_servo_pulsewidth(GPIOX, self.angle_to_width(self.current_angle_x, "X"))
if self._settings.get_boolean(["xInvert"])==True:
self._settings.set(["xInvert"], False)
self._settings.save()
self.current_angle_x = self.move_servo_to_ang(GPIOX, saved_angle_x, xAutoAngle)
self._settings.set(["xInvert"], True)
self._settings.save()
else:
self.current_angle_x = self.move_servo_to_ang(GPIOX, saved_angle_x, xAutoAngle)
# initialize y axis
saved_angle_y = self._settings.get_int(["saved_angle_y"])
self.pi.set_servo_pulsewidth(GPIOY, 0)
self._logger.info("moving GPIO %d to %d degrees" % (GPIOY,self.current_angle_y))
self.pi.set_servo_pulsewidth(GPIOY, self.angle_to_width(self.current_angle_y, "X"))
if self._settings.get_boolean(["yInvert"])==True:
self._settings.set(["yInvert"], False)
self._settings.save()
self.current_angle_y = self.move_servo_to_ang(GPIOY, saved_angle_y, yAutoAngle)
self._settings.set(["yInvert"], True)
self._settings.save()
else:
self.current_angle_y = self.move_servo_to_ang(GPIOY, saved_angle_y, yAutoAngle)


##~~ ShutdownPlugin mixin
Expand Down Expand Up @@ -116,41 +140,84 @@ def get_update_information(self):

##~~ Utility functions

def angle_to_width (self, ang, axis): #Easier conversion for the angle
def angle_to_width(self, ang): #Easier conversion for the angle
if ang > 180:
if axis == "X":
self.current_angle_x = 180
if axis == "Y":
self.current_angle_y = 180
ang = 180
elif ang < 0:
if axis == "X":
self.current_angle_x = 0
if axis == "Y":
self.current_angle_y = 0
ang = 0

ratio = (2500 - 500)/180 #Calcul ratio from angle to percent

angle_as_width = ang * ratio
return int(500 + angle_as_width)

def width_to_angle(self, width):
ratio = (180.0)/(2500.0-500.0)

width_as_angle = float(width) * ratio
return float(width_as_angle - 45.0)

def move_servo_to_ang(self, pin, start_angle, destination_angle):
angle_difference = destination_angle - start_angle
move_results = self.move_servo_by(pin, angle_difference)
return move_results

def move_servo_by(self, pin, angle_difference):
if angle_difference < 0:
direction = -1
else:
direction = 1

if self._settings.get_int(["GPIOX"]) == int(pin):
angle_start = self._settings.get_int(["saved_angle_x"])
width_start = self.pi.get_servo_pulsewidth(int(pin))
if self._settings.get_int(["GPIOY"]) == int(pin):
angle_start = self._settings.get_int(["saved_angle_y"])
width_start = self.pi.get_servo_pulsewidth(int(pin))

angle_end = angle_start + angle_difference
width_end = self.angle_to_width(angle_end)
angle_current = angle_start
width_current = width_start
if self._settings.get_boolean(["xInvert"])==True and self._settings.get_int(["GPIOX"]) == int(pin):
direction = direction*-1
angle_end = -angle_end
angle_start = -angle_start
if self._settings.get_boolean(["yInvert"])==True and self._settings.get_int(["GPIOY"]) == int(pin):
direction = direction*-1
angle_end = -angle_end
angle_start = -angle_start
#self._logger.info("pin {} angle_start {} angle_end {} direction {} angle_difference {} width_start {} width_end {}.".format(pin, angle_start, angle_end, direction, angle_difference, width_start, width_end))
if width_start != width_end:
for x in range(0, int(((angle_end - angle_start) * direction) * 10)):
angle_current = angle_current + (0.1 * direction)
width_current = self.angle_to_width(angle_current)
self.pi.set_servo_pulsewidth(int(pin), width_current)
#self._logger.info("Moved GPIO {} to width: {} angle: {}.".format(pin, width_current, angle_current))
time.sleep(0.01)
if width_current > 2478 or width_current < 501: #Noticed that the angle was 180.0° for 2479us and 500 was giving strange values .......
break
if self._settings.get_int(["GPIOX"]) == int(pin):
self._settings.set(["saved_angle_x"], round((angle_current), 1))
if self._settings.get_int(["GPIOY"]) == int(pin):
self._settings.set(["saved_angle_y"], round((angle_current), 1))
self._settings.save()
return angle_current

##~~ atcommand hook

def processAtCommand(self, comm_instance, phase, command, parameters, tags=None, *args, **kwargs):
if command == 'EASYSERVO':
#get GPIO and angle from parameters
GPIO,ang = parameters.split(' ')
GPIO,ang= parameters.split(' ')
if int(GPIO) == self._settings.get_int(["GPIOX"]):
self._logger.info("moving GPIO %d to %d degrees" % (int(GPIO),self.current_angle_x))
self.current_angle_x = self.current_angle_x + int(ang)
self.pi.set_servo_pulsewidth(int(GPIO), self.angle_to_width(self.current_angle_x, "X"))
self.current_angle_x = self.move_servo_by(int(GPIO), int(ang))
elif int(GPIO) == self._settings.get_int(["GPIOY"]):
self._logger.info("moving GPIO %d to %d degrees" % (int(GPIO),self.current_angle_y))
self.current_angle_y = self.current_angle_y + int(ang)
self.pi.set_servo_pulsewidth(int(GPIO), self.angle_to_width(self.current_angle_y, "Y"))
self.current_angle_y = self.move_servo_by(int(GPIO), int(ang))
else:
self._logger.info("unknown GPIO %d" % int(GPIO))
if command == 'EASYSERVOAUTOHOME':
self.on_after_startup()


__plugin_name__ = "Easy Servo"
Expand Down
2 changes: 2 additions & 0 deletions EasyServo/static/js/EasyServo.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ $(function() {
self.controlViewModel.left = ko.observable('@EASYSERVO ' + self.settingsViewModel.settings.plugins.EasyServo.GPIOX() + ' 10');
self.controlViewModel.up = ko.observable('@EASYSERVO ' + self.settingsViewModel.settings.plugins.EasyServo.GPIOY() + ' -10');
self.controlViewModel.down = ko.observable('@EASYSERVO ' + self.settingsViewModel.settings.plugins.EasyServo.GPIOY() + ' 10');
self.controlViewModel.autoHome = ko.observable('@EASYSERVOAUTOHOME ');
}

self.onEventSettingsUpdated = function (payload) {
self.controlViewModel.right('@EASYSERVO ' + self.settingsViewModel.settings.plugins.EasyServo.GPIOX() + ' -10');
self.controlViewModel.left('@EASYSERVO ' + self.settingsViewModel.settings.plugins.EasyServo.GPIOX() + ' 10');
self.controlViewModel.up('@EASYSERVO ' + self.settingsViewModel.settings.plugins.EasyServo.GPIOY() + ' -10');
self.controlViewModel.down('@EASYSERVO ' + self.settingsViewModel.settings.plugins.EasyServo.GPIOY() + ' 10');
self.controlViewModel.autoHome('@EASYSERVOAUTOHOME ');
};
}

Expand Down
2 changes: 1 addition & 1 deletion EasyServo/templates/EasyServo.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</div>
<div>
<button id="control-xdec-servo" class="btn box pull-left" data-bind="enable: isOperational(), click: function() { OctoPrint.control.sendGcode(left()); }"><i class="fa fa-arrow-left"></i></button>
<button id="control-xyhome-servo" class="btn box pull-left disabled" disabled><i class="fa fa-arrows"></i></button>
<button id="control-xyhome-servo" class="btn box pull-left" data-bind="enable: isOperational(), click: function() { OctoPrint.control.sendGcode(autoHome());}"><i class="fa fa-home"></i></button>
<button id="control-xinc-servo" class="btn box pull-left" data-bind="enable: isOperational(), click: function() { OctoPrint.control.sendGcode(right()); }"><i class="fa fa-arrow-right"></i></button>
</div>
<div>
Expand Down
25 changes: 25 additions & 0 deletions EasyServo/templates/EasyServo_settings.jinja2
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<h4>Easy Servo Settings<div class="label label-info pull-right"><small style="color:white;">Please make sure that all prerequsites are met as descibed <a style="color:white;" href="https://github.com/jneilliii/OctoPrint-EasyServo#pre-installation-requirements">here</a>.</small></div></h4>

<form class="form" id="settings_plugin_EasyServo_form">
<div class="control-group">
<label class="control-label">{{ _('X Axis GPIO Number') }}</label>
Expand All @@ -12,4 +13,28 @@
<input type="number" class="input-mini" data-bind="value: settings.plugins.EasyServo.GPIOY">
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('X AutoHome Angle') }}</label>
<div class="controls">
<input type="number" class="input-mini" data-bind="value: settings.plugins.EasyServo.xAutoAngle">
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('Y AutoHome Angle') }}</label>
<div class="controls">
<input type="number" class="input-mini" data-bind="value: settings.plugins.EasyServo.yAutoAngle">
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('X Axis Inversion') }}</label>
<div class="control">
<input type="checkbox" class="input-block-level" data-bind="checked: settings.plugins.EasyServo.xInvert">
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('Y Axis Inversion') }}</label>
<div class="control">
<input type="checkbox" class="input-block-level" data-bind="checked: settings.plugins.EasyServo.yInvert">
</div>
</div>
</form>
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
plugin_name = "Easy Servo"

# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
plugin_version = "0.1.0"
plugin_version = "0.1.1"

# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
# module
plugin_description = "Petit plugin pour controler des servo moteurs"
plugin_description = "Here is a small plugin so you can control some Servo motors using the octoprint interface"

# The plugin's author. Can be overwritten within OctoPrint's internal data via __plugin_author__ in the plugin module
plugin_author = "iFrostizz"
Expand Down

0 comments on commit 8e4b0aa

Please sign in to comment.