event handling for classes interfacing with hardware components

Hi all,

I have a class that I have in mind to work as a high level interface to operate with buttons for embedded systems. I would like it to be reusable in different projects.

I want the programmer to be able to use the class with state machines and poll pressing events from the user.

I was thinking I could link a state machine event buffer to each class instance, and link events that could be application specific. The programmer could enum the possible events, and set them for each button. This would be an idea for the constructor:

 
      button(int mcu_pin, uint8_t event_buffer, uint8_t short_press_event, uint8_t release_press_event, uint8_t long_press_event);                              // Constructor 


As you can see, each button could trigger an event from being pressed, released, or pressed for a long period of time, and the event would be sent to the buffer belonging to a higher level state machine operating the buttons.

Does this design seem to hold water?

I am mostly concerned about the event variables, I think it looks sleek to pass the events as variables this way, but I am not sure it is a good coding practice. Another example of the in use:


1
2
3
4
5
6
7
8
9
#define CENTRAL_B_PIN (1)
#define STATE_M_BUFFER_SIZE (10)
uint8_t buffer[STATE_M_BUFFER_SIZE];
typedef enum {
 S_EV_NOTHING,  // no event
 S_EV_ENTER,    // enter data entry, ...
 S_EV_SKIP      // skip page, whatever, ...
} StateMachineEvents_t
button centralButton = button(CENTRAL_B_PIN, buffer, S_EV_ENTER, S_EV_NOTHING, S_EV_SKIP);  


In that particular case, the central button would act as enter when pressed, and act as a skip (whatever that would mean in the specific app) when pressed long enough, and nothing would happen upon release.

What are your thoughts, any improvement or different idea you would have in mind?

Thanks a lot!!
If you're dealing with Events, your code will look something like:
1
2
3
4
5
6
7
8
switch (<something>) {
case BUTTON_PRESSED:
    // handle button press
    onButtonPressed(...)
    break;
default:
    onDefaults(...):
}

And this allows you to wrote code like:
1
2
3
MyThing::onButtonPressed(...) {
    // handle button press
}

But that may involve changing your app from a straight procedural flow to and event driven flow. If it's just handling one button press, it may not be worth the effort.
@kbw This would be at the point where the state machine would execute actions from events stored in <something>.

I am actually looking for the cleanest way to store the button events in this <something> variable.

the event buffer receiving the events from the button instances would be the <something> in my scenario, if that makes sense..
Typically you'd have some kind of event id and some associated information. which gives you something like:
1
2
3
4
5
6
struct Event {
    int id;
    // related information
};

The details depends on what the event is, and how you know it's happened.  Then that <something> in 
the pseudo-code above becomes event.id, and you'd pass the Event* to the handler.

It's difficult to be more precise without details.
Last edited on
Topic archived. No new replies allowed.