Open alexellis opened 9 years ago
I am also running into this problem. So far, the only thing I can think of is to run a separate thread with something like:
while True:
if global_vars.wiimote is not None:
try:
global_vars.wiimote.request_status()
except ValueError:
# Wiimote object is closed - don't worry about it
pass
except RuntimeError:
print "Disconnected suddenly"
stop_moving()
time.sleep(1)
Unfortunately, this is a pretty bad solution - during testing, if I unplug the batteries to my wiimote all of a sudden while the robot's motors (wheels) are running, the request_status() function won't error out for over 20 seconds. The robot could have run into all sorts of things in 20 seconds.
Is there a better way to do this?
Hi folks, I think I have solved this problem. The underlying issue is that bluetooth is a pretty tolerant protocol - it expects people with bluetooth devices to wander away and come back and find everything reconnects happily. This is fine if you're playing music or using a keyboard, but not so great if you're controlling a robot car (which I am also implementing :+1: ). I can't find an easy way to change the timeout in cwiid
However, the command line tool hcitool
gives us a way of changing the timeout (at least on linux):
hcitool (from the man page) \<snip> lst
[value] With no value, displays link supervision timeout for the connec‐ tion to the device with Bluetooth address bdaddr. If value is given, sets the link supervision timeout for that connection to value slots, or to infinite if value is 0.
So, I have devised a connection strategy:
import re
import cwiid
import subprocess
# set bluetooth timeout in ms
BLUETOOTH_TIMEOUT = 1000
def connect():
wm = cwiid.Wiimote()
# get all connected bluetooth devices
connected_devices = subprocess.check_output(("hcitool","con"))
# extract bluetooth MAC addresses
addresses = re.findall(r"(([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2}))",connected_devices)
for i in addresses:
name = subprocess.check_output(("hcitool","name",i[0]))
# identify Wiimotes. You may need to change this if looking for balance boards
# we are also assuming that you only have one Wiimote attached at one time,
# or that we want to set them all to have the same timeout
if name.strip()=="Nintendo RVL-CNT-01":
subprocess.call(("hcitool","lst",i[0],str(BLUETOOTH_TIMEOUT*16/10)))
return wm
We can then implement @terminator14 's strategy of having a background thread to monitor the response from the wiimote.
I have implemented all the above for my project and everything stops within a couple of seconds of removing the batteries
Hope this helps,
Phil
@furbrain this thread is two years old already but great to hear you found a potential solution. I'd like to try it out next time I fire up my robot. http://blog.alexellis.io/piwars-v2-0/
@furbrain That worked really well, you're a life saver!
Hi, I'm using this library on a Raspberry PI with Python 2.7 to control a robot/car. This works brilliantly with a high range until the range is too far at which point I can't detect loss of signal/input and the car continues off into the distance etc.
Is there a way to resolve this?
Thanks