User avatar
raspberrypiguy1
Posts: 379
Joined: Sun Sep 02, 2012 7:01 pm

HELP! I need Python to ignore this little error!

Sun Mar 02, 2014 1:38 pm

Hello all,

I am using a Python library called cwiid in order to get data from a Wiimote and I want to make it into a tutorial! I have just coded a fairly big program that also gets accelerometer data from the Wiimote... It all works however periodically through the program I get warnings that say this:

Code: Select all

Received unexpected write report
They do not affect the program but I think that they do not look pretty and I can't be doing a tutorial with them in!

How on earth do I get Python to ignore them?!

Here is my program:

Code: Select all

 This program utilises the cwiid Python library in order to get input over bluetooth from a wiimote.
# The following lines of code demonstrate many of the features realted to wiimotes, such as capturing button presses and rumbling the controller.
# Whilst cwiid does have support for accelerometer data, it is not very well documented and thus hard to implement efficiently!

# Coded by The Raspberry Pi Guy. Work based on some of Matt Hawkin's!

import cwiid, time

button_delay = 0.1

print 'Please press buttons 1 + 2 on your Wiimote now ...'
time.sleep(1)

# This code attempts to connect to your Wiimote and if it fails the program quits
try:
  wii=cwiid.Wiimote()
except RuntimeError:
  print "Cannot connect to your Wiimote. Run again and make sure you are holding buttons 1 + 2!"
  quit()

print 'Wiimote connection established!\n'
print 'Go ahead and press some buttons\n'
print 'Press PLUS and MINUS together to disconnect and quit.\n'

wii.rpt_mode = cwiid.RPT_BTN

while True:

  buttons = wii.state['buttons']

  # Detects whether + and - are held down and if they are it quits the program
  if (buttons - cwiid.BTN_PLUS - cwiid.BTN_MINUS == 0):
    print '\nClosing connection ...'
    # NOTE: This is how you RUMBLE the Wiimote
    wii.rumble = 1
    time.sleep(1)
    wii.rumble = 0
    exit(wii)

  # The following code detects whether any of the Wiimotes buttons have been pressed and then prints a statement to the screen!
  if (buttons & cwiid.BTN_LEFT):
    print 'Left pressed'
    time.sleep(button_delay)

  if(buttons & cwiid.BTN_RIGHT):
    print 'Right pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_UP):
    print 'Up pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_DOWN):
    print 'Down pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_1):
    print 'Button 1 pressed'    
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_2):
    print 'Button 2 pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_A):
    print 'Button A pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_B):
    print 'Button B pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_HOME):
    wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC
    check = 0
    while check == 0:
      print(wii.state['acc'])
      time.sleep(0.01)
      check = (buttons & cwiid.BTN_HOME)
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_MINUS):
    print 'Minus Button pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_PLUS):
    print 'Plus Button pressed'
    time.sleep(button_delay)

Thanks,

The Raspberry Pi Guy
Matt, The Raspberry Pi Guy YouTube channel, author of Learn Robotics with Raspberry Pi, available now: http://mybook.to/raspirobots, Computer Science & Electronics Undergraduate at The University of Edinburgh

User avatar
raspberrypiguy1
Posts: 379
Joined: Sun Sep 02, 2012 7:01 pm

Re: HELP! I need Python to ignore this little error!

Sun Mar 02, 2014 2:18 pm

Forgot to add that you will get a special thanks in my upcoming tutorial as well!

Thanks

The Raspberry Pi Guy
Matt, The Raspberry Pi Guy YouTube channel, author of Learn Robotics with Raspberry Pi, available now: http://mybook.to/raspirobots, Computer Science & Electronics Undergraduate at The University of Edinburgh

User avatar
DougieLawson
Posts: 35798
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website Twitter

Re: HELP! I need Python to ignore this little error!

Sun Mar 02, 2014 2:41 pm

raspberrypiguy1 wrote:
How on earth do I get Python to ignore them?!
The normal way to get Python to ignore stuff is to wrap a try: except: block round it.

Code: Select all

try:
  something that may not work goes here
except:
  pass
It's difficult to suggest debugging options without more detail.
1. What line of your code gets the exception?
2. Where does the cwiid library come from? Have you checked its bug lists?
Note: Having anything humorous in your signature is completely banned on this forum. Wear a tin-foil hat and you'll get a ban.

