Reputation: 103
I have a C function allocates an integer, passes the pointer to a callback function before returning the pointer.
void change_state(int gpio, int level, uint32_t tick, void *ptr){
if (level == 1){
printf("Button was pressed!\n");
*((int*)ptr) += 1;
}
}
int * allocate_void_ptr_start_watchdog(int BUTTON){
void *current_state_ptr = malloc(sizeof(int)); /*Creates a ptr of size int*/
*((int*)current_state_ptr) = 0; /*Casts ptr to type int and set to 0*/
gpioSetAlertFuncEx(BUTTON, change_state, current_state_ptr); /*Function to watch for GPIO state change*/
return current_state_ptr;
}
The return value is then passed back to Python:
allocate_ptr_start_watchdog = button_functions.allocate_void_ptr_start_watchdog
allocate_ptr_start_watchdog.restype = ctypes.POINTER(ctypes.c_int)
ptr = allocate_ptr_start_watchdog(BUTTON)
Using a while True
loop as follows works as expected (1 press of button at GPIO 25 will turn lights on, second press turns it off)
while True:
current_val = ptr.contents.value
if current_val == 0:
continue
elif current_val == 1:
button_functions.turn_on_lights(LED_1, LED_2)
else:
button_functions.clear_all(LED_1, LED_2)
ptr.contents.value = 0
However once I try to use multiprocessing the function breaks as the button presses don't turn on or off the lights anymore. However, the printf
from the C library still prints so I doubt it's an issue with the library.
def button_start(ptr):
while True:
current_val = ptr.contents.value
if current_val == 0:
continue
elif current_val == 1:
button_functions.turn_on_lights(LED_1, LED_2)
else:
button_functions.clear_all(LED_1, LED_2)
ptr.contents.value = 0
multiprocessing.Process(target=button_start, args=(ptr,)).start()
This is running on Raspbian Buster with kernel 5.10.63-v7l+. What am I missing/failing to see here?
Upvotes: 2
Views: 88
Reputation: 103
As the MP process needs to connect back to the pigpio daemon there needs to be a function that performs that.
int connect_to_daemon(){ /*Connect to pigpio daemon*/
printf("Connecting to daemon\n");
int daemon_instance = pigpio_start("192.168.86.234", NULL);
printf("Successfully connected to daemon\n");
return daemon_instance;
}
We can then assign a variable to this instance in Python daemon_instance = button_function.connect_to_daemon()
before calling our callback function.
int * start_callback(int daemon_instance, int BUTTON){
void *current_state_ptr = malloc(sizeof(int)); /*Creates a ptr of size int*/
*((int*)current_state_ptr) = 0; /*Casts ptr to type int and set to 0*/
callback_ex(daemon_instance, BUTTON, FALLING_EDGE, change_state, current_state_ptr);
return current_state_ptr;
}
In Python:
ptr = button_functions.start_callback(daemon_instance, BUTTON)
print(ptr.contents.value) # This should return the correct value now
Big thanks to 2e0byo!
Upvotes: 1