Delays between servo movements in pyfirmata don't work - python

I'm writing a program in python where moving servos at specific times is a crucial part of the project. To achive this, I am using the pyfirmata library.
I've tried two methods of delays, but none of them seem to work.
When I run the code, the servo turns the first time, but after the delay, it doesn't turn and the program just stops, instead of moving the servo to 0 degrees and then stopping.
This is the one with the board.pass_time() built in to the pyfirmata library:
from pyfirmata import Arduino, util
import time
board = Arduino('COM3')
servo = board.get_pin('d:9:s')
servo.write(180) #This works and turns the servo
time.sleep(1)
servo.write(0) #This time the servo does not turn, then the program ends
And here's the one with time.sleep():
from pyfirmata import Arduino, util
board = Arduino('COM3')
servo = board.get_pin('d:9:s')
servo.write(180) #This works and turns the servo
board.pass_time(1)
servo.write(0) #This time the servo does not turn, then the program ends
I would highly appreciate if someone could help.
Thank you,
David

I found the answer!
There might be a better answer, but if I write board.get_pin('d:9:s') as board.get_pin('d:9:'), like this, I need to control it with a value from 0 to 5 instead of 0 to 360, but the delays work

Your code is correct but you need to make the delay again to turn it back to 0 degree. So your code should look something like this.
servo.write(180)
time.sleep(2)
servo.write(0)
time.sleep(2)
You need to give the delay everytime you make changes to the servo motor in order to make those changes

Related

Webots NAO controller sequence not working

I am using the NAO_demo_python controller of the latest version of webots on linux (ubuntu 18) to flash leds and open/close the hands.
However only the last part of the sequences are executed, and not in a single simulation run.
e.g. if i ask to just open the hand and light the leds, after 1 run the lights will be on and after 5 runs of the main while loop it will be opened -reaaallly slowly-. However if i ask lit leds, open hand then close hand unlit leds then the simulation will only close hand and unlit leds.
The code should be working, it is on another person's computer. In case you want it here it is (it's really basic, it's a slight modification of nao-demo-python.py):
def run(self):
while robot.step(self.timeStep) != -1:
self.setAllLedsColor(0xff0000) #red leds on
self.setHandsAngle(0.96) #open hand
#rospy.sleep(5) #originally i am to use webots and nao with ros
print("done") #to check how many runs are made
self.setHandsAngle(0.0) #close hand
self.setAllLedsColor(0x000000) #red leds off
Also, something that may be interesting: if i ask to open close the hand N times and each time print something, all the prints will be printed at once and the simulation time jump from 0:0:0 to 0:0:20 after each main loop run (+20 at each run), else, even if the simulation runs the time doesn't flow, it jumps.
I tried to update my drivers, to take off all shadows and stuff from the simulation, as webots advices. No can do. I couldn't find something on Softbank, i can't find an active forum concerning nao and webots anymore...
I have an i5 9th gen and a GTX1050Ti.
May the problem be that the simulation time isn't 1.0x? but at most 0.05x? (after taking off shadows, effect of lights, all objects, using 1 thread etc, as explained here: https://www.cyberbotics.com/doc/guide/speed-performance)
SUMMARY: Only the last sequence of the controller is executed, and if it's a motion it takes several main loops before being fully executed. Meanwhile the time jumps from 0 to +20s after each main loop run.
May someone help me out to make all the sequence work on simulation please :)
all the prints will be printed at once
Only the last sequence of the controller is executed
It sounds like the setHandsAngle function might be asynchronous (doesn't wait for the hand to move to that point before running the next piece of code)? This could be responsible for at least some of the problems you're experiencing. In this case the rospy.sleep(5) should be replaced with robot.step(5000), so the simulator has time to move the hand before sending the next command.
Thank to your indications, this works:
self.CloseHand = Motion('../../motions/closeHand.motion')
def startMotion(self, motion):
if self.currentlyPlaying: #interrupt current motion
self.currentlyPlaying.stop()
motion.play() #start new motion
self.currentlyPlaying = motion
self.startMotion(self.CloseHand)
while not self.CloseHand.isOver():
robot.step(self.timeStep)
And in the CloseHand.motion :
#WEBOTS_MOTION,V1.0,LPhalanx1,RphalanxN (until 9)
00:00:000,Pose1,0.00,0.00 etc
with 00:00:000 the moment of execution and 0.00 the angle of the hand (phalanx by phalanx).
THANK you very much! I couldn't have realized that without your advice.
The synchronization webots/ros is still unresolved but the issue of my initial question is. Thank you!

One joystick works with pygame and another won't?

I am currently building a robot that I would like to control with a pair of nice joysticks I bought. Up until now I've been using pygame.joystick with no problems at all with my PS4 controller. However the new joysticks have a problem. They output the correct values for like twenty or thirty seconds and function properly, but then they just freeze on a value. I can't think of any reasons they would work fine for a certain amount time and then all of a sudden just freeze.
My code is as simple as:
pygame.init()
leftjoy = pygame.Joystick.joystick(0)
leftjoy.init()
while True:
print(leftjoy.get_axis(0))
pygame.event.pump()
Update:
I tried this same code on Windows instead of raspberry pi and it worked perfectly. I plan on using ssh when controlling the robot so it should work well for that application. But I would still like to know how to fix this problem for testing.
A couple shots in the dark, without access to your hardware...
Since the PS4 controller works, I'm guessing the code and the RasPi are in good health, so the joysticks themselves might be somewhat buggy. The problem could be that the joysticks momentarily disconnect (power issue, faulty cable, just faulty hardware), and upon reconnect are assigned a new address such as 1. I don't recall that being a common problem in RasPi in general, but PyGame might have issues. Here's another post with some code that might help you detect and debug joystick disconnects in software. To much more quickly test that possibility in hardware, intentionally do a momentary disconnect-connect early, while your game is "working" and see if the same result happens.
Finally, maybe the RasPi is polling too quickly and causes the joystick to freeze. To debug this, you could try putting a delay in your loop.

Start Loop when input start from a PI and stop when input stops (python)

Python: I'm writing a system that needs the program to wait until an input from the GPIO board on a raspberry comes through then loop until the input stops? Any ideas on the best way to do this?
The best way , imho, is to use the event_detected() function of the RPI.GPIO module.
Take a look at http://raspi.tv/2014/rpi-gpio-update-and-detecting-both-rising-and-falling-edges
The example program detects rising and falling edges on GPIO 25

GPIO pins no errors but not getting the expected result?

Sorry I am a beginner to both Raspberry Pi and python. I am write a simple python program to use the pulse width modulator, Here is the code.
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(12,GPIO.OUT)
pwm=GPIO.PWM(12,50)
pwm.start(0)
while True:
for i in range(50):
pwm.ChangeDutyCycle(i)
time.sleep(0.05)
for i in range(50,0,-1):
pwm.ChangeDutyCycle(i)
time.sleep(0.05)
I connected the led between 12 and ground with the suitable resistor. But when I execute, I don't get any error but it wont work.
The code seems to work fine on my Rpi-3. So we cannot help you if we can't see the circuit design. I can make a guess that you probably used the normal numbering to connect the led, but used the BCM numbering in your program. So either change it to board numbering by GPIO.setmode(GPIO.BOARD) or refer the below chart for correct numbers.
I got the problem. I need to use the proper numbering. The reason for having two types of numbering is,
The GPIO.BOARD option specifies that you are referring to the pins by the number of the pin the the plug - i.e the numbers printed on the board (e.g. P1).
The GPIO.BCM option means that you are referring to the pins by the "Broadcom SOC channel" number.
I hope this helps anyone.

How do I use a button on a Raspberry Pi to toggle states in a while loop?

I'm trying to figure out a way to use a button on a Raspberry Pi to toggle between two different conditions in a while loop. Ideally, by merely pressing the button, I could switch back and forth.
I know this is wrong, but I'm not sure where to go from here.
Roughly, my code looks like this:
from gpiozero import Button
btn=Button(17) #The GPIO pin is 17
def addSurf():
i = i + 1
i = 0
btn.when_pressed = addSurf
while True:
if i % 2 == 0:
#do some stuff
else:
#do some other stuff
Since I started i at 0 before the while loop, I figured that by adding integers when the button was pressed, and checking to see if the modulo was zero or not, I could navigate back and forth between the two states.
However, I don't know how to incorporate the .when_pressed function into the loop so that it's always going to respond to move the program into one state or the other.
Forgive me if I'm a bit of a newbie here, but I tried looking into the documentation for raspberry-gpio-python for information about event detection and multithreading, but I didn't understand it.
It turns out that the problem with the button.when_pressed function is that it can't take any argument, so there's no way to have it act as a variable.
Though it may not be the proper way to do it, I ended up running two different while loops in their own threads and having the button.when_pressed function toggle the sign of an integer in a global variable, as as a kind of switch for the other thread.

Categories

Resources