6

Testing out the wiringPi2 interrupts on python 2.7 / RaspberryPi and can't seem to get it to work.

With the following code, the interrupt generates a segmentation fault.

#!/usr/bin/env python2
import wiringpi2
import time

def my_int():
    print('Interrupt')

wpi = wiringpi2.GPIO(wiringpi2.GPIO.WPI_MODE_PINS)
wpi.pullUpDnControl(4,wpi.PUD_UP) 
wpi.wiringPiISR(4, wpi.INT_EDGE_BOTH, my_int())
while True:
    time.sleep(1)
    print('Waiting...')

Waiting...
Waiting...
Waiting...
Waiting...
Segmentation fault

If I callback without the "()" then I get another error:

wpi.wiringPiISR(4, wpi.INT_EDGE_BOTH, my_int)

> TypeError: in method 'wiringPiISR', argument 3 of type 'void (*)(void)'

What am I doing wrong ???

crankshaft
  • 2,607
  • 4
  • 45
  • 77
  • You definitely need to use the callback without `()` as you'd otherwise call the function and use its return value of your function as the pointer to the callback function (`null`, hence the segfault) – Nils Werner Nov 07 '13 at 09:38
  • Thanks, but if I call without the () then I get the TypeError - does this suggest that the wiringpi2 module has an error with the wiringPiISR() function ? – crankshaft Nov 07 '13 at 10:06

1 Answers1

3

I am not too good with C, but as far as I understood from sources https://github.com/Gadgetoid/WiringPi2-Python/blob/master/wiringpi_wrap.c you've got this error because of this code (it checks if function returns void and displays error):

int res = SWIG_ConvertFunctionPtr(obj2, (void**)(&arg3), SWIGTYPE_p_f_void__void);
if (!SWIG_IsOK(res)) {
  SWIG_exception_fail(SWIG_ArgError(res), "in method '" "wiringPiISR" "', argument " "3"" of type '" "void (*)(void)""'");
}

So, I recommend to return True or 1 in my_int() function explicitly. Now python returns None for the function that have reached the end of function code but returned no value.

Modified code:

#!/usr/bin/env python2
import wiringpi2
import time

def my_int():
    print('Interrupt')
    return True
# setup
wiringpi2.wiringPiSetupGpio()
# set up pin 4 as input
wiringpi2.pinMode(4, 0)
# enable pull up down for pin 4
wiringpi2.pullUpDnControl(4, 1) 
# attaching function to interrupt
wiringpi2.wiringPiISR(4, wiringpi2.INT_EDGE_BOTH, my_int)

while True:
    time.sleep(1)
    print('Waiting...')

EDIT: It seems that you've initialize wiringpi2 wrongly. Please check tutorial for details: http://raspi.tv/2013/how-to-use-wiringpi2-for-python-on-the-raspberry-pi-in-raspbian

nickzam
  • 793
  • 4
  • 8
  • Thanks so much for the suggestion, I just tried and unfortunately it returns the same TypeError. – crankshaft Nov 07 '13 at 10:50
  • Thanks, I am using the class-based method for wiringPi, it works fine I can read / write to the ports, and capture inputs using tight loops etc, the only function that does not appear to work is the interrupt, everything else works as expected. – crankshaft Nov 07 '13 at 11:24
  • Ahh, ok. So, it's possible a bug in SWIG object description. Can't test it on my side, sorry. I've seen you report in git for wiringpi2. Let's see what author will answer. – nickzam Nov 07 '13 at 11:26