frc4564 / maestro Goto Github PK
View Code? Open in Web Editor NEWPython class to support Pololu's Maestro servo controller over USB serial. Great with Raspberry Pi.
License: MIT License
Python class to support Pololu's Maestro servo controller over USB serial. Great with Raspberry Pi.
License: MIT License
It might be worth noting in the documentation and/or code that this is also a way of identifying a Maestro:
self.servoControllerA = maestro.Controller("/dev/serial/by-id/usb-Pololu_Corporation_Pololu_Micro_Maestro_6-Servo_Controller_XXXXXXXX-if00")
Where XXXXXXXX is the ID of the Maestro.
If you use the /dev/ttyA*** method, they may change depending on the order in which devices are attached or powered up. The soft link provided by /dev/serial/by-id will always attach to the the same controller.
(PS thanks for the code!)
I'm completely new to the Maestro hardware and software, and I had some trouble making it work on Windows with Python.
I made some changes to the README to guide complete newbies like me:
Thanks!
hey,
I tested your library and its a good job done by you
but your code has some issues
it works for only one servo at a time
let me explain
first it gives error saying it needs to be encoded to bytes, unicode not supported
so we should simply edit it to cmd.encode()
this solves the problem in python shell
but if you try to send command for 2 servos like this
maestro.setTarget(0,6000)
maestro.setTarget(1,6000)
maestro will always understand the second command
and the servo1 will reach to position to 6000 and hold the position
and servo 0 will not go anywhere also you can freely rotate servo 0 with your hands
this concludes that there is some error in sending bytes to maestro which will always light up red led
i have also posted this issue on pololu forum
https://forum.pololu.com/t/controlling-two-servos-at-same-time-problem/12282
Today i figured out the problem
using .encode() solves the problem from python side but it also adds up an extra byte '/xc2'
this creates error in maestro servo controller
suppose you want to give command like this
maestro.setTarget(0,6000)
maestro.setTarget(1,6000)
this sends bytes like
'\xc2\xaa\0xc\0x04\channelbyte 0\byte lsb0\byte msb0 \xc2 \xaa\0xc\0x04\channelbyte1\byte lsb1\byte msb1'
if i am not wrong
this means maestro detects wrong command
\xc2\xaa\0xc\0x04\channelbyte 0\byte lsb0\byte msb0 \xc2' upto here
and next command '\xaa\0xc\0x04\channelbyte1\byte lsb1\byte msb1' gets valid
this ends up controlling only servo 1
also lights up red led on maestro indicating unknown command error
so i have to again modify the code like this
import serial
ser=serial.Serial('COM10',115200,timeout=1)
def setTarget(chan, target):
lsb = target & 0x7f #7 bits for least significant byte
msb = (target >> 7) & 0x7f #shift 7 and take next 7 bits for msb
# Send Pololu intro, device number, command, channel, and target lsb/msb
cmd = (chr(0xaa) + chr(0xc) + chr(0x04) + chr(chan) + chr(lsb) + chr(msb)).encode()
command = cmd.split(b'\xc2',1)
ser.write(command[1])
i=9000
setTarget(0, i)
setTarget(1, i)
which will split the bytes by \xc2 and will send the exact required command
this finally solves all the problem and all the servo reaches correct position also no red error led
hope You will understand this long issue
and modify the library
so that our python guys gets no issues
maybe the issue was because i am coding on my pc using python
and will not cause any problem on RPi
So there is a sendcmd in the code, in case I need to read a designated serial input (like a sensor input), is there a way to do it? thanks in advance.
p.s sorry, I tried to put this topic in the question category and somehow it popped up here.
I'm trying to utilize this to code a sequence, but it seems to only go to the last position. Is there any way to do this? Here's my attempt:
import time
MIN_S = 0
MIN_G = 0
CENTER_S = 6000
CENTER_G = 6000
MAX_S = 12000
MAX_G = 12000
class RubikSolve:
# Pass the maestro controller object and the maestro channel numbers being used
# for the left and right motor controllers. See maestro.py on how to instantiate maestro.
def __init__(self, maestro, rightSlider, rightGripper):
self.maestro = maestro
self.rightSlider = rightSlider
self.rightGripper = rightGripper
# Init motor accel/speed params
self.maestro.setAccel(rightSlider,0)
self.maestro.setAccel(rightGripper,0)
self.maestro.setSpeed(rightSlider, 0)
self.maestro.setSpeed(rightGripper, 110)
# Motor min/center/max values
self.minS = MIN_S
self.minG = MIN_G
self.centerS = CENTER_S
self.centerG = CENTER_G
self.maxS = MAX_S
self.maxG = MAX_G
def servoMove(self, servo, position):
self.maestro.setTarget(servo, position)
# Right
def R_clock(self):
self.servoMove(self.rightSlider, self.minS)
print('rightSlider')
time.sleep(1)
self.servoMove(self.rightGripper, self.minG)
print('rightGripper')
time.sleep(1)
self.servoMove(self.rightSlider, self.maxS)
print('rightSlider')
time.sleep(1)
self.servoMove(self.rightGripper, self.maxG)
print('rightGripper')
Then once that's defined I run this:
import maestro
m = maestro.Controller()
rs = RubikSolve(m, 0, 1) #maestro channels 0 and 1 for left and right motors
for i in range(1):
rs.R_clock()
m.close()
Am I missing something simple here?
Can you add a license file or explicit notice in the source code for others who wish to use the module?
Should this code work with the Maestro 24? Pololu's docs all state each channel needs to be enabled before using and that once enabled the yellow LED should flash twice, but I don't see anything in your code that enables the channel before use.
Also, I believe most pins on the Maestros also double as a true analog input, but there doesn't appear to be an interface for this in your class. Is this possible?
Hi,
I have a question about what I can best do when the servo is stuck in a feedback loop. When I set a target for the servo channel, it sometimes happens that the target it not fully reached and the servo keeps trying to get to the indicated position. This has happened for different target values. Unfortunately, I cannot tell it to stop the PWM sending, as only one of the channels has that option, and I plan on using two channels. I tried to fix it with this code, by simply restating the target when getting close to it, but it doesn't always solve the problem:
if abs(servo.getPosition(0) - target) < 5.:
servo.setTarget(0, servo.getPosition(0))
servo.close()
Even when you close the servo, the servo keeps working and you have to disable it manualy in the Maestro Control Center. Besides, you'd rather not have to fully close and reconnect the servo after each target statement, but rather only temporarily the channel that is experiencing issues. It's just that I don't know how best to define the rapid back-and-forth positions when it's stuck, since you don't have an iterative overview of all positions as the target it set.
I've tried using the fact that it's moving as a control condition, but while jammed/stuck in the loop it claimes it's not moving, even though you can hear it vibrating and working. This makes it difficult for me to pinpoint a solution, other than "keep the Maestro Control Center at hand in case of emergency".
In the Maestro Control Center I've also experienced this same problem, but there I could avoid damage to the servo controller by manually disabling the respective channel. Is there a way to also do this through python? Or are there other suggestions?
Are the settings like speed and acceleration relevant for this? I tend to use v=10 and a=5, but have this problem for different values as well.
Thanks!
Vera
Can the Maestro PY class be configured to work for circuit python? This would be a fantastic combination to be able to use the maestro servo controller with the adafruit feather microcontroller using circuit python.
I am using the Maestro controller to control animatronics for Halloween and Christmas displays. I had a problem where the display got stuck and the servo kept trying to move it. This is real bad for the servo.
I can detect that the servo did not reach its commanded position, but I cannot figure out how to stop it immediately.
I appreciate any ideas. Thanks,
Paul
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.