Hi,
for a nordic based pcb I'd like to implement micropython callbacks to be triggered once a button was pressed/released.
Similar to the stmhal hardware interrupt in usrsw.c, I'd like to register a button callback in micropython which can be triggered from a software interrupt coming from nordics button driver implementation where I can register several function pointers that will be called on (debounced) short/long pressed/released events.
Since I'm quiet new to micropython I'd appreciate if someone can give me a hint if it's possible to pass function pointers from a micropython module to the button dirver implementation in order to trigger the python callback function.
Best
Christian
Software interrupt on nRF52832
Re: Software interrupt on nRF52832
You should probably check out this thread:
http://forum.micropython.org/viewtopic. ... 72&p=16471
There is sample code here:
https://github.com/dhylands/micropython ... 055abb5fef
http://forum.micropython.org/viewtopic. ... 72&p=16471
There is sample code here:
https://github.com/dhylands/micropython ... 055abb5fef
Re: Software interrupt on nRF52832
Hey,
thanks for your support and the example code. I meanwhile got it working so far.
Now I'm facing another issue which might be related to the garbage collector or maybe not. The problem occurs when I'm trying to increment a global variable within a C callback function. I can read and print the value of that variable but once I start writing to it I get the python error: "NameError:"
This is how the C function looks like:
[code]
void ext_button_released_callback(uint8_t button_id, bool long_press)
{
pb_button_obj_t *self = MP_STATE_PORT(pb_button_objects)[button_id];
if(mp_const_none != self->callback)
{
gc_lock();
nlr_buf_t nlr;
if(0 == nlr_push(&nlr))
{
mp_call_function_1(self->callback,mp_obj_new_bool(long_press));
nlr_pop();
}
else
{
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
gc_unlock();
}
}
[/code]
Is it somehow possible to modify a global var within a callback function?
Christian
PS: Sorry for the bad formatting. Obviously BBCode is not enabled for my account.
thanks for your support and the example code. I meanwhile got it working so far.
Now I'm facing another issue which might be related to the garbage collector or maybe not. The problem occurs when I'm trying to increment a global variable within a C callback function. I can read and print the value of that variable but once I start writing to it I get the python error: "NameError:"
This is how the C function looks like:
[code]
void ext_button_released_callback(uint8_t button_id, bool long_press)
{
pb_button_obj_t *self = MP_STATE_PORT(pb_button_objects)[button_id];
if(mp_const_none != self->callback)
{
gc_lock();
nlr_buf_t nlr;
if(0 == nlr_push(&nlr))
{
mp_call_function_1(self->callback,mp_obj_new_bool(long_press));
nlr_pop();
}
else
{
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
gc_unlock();
}
}
[/code]
Is it somehow possible to modify a global var within a callback function?
Christian
PS: Sorry for the bad formatting. Obviously BBCode is not enabled for my account.
Re: Software interrupt on nRF52832
The formatting will automagically start to work for you after you have enough posts to no longer require moderation.
I don't see any code trying to increment a global. Are you trying to increment a C global? or a python global?
Are you getting the NameError from within the callback? Can you share your python code?
I don't see any code trying to increment a global. Are you trying to increment a C global? or a python global?
Are you getting the NameError from within the callback? Can you share your python code?
Re: Software interrupt on nRF52832
Sorry for the lack of information. What I'm trying to do is to increase/decrease the duty time for a LED pwm.
For this I first create an instance of the button and the LED and register a callback as follows:
When I comment the line "duty = (duty + 5) % 100" in the callback function everything works. The duty value is printed and the led value is set. Once I uncomment it I get the following error:
For sake of readablity I'll attach the C callback function that'll be called on pushing a button:
Maybe there is something wrong/missing here. I recycled it from stmhal/timer.c implementation.
For this I first create an instance of the button and the LED and register a callback as follows:
Code: Select all
import pb
#instantiatte led and buttons
red = pb.LED(0)
record = pb.BUTTON(2)
duty=50
#button callback function
def record_pressed(long_press):
#printing the duty works well
print(duty)
#changing the duty cycle gives error
duty = (duty + 5) % 100
#set the new duty for red LED
red.brightness(duty)
red.callback(record_pressed)
Code: Select all
>>> NameError:
Code: Select all
void ext_button_released_callback(uint8_t button_id, bool long_press)
{
pb_button_obj_t *self = MP_STATE_PORT(pb_button_objects)[button_id];
if(mp_const_none != self->callback)
{
gc_lock();
nlr_buf_t nlr;
if(0 == nlr_push(&nlr))
{
mp_call_function_1(self->callback,mp_obj_new_bool(long_press));
nlr_pop();
}
else
{
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
gc_unlock();
}
}
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Software interrupt on nRF52832
You need
If you assign to a variable in a Python function, and it is not declared as global, Python creates it as a local variable. However your code requires the value to be read, so you get "NameError: local variable referenced before assignment".
Note that a global declaration is not needed if you only intend to read a global variable. If Python fails to find a name in the local namespace it then looks in global.
This is a perennial source of confusion to people new to Python.
Code: Select all
def record_pressed(long_press):
global duty
Note that a global declaration is not needed if you only intend to read a global variable. If Python fails to find a name in the local namespace it then looks in global.
This is a perennial source of confusion to people new to Python.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Software interrupt on nRF52832
Thanks Peter,pythoncoder wrote:You need
However your code requires the value to be read, so you get "NameError: local variable referenced before assignment".
Note that a global declaration is not needed if you only intend to read a global variable. If Python fails to find a name in the local namespace it then looks in global.
This is a perennial source of confusion to people new to Python.
except a few (slight) contacts with python I'm learning python by implementing the modules needed for my custom board
Although I might have used the keyword in the past, I couldn't assign the error since it only says "NameError:" without the meaningful description you pointed out. It would have helped me a lot.
Nevertheless with your suggestion the code is working and I don't need to debug any further. Thank you for that.
Best
Christian
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Software interrupt on nRF52832
Error reporting on the ESP8266 still leaves a lot to be desired and it sounds like the nRF52832 has the same problem. It is confusing. On other MicroPython platforms you get the full message.chrizztus wrote:... I couldn't assign the error since it only says "NameError:" without the meaningful description you pointed out. It would have helped me a lot...
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.