Any DMs sent on Twitter will be answered next month.

This is a doctor free zone.

asb
Forum Moderator
Forum Moderator
Posts: 853
Joined: Fri Sep 16, 2011 7:16 pm
Contact: Website

Re: HELP! I need Python to ignore this little error!

Sun Mar 02, 2014 2:43 pm

The problem here is that the cwiid library (the underlying C implementation) has a whole bunch of calls to a function that prints error messages. By default, this will print to standard error (for background see http://en.wikipedia.org/wiki/Standard_s ... 8stderr.29 - every process has stdin, stdout, and stderr). There is a function in that C library to change the function used to handle these errors/warnings, but it's not exposed to the cwiid python binding as far as I can see. Therefore, the simplest workaround is to just redirect stderr to /dev/null so anything printed to stderr will be dropped. This can be done with e.g.

Code: Select all

python mycode.py 2>/dev/null
. The disadvantage is you can't use stderr yourself for anything.

asb
Forum Moderator
Forum Moderator
Posts: 853
Joined: Fri Sep 16, 2011 7:16 pm
Contact: Website

Re: HELP! I need Python to ignore this little error!

Sun Mar 02, 2014 2:45 pm

DougieLawson wrote:
raspberrypiguy1 wrote:
How on earth do I get Python to ignore them?!
The normal way to get Python to ignore stuff is to wrap a try: except: block round it.

Code: Select all

try:
  something that may not work goes here
except:
  pass
The problem is it's not an exception, it's just the library being noisy. It might be possible to get a handle to the cwiid.so that was loaded when you do import cwiid and call cwiid_set_err(NULL) using ctypes or cffi, but otherwise just dumping all stderr gets the job done.

User avatar
raspberrypiguy1
Posts: 379
Joined: Sun Sep 02, 2012 7:01 pm

Re: HELP! I need Python to ignore this little error!

Sun Mar 02, 2014 2:49 pm

As Alex said, unfortunately it is not an exception - otherwise it would have been a piece of cake to get round!

It is all working now thanks to python mycode.py 2>/dev/null!

Cheers fellas,

Matt
Matt, The Raspberry Pi Guy YouTube channel, author of Learn Robotics with Raspberry Pi, available now: http://mybook.to/raspirobots, Computer Science & Electronics Undergraduate at The University of Edinburgh

ZacharyIgielman
Posts: 101
Joined: Sun Dec 08, 2013 11:27 am
Location: London

Re: HELP! I need Python to ignore this little error!

Sun Mar 02, 2014 2:50 pm

asb wrote:
DougieLawson wrote:
raspberrypiguy1 wrote:
How on earth do I get Python to ignore them?!
The normal way to get Python to ignore stuff is to wrap a try: except: block round it.

Code: Select all

try:
  something that may not work goes here
except:
  pass
The problem is it's not an exception, it's just the library being noisy. It might be possible to get a handle to the cwiid.so that was loaded when you do import cwiid and call cwiid_set_err(NULL) using ctypes or cffi, but otherwise just dumping all stderr gets the job done.
Is there anything he can't solve? How about a competition, 'find something that Alex doesn't know or can't fix'? The prize is being smarter than the genius! Well done Alex (again)!
Don't be mean, I'm only fifteen :D

User avatar
jojopi
Posts: 3079
Joined: Tue Oct 11, 2011 8:38 pm

Re: HELP! I need Python to ignore this little error!

Sun Mar 02, 2014 3:26 pm

asb wrote:It might be possible to get a handle to the cwiid.so that was loaded when you do import cwiid and call cwiid_set_err(NULL) using ctypes or cffi, but otherwise just dumping all stderr gets the job done.
How about:

Code: Select all

import sys, os
sys.stderr = os.fdopen(os.dup(2), "w")
os.dup2(os.open("/dev/null", os.O_WRONLY), 2)
Now as far as POSIX is concerned, stderr (by definition, file descriptor 2) is /dev/null. But Python still has a working sys.stderr object, so you do not lose any error messages from the interpreter.

(I am not able to check this against cwiid. Any child processes will inherit the POSIX stderr, not the Python one.)

Return to “Python